1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 265fcba12SAlexey Brodkin /* 365fcba12SAlexey Brodkin * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. 465fcba12SAlexey Brodkin */ 565fcba12SAlexey Brodkin 665fcba12SAlexey Brodkin #include <common.h> 765fcba12SAlexey Brodkin #include <dwmmc.h> 865fcba12SAlexey Brodkin #include <malloc.h> 92a5062caSAlexey Brodkin #include <asm/arcregs.h> 1065fcba12SAlexey Brodkin #include "axs10x.h" 1165fcba12SAlexey Brodkin 1265fcba12SAlexey Brodkin DECLARE_GLOBAL_DATA_PTR; 1365fcba12SAlexey Brodkin 1465fcba12SAlexey Brodkin int board_mmc_init(bd_t *bis) 1565fcba12SAlexey Brodkin { 1665fcba12SAlexey Brodkin struct dwmci_host *host = NULL; 1765fcba12SAlexey Brodkin 1865fcba12SAlexey Brodkin host = malloc(sizeof(struct dwmci_host)); 1965fcba12SAlexey Brodkin if (!host) { 2065fcba12SAlexey Brodkin printf("dwmci_host malloc fail!\n"); 2165fcba12SAlexey Brodkin return 1; 2265fcba12SAlexey Brodkin } 2365fcba12SAlexey Brodkin 2465fcba12SAlexey Brodkin memset(host, 0, sizeof(struct dwmci_host)); 2565fcba12SAlexey Brodkin host->name = "Synopsys Mobile storage"; 2665fcba12SAlexey Brodkin host->ioaddr = (void *)ARC_DWMMC_BASE; 2765fcba12SAlexey Brodkin host->buswidth = 4; 2865fcba12SAlexey Brodkin host->dev_index = 0; 2965fcba12SAlexey Brodkin host->bus_hz = 50000000; 3065fcba12SAlexey Brodkin 3165fcba12SAlexey Brodkin add_dwmci(host, host->bus_hz / 2, 400000); 3265fcba12SAlexey Brodkin 3365fcba12SAlexey Brodkin return 0; 3465fcba12SAlexey Brodkin } 3565fcba12SAlexey Brodkin 3665fcba12SAlexey Brodkin #define AXS_MB_CREG 0xE0011000 3765fcba12SAlexey Brodkin 3865fcba12SAlexey Brodkin int board_early_init_f(void) 3965fcba12SAlexey Brodkin { 4065fcba12SAlexey Brodkin if (readl((void __iomem *)AXS_MB_CREG + 0x234) & (1 << 28)) 4165fcba12SAlexey Brodkin gd->board_type = AXS_MB_V3; 4265fcba12SAlexey Brodkin else 4365fcba12SAlexey Brodkin gd->board_type = AXS_MB_V2; 4465fcba12SAlexey Brodkin 4565fcba12SAlexey Brodkin return 0; 4665fcba12SAlexey Brodkin } 4765fcba12SAlexey Brodkin 4865fcba12SAlexey Brodkin #ifdef CONFIG_ISA_ARCV2 49f665c14fSEugeniy Paltsev 50f665c14fSEugeniy Paltsev void board_jump_and_run(ulong entry, int zero, int arch, uint params) 51f665c14fSEugeniy Paltsev { 52f665c14fSEugeniy Paltsev void (*kernel_entry)(int zero, int arch, uint params); 53f665c14fSEugeniy Paltsev 54f665c14fSEugeniy Paltsev kernel_entry = (void (*)(int, int, uint))entry; 55f665c14fSEugeniy Paltsev 56f665c14fSEugeniy Paltsev smp_set_core_boot_addr(entry, -1); 57f665c14fSEugeniy Paltsev smp_kick_all_cpus(); 58f665c14fSEugeniy Paltsev kernel_entry(zero, arch, params); 59f665c14fSEugeniy Paltsev } 60f665c14fSEugeniy Paltsev 6165fcba12SAlexey Brodkin #define RESET_VECTOR_ADDR 0x0 6265fcba12SAlexey Brodkin 6365fcba12SAlexey Brodkin void smp_set_core_boot_addr(unsigned long addr, int corenr) 6465fcba12SAlexey Brodkin { 6565fcba12SAlexey Brodkin /* All cores have reset vector pointing to 0 */ 6665fcba12SAlexey Brodkin writel(addr, (void __iomem *)RESET_VECTOR_ADDR); 6765fcba12SAlexey Brodkin 6865fcba12SAlexey Brodkin /* Make sure other cores see written value in memory */ 6965fcba12SAlexey Brodkin flush_dcache_all(); 7065fcba12SAlexey Brodkin } 7165fcba12SAlexey Brodkin 7265fcba12SAlexey Brodkin void smp_kick_all_cpus(void) 7365fcba12SAlexey Brodkin { 7465fcba12SAlexey Brodkin /* CPU start CREG */ 7565fcba12SAlexey Brodkin #define AXC003_CREG_CPU_START 0xF0001400 7665fcba12SAlexey Brodkin /* Bits positions in CPU start CREG */ 7765fcba12SAlexey Brodkin #define BITS_START 0 780b0db98bSAlexey Brodkin #define BITS_START_MODE 4 7965fcba12SAlexey Brodkin #define BITS_CORE_SEL 9 8065fcba12SAlexey Brodkin 812a5062caSAlexey Brodkin /* 822a5062caSAlexey Brodkin * In axs103 v1.1 START bits semantics has changed quite a bit. 832a5062caSAlexey Brodkin * We used to have a generic START bit for all cores selected by CORE_SEL mask. 842a5062caSAlexey Brodkin * But now we don't touch CORE_SEL at all because we have a dedicated START bit 852a5062caSAlexey Brodkin * for each core: 862a5062caSAlexey Brodkin * bit 0: Core 0 (master) 872a5062caSAlexey Brodkin * bit 1: Core 1 (slave) 882a5062caSAlexey Brodkin */ 892a5062caSAlexey Brodkin #define BITS_START_CORE1 1 902a5062caSAlexey Brodkin 912a5062caSAlexey Brodkin #define ARCVER_HS38_3_0 0x53 922a5062caSAlexey Brodkin 932a5062caSAlexey Brodkin int core_family = read_aux_reg(ARC_AUX_IDENTITY) & 0xff; 940b0db98bSAlexey Brodkin int cmd = readl((void __iomem *)AXC003_CREG_CPU_START); 952a5062caSAlexey Brodkin 962a5062caSAlexey Brodkin if (core_family < ARCVER_HS38_3_0) { 970b0db98bSAlexey Brodkin cmd |= (1 << BITS_CORE_SEL) | (1 << BITS_START); 980b0db98bSAlexey Brodkin cmd &= ~(1 << BITS_START_MODE); 992a5062caSAlexey Brodkin } else { 1002a5062caSAlexey Brodkin cmd |= (1 << BITS_START_CORE1); 1012a5062caSAlexey Brodkin } 1020b0db98bSAlexey Brodkin writel(cmd, (void __iomem *)AXC003_CREG_CPU_START); 10365fcba12SAlexey Brodkin } 10465fcba12SAlexey Brodkin #endif 105