blob: da6fbb0e9b36d0854d932d56c46ffd75ebe882b1 [file] [log] [blame]
Stephen Boyd322a9922011-09-20 01:05:54 -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
13#include <linux/kernel.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/elf.h>
17#include <linux/delay.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/platform_device.h>
21
22#include <mach/msm_iomap.h>
23
24#include "peripheral-loader.h"
25#include "scm-pas.h"
26
27#define RIVA_PMU_A2XB_CFG 0xB8
28#define RIVA_PMU_A2XB_CFG_EN BIT(0)
29
30#define RIVA_PMU_CFG 0x28
31#define RIVA_PMU_CFG_WARM_BOOT BIT(0)
32#define RIVA_PMU_CFG_IRIS_XO_MODE 0x6
33#define RIVA_PMU_CFG_IRIS_XO_MODE_48 (3 << 1)
34
35#define RIVA_PMU_OVRD_VAL 0x30
36#define RIVA_PMU_OVRD_VAL_CCPU_RESET BIT(0)
37#define RIVA_PMU_OVRD_VAL_CCPU_CLK BIT(1)
38
39#define RIVA_PMU_CCPU_CTL 0x9C
40#define RIVA_PMU_CCPU_CTL_HIGH_IVT BIT(0)
41#define RIVA_PMU_CCPU_CTL_REMAP_EN BIT(2)
42
43#define RIVA_PMU_CCPU_BOOT_REMAP_ADDR 0xA0
44
45#define RIVA_PLL_MODE (MSM_CLK_CTL_BASE + 0x31A0)
46#define PLL_MODE_OUTCTRL BIT(0)
47#define PLL_MODE_BYPASSNL BIT(1)
48#define PLL_MODE_RESET_N BIT(2)
49#define PLL_MODE_REF_XO_SEL 0x30
50#define PLL_MODE_REF_XO_SEL_CXO (2 << 4)
51#define PLL_MODE_REF_XO_SEL_RF (3 << 4)
52#define RIVA_PLL_L_VAL (MSM_CLK_CTL_BASE + 0x31A4)
53#define RIVA_PLL_M_VAL (MSM_CLK_CTL_BASE + 0x31A8)
54#define RIVA_PLL_N_VAL (MSM_CLK_CTL_BASE + 0x31Ac)
55#define RIVA_PLL_CONFIG (MSM_CLK_CTL_BASE + 0x31B4)
56#define RIVA_PLL_STATUS (MSM_CLK_CTL_BASE + 0x31B8)
57
58#define RIVA_PMU_ROOT_CLK_SEL 0xC8
59#define RIVA_PMU_ROOT_CLK_SEL_3 BIT(2)
60
61#define RIVA_PMU_CLK_ROOT3 0x78
62#define RIVA_PMU_CLK_ROOT3_ENA BIT(0)
63#define RIVA_PMU_CLK_ROOT3_SRC0_DIV 0x3C
64#define RIVA_PMU_CLK_ROOT3_SRC0_DIV_2 (1 << 2)
65#define RIVA_PMU_CLK_ROOT3_SRC0_SEL 0x1C0
66#define RIVA_PMU_CLK_ROOT3_SRC0_SEL_RIVA (1 << 6)
67#define RIVA_PMU_CLK_ROOT3_SRC1_DIV 0x1E00
68#define RIVA_PMU_CLK_ROOT3_SRC1_DIV_2 (1 << 9)
69#define RIVA_PMU_CLK_ROOT3_SRC1_SEL 0xE000
70#define RIVA_PMU_CLK_ROOT3_SRC1_SEL_RIVA (1 << 13)
71
72struct riva_data {
73 void __iomem *base;
74 unsigned long start_addr;
75};
76
77static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
78{
79 return 0;
80}
81
82static int pil_riva_init_image(struct pil_desc *pil, const u8 *metadata,
83 size_t size)
84{
85 const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
86 struct riva_data *drv = dev_get_drvdata(pil->dev);
87 drv->start_addr = ehdr->e_entry;
88 return 0;
89}
90
91static int pil_riva_reset(struct pil_desc *pil)
92{
93 u32 reg, sel;
94 bool xo;
95 struct riva_data *drv = dev_get_drvdata(pil->dev);
96 void __iomem *base = drv->base;
97 unsigned long start_addr = drv->start_addr;
98
99 /* Enable A2XB bridge */
100 reg = readl_relaxed(base + RIVA_PMU_A2XB_CFG);
101 reg |= RIVA_PMU_A2XB_CFG_EN;
102 writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
103
104 /* Determine which XO to use */
105 reg = readl_relaxed(base + RIVA_PMU_CFG);
106 xo = (reg & RIVA_PMU_CFG_IRIS_XO_MODE) == RIVA_PMU_CFG_IRIS_XO_MODE_48;
107
108 /* Program PLL 13 to 960 MHz */
109 reg = readl_relaxed(RIVA_PLL_MODE);
110 reg &= ~(PLL_MODE_BYPASSNL | PLL_MODE_OUTCTRL | PLL_MODE_RESET_N);
111 writel_relaxed(reg, RIVA_PLL_MODE);
112
113 if (xo)
114 writel_relaxed(0x40000C00 | 40, RIVA_PLL_L_VAL);
115 else
116 writel_relaxed(0x40000C00 | 50, RIVA_PLL_L_VAL);
117 writel_relaxed(0, RIVA_PLL_M_VAL);
118 writel_relaxed(1, RIVA_PLL_N_VAL);
119 writel_relaxed(0x01495227, RIVA_PLL_CONFIG);
120
121 reg = readl_relaxed(RIVA_PLL_MODE);
122 reg &= ~(PLL_MODE_REF_XO_SEL);
123 reg |= xo ? PLL_MODE_REF_XO_SEL_RF : PLL_MODE_REF_XO_SEL_CXO;
124 writel_relaxed(reg, RIVA_PLL_MODE);
125
126 /* Enable PLL 13 */
127 reg |= PLL_MODE_BYPASSNL;
128 writel_relaxed(reg, RIVA_PLL_MODE);
129
130 /*
131 * H/W requires a 5us delay between disabling the bypass and
132 * de-asserting the reset. Delay 10us just to be safe.
133 */
134 mb();
135 usleep_range(10, 20);
136
137 reg |= PLL_MODE_RESET_N;
138 writel_relaxed(reg, RIVA_PLL_MODE);
139 reg |= PLL_MODE_OUTCTRL;
140 writel_relaxed(reg, RIVA_PLL_MODE);
141
142 /* Wait for PLL to settle */
143 mb();
144 usleep_range(50, 100);
145
146 /* Configure cCPU for 240 MHz */
147 sel = readl_relaxed(base + RIVA_PMU_ROOT_CLK_SEL);
148 reg = readl_relaxed(base + RIVA_PMU_CLK_ROOT3);
149 if (sel & RIVA_PMU_ROOT_CLK_SEL_3) {
150 reg &= ~(RIVA_PMU_CLK_ROOT3_SRC0_SEL |
151 RIVA_PMU_CLK_ROOT3_SRC0_DIV);
152 reg |= RIVA_PMU_CLK_ROOT3_SRC0_SEL_RIVA |
153 RIVA_PMU_CLK_ROOT3_SRC0_DIV_2;
154 } else {
155 reg &= ~(RIVA_PMU_CLK_ROOT3_SRC1_SEL |
156 RIVA_PMU_CLK_ROOT3_SRC1_DIV);
157 reg |= RIVA_PMU_CLK_ROOT3_SRC1_SEL_RIVA |
158 RIVA_PMU_CLK_ROOT3_SRC1_DIV_2;
159 }
160 writel_relaxed(reg, base + RIVA_PMU_CLK_ROOT3);
161 reg |= RIVA_PMU_CLK_ROOT3_ENA;
162 writel_relaxed(reg, base + RIVA_PMU_CLK_ROOT3);
163 reg = readl_relaxed(base + RIVA_PMU_ROOT_CLK_SEL);
164 reg ^= RIVA_PMU_ROOT_CLK_SEL_3;
165 writel_relaxed(reg, base + RIVA_PMU_ROOT_CLK_SEL);
166
167 /* Use the high vector table */
168 reg = readl_relaxed(base + RIVA_PMU_CCPU_CTL);
169 reg |= RIVA_PMU_CCPU_CTL_HIGH_IVT | RIVA_PMU_CCPU_CTL_REMAP_EN;
170 writel_relaxed(reg, base + RIVA_PMU_CCPU_CTL);
171
172 /* Set base memory address */
173 writel_relaxed(start_addr >> 16, base + RIVA_PMU_CCPU_BOOT_REMAP_ADDR);
174
175 /* Clear warmboot bit indicating this is a cold boot */
176 reg = readl_relaxed(base + RIVA_PMU_CFG);
177 reg &= ~(RIVA_PMU_CFG_WARM_BOOT);
178 writel_relaxed(reg, base + RIVA_PMU_CFG);
179
180 /* Enable the cCPU clock */
181 reg = readl_relaxed(base + RIVA_PMU_OVRD_VAL);
182 reg |= RIVA_PMU_OVRD_VAL_CCPU_CLK;
183 writel_relaxed(reg, base + RIVA_PMU_OVRD_VAL);
184
185 /* Take cCPU out of reset */
186 reg |= RIVA_PMU_OVRD_VAL_CCPU_RESET;
187 writel_relaxed(reg, base + RIVA_PMU_OVRD_VAL);
188
189 return 0;
190}
191
192static int pil_riva_shutdown(struct pil_desc *pil)
193{
194 struct riva_data *drv = dev_get_drvdata(pil->dev);
195 u32 reg;
196
197 reg = readl_relaxed(drv->base + RIVA_PMU_OVRD_VAL);
198 reg &= ~(RIVA_PMU_OVRD_VAL_CCPU_RESET | RIVA_PMU_OVRD_VAL_CCPU_CLK);
199 writel_relaxed(reg, drv->base + RIVA_PMU_OVRD_VAL);
200
201 return 0;
202}
203
204static struct pil_reset_ops pil_riva_ops = {
205 .init_image = pil_riva_init_image,
206 .verify_blob = nop_verify_blob,
207 .auth_and_reset = pil_riva_reset,
208 .shutdown = pil_riva_shutdown,
209};
210
211static int pil_riva_init_image_trusted(struct pil_desc *pil,
212 const u8 *metadata, size_t size)
213{
214 return pas_init_image(PAS_RIVA, metadata, size);
215}
216
217static int pil_riva_reset_trusted(struct pil_desc *pil)
218{
219 return pas_auth_and_reset(PAS_RIVA);
220}
221
222static int pil_riva_shutdown_trusted(struct pil_desc *pil)
223{
224 return pas_shutdown(PAS_RIVA);
225}
226
227static struct pil_reset_ops pil_riva_ops_trusted = {
228 .init_image = pil_riva_init_image_trusted,
229 .verify_blob = nop_verify_blob,
230 .auth_and_reset = pil_riva_reset_trusted,
231 .shutdown = pil_riva_shutdown_trusted,
232};
233
234static int __devinit pil_riva_probe(struct platform_device *pdev)
235{
236 struct riva_data *drv;
237 struct resource *res;
238 struct pil_desc *desc;
239
240 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
241 if (!res)
242 return -EINVAL;
243
244 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
245 if (!drv)
246 return -ENOMEM;
247 platform_set_drvdata(pdev, drv);
248
249 drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
250 if (!drv->base)
251 return -ENOMEM;
252
253 desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
254 if (!desc)
255 return -ENOMEM;
256
257 desc->name = "wcnss";
258 desc->dev = &pdev->dev;
259
260 if (pas_supported(PAS_RIVA) > 0) {
261 desc->ops = &pil_riva_ops_trusted;
262 dev_info(&pdev->dev, "using secure boot\n");
263 } else {
264 desc->ops = &pil_riva_ops;
265 dev_info(&pdev->dev, "using non-secure boot\n");
266 }
267 return msm_pil_register(desc);
268}
269
270static int __devexit pil_riva_remove(struct platform_device *pdev)
271{
272 return 0;
273}
274
275static struct platform_driver pil_riva_driver = {
276 .probe = pil_riva_probe,
277 .remove = __devexit_p(pil_riva_remove),
278 .driver = {
279 .name = "pil_riva",
280 .owner = THIS_MODULE,
281 },
282};
283
284static int __init pil_riva_init(void)
285{
286 return platform_driver_register(&pil_riva_driver);
287}
288module_init(pil_riva_init);
289
290static void __exit pil_riva_exit(void)
291{
292 platform_driver_unregister(&pil_riva_driver);
293}
294module_exit(pil_riva_exit);
295
296MODULE_DESCRIPTION("Support for booting RIVA (WCNSS) processors");
297MODULE_LICENSE("GPL v2");