1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2010-2011 Calxeda, Inc. 4 */ 5 6#include <ahci.h> 7#include <cpu_func.h> 8#include <env.h> 9#include <fdt_support.h> 10#include <fdtdec.h> 11#include <init.h> 12#include <net.h> 13#include <scsi.h> 14#include <asm/global_data.h> 15 16#include <linux/sizes.h> 17#include <asm/io.h> 18 19#define HB_AHCI_BASE 0xffe08000 20 21#define HB_SCU_A9_PWR_STATUS 0xfff10008 22#define HB_SREG_A9_PWR_REQ 0xfff3cf00 23#define HB_SREG_A9_BOOT_SRC_STAT 0xfff3cf04 24#define HB_SREG_A9_PWRDOM_STAT 0xfff3cf20 25#define HB_SREG_A15_PWR_CTRL 0xfff3c200 26 27#define HB_PWR_SUSPEND 0 28#define HB_PWR_SOFT_RESET 1 29#define HB_PWR_HARD_RESET 2 30#define HB_PWR_SHUTDOWN 3 31 32#define PWRDOM_STAT_SATA 0x80000000 33#define PWRDOM_STAT_PCI 0x40000000 34#define PWRDOM_STAT_EMMC 0x20000000 35 36#define HB_SCU_A9_PWR_NORMAL 0 37#define HB_SCU_A9_PWR_DORMANT 2 38#define HB_SCU_A9_PWR_OFF 3 39 40DECLARE_GLOBAL_DATA_PTR; 41 42void cphy_disable_overrides(void); 43 44/* 45 * Miscellaneous platform dependent initialisations 46 */ 47int board_init(void) 48{ 49 icache_enable(); 50 51 return 0; 52} 53 54#ifdef CONFIG_MISC_INIT_R 55int misc_init_r(void) 56{ 57 char envbuffer[16]; 58 u32 boot_choice; 59 60 boot_choice = readl(HB_SREG_A9_BOOT_SRC_STAT) & 0xff; 61 sprintf(envbuffer, "bootcmd%d", boot_choice); 62 if (env_get(envbuffer)) { 63 sprintf(envbuffer, "run bootcmd%d", boot_choice); 64 env_set("bootcmd", envbuffer); 65 } else 66 env_set("bootcmd", ""); 67 68 return 0; 69} 70#endif 71 72int dram_init(void) 73{ 74 return fdtdec_setup_mem_size_base(); 75} 76 77int dram_init_banksize(void) 78{ 79 return fdtdec_setup_memory_banksize(); 80} 81 82#if defined(CONFIG_OF_BOARD_SETUP) 83int ft_board_setup(void *fdt, struct bd_info *bd) 84{ 85 static const char disabled[] = "disabled"; 86 u32 reg = readl(HB_SREG_A9_PWRDOM_STAT); 87 88 if (!(reg & PWRDOM_STAT_SATA)) 89 do_fixup_by_compat(fdt, "calxeda,hb-ahci", "status", 90 disabled, sizeof(disabled), 1); 91 92 if (!(reg & PWRDOM_STAT_EMMC)) 93 do_fixup_by_compat(fdt, "calxeda,hb-sdhci", "status", 94 disabled, sizeof(disabled), 1); 95 96 return 0; 97} 98#endif 99 100void *board_fdt_blob_setup(int *err) 101{ 102 *err = 0; 103 /* 104 * The ECME management processor loads the DTB from NOR flash 105 * into DRAM (at 4KB), where it gets patched to contain the 106 * detected memory size. 107 */ 108 return (void *)0x1000; 109} 110 111static int is_highbank(void) 112{ 113 uint32_t midr; 114 115 asm volatile ("mrc p15, 0, %0, c0, c0, 0\n" : "=r"(midr)); 116 117 return (midr & 0xfff0) == 0xc090; 118} 119 120void reset_cpu(void) 121{ 122 writel(HB_PWR_HARD_RESET, HB_SREG_A9_PWR_REQ); 123 if (is_highbank()) 124 writeb(HB_SCU_A9_PWR_OFF, HB_SCU_A9_PWR_STATUS); 125 else 126 writel(0x1, HB_SREG_A15_PWR_CTRL); 127 128 wfi(); 129} 130 131/* 132 * turn off the override before transferring control to Linux, since Linux 133 * may not support spread spectrum. 134 */ 135void arch_preboot_os(void) 136{ 137 cphy_disable_overrides(); 138} 139