1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2004, Psyent Corporation <www.psyent.com> 4 * Scott McNutt <smcnutt@psyent.com> 5 */ 6 7#include <common.h> 8#include <command.h> 9#include <cpu.h> 10#include <cpu_func.h> 11#include <dm.h> 12#include <errno.h> 13#include <event.h> 14#include <init.h> 15#include <irq_func.h> 16#include <asm/cache.h> 17#include <asm/global_data.h> 18#include <asm/system.h> 19 20DECLARE_GLOBAL_DATA_PTR; 21 22#ifdef CONFIG_DISPLAY_CPUINFO 23int print_cpuinfo(void) 24{ 25 printf("CPU: Nios-II\n"); 26 return 0; 27} 28#endif /* CONFIG_DISPLAY_CPUINFO */ 29 30#ifdef CONFIG_ALTERA_SYSID 31int checkboard(void) 32{ 33 display_sysid(); 34 return 0; 35} 36#endif 37 38void reset_cpu(void) 39{ 40 disable_interrupts(); 41 /* indirect call to go beyond 256MB limitation of toolchain */ 42 nios2_callr(gd->arch.reset_addr); 43} 44 45int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 46{ 47 reset_cpu(); 48 49 return 0; 50} 51 52/* 53 * COPY EXCEPTION TRAMPOLINE -- copy the tramp to the 54 * exception address. Define CONFIG_ROM_STUBS to prevent 55 * the copy (e.g. exception in flash or in other 56 * softare/firmware component). 57 */ 58#ifndef CONFIG_ROM_STUBS 59static void copy_exception_trampoline(void) 60{ 61 extern int _except_start, _except_end; 62 void *except_target = (void *)gd->arch.exception_addr; 63 64 if (&_except_start != except_target) { 65 memcpy(except_target, &_except_start, 66 &_except_end - &_except_start); 67 flush_cache(gd->arch.exception_addr, 68 &_except_end - &_except_start); 69 } 70} 71#endif 72 73static int nios_cpu_setup(void) 74{ 75 struct udevice *dev; 76 int ret; 77 78 ret = uclass_first_device_err(UCLASS_CPU, &dev); 79 if (ret) 80 return ret; 81 82 gd->ram_size = CFG_SYS_SDRAM_SIZE; 83#ifndef CONFIG_ROM_STUBS 84 copy_exception_trampoline(); 85#endif 86 87 return 0; 88} 89EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_F, nios_cpu_setup); 90 91static int altera_nios2_get_desc(const struct udevice *dev, char *buf, 92 int size) 93{ 94 const char *cpu_name = "Nios-II"; 95 96 if (size < strlen(cpu_name)) 97 return -ENOSPC; 98 strcpy(buf, cpu_name); 99 100 return 0; 101} 102 103static int altera_nios2_get_info(const struct udevice *dev, 104 struct cpu_info *info) 105{ 106 info->cpu_freq = gd->cpu_clk; 107 info->features = (1 << CPU_FEAT_L1_CACHE) | 108 (gd->arch.has_mmu ? (1 << CPU_FEAT_MMU) : 0); 109 110 return 0; 111} 112 113static int altera_nios2_get_count(const struct udevice *dev) 114{ 115 return 1; 116} 117 118static int altera_nios2_probe(struct udevice *dev) 119{ 120 const void *blob = gd->fdt_blob; 121 int node = dev_of_offset(dev); 122 123 gd->cpu_clk = fdtdec_get_int(blob, node, 124 "clock-frequency", 0); 125 gd->arch.dcache_line_size = fdtdec_get_int(blob, node, 126 "dcache-line-size", 0); 127 gd->arch.icache_line_size = fdtdec_get_int(blob, node, 128 "icache-line-size", 0); 129 gd->arch.dcache_size = fdtdec_get_int(blob, node, 130 "dcache-size", 0); 131 gd->arch.icache_size = fdtdec_get_int(blob, node, 132 "icache-size", 0); 133 gd->arch.reset_addr = fdtdec_get_int(blob, node, 134 "altr,reset-addr", 0); 135 gd->arch.exception_addr = fdtdec_get_int(blob, node, 136 "altr,exception-addr", 0); 137 gd->arch.has_initda = fdtdec_get_int(blob, node, 138 "altr,has-initda", 0); 139 gd->arch.has_mmu = fdtdec_get_int(blob, node, 140 "altr,has-mmu", 0); 141 gd->arch.io_region_base = gd->arch.has_mmu ? 0xe0000000 : 0x80000000; 142 gd->arch.mem_region_base = gd->arch.has_mmu ? 0xc0000000 : 0x00000000; 143 gd->arch.physaddr_mask = gd->arch.has_mmu ? 0x1fffffff : 0x7fffffff; 144 145 return 0; 146} 147 148static const struct cpu_ops altera_nios2_ops = { 149 .get_desc = altera_nios2_get_desc, 150 .get_info = altera_nios2_get_info, 151 .get_count = altera_nios2_get_count, 152}; 153 154static const struct udevice_id altera_nios2_ids[] = { 155 { .compatible = "altr,nios2-1.0" }, 156 { .compatible = "altr,nios2-1.1" }, 157 { } 158}; 159 160U_BOOT_DRIVER(altera_nios2) = { 161 .name = "altera_nios2", 162 .id = UCLASS_CPU, 163 .of_match = altera_nios2_ids, 164 .probe = altera_nios2_probe, 165 .ops = &altera_nios2_ops, 166 .flags = DM_FLAG_PRE_RELOC, 167}; 168 169/* This is a dummy function on nios2 */ 170int dram_init(void) 171{ 172 return 0; 173} 174