mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 07:34:31 +00:00
e27d6c7d32
Currently, uniphier_get_soc_type() converts the SoC ID (this is read from the revision register) to an enum symbol to use it for SoC identification. Come to think of it, there is no need for the conversion in the first place. Using the SoC ID from the register as-is a straightforward way. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
246 lines
5 KiB
C
246 lines
5 KiB
C
/*
|
|
* 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);
|
|
}
|
|
#endif
|
|
|
|
#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);
|
|
}
|
|
#ifdef CONFIG_ARMV8_MULTIENTRY
|
|
cci500_init(2);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
struct uniphier_initdata {
|
|
unsigned int soc_id;
|
|
bool nand_2cs;
|
|
void (*sbc_init)(void);
|
|
void (*pll_init)(void);
|
|
void (*clk_init)(void);
|
|
void (*misc_init)(void);
|
|
};
|
|
|
|
static const struct uniphier_initdata uniphier_initdata[] = {
|
|
#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
|
|
{
|
|
.soc_id = UNIPHIER_SLD3_ID,
|
|
.nand_2cs = true,
|
|
.sbc_init = uniphier_sbc_init_admulti,
|
|
.pll_init = uniphier_sld3_pll_init,
|
|
.clk_init = uniphier_ld4_clk_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_LD4)
|
|
{
|
|
.soc_id = UNIPHIER_LD4_ID,
|
|
.nand_2cs = true,
|
|
.sbc_init = uniphier_ld4_sbc_init,
|
|
.pll_init = uniphier_ld4_pll_init,
|
|
.clk_init = uniphier_ld4_clk_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_PRO4)
|
|
{
|
|
.soc_id = UNIPHIER_PRO4_ID,
|
|
.nand_2cs = false,
|
|
.sbc_init = uniphier_sbc_init_savepin,
|
|
.pll_init = uniphier_pro4_pll_init,
|
|
.clk_init = uniphier_pro4_clk_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_SLD8)
|
|
{
|
|
.soc_id = UNIPHIER_SLD8_ID,
|
|
.nand_2cs = true,
|
|
.sbc_init = uniphier_ld4_sbc_init,
|
|
.pll_init = uniphier_ld4_pll_init,
|
|
.clk_init = uniphier_ld4_clk_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
|
|
{
|
|
.soc_id = UNIPHIER_PRO5_ID,
|
|
.nand_2cs = true,
|
|
.sbc_init = uniphier_sbc_init_savepin,
|
|
.clk_init = uniphier_pro5_clk_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_PXS2)
|
|
{
|
|
.soc_id = UNIPHIER_PXS2_ID,
|
|
.nand_2cs = true,
|
|
.sbc_init = uniphier_pxs2_sbc_init,
|
|
.clk_init = uniphier_pxs2_clk_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_LD6B)
|
|
{
|
|
.soc_id = UNIPHIER_LD6B_ID,
|
|
.nand_2cs = true,
|
|
.sbc_init = uniphier_pxs2_sbc_init,
|
|
.clk_init = uniphier_pxs2_clk_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_LD11)
|
|
{
|
|
.soc_id = UNIPHIER_LD11_ID,
|
|
.nand_2cs = false,
|
|
.sbc_init = uniphier_ld11_sbc_init,
|
|
.pll_init = uniphier_ld11_pll_init,
|
|
.clk_init = uniphier_ld11_clk_init,
|
|
.misc_init = uniphier_ld11_misc_init,
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARCH_UNIPHIER_LD20)
|
|
{
|
|
.soc_id = UNIPHIER_LD20_ID,
|
|
.nand_2cs = false,
|
|
.sbc_init = uniphier_ld11_sbc_init,
|
|
.pll_init = uniphier_ld20_pll_init,
|
|
.misc_init = uniphier_ld20_misc_init,
|
|
},
|
|
#endif
|
|
};
|
|
|
|
static const struct uniphier_initdata *uniphier_get_initdata(
|
|
unsigned int 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];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int board_init(void)
|
|
{
|
|
const struct uniphier_initdata *initdata;
|
|
unsigned int soc_id;
|
|
int ret;
|
|
|
|
led_puts("U0");
|
|
|
|
soc_id = uniphier_get_soc_id();
|
|
initdata = uniphier_get_initdata(soc_id);
|
|
if (!initdata) {
|
|
pr_err("unsupported board\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
initdata->sbc_init();
|
|
|
|
support_card_init();
|
|
|
|
led_puts("U0");
|
|
|
|
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();
|
|
|
|
led_puts("U2");
|
|
|
|
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_ARMV8_MULTIENTRY
|
|
uniphier_smp_kick_all_cpus();
|
|
#endif
|
|
|
|
led_puts("Uboo");
|
|
|
|
return 0;
|
|
}
|