blob: 177c80d152ff4179f84be87dee1327b41bcb7f1e [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-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/clk.h>
21#include <linux/timer.h>
22#include <linux/jiffies.h>
Stephen Boyd3f4da322011-08-30 01:03:23 -070023#include <linux/platform_device.h>
24
25#include <asm/mach-types.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070026
27#include <mach/scm.h>
28#include <mach/msm_iomap.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029
30#include "peripheral-loader.h"
Stephen Boyde44ec392011-08-29 12:03:24 -070031#include "scm-pas.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070032
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070033#define PPSS_RESET (MSM_CLK_CTL_BASE + 0x2594)
34#define PPSS_PROC_CLK_CTL (MSM_CLK_CTL_BASE + 0x2588)
35#define CLK_HALT_DFAB_STATE (MSM_CLK_CTL_BASE + 0x2FC8)
36
Stephen Boyd4eb885b2011-09-29 01:16:03 -070037static int dsps_start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070038
Stephen Boyd3f4da322011-08-30 01:03:23 -070039static int init_image_dsps_trusted(struct pil_desc *pil, const u8 *metadata,
Stephen Boyd5bd999a2011-08-02 18:50:57 -070040 size_t size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070041{
Stephen Boyde44ec392011-08-29 12:03:24 -070042 return pas_init_image(PAS_DSPS, metadata, size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043}
44
Stephen Boyd3f4da322011-08-30 01:03:23 -070045static int init_image_dsps_untrusted(struct pil_desc *pil, const u8 *metadata,
Stephen Boyd5bd999a2011-08-02 18:50:57 -070046 size_t size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070047{
48 struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
49 dsps_start = ehdr->e_entry;
50 /* Bring memory and bus interface out of reset */
51 __raw_writel(0x2, PPSS_RESET);
52 mb();
53 return 0;
54}
55
Stephen Boyd3f4da322011-08-30 01:03:23 -070056static int verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070057{
58 return 0;
59}
60
Stephen Boyd3f4da322011-08-30 01:03:23 -070061static int reset_dsps_untrusted(struct pil_desc *pil)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062{
63 __raw_writel(0x10, PPSS_PROC_CLK_CTL);
64 while (__raw_readl(CLK_HALT_DFAB_STATE) & BIT(18))
65 cpu_relax();
66
67 /* Bring DSPS out of reset */
68 __raw_writel(0x0, PPSS_RESET);
69 return 0;
70}
71
Stephen Boyd3f4da322011-08-30 01:03:23 -070072static int reset_dsps_trusted(struct pil_desc *pil)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073{
Stephen Boyde44ec392011-08-29 12:03:24 -070074 return pas_auth_and_reset(PAS_DSPS);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075}
76
Stephen Boyd3f4da322011-08-30 01:03:23 -070077static int shutdown_dsps_trusted(struct pil_desc *pil)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070078{
Stephen Boyde44ec392011-08-29 12:03:24 -070079 return pas_shutdown(PAS_DSPS);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070080}
81
Stephen Boyd3f4da322011-08-30 01:03:23 -070082static int shutdown_dsps_untrusted(struct pil_desc *pil)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083{
84 __raw_writel(0x2, PPSS_RESET);
85 __raw_writel(0x0, PPSS_PROC_CLK_CTL);
86 return 0;
87}
88
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070089struct pil_reset_ops pil_dsps_ops = {
90 .init_image = init_image_dsps_untrusted,
91 .verify_blob = verify_blob,
92 .auth_and_reset = reset_dsps_untrusted,
93 .shutdown = shutdown_dsps_untrusted,
94};
95
Stephen Boyd3f4da322011-08-30 01:03:23 -070096static struct platform_device pil_dsps = {
97 .name = "pil_dsps",
98};
99
100static struct pil_desc pil_dsps_desc = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700101 .name = "dsps",
Stephen Boyd3f4da322011-08-30 01:03:23 -0700102 .dev = &pil_dsps.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700103 .ops = &pil_dsps_ops,
104};
105
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700106static int __init msm_peripheral_reset_init(void)
107{
Stephen Boyde44ec392011-08-29 12:03:24 -0700108 if (pas_supported(PAS_DSPS) > 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700109 pil_dsps_ops.init_image = init_image_dsps_trusted;
110 pil_dsps_ops.auth_and_reset = reset_dsps_trusted;
111 pil_dsps_ops.shutdown = shutdown_dsps_trusted;
112 }
113
Stephen Boyd3f4da322011-08-30 01:03:23 -0700114 if (machine_is_msm8x60_fluid())
115 pil_dsps_desc.name = "dsps_fluid";
116 BUG_ON(platform_device_register(&pil_dsps));
117 BUG_ON(msm_pil_register(&pil_dsps_desc));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700118
119 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120}
121
122arch_initcall(msm_peripheral_reset_init);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700123
124MODULE_LICENSE("GPL v2");
125MODULE_DESCRIPTION("Validate and bring peripherals out of reset");