1 /* 2 * Copyright (C) 2012-2015 Panasonic Corporation 3 * Copyright (C) 2015-2016 Socionext Inc. 4 * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <libfdt.h> 11 #include <linux/io.h> 12 13 #include "init.h" 14 #include "micro-support-card.h" 15 #include "sg-regs.h" 16 #include "soc-info.h" 17 18 DECLARE_GLOBAL_DATA_PTR; 19 20 static void uniphier_setup_xirq(void) 21 { 22 const void *fdt = gd->fdt_blob; 23 int soc_node, aidet_node; 24 const fdt32_t *val; 25 unsigned long aidet_base; 26 u32 tmp; 27 28 soc_node = fdt_path_offset(fdt, "/soc"); 29 if (soc_node < 0) 30 return; 31 32 aidet_node = fdt_subnode_offset_namelen(fdt, soc_node, "aidet", 5); 33 if (aidet_node < 0) 34 return; 35 36 val = fdt_getprop(fdt, aidet_node, "reg", NULL); 37 if (!val) 38 return; 39 40 aidet_base = fdt32_to_cpu(*val); 41 42 tmp = readl(aidet_base + 8); /* AIDET DETCONFR2 */ 43 tmp |= 0x00ff0000; /* Set XIRQ0-7 low active */ 44 writel(tmp, aidet_base + 8); 45 46 tmp = readl(0x55000090); /* IRQCTL */ 47 tmp |= 0x000000ff; 48 writel(tmp, 0x55000090); 49 } 50 51 #ifdef CONFIG_ARCH_UNIPHIER_LD11 52 static void uniphier_ld11_misc_init(void) 53 { 54 sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */ 55 sg_set_iectrl(149); 56 sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */ 57 sg_set_iectrl(153); 58 } 59 #endif 60 61 #ifdef CONFIG_ARCH_UNIPHIER_LD20 62 static void uniphier_ld20_misc_init(void) 63 { 64 sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */ 65 sg_set_iectrl(149); 66 sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */ 67 sg_set_iectrl(153); 68 69 /* ES1 errata: increase VDD09 supply to suppress VBO noise */ 70 if (uniphier_get_soc_revision() == 1) { 71 writel(0x00000003, 0x6184e004); 72 writel(0x00000100, 0x6184e040); 73 writel(0x0000b500, 0x6184e024); 74 writel(0x00000001, 0x6184e000); 75 } 76 } 77 #endif 78 79 struct uniphier_initdata { 80 unsigned int soc_id; 81 void (*sbc_init)(void); 82 void (*pll_init)(void); 83 void (*clk_init)(void); 84 void (*misc_init)(void); 85 }; 86 87 static const struct uniphier_initdata uniphier_initdata[] = { 88 #if defined(CONFIG_ARCH_UNIPHIER_LD4) 89 { 90 .soc_id = UNIPHIER_LD4_ID, 91 .sbc_init = uniphier_ld4_sbc_init, 92 .pll_init = uniphier_ld4_pll_init, 93 .clk_init = uniphier_ld4_clk_init, 94 }, 95 #endif 96 #if defined(CONFIG_ARCH_UNIPHIER_PRO4) 97 { 98 .soc_id = UNIPHIER_PRO4_ID, 99 .sbc_init = uniphier_sbc_init_savepin, 100 .pll_init = uniphier_pro4_pll_init, 101 .clk_init = uniphier_pro4_clk_init, 102 }, 103 #endif 104 #if defined(CONFIG_ARCH_UNIPHIER_SLD8) 105 { 106 .soc_id = UNIPHIER_SLD8_ID, 107 .sbc_init = uniphier_ld4_sbc_init, 108 .pll_init = uniphier_ld4_pll_init, 109 .clk_init = uniphier_ld4_clk_init, 110 }, 111 #endif 112 #if defined(CONFIG_ARCH_UNIPHIER_PRO5) 113 { 114 .soc_id = UNIPHIER_PRO5_ID, 115 .sbc_init = uniphier_sbc_init_savepin, 116 .clk_init = uniphier_pro5_clk_init, 117 }, 118 #endif 119 #if defined(CONFIG_ARCH_UNIPHIER_PXS2) 120 { 121 .soc_id = UNIPHIER_PXS2_ID, 122 .sbc_init = uniphier_pxs2_sbc_init, 123 .clk_init = uniphier_pxs2_clk_init, 124 }, 125 #endif 126 #if defined(CONFIG_ARCH_UNIPHIER_LD6B) 127 { 128 .soc_id = UNIPHIER_LD6B_ID, 129 .sbc_init = uniphier_pxs2_sbc_init, 130 .clk_init = uniphier_pxs2_clk_init, 131 }, 132 #endif 133 #if defined(CONFIG_ARCH_UNIPHIER_LD11) 134 { 135 .soc_id = UNIPHIER_LD11_ID, 136 .sbc_init = uniphier_ld11_sbc_init, 137 .pll_init = uniphier_ld11_pll_init, 138 .clk_init = uniphier_ld11_clk_init, 139 .misc_init = uniphier_ld11_misc_init, 140 }, 141 #endif 142 #if defined(CONFIG_ARCH_UNIPHIER_LD20) 143 { 144 .soc_id = UNIPHIER_LD20_ID, 145 .sbc_init = uniphier_ld11_sbc_init, 146 .pll_init = uniphier_ld20_pll_init, 147 .clk_init = uniphier_ld20_clk_init, 148 .misc_init = uniphier_ld20_misc_init, 149 }, 150 #endif 151 #if defined(CONFIG_ARCH_UNIPHIER_PXS3) 152 { 153 .soc_id = UNIPHIER_PXS3_ID, 154 .sbc_init = uniphier_pxs2_sbc_init, 155 .pll_init = uniphier_pxs3_pll_init, 156 .clk_init = uniphier_pxs3_clk_init, 157 }, 158 #endif 159 }; 160 UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_initdata, uniphier_initdata) 161 162 int board_init(void) 163 { 164 const struct uniphier_initdata *initdata; 165 166 led_puts("U0"); 167 168 initdata = uniphier_get_initdata(); 169 if (!initdata) { 170 pr_err("unsupported SoC\n"); 171 return -EINVAL; 172 } 173 174 initdata->sbc_init(); 175 176 support_card_init(); 177 178 led_puts("U0"); 179 180 if (initdata->pll_init) 181 initdata->pll_init(); 182 183 led_puts("U1"); 184 185 if (initdata->clk_init) 186 initdata->clk_init(); 187 188 led_puts("U2"); 189 190 if (initdata->misc_init) 191 initdata->misc_init(); 192 193 led_puts("U3"); 194 195 uniphier_setup_xirq(); 196 197 led_puts("U4"); 198 199 support_card_late_init(); 200 201 led_puts("Uboo"); 202 203 return 0; 204 } 205