10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/stddef.h>
15 #include <linux/string.h>
16 #include <asm/cputype.h>
18 #include <asm/memory.h>
23 static bool dtcm_present;
24 static bool itcm_present;
53 .virtual = DTCM_OFFSET,
60 static struct map_desc itcm_iomap[] __initdata = {
83 return (
void *)
vaddr;
111 const int tcm_sizes[16] = { 0, -1, -1, 4, 8, 16, 32, 64, 128,
112 256, 512, 1024, -1, -1, -1, -1 };
122 asm(
"mcr p15, 0, %0, c9, c2, 0"
128 asm(
"mrc p15, 0, %0, c9, c1, 0"
129 :
"=r" (tcm_region));
131 asm(
"mrc p15, 0, %0, c9, c1, 1"
132 :
"=r" (tcm_region));
134 tcm_size = tcm_sizes[(tcm_region >> 2) & 0x0f];
136 pr_err(
"CPU: %sTCM%d of unknown size\n",
137 type ?
"I" :
"D", bank);
139 }
else if (tcm_size > 32) {
140 pr_err(
"CPU: %sTCM%d larger than 32k found\n",
141 type ?
"I" :
"D", bank);
144 pr_info(
"CPU: found %sTCM%d %dk @ %08x, %senabled\n",
148 (tcm_region & 0xfffff000U),
149 (tcm_region & 1) ?
"" :
"not ");
157 tcm_region = *offset | (tcm_region & 0x00000ffe
U) | 1;
160 asm(
"mcr p15, 0, %0, c9, c1, 0"
164 asm(
"mcr p15, 0, %0, c9, c1, 1"
169 *offset += (tcm_size << 10);
171 pr_info(
"CPU: moved %sTCM%d %dk to %08x, enabled\n",
175 (tcm_region & 0xfffff000U));
200 if (dtcm_code_sz || itcm_code_sz)
201 pr_info(
"CPU TCM: %u bytes of DTCM and %u bytes of "
202 "ITCM code compiled in, but no TCM present "
203 "in pre-v5 CPU\n", dtcm_code_sz, itcm_code_sz);
207 tcm_status = read_cpuid_tcmstatus();
208 dtcm_banks = (tcm_status >> 16) & 0x03;
209 itcm_banks = (tcm_status & 0x03);
218 if (dtcm_banks > 0) {
219 for (i = 0; i < dtcm_banks; i++) {
220 ret = setup_tcm_bank(0, i, dtcm_banks, &
dtcm_end);
225 if (dtcm_code_sz > (
dtcm_end - DTCM_OFFSET)) {
226 pr_info(
"CPU DTCM: %u bytes of code compiled to "
227 "DTCM but only %lu bytes of DTCM present\n",
228 dtcm_code_sz, (
dtcm_end - DTCM_OFFSET));
233 dtcm_iomap[0].length =
dtcm_end - DTCM_OFFSET;
236 start = &__sdtcm_data;
239 memcpy(start, ram, dtcm_code_sz);
240 pr_debug(
"CPU DTCM: copied data from %p - %p\n",
243 }
else if (dtcm_code_sz) {
244 pr_info(
"CPU DTCM: %u bytes of code compiled to DTCM but no "
245 "DTCM banks present in CPU\n", dtcm_code_sz);
250 if (itcm_banks > 0) {
251 for (i = 0; i < itcm_banks; i++) {
252 ret = setup_tcm_bank(1, i, itcm_banks, &
itcm_end);
257 if (itcm_code_sz > (
itcm_end - ITCM_OFFSET)) {
258 pr_info(
"CPU ITCM: %u bytes of code compiled to "
259 "ITCM but only %lu bytes of ITCM present\n",
260 itcm_code_sz, (
itcm_end - ITCM_OFFSET));
265 itcm_iomap[0].length =
itcm_end - ITCM_OFFSET;
268 start = &__sitcm_text;
271 memcpy(start, ram, itcm_code_sz);
272 pr_debug(
"CPU ITCM: copied code from %p - %p\n",
275 }
else if (itcm_code_sz) {
276 pr_info(
"CPU ITCM: %u bytes of code compiled to ITCM but no "
277 "ITCM banks present in CPU\n", itcm_code_sz);
286 static int __init setup_tcm_pool(
void)
288 u32 dtcm_pool_start = (
u32) &__edtcm_data;
289 u32 itcm_pool_start = (
u32) &__eitcm_text;
299 pr_debug(
"Setting up TCM memory pool\n");
304 ret = gen_pool_add(tcm_pool, dtcm_pool_start,
307 pr_err(
"CPU DTCM: could not add DTCM " \
308 "remainder to pool!\n");
311 pr_debug(
"CPU DTCM: Added %08x bytes @ %08x to " \
312 "the TCM memory pool\n",
321 ret = gen_pool_add(tcm_pool, itcm_pool_start,
324 pr_err(
"CPU ITCM: could not add ITCM " \
325 "remainder to pool!\n");
328 pr_debug(
"CPU ITCM: Added %08x bytes @ %08x to " \
329 "the TCM memory pool\n",