1 /* 2 * Copyright (C) 2015-2016 Socionext Inc. 3 * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <debug_uart.h> 10 #include <spl.h> 11 12 #include "init.h" 13 #include "micro-support-card.h" 14 #include "soc-info.h" 15 16 struct uniphier_spl_initdata { 17 enum uniphier_soc_id soc_id; 18 void (*bcu_init)(const struct uniphier_board_data *bd); 19 void (*early_clk_init)(void); 20 int (*dpll_init)(const struct uniphier_board_data *bd); 21 int (*memconf_init)(const struct uniphier_board_data *bd); 22 void (*dram_clk_init)(void); 23 int (*umc_init)(const struct uniphier_board_data *bd); 24 }; 25 26 static const struct uniphier_spl_initdata uniphier_spl_initdata[] = { 27 #if defined(CONFIG_ARCH_UNIPHIER_SLD3) 28 { 29 .soc_id = SOC_UNIPHIER_SLD3, 30 .bcu_init = uniphier_sld3_bcu_init, 31 .early_clk_init = uniphier_sld3_early_clk_init, 32 .dpll_init = uniphier_sld3_dpll_init, 33 .memconf_init = uniphier_memconf_3ch_no_disbit_init, 34 .dram_clk_init = uniphier_sld3_dram_clk_init, 35 .umc_init = uniphier_sld3_umc_init, 36 }, 37 #endif 38 #if defined(CONFIG_ARCH_UNIPHIER_LD4) 39 { 40 .soc_id = SOC_UNIPHIER_LD4, 41 .bcu_init = uniphier_ld4_bcu_init, 42 .early_clk_init = uniphier_sld3_early_clk_init, 43 .dpll_init = uniphier_ld4_dpll_init, 44 .memconf_init = uniphier_memconf_2ch_init, 45 .dram_clk_init = uniphier_sld3_dram_clk_init, 46 .umc_init = uniphier_ld4_umc_init, 47 }, 48 #endif 49 #if defined(CONFIG_ARCH_UNIPHIER_PRO4) 50 { 51 .soc_id = SOC_UNIPHIER_PRO4, 52 .early_clk_init = uniphier_sld3_early_clk_init, 53 .dpll_init = uniphier_pro4_dpll_init, 54 .memconf_init = uniphier_memconf_2ch_init, 55 .dram_clk_init = uniphier_sld3_dram_clk_init, 56 .umc_init = uniphier_pro4_umc_init, 57 }, 58 #endif 59 #if defined(CONFIG_ARCH_UNIPHIER_SLD8) 60 { 61 .soc_id = SOC_UNIPHIER_SLD8, 62 .bcu_init = uniphier_ld4_bcu_init, 63 .early_clk_init = uniphier_sld3_early_clk_init, 64 .dpll_init = uniphier_sld8_dpll_init, 65 .memconf_init = uniphier_memconf_2ch_init, 66 .dram_clk_init = uniphier_sld3_dram_clk_init, 67 .umc_init = uniphier_sld8_umc_init, 68 }, 69 #endif 70 #if defined(CONFIG_ARCH_UNIPHIER_PRO5) 71 { 72 .soc_id = SOC_UNIPHIER_PRO5, 73 .early_clk_init = uniphier_sld3_early_clk_init, 74 .dpll_init = uniphier_pro5_dpll_init, 75 .memconf_init = uniphier_memconf_2ch_init, 76 .dram_clk_init = uniphier_pro5_dram_clk_init, 77 .umc_init = uniphier_pro5_umc_init, 78 }, 79 #endif 80 #if defined(CONFIG_ARCH_UNIPHIER_PXS2) 81 { 82 .soc_id = SOC_UNIPHIER_PXS2, 83 .early_clk_init = uniphier_sld3_early_clk_init, 84 .dpll_init = uniphier_pxs2_dpll_init, 85 .memconf_init = uniphier_memconf_3ch_init, 86 .dram_clk_init = uniphier_pxs2_dram_clk_init, 87 .umc_init = uniphier_pxs2_umc_init, 88 }, 89 #endif 90 #if defined(CONFIG_ARCH_UNIPHIER_LD6B) 91 { 92 .soc_id = SOC_UNIPHIER_LD6B, 93 .early_clk_init = uniphier_sld3_early_clk_init, 94 .dpll_init = uniphier_pxs2_dpll_init, 95 .memconf_init = uniphier_memconf_3ch_init, 96 .dram_clk_init = uniphier_pxs2_dram_clk_init, 97 .umc_init = uniphier_pxs2_umc_init, 98 }, 99 #endif 100 #if defined(CONFIG_ARCH_UNIPHIER_LD11) 101 { 102 .soc_id = SOC_UNIPHIER_LD11, 103 .early_clk_init = uniphier_ld11_early_clk_init, 104 .dpll_init = uniphier_ld11_dpll_init, 105 .memconf_init = uniphier_memconf_2ch_init, 106 .dram_clk_init = uniphier_ld11_dram_clk_init, 107 .umc_init = uniphier_ld11_umc_init, 108 }, 109 #endif 110 #if defined(CONFIG_ARCH_UNIPHIER_LD20) 111 { 112 .soc_id = SOC_UNIPHIER_LD20, 113 .early_clk_init = uniphier_ld11_early_clk_init, 114 .dpll_init = uniphier_ld20_dpll_init, 115 .memconf_init = uniphier_memconf_3ch_init, 116 .dram_clk_init = uniphier_ld20_dram_clk_init, 117 .umc_init = uniphier_ld20_umc_init, 118 }, 119 #endif 120 }; 121 122 static const struct uniphier_spl_initdata *uniphier_get_spl_initdata( 123 enum uniphier_soc_id soc_id) 124 { 125 int i; 126 127 for (i = 0; i < ARRAY_SIZE(uniphier_spl_initdata); i++) { 128 if (uniphier_spl_initdata[i].soc_id == soc_id) 129 return &uniphier_spl_initdata[i]; 130 } 131 132 return NULL; 133 } 134 135 void spl_board_init(void) 136 { 137 const struct uniphier_board_data *bd; 138 const struct uniphier_spl_initdata *initdata; 139 enum uniphier_soc_id soc_id; 140 int ret; 141 142 #ifdef CONFIG_DEBUG_UART 143 debug_uart_init(); 144 #endif 145 146 bd = uniphier_get_board_param(); 147 if (!bd) 148 hang(); 149 150 soc_id = uniphier_get_soc_type(); 151 initdata = uniphier_get_spl_initdata(soc_id); 152 if (!initdata) 153 hang(); 154 155 if (initdata->bcu_init) 156 initdata->bcu_init(bd); 157 158 159 initdata->early_clk_init(); 160 161 162 #ifdef CONFIG_SPL_SERIAL_SUPPORT 163 preloader_console_init(); 164 #endif 165 166 ret = initdata->dpll_init(bd); 167 if (ret) { 168 pr_err("failed to init DPLL\n"); 169 hang(); 170 } 171 172 ret = initdata->memconf_init(bd); 173 if (ret) { 174 pr_err("failed to init MEMCONF\n"); 175 hang(); 176 } 177 178 initdata->dram_clk_init(); 179 180 ret = initdata->umc_init(bd); 181 if (ret) { 182 pr_err("failed to init DRAM\n"); 183 hang(); 184 } 185 } 186