Newer
Older
* Copyright (C) 2012-2015 Panasonic Corporation
* Copyright (C) 2015-2016 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <libfdt.h>
#include <linux/io.h>
#include "init.h"
#include "micro-support-card.h"
#include "sg-regs.h"
#include "soc-info.h"
DECLARE_GLOBAL_DATA_PTR;
static void uniphier_setup_xirq(void)
{
const void *fdt = gd->fdt_blob;
int soc_node, aidet_node;
const u32 *val;
unsigned long aidet_base;
u32 tmp;
soc_node = fdt_path_offset(fdt, "/soc");
if (soc_node < 0)
return;
aidet_node = fdt_subnode_offset_namelen(fdt, soc_node, "aidet", 5);
if (aidet_node < 0)
return;
val = fdt_getprop(fdt, aidet_node, "reg", NULL);
if (!val)
return;
aidet_base = fdt32_to_cpu(*val);
tmp = readl(aidet_base + 8); /* AIDET DETCONFR2 */
tmp |= 0x00ff0000; /* Set XIRQ0-7 low active */
writel(tmp, aidet_base + 8);
tmp = readl(0x55000090); /* IRQCTL */
tmp |= 0x000000ff;
writel(tmp, 0x55000090);
}
#ifdef CONFIG_ARCH_UNIPHIER_LD11
static void uniphier_ld11_misc_init(void)
sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */
sg_set_iectrl(149);
sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */
sg_set_iectrl(153);
#ifdef CONFIG_ARCH_UNIPHIER_LD20
static void uniphier_ld20_misc_init(void)
sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */
sg_set_iectrl(149);
sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */
sg_set_iectrl(153);
/* ES1 errata: increase VDD09 supply to suppress VBO noise */
if (uniphier_get_soc_revision() == 1) {
writel(0x00000003, 0x6184e004);
writel(0x00000100, 0x6184e040);
writel(0x0000b500, 0x6184e024);
writel(0x00000001, 0x6184e000);
}
cci500_init(2);
}
#endif
struct uniphier_initdata {
enum uniphier_soc_id soc_id;
bool nand_2cs;
void (*pll_init)(void);
void (*clk_init)(void);
void (*misc_init)(void);
};
struct uniphier_initdata uniphier_initdata[] = {
#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
{
.soc_id = SOC_UNIPHIER_SLD3,
.nand_2cs = true,
.pll_init = uniphier_sld3_pll_init,
.clk_init = uniphier_ld4_clk_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_LD4)
{
.soc_id = SOC_UNIPHIER_LD4,
.nand_2cs = true,
.pll_init = uniphier_ld4_pll_init,
.clk_init = uniphier_ld4_clk_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_PRO4)
{
.soc_id = SOC_UNIPHIER_PRO4,
.nand_2cs = false,
.pll_init = uniphier_pro4_pll_init,
.clk_init = uniphier_pro4_clk_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_SLD8)
{
.soc_id = SOC_UNIPHIER_SLD8,
.nand_2cs = true,
.pll_init = uniphier_ld4_pll_init,
.clk_init = uniphier_ld4_clk_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
{
.soc_id = SOC_UNIPHIER_PRO5,
.nand_2cs = true,
.clk_init = uniphier_pro5_clk_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_PXS2)
{
.soc_id = SOC_UNIPHIER_PXS2,
.nand_2cs = true,
.clk_init = uniphier_pxs2_clk_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_LD6B)
{
.soc_id = SOC_UNIPHIER_LD6B,
.nand_2cs = true,
.clk_init = uniphier_pxs2_clk_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_LD11)
{
.soc_id = SOC_UNIPHIER_LD11,
.nand_2cs = false,
.pll_init = uniphier_ld11_pll_init,
.clk_init = uniphier_ld11_clk_init,
.misc_init = uniphier_ld11_misc_init,
},
#if defined(CONFIG_ARCH_UNIPHIER_LD20)
{
.soc_id = SOC_UNIPHIER_LD20,
.nand_2cs = false,
.pll_init = uniphier_ld20_pll_init,
.misc_init = uniphier_ld20_misc_init,
},
};
static struct uniphier_initdata *uniphier_get_initdata(
enum uniphier_soc_id soc_id)
{
int i;
for (i = 0; i < ARRAY_SIZE(uniphier_initdata); i++) {
if (uniphier_initdata[i].soc_id == soc_id)
return &uniphier_initdata[i];
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
return NULL;
}
int board_init(void)
{
struct uniphier_initdata *initdata;
enum uniphier_soc_id soc_id;
int ret;
led_puts("U0");
soc_id = uniphier_get_soc_type();
initdata = uniphier_get_initdata(soc_id);
if (!initdata) {
pr_err("unsupported board\n");
return -EINVAL;
}
if (IS_ENABLED(CONFIG_NAND_DENALI)) {
ret = uniphier_pin_init(initdata->nand_2cs ?
"nand2cs_grp" : "nand_grp");
if (ret)
pr_err("failed to init NAND pins\n");
}
led_puts("U1");
if (initdata->pll_init)
initdata->pll_init();
if (initdata->clk_init)
initdata->clk_init();
led_puts("U3");
if (initdata->misc_init)
initdata->misc_init();
led_puts("U4");
uniphier_setup_xirq();
led_puts("U5");
support_card_late_init();
led_puts("U6");
#ifdef CONFIG_ARM64
uniphier_smp_kick_all_cpus();
#endif
led_puts("Uboo");
return 0;
}