blob: 701a3a1f69ff1065b3508fa9328973925a95a316 [file] [log] [blame]
Mayank Grovera49a4c32017-04-20 17:57:15 +05301/* Copyright (c) 2015,2020 The Linux Foundation. All rights reserved.
vijay kumarca1672a2015-04-09 16:45:40 +05302 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <reg.h>
31#include <platform/iomap.h>
32#include <qgic.h>
33#include <qtimer.h>
34#include <mmu.h>
35#include <arch/arm/mmu.h>
36#include <smem.h>
37
vijay kumar689fc9e2015-08-24 15:37:38 +053038#define MB (1024 *1024)
39
40#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
41
42#define A7_SS_SIZE ((A7_SS_END - A7_SS_BASE)/MB)
43
44/* LK memory */
45#define LK_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
46 MMU_MEMORY_AP_READ_WRITE)
47/* Scratch memory - Strongly ordered, non-executable */
48#define SCRATCH_MEMORY (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
49 MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
50/* Peripherals - shared device */
51#define IOMAP_MEMORY (MMU_MEMORY_TYPE_DEVICE_SHARED | \
52 MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
vijay kumar65143242015-11-17 17:43:35 +053053#define SCRATCH_REGION1_VIRT_START_128 0x88000000
54#define SCRATCH_REGION2_VIRT_START_128 (SCRATCH_REGION1_VIRT_START_128 + SCRATCH_REGION1_SIZE_128)
vijay kumar689fc9e2015-08-24 15:37:38 +053055
Mayank Grovera49a4c32017-04-20 17:57:15 +053056#define SCRATCH_REGION2_VIRT_START_256 (SCRATCH_REGION_256 + SCRATCH_REGION_SIZE_256)
57
vijay kumar65143242015-11-17 17:43:35 +053058static void ddr_based_mmu_mappings(mmu_section_t *table, uint32_t table_size);
59static uint64_t ddr_size;
60static void board_ddr_detect();
vijay kumar689fc9e2015-08-24 15:37:38 +053061
62/* Map all the accesssible memory according to the following rules:
63 * 1. Map 1MB from MSM_SHARED_BASE with 1 -1 mapping.
64 * 2. Map MEMBASE - MEMSIZE with 1 -1 mapping.
65 * 3. Map all the scratch regions immediately after Appsbl memory.
66 * Virtual addresses start right after Appsbl Virtual address.
67 * 4. Map all the IOMAP space with 1 - 1 mapping.
68 * 5. Map all the rest of the SDRAM/ IMEM regions as 1 -1.
69 */
70mmu_section_t mmu_section_table[] = {
71/* Physical addr, Virtual addr, Size (in MB), Flags */
72 {MSM_SHARED_BASE, MSM_SHARED_BASE, 1, SCRATCH_MEMORY},
73 {MEMBASE, MEMBASE, MEMSIZE / MB, LK_MEMORY},
74 {MSM_IOMAP_BASE, MSM_IOMAP_BASE, MSM_IOMAP_SIZE, IOMAP_MEMORY},
75 {A7_SS_BASE, A7_SS_BASE, A7_SS_SIZE, IOMAP_MEMORY},
76 {MSM_SHARED_IMEM_BASE, MSM_SHARED_IMEM_BASE, 1, IOMAP_MEMORY},
vijay kumar689fc9e2015-08-24 15:37:38 +053077};
78
vijay kumar65143242015-11-17 17:43:35 +053079mmu_section_t mmu_section_table_128[] = {
80 {SCRATCH_REGION1_128, SCRATCH_REGION1_VIRT_START_128, SCRATCH_REGION1_SIZE_128/ MB, SCRATCH_MEMORY},
81 {SCRATCH_REGION2_128, SCRATCH_REGION2_VIRT_START_128, SCRATCH_REGION2_SIZE_128/ MB, SCRATCH_MEMORY},
82};
83
84mmu_section_t mmu_section_table_256[] = {
Mayank Grovera49a4c32017-04-20 17:57:15 +053085 {SCRATCH_REGION_256, SCRATCH_REGION_256, SCRATCH_REGION_SIZE_256/ MB, SCRATCH_MEMORY},
86 {SCRATCH_REGION2_256, SCRATCH_REGION2_VIRT_START_256, SCRATCH_REGION2_SIZE_256/ MB, SCRATCH_MEMORY},
87 {KERNEL_REGION, KERNEL_REGION, KERNEL_REGION_SIZE/ MB, SCRATCH_MEMORY},
vijay kumar65143242015-11-17 17:43:35 +053088};
89
90static void board_ddr_detect()
91{
92 ddr_size = smem_get_ddr_size();
93 /*128MB DDR*/
94 if(ddr_size == 0x8000000)
95 ddr_based_mmu_mappings(mmu_section_table_128, ARRAY_SIZE(mmu_section_table_128));
96 else
97 ddr_based_mmu_mappings(mmu_section_table_256, ARRAY_SIZE(mmu_section_table_256));
98}
99
vijay kumarca1672a2015-04-09 16:45:40 +0530100void platform_early_init(void)
101{
vijay kumarec490942015-07-23 12:43:54 +0530102 board_init();
103 platform_clock_init();
vijay kumarca1672a2015-04-09 16:45:40 +0530104 qgic_init();
105 qtimer_init();
vijay kumarec490942015-07-23 12:43:54 +0530106 scm_init();
vijay kumar65143242015-11-17 17:43:35 +0530107 board_ddr_detect();
vijay kumarca1672a2015-04-09 16:45:40 +0530108}
109
110void platform_init(void)
111{
112 dprintf(INFO, "platform_init()\n");
113}
114
115void platform_uninit(void)
116{
117 qtimer_uninit();
vijay kumarec490942015-07-23 12:43:54 +0530118 qpic_nand_uninit();
vijay kumarca1672a2015-04-09 16:45:40 +0530119}
120
121uint32_t platform_get_sclk_count(void)
122{
123 return readl(MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL);
124}
125
126addr_t get_bs_info_addr()
127{
128 return ((addr_t)BS_INFO_ADDR);
129}
130
vijay kumar689fc9e2015-08-24 15:37:38 +0530131addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr)
132{
vijay kumar65143242015-11-17 17:43:35 +0530133 uint32_t paddr;
134 uint32_t table_size = ARRAY_SIZE(mmu_section_table);
135 uint32_t limit;
136
137 for (uint32_t i = 0; i < table_size; i++)
138 {
139 limit = (mmu_section_table[i].num_of_sections * MB) - 0x1;
140
141 if (virt_addr >= mmu_section_table[i].vaddress &&
142 virt_addr <= (mmu_section_table[i].vaddress + limit))
143 {
144 paddr = mmu_section_table[i].paddress + (virt_addr - mmu_section_table[i].vaddress);
145 return paddr;
146 }
147 }
148 if(ddr_size == 0x8000000)
149 {
150 table_size = ARRAY_SIZE(mmu_section_table_128);
151 for (uint32_t i = 0; i < table_size; i++)
152 {
153 limit = (mmu_section_table_128[i].num_of_sections * MB) - 0x1;
154
155 if (virt_addr >= mmu_section_table_128[i].vaddress &&
156 virt_addr <= (mmu_section_table_128[i].vaddress + limit))
157 {
158 paddr = mmu_section_table_128[i].paddress + (virt_addr - mmu_section_table_128[i].vaddress);
159 return paddr;
160 }
161 }
162 }
163 else
164 {
165 /* Any DDR > 256MB would be mapped here & LK would use only first 256 MB */
166 table_size = ARRAY_SIZE(mmu_section_table_256);
167 for (uint32_t i = 0; i < table_size; i++)
168 {
169 limit = (mmu_section_table_256[i].num_of_sections * MB) - 0x1;
170
171 if (virt_addr >= mmu_section_table_256[i].vaddress &&
172 virt_addr <= (mmu_section_table_256[i].vaddress + limit))
173 {
174 paddr = mmu_section_table_256[i].paddress + (virt_addr - mmu_section_table_256[i].vaddress);
175 return paddr;
176 }
177 }
178 }
179 /* No special mapping found.
180 * Assume 1-1 mapping.
181 */
182 paddr = virt_addr;
183 return paddr;
184
vijay kumar689fc9e2015-08-24 15:37:38 +0530185}
186
187addr_t platform_get_phys_to_virt_mapping(addr_t phys_addr)
188{
vijay kumar65143242015-11-17 17:43:35 +0530189 uint32_t vaddr;
190 uint32_t table_size = ARRAY_SIZE(mmu_section_table);
191 uint32_t limit;
192
193 for (uint32_t i = 0; i < table_size; i++)
194 {
195 limit = (mmu_section_table[i].num_of_sections * MB) - 0x1;
196
197 if (phys_addr >= mmu_section_table[i].paddress &&
198 phys_addr <= (mmu_section_table[i].paddress + limit))
199 {
200 vaddr = mmu_section_table[i].vaddress + (phys_addr - mmu_section_table[i].paddress);
201 return vaddr;
202 }
203 }
204 if(ddr_size == 0x8000000)
205 {
206 table_size = ARRAY_SIZE(mmu_section_table_128);
207 for (uint32_t i = 0; i < table_size; i++)
208 {
209 limit = (mmu_section_table_128[i].num_of_sections * MB) - 0x1;
210
211 if (phys_addr >= mmu_section_table_128[i].paddress &&
212 phys_addr <= (mmu_section_table_128[i].paddress + limit))
213 {
214 vaddr = mmu_section_table_128[i].vaddress + (phys_addr - mmu_section_table_128[i].paddress);
215 return vaddr;
216 }
217 }
218 }
219 else
220 {
221 /* Any DDR > 256MB would be mapped here & LK would use only first 256 MB */
222 table_size = ARRAY_SIZE(mmu_section_table_256);
223 for (uint32_t i = 0; i < table_size; i++)
224 {
225 limit = (mmu_section_table_256[i].num_of_sections * MB) - 0x1;
226
227 if (phys_addr >= mmu_section_table_256[i].paddress &&
228 phys_addr <= (mmu_section_table_256[i].paddress + limit))
229 {
230 vaddr = mmu_section_table_256[i].vaddress + (phys_addr - mmu_section_table_256[i].paddress);
231 return vaddr;
232 }
233 }
234 }
235
236 /* No special mapping found.
237 * Assume 1-1 mapping.
238 */
239 vaddr = phys_addr;
240
241 return vaddr;
vijay kumar689fc9e2015-08-24 15:37:38 +0530242}
243
244/* Setup memory for this platform */
245void platform_init_mmu_mappings(void)
246{
247 uint32_t i;
248 uint32_t sections;
249 uint32_t table_size = ARRAY_SIZE(mmu_section_table);
250
251 /* Configure the MMU page entries for memory read from the
252 mmu_section_table */
253 for (i = 0; i < table_size; i++)
254 {
255 sections = mmu_section_table[i].num_of_sections;
256
257 while (sections--)
258 {
259 arm_mmu_map_section(mmu_section_table[i].paddress +
260 sections * MB,
261 mmu_section_table[i].vaddress +
262 sections * MB,
263 mmu_section_table[i].flags);
264 }
265 }
266}
vijay kumar65143242015-11-17 17:43:35 +0530267
268/* Setup memory for this platform */
269static void ddr_based_mmu_mappings(mmu_section_t *table,uint32_t table_size)
270{
271 uint32_t i;
272 uint32_t sections;
273
274 /* Configure the MMU page entries for memory read from the
275 mmu_section_table */
276 for (i = 0; i < table_size; i++)
277 {
278 sections = table->num_of_sections;
279
280 while (sections--)
281 {
282 arm_mmu_map_section(table->paddress +
283 sections * MB,
284 table->vaddress +
285 sections * MB,
286 table->flags);
287 }
288 table++;
289 }
290}
291
vijay kumarca1672a2015-04-09 16:45:40 +0530292int platform_use_identity_mmu_mappings(void)
293{
294 /* Use only the mappings specified in this file. */
vijay kumar689fc9e2015-08-24 15:37:38 +0530295 return 0;
vijay kumarca1672a2015-04-09 16:45:40 +0530296}
Mayank Grover42664672017-03-06 17:57:26 +0530297
298bool platform_is_mdm9206()
299{
300 uint32_t platform_id = board_platform_id();
301 bool ret;
302
303 switch(platform_id)
304 {
305 case MDM9206:
306 ret = true;
307 break;
308 default:
309 ret = false;
310 }
311
312 return ret;
313}