blob: aae0a5dac066f159fdbae56cfacdf2e130beee07 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2020 - Cortina Access Inc.
*
*/
#include <common.h>
#include <init.h>
#include <malloc.h>
#include <errno.h>
#include <netdev.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <configs/presidio_asic.h>
#include <linux/psci.h>
#include <asm/psci.h>
#include <cpu_func.h>
#include <asm/armv8/mmu.h>
DECLARE_GLOBAL_DATA_PTR;
#define CA_PERIPH_BASE 0xE0000000UL
#define CA_PERIPH_SIZE 0x20000000UL
#define CA_GLOBAL_BASE 0xf4320000
#define CA_GLOBAL_JTAG_ID 0xf4320000
#define CA_GLOBAL_BLOCK_RESET 0xf4320004
#define CA_GLOBAL_BLOCK_RESET_RESET_DMA BIT(16)
#define CA_DMA_SEC_SSP_BAUDRATE_CTRL 0xf7001b94
#define CA_DMA_SEC_SSP_ID 0xf7001b80
int print_cpuinfo(void)
{
printf("CPU: Cortina Presidio G3\n");
return 0;
}
static struct mm_region presidio_mem_map[] = {
{
.virt = DDR_BASE,
.phys = DDR_BASE,
.size = PHYS_SDRAM_1_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE
},
{
.virt = CA_PERIPH_BASE,
.phys = CA_PERIPH_BASE,
.size = CA_PERIPH_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
},
{
/* List terminator */
0,
}
};
struct mm_region *mem_map = presidio_mem_map;
static noinline int invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
asm volatile("mov x0, %0\n"
"mov x1, %1\n"
"mov x2, %2\n"
"mov x3, %3\n"
"smc #0\n"
: "+r" (function_id)
: "r" (arg0), "r" (arg1), "r" (arg2)
);
return function_id;
}
int board_early_init_r(void)
{
dcache_disable();
return 0;
}
int board_init(void)
{
unsigned int reg_data, jtag_id;
/* Enable timer */
writel(1, CFG_SYS_TIMER_BASE);
/* Enable snoop in CCI400 slave port#4 */
writel(3, 0xF5595000);
jtag_id = readl(CA_GLOBAL_JTAG_ID);
/* If this is HGU variant then do not use
* the Saturn daughter card ref. clk
*/
if (jtag_id == 0x1010D8F3) {
reg_data = readl(0xF3100064);
/* change multifunc. REF CLK pin to
* a simple GPIO pin
*/
reg_data |= (1 << 1);
writel(reg_data, 0xf3100064);
}
return 0;
}
int dram_init(void)
{
unsigned int ddr_size;
ddr_size = readl(0x111100c);
gd->ram_size = ddr_size * 0x100000;
return 0;
}
void reset_cpu(void)
{
invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
}
#ifdef CONFIG_LAST_STAGE_INIT
int last_stage_init(void)
{
u32 val;
val = readl(CA_GLOBAL_BLOCK_RESET);
val &= ~CA_GLOBAL_BLOCK_RESET_RESET_DMA;
writel(val, CA_GLOBAL_BLOCK_RESET);
/* reduce output pclk ~3.7Hz to save power consumption */
writel(0x000000FF, CA_DMA_SEC_SSP_BAUDRATE_CTRL);
return 0;
}
#endif