1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/highmem.h>
4 #include <linux/genalloc.h>
5 #include <asm/tlbflush.h>
6 #include <asm/fixmap.h>
8 #if (CONFIG_ITCM_RAM_BASE == 0xffffffff)
9 #error "You should define ITCM_RAM_BASE"
12 #ifdef CONFIG_HAVE_DTCM
13 #if (CONFIG_DTCM_RAM_BASE == 0xffffffff)
14 #error "You should define DTCM_RAM_BASE"
17 #if (CONFIG_DTCM_RAM_BASE == CONFIG_ITCM_RAM_BASE)
18 #error "You should define correct DTCM_RAM_BASE"
22 extern char __tcm_start
, __tcm_end
, __dtcm_start
;
24 static struct gen_pool
*tcm_pool
;
26 static void __init
tcm_mapping_init(void)
29 unsigned long vaddr
, paddr
;
32 paddr
= CONFIG_ITCM_RAM_BASE
;
34 if (pfn_valid(PFN_DOWN(CONFIG_ITCM_RAM_BASE
)))
37 #ifndef CONFIG_HAVE_DTCM
38 for (i
= 0; i
< TCM_NR_PAGES
; i
++) {
40 for (i
= 0; i
< CONFIG_ITCM_NR_PAGES
; i
++) {
42 vaddr
= __fix_to_virt(FIX_TCM
- i
);
45 pte_offset_kernel((pmd_t
*)pgd_offset_k(vaddr
), vaddr
);
47 set_pte(tcm_pte
, pfn_pte(__phys_to_pfn(paddr
), PAGE_KERNEL
));
51 paddr
= paddr
+ PAGE_SIZE
;
54 #ifdef CONFIG_HAVE_DTCM
55 if (pfn_valid(PFN_DOWN(CONFIG_DTCM_RAM_BASE
)))
58 paddr
= CONFIG_DTCM_RAM_BASE
;
60 for (i
= 0; i
< CONFIG_DTCM_NR_PAGES
; i
++) {
61 vaddr
= __fix_to_virt(FIX_TCM
- CONFIG_ITCM_NR_PAGES
- i
);
64 pte_offset_kernel((pmd_t
*) pgd_offset_k(vaddr
), vaddr
);
66 set_pte(tcm_pte
, pfn_pte(__phys_to_pfn(paddr
), PAGE_KERNEL
));
70 paddr
= paddr
+ PAGE_SIZE
;
74 #ifndef CONFIG_HAVE_DTCM
75 memcpy((void *)__fix_to_virt(FIX_TCM
),
76 &__tcm_start
, &__tcm_end
- &__tcm_start
);
78 pr_info("%s: mapping tcm va:0x%08lx to pa:0x%08x\n",
79 __func__
, __fix_to_virt(FIX_TCM
), CONFIG_ITCM_RAM_BASE
);
81 pr_info("%s: __tcm_start va:0x%08lx size:%d\n",
82 __func__
, (unsigned long)&__tcm_start
, &__tcm_end
- &__tcm_start
);
84 memcpy((void *)__fix_to_virt(FIX_TCM
),
85 &__tcm_start
, &__dtcm_start
- &__tcm_start
);
87 pr_info("%s: mapping itcm va:0x%08lx to pa:0x%08x\n",
88 __func__
, __fix_to_virt(FIX_TCM
), CONFIG_ITCM_RAM_BASE
);
90 pr_info("%s: __itcm_start va:0x%08lx size:%d\n",
91 __func__
, (unsigned long)&__tcm_start
, &__dtcm_start
- &__tcm_start
);
93 memcpy((void *)__fix_to_virt(FIX_TCM
- CONFIG_ITCM_NR_PAGES
),
94 &__dtcm_start
, &__tcm_end
- &__dtcm_start
);
96 pr_info("%s: mapping dtcm va:0x%08lx to pa:0x%08x\n",
97 __func__
, __fix_to_virt(FIX_TCM
- CONFIG_ITCM_NR_PAGES
),
98 CONFIG_DTCM_RAM_BASE
);
100 pr_info("%s: __dtcm_start va:0x%08lx size:%d\n",
101 __func__
, (unsigned long)&__dtcm_start
, &__tcm_end
- &__dtcm_start
);
106 panic("TCM init error");
109 void *tcm_alloc(size_t len
)
116 vaddr
= gen_pool_alloc(tcm_pool
, len
);
120 return (void *) vaddr
;
122 EXPORT_SYMBOL(tcm_alloc
);
124 void tcm_free(void *addr
, size_t len
)
126 gen_pool_free(tcm_pool
, (unsigned long) addr
, len
);
128 EXPORT_SYMBOL(tcm_free
);
130 static int __init
tcm_setup_pool(void)
132 #ifndef CONFIG_HAVE_DTCM
133 u32 pool_size
= (u32
) (TCM_NR_PAGES
* PAGE_SIZE
)
134 - (u32
) (&__tcm_end
- &__tcm_start
);
136 u32 tcm_pool_start
= __fix_to_virt(FIX_TCM
)
137 + (u32
) (&__tcm_end
- &__tcm_start
);
139 u32 pool_size
= (u32
) (CONFIG_DTCM_NR_PAGES
* PAGE_SIZE
)
140 - (u32
) (&__tcm_end
- &__dtcm_start
);
142 u32 tcm_pool_start
= __fix_to_virt(FIX_TCM
- CONFIG_ITCM_NR_PAGES
)
143 + (u32
) (&__tcm_end
- &__dtcm_start
);
147 tcm_pool
= gen_pool_create(2, -1);
149 ret
= gen_pool_add(tcm_pool
, tcm_pool_start
, pool_size
, -1);
151 pr_err("%s: gen_pool add failed!\n", __func__
);
155 pr_info("%s: Added %d bytes @ 0x%08x to memory pool\n",
156 __func__
, pool_size
, tcm_pool_start
);
161 static int __init
tcm_init(void)
169 arch_initcall(tcm_init
);