blob: 9ef0c1823f4c6dba0b9a59e795a1f470b5f5bc52 [file] [log] [blame]
Dima Zavina404bce2009-01-26 12:32:22 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 *
lijuangd1175052015-08-13 16:41:12 +08005 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -07006 *
Dima Zavina404bce2009-01-26 12:32:22 -08007 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <debug.h>
32#include <reg.h>
33#include <sys/types.h>
34#include <platform/iomap.h>
lijuangd1175052015-08-13 16:41:12 +080035#include <board.h>
Dima Zavina404bce2009-01-26 12:32:22 -080036
37#include "smem.h"
38
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -070039static struct smem *smem;
Dima Zavina404bce2009-01-26 12:32:22 -080040
lijuangd1175052015-08-13 16:41:12 +080041const char *hw_platform[] = {
42 [HW_PLATFORM_UNKNOWN] = "Unknown",
43 [HW_PLATFORM_SURF] = "Surf",
44 [HW_PLATFORM_FFA] = "FFA",
45 [HW_PLATFORM_FLUID] = "Fluid",
46 [HW_PLATFORM_SVLTE] = "SVLTE",
47 [HW_PLATFORM_MTP_MDM] = "MDM_MTP_NO_DISPLAY",
48 [HW_PLATFORM_MTP] = "MTP",
49 [HW_PLATFORM_RCM] = "RCM",
50 [HW_PLATFORM_LIQUID] = "Liquid",
51 [HW_PLATFORM_DRAGON] = "Dragon",
52 [HW_PLATFORM_QRD] = "QRD",
53 [HW_PLATFORM_HRD] = "HRD",
54 [HW_PLATFORM_DTV] = "DTV",
55 [HW_PLATFORM_STP] = "STP",
56 [HW_PLATFORM_SBC] = "SBC",
57};
58
Channagoud Kadabi9e574882014-06-24 16:15:23 -070059/* DYNAMIC SMEM REGION feature enables LK to dynamically
60 * read the SMEM addr info from TCSR register or IMEM location.
61 * The first word read, if indicates a MAGIC number, then
62 * Dynamic SMEM is assumed to be enabled. Read the remaining
63 * SMEM info for SMEM Size and Phy_addr from the other bytes.
64 */
65
66#if DYNAMIC_SMEM
67uint32_t smem_get_base_addr()
68{
69 struct smem_addr_info *smem_info = NULL;
70
71 smem_info = (struct smem_addr_info *) SMEM_TARG_INFO_ADDR;
72 if(smem_info && (smem_info->identifier == SMEM_TARGET_INFO_IDENTIFIER))
73 return smem_info->phy_addr;
74 else
75 return MSM_SHARED_BASE;
76}
77#endif
78
Ajay Dudanic78b36f2010-07-08 19:34:06 -070079/* buf MUST be 4byte aligned, and len MUST be a multiple of 8. */
Dima Zavina404bce2009-01-26 12:32:22 -080080unsigned smem_read_alloc_entry(smem_mem_type_t type, void *buf, int len)
81{
82 struct smem_alloc_info *ainfo;
83 unsigned *dest = buf;
84 unsigned src;
85 unsigned size;
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -070086 uint32_t smem_addr = 0;
87
Channagoud Kadabi9e574882014-06-24 16:15:23 -070088#if DYNAMIC_SMEM
89 smem_addr = smem_get_base_addr();
90#else
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -070091 smem_addr = platform_get_smem_base_addr();
Channagoud Kadabi9e574882014-06-24 16:15:23 -070092#endif
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -070093
94 smem = (struct smem *)smem_addr;
Dima Zavina404bce2009-01-26 12:32:22 -080095
96 if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0))
97 return 1;
98
99 if (type < SMEM_FIRST_VALID_TYPE || type > SMEM_LAST_VALID_TYPE)
100 return 1;
101
102 /* TODO: Use smem spinlocks */
103 ainfo = &smem->alloc_info[type];
104 if (readl(&ainfo->allocated) == 0)
105 return 1;
106
Ajay Dudanic78b36f2010-07-08 19:34:06 -0700107 size = readl(&ainfo->size);
108
Sridhar Parasuramd63ea9c2014-10-22 12:39:11 -0700109 if (size < (unsigned)((len + 7) & ~0x00000007))
Dima Zavina404bce2009-01-26 12:32:22 -0800110 return 1;
111
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -0700112 src = smem_addr + readl(&ainfo->offset);
Ajay Dudanic78b36f2010-07-08 19:34:06 -0700113 for (; len > 0; src += 4, len -= 4)
Dima Zavina404bce2009-01-26 12:32:22 -0800114 *(dest++) = readl(src);
115
116 return 0;
117}
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800118
Sundarajan Srinivasan28106e32014-07-24 16:39:58 -0700119/* Return a pointer to smem_item with size */
120void* smem_get_alloc_entry(smem_mem_type_t type, uint32_t* size)
121{
122 struct smem_alloc_info *ainfo = NULL;
123 uint32_t smem_addr = 0;
124 uint32_t base_ext = 0;
125 uint32_t offset = 0;
vijay kumar4f4405f2014-08-08 11:49:53 +0530126 void *ret = NULL;
Sundarajan Srinivasan28106e32014-07-24 16:39:58 -0700127
128#if DYNAMIC_SMEM
129 smem_addr = smem_get_base_addr();
130#else
131 smem_addr = platform_get_smem_base_addr();
132#endif
133 smem = (struct smem *)smem_addr;
134
135 if (type < SMEM_FIRST_VALID_TYPE || type > SMEM_LAST_VALID_TYPE)
vijay kumar4f4405f2014-08-08 11:49:53 +0530136 return ret;
Sundarajan Srinivasan28106e32014-07-24 16:39:58 -0700137
138 ainfo = &smem->alloc_info[type];
139 if (readl(&ainfo->allocated) == 0)
vijay kumar4f4405f2014-08-08 11:49:53 +0530140 return ret;
Sundarajan Srinivasan28106e32014-07-24 16:39:58 -0700141
142 *size = readl(&ainfo->size);
143 base_ext = readl(&ainfo->base_ext);
144 offset = readl(&ainfo->offset);
145
146 if(base_ext)
147 {
vijay kumar4f4405f2014-08-08 11:49:53 +0530148 ret = (void*)base_ext + offset;
Sundarajan Srinivasan28106e32014-07-24 16:39:58 -0700149 }
150 else
151 {
152 ret = (void*) smem_addr + offset;
153 }
154
155 return ret;
156}
157
Ajay Dudanib01e5062011-12-03 23:23:42 -0800158unsigned
159smem_read_alloc_entry_offset(smem_mem_type_t type, void *buf, int len,
160 int offset)
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800161{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800162 struct smem_alloc_info *ainfo;
163 unsigned *dest = buf;
164 unsigned src;
165 unsigned size = len;
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -0700166 uint32_t smem_addr = 0;
167
Channagoud Kadabi9e574882014-06-24 16:15:23 -0700168#if DYNAMIC_SMEM
169 smem_addr = smem_get_base_addr();
170#else
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -0700171 smem_addr = platform_get_smem_base_addr();
Channagoud Kadabi9e574882014-06-24 16:15:23 -0700172#endif
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -0700173
174 smem = (struct smem *)smem_addr;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800175
Ajay Dudanib01e5062011-12-03 23:23:42 -0800176 if (((len & 0x3) != 0) || (((unsigned)buf & 0x3) != 0))
177 return 1;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800178
Ajay Dudanib01e5062011-12-03 23:23:42 -0800179 if (type < SMEM_FIRST_VALID_TYPE || type > SMEM_LAST_VALID_TYPE)
180 return 1;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800181
Ajay Dudanib01e5062011-12-03 23:23:42 -0800182 ainfo = &smem->alloc_info[type];
183 if (readl(&ainfo->allocated) == 0)
184 return 1;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800185
Sundarajan Srinivasan79e5f512014-03-28 16:43:06 -0700186 src = smem_addr + readl(&ainfo->offset) + offset;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800187 for (; size > 0; src += 4, size -= 4)
188 *(dest++) = readl(src);
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800189
Ajay Dudanib01e5062011-12-03 23:23:42 -0800190 return 0;
Chandan Uddaraju1434a602010-03-08 17:13:38 -0800191}
lijuangd1175052015-08-13 16:41:12 +0800192
193size_t smem_get_hw_platform_name(void *buf, uint32 buf_size)
194{
195 uint32 hw_id;
196
197 if (buf == NULL) {
198 dprintf(CRITICAL, "ERROR: buf is NULL\n");
199 return 1;
200 }
201
202 hw_id = board_hardware_id();
203 if (buf_size < strlen(hw_platform[hw_id]) + 1)
204 return 1;
205
206 return snprintf(buf, strlen(hw_platform[hw_id]) + 1,
207 "%s\n", hw_platform[hw_id]);
208}