}
EXPORT_SYMBOL(tcm_free);
-
-static void __init setup_tcm_bank(u8 type, u32 offset, u32 expected_size)
+static void __init setup_tcm_bank(u8 type, u8 bank, u8 banks,
+ u32 offset, u32 expected_size)
{
const int tcm_sizes[16] = { 0, -1, -1, 4, 8, 16, 32, 64, 128,
256, 512, 1024, -1, -1, -1, -1 };
u32 tcm_region;
int tcm_size;
+ /*
+ * If there are more than one TCM bank of this type,
+ * select the TCM bank to operate on in the TCM selection
+ * register.
+ */
+ if (banks > 1)
+ asm("mcr p15, 0, %0, c9, c2, 0"
+ : /* No output operands */
+ : "r" (bank));
+
/* Read the special TCM region register c9, 0 */
if (!type)
asm("mrc p15, 0, %0, c9, c1, 0"
tcm_size = tcm_sizes[(tcm_region >> 2) & 0x0f];
if (tcm_size < 0) {
- pr_err("CPU: %sTCM of unknown size!\n",
- type ? "I" : "D");
+ pr_err("CPU: %sTCM%d of unknown size!\n",
+ type ? "I" : "D", bank);
} else {
- pr_info("CPU: found %sTCM %dk @ %08x, %senabled\n",
+ pr_info("CPU: found %sTCM%d %dk @ %08x, %senabled\n",
type ? "I" : "D",
+ bank,
tcm_size,
(tcm_region & 0xfffff000U),
(tcm_region & 1) ? "" : "not ");
}
- if (tcm_size != expected_size) {
- pr_crit("CPU: %sTCM was detected %dk but expected %dk!\n",
- type ? "I" : "D",
- tcm_size,
- expected_size);
+ if (tcm_size != (expected_size >> 10)) {
+ pr_crit("CPU: %sTCM%d was detected %dk but expected %dk!\n",
+ type ? "I" : "D",
+ bank,
+ tcm_size,
+ (expected_size >> 10));
/* Adjust to the expected size? what can we do... */
}
: /* No output operands */
: "r" (tcm_region));
- pr_debug("CPU: moved %sTCM %dk to %08x, enabled\n",
- type ? "I" : "D",
- tcm_size,
- (tcm_region & 0xfffff000U));
+ pr_info("CPU: moved %sTCM%d %dk to %08x, enabled\n",
+ type ? "I" : "D",
+ bank,
+ tcm_size,
+ (tcm_region & 0xfffff000U));
}
+/* We expect to find what is configured for the platform */
+#define DTCM_EXPECTED (DTCM_END - DTCM_OFFSET + 1)
+#define ITCM_EXPECTED (ITCM_END - ITCM_OFFSET + 1)
+
/*
* This initializes the TCM memory
*/
void __init tcm_init(void)
{
u32 tcm_status = read_cpuid_tcmstatus();
+ u8 dtcm_banks = (tcm_status >> 16) & 0x03;
+ u32 dtcm_banksize = DTCM_EXPECTED / dtcm_banks;
+ u8 itcm_banks = (tcm_status & 0x03);
+ u32 itcm_banksize = ITCM_EXPECTED / itcm_banks;
char *start;
char *end;
char *ram;
+ int i;
/* Setup DTCM if present */
- if (tcm_status & (1 << 16)) {
- setup_tcm_bank(0, DTCM_OFFSET,
- (DTCM_END - DTCM_OFFSET + 1) >> 10);
+ for (i = 0; i < dtcm_banks; i++) {
+ setup_tcm_bank(0, i, dtcm_banks,
+ DTCM_OFFSET + (i * dtcm_banksize),
+ dtcm_banksize);
request_resource(&iomem_resource, &dtcm_res);
iotable_init(dtcm_iomap, 1);
/* Copy data from RAM to DTCM */
}
/* Setup ITCM if present */
- if (tcm_status & 1) {
- setup_tcm_bank(1, ITCM_OFFSET,
- (ITCM_END - ITCM_OFFSET + 1) >> 10);
+ for (i = 0; i < itcm_banks; i++) {
+ setup_tcm_bank(1, i, itcm_banks,
+ ITCM_OFFSET + (i * itcm_banksize),
+ itcm_banksize);
request_resource(&iomem_resource, &itcm_res);
iotable_init(itcm_iomap, 1);
/* Copy code from RAM to ITCM */
pr_debug("Setting up TCM memory pool\n");
/* Add the rest of DTCM to the TCM pool */
- if (tcm_status & (1 << 16)) {
+ if (tcm_status & (0x03 << 16)) {
if (dtcm_pool_start < DTCM_END) {
ret = gen_pool_add(tcm_pool, dtcm_pool_start,
DTCM_END - dtcm_pool_start + 1, -1);
}
/* Add the rest of ITCM to the TCM pool */
- if (tcm_status & 1) {
+ if (tcm_status & 0x03) {
if (itcm_pool_start < ITCM_END) {
ret = gen_pool_add(tcm_pool, itcm_pool_start,
ITCM_END - itcm_pool_start + 1, -1);