14c835a60SStefan Roese // SPDX-License-Identifier: GPL-2.0+ 24c835a60SStefan Roese /* 34c835a60SStefan Roese * Copyright (C) 2018 Stefan Roese <sr@denx.de> 44c835a60SStefan Roese */ 54c835a60SStefan Roese 64c835a60SStefan Roese #include <common.h> 74c835a60SStefan Roese #include <dm.h> 84c835a60SStefan Roese #include <ram.h> 94ff942b0SStefan Roese #include <wdt.h> 104c835a60SStefan Roese #include <asm/io.h> 114c835a60SStefan Roese #include <linux/io.h> 124c835a60SStefan Roese #include <linux/sizes.h> 134c835a60SStefan Roese #include "mt76xx.h" 144c835a60SStefan Roese 154c835a60SStefan Roese #define STR_LEN 6 164c835a60SStefan Roese 174c835a60SStefan Roese #ifdef CONFIG_BOOT_ROM 184c835a60SStefan Roese int mach_cpu_init(void) 194c835a60SStefan Roese { 204c835a60SStefan Roese ddr_calibrate(); 214c835a60SStefan Roese 224c835a60SStefan Roese return 0; 234c835a60SStefan Roese } 244c835a60SStefan Roese #endif 254c835a60SStefan Roese 264c835a60SStefan Roese int dram_init(void) 274c835a60SStefan Roese { 284c835a60SStefan Roese gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M); 294c835a60SStefan Roese 304c835a60SStefan Roese return 0; 314c835a60SStefan Roese } 324c835a60SStefan Roese 334c835a60SStefan Roese int print_cpuinfo(void) 344c835a60SStefan Roese { 354c835a60SStefan Roese static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)", 364c835a60SStefan Roese "PLL (4-Byte SPI Addr)", 374c835a60SStefan Roese "XTAL (3-Byte SPI Addr)", 384c835a60SStefan Roese "XTAL (4-Byte SPI Addr)" }; 394c835a60SStefan Roese const void *blob = gd->fdt_blob; 404c835a60SStefan Roese void __iomem *sysc_base; 414c835a60SStefan Roese char buf[STR_LEN + 1]; 424c835a60SStefan Roese fdt_addr_t base; 434c835a60SStefan Roese fdt_size_t size; 444c835a60SStefan Roese char *str; 454c835a60SStefan Roese int node; 464c835a60SStefan Roese u32 val; 474c835a60SStefan Roese 484c835a60SStefan Roese /* Get system controller base address */ 494c835a60SStefan Roese node = fdt_node_offset_by_compatible(blob, -1, "ralink,mt7620a-sysc"); 504c835a60SStefan Roese if (node < 0) 514c835a60SStefan Roese return -FDT_ERR_NOTFOUND; 524c835a60SStefan Roese 534c835a60SStefan Roese base = fdtdec_get_addr_size_auto_noparent(blob, node, "reg", 544c835a60SStefan Roese 0, &size, true); 554c835a60SStefan Roese if (base == FDT_ADDR_T_NONE) 564c835a60SStefan Roese return -EINVAL; 574c835a60SStefan Roese 584c835a60SStefan Roese sysc_base = ioremap_nocache(base, size); 594c835a60SStefan Roese 604c835a60SStefan Roese str = (char *)sysc_base + MT76XX_CHIPID_OFFS; 614c835a60SStefan Roese snprintf(buf, STR_LEN + 1, "%s", str); 624c835a60SStefan Roese val = readl(sysc_base + MT76XX_CHIP_REV_ID_OFFS); 634c835a60SStefan Roese printf("CPU: %-*s Rev %ld.%ld - ", STR_LEN, buf, 644c835a60SStefan Roese (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0)); 654c835a60SStefan Roese 664c835a60SStefan Roese val = (readl(sysc_base + MT76XX_SYSCFG0_OFFS) & GENMASK(3, 1)) >> 1; 674c835a60SStefan Roese printf("Boot from %s\n", boot_str[val]); 684c835a60SStefan Roese 694c835a60SStefan Roese return 0; 704c835a60SStefan Roese } 714ff942b0SStefan Roese 724ff942b0SStefan Roese #ifdef CONFIG_WATCHDOG 734ff942b0SStefan Roese static struct udevice *watchdog_dev; 744ff942b0SStefan Roese 754ff942b0SStefan Roese /* Called by macro WATCHDOG_RESET */ 764ff942b0SStefan Roese void watchdog_reset(void) 774ff942b0SStefan Roese { 784ff942b0SStefan Roese static ulong next_reset; 794ff942b0SStefan Roese ulong now; 804ff942b0SStefan Roese 814ff942b0SStefan Roese if (!watchdog_dev) 824ff942b0SStefan Roese return; 834ff942b0SStefan Roese 844ff942b0SStefan Roese now = get_timer(0); 854ff942b0SStefan Roese 864ff942b0SStefan Roese /* Do not reset the watchdog too often */ 874ff942b0SStefan Roese if (now > next_reset) { 884ff942b0SStefan Roese next_reset = now + 1000; /* reset every 1000ms */ 894ff942b0SStefan Roese wdt_reset(watchdog_dev); 904ff942b0SStefan Roese } 914ff942b0SStefan Roese } 92*a5f50e01SStefan Roese #endif 934ff942b0SStefan Roese 944ff942b0SStefan Roese int arch_misc_init(void) 954ff942b0SStefan Roese { 96*a5f50e01SStefan Roese /* 97*a5f50e01SStefan Roese * It has been noticed, that sometimes the d-cache is not in a 98*a5f50e01SStefan Roese * "clean-state" when U-Boot is running on MT7688. This was 99*a5f50e01SStefan Roese * detected when using the ethernet driver (which uses d-cache) 100*a5f50e01SStefan Roese * and a TFTP command does not complete. Flushing the complete 101*a5f50e01SStefan Roese * d-cache (again?) here seems to fix this issue. 102*a5f50e01SStefan Roese */ 103*a5f50e01SStefan Roese flush_dcache_range(gd->bd->bi_memstart, 104*a5f50e01SStefan Roese gd->bd->bi_memstart + gd->ram_size - 1); 105*a5f50e01SStefan Roese 106*a5f50e01SStefan Roese #ifdef CONFIG_WATCHDOG 1074ff942b0SStefan Roese /* Init watchdog */ 1084ff942b0SStefan Roese if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { 1094ff942b0SStefan Roese debug("Watchdog: Not found by seq!\n"); 1104ff942b0SStefan Roese if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { 1114ff942b0SStefan Roese puts("Watchdog: Not found!\n"); 1124ff942b0SStefan Roese return 0; 1134ff942b0SStefan Roese } 1144ff942b0SStefan Roese } 1154ff942b0SStefan Roese 1164ff942b0SStefan Roese wdt_start(watchdog_dev, 60000, 0); /* 60 seconds */ 1174ff942b0SStefan Roese printf("Watchdog: Started\n"); 118*a5f50e01SStefan Roese #endif 1194ff942b0SStefan Roese 1204ff942b0SStefan Roese return 0; 1214ff942b0SStefan Roese } 122