1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * board/hoperun/hihope-rzg2/hihope-rzg2.c
4 *     This file is HiHope RZ/G2[HMN] board support.
5 *
6 * Copyright (C) 2021 Renesas Electronics Corporation
7 */
8
9#include <common.h>
10#include <asm/global_data.h>
11#include <asm/io.h>
12#include <asm/processor.h>
13#include <asm/arch/renesas.h>
14#include <asm/arch/rcar-mstp.h>
15#include <linux/bitops.h>
16#include <linux/delay.h>
17#include <linux/libfdt.h>
18
19#define RST_BASE	0xE6160000
20#define RST_CA57RESCNT	(RST_BASE + 0x40)
21#define RST_CA53RESCNT	(RST_BASE + 0x44)
22#define RST_CA57_CODE	0xA5A5000F
23#define RST_CA53_CODE	0x5A5A000F
24
25DECLARE_GLOBAL_DATA_PTR;
26#define HSUSB_MSTP704		BIT(4)	/* HSUSB */
27
28/* HSUSB block registers */
29#define HSUSB_REG_LPSTS			0xE6590102
30#define HSUSB_REG_LPSTS_SUSPM_NORMAL	BIT(14)
31#define HSUSB_REG_UGCTRL2		0xE6590184
32#define HSUSB_REG_UGCTRL2_USB0SEL_EHCI	0x10
33#define HSUSB_REG_UGCTRL2_RESERVED_3	0x1 /* bit[3:0] should be B'0001 */
34
35#define PRR_REGISTER (0xFFF00044)
36
37int board_init(void)
38{
39	u32 i;
40
41	/* address of boot parameters */
42	gd->bd->bi_boot_params = CONFIG_TEXT_BASE + 0x50000;
43
44	/* Configure the HSUSB block */
45	mstp_clrbits_le32(SMSTPCR7, SMSTPCR7, HSUSB_MSTP704);
46	/*
47	 * We need to add a barrier instruction after HSUSB module stop release.
48	 * This barrier instruction can be either reading back the same MSTP
49	 * register or any other register in the same IP block. So like linux
50	 * adding check for MSTPSR register, which indicates the clock has been
51	 * started.
52	 */
53	for (i = 1000; i > 0; --i) {
54		if (!(readl(MSTPSR7) & HSUSB_MSTP704))
55			break;
56		cpu_relax();
57	}
58
59	/* Select EHCI/OHCI host module for USB2.0 ch0 */
60	writel(HSUSB_REG_UGCTRL2_USB0SEL_EHCI | HSUSB_REG_UGCTRL2_RESERVED_3,
61	       HSUSB_REG_UGCTRL2);
62	/* low power status */
63	setbits_le16(HSUSB_REG_LPSTS, HSUSB_REG_LPSTS_SUSPM_NORMAL);
64
65	return 0;
66}
67
68void reset_cpu(void)
69{
70	unsigned long midr, cputype;
71
72	asm volatile("mrs %0, midr_el1" : "=r" (midr));
73	cputype = (midr >> 4) & 0xfff;
74
75	if (cputype == 0xd03)
76		writel(RST_CA53_CODE, RST_CA53RESCNT);
77	else
78		writel(RST_CA57_CODE, RST_CA57RESCNT);
79}
80
81#if defined(CONFIG_MULTI_DTB_FIT)
82/* If the firmware passed a device tree, use it for board identification. */
83extern u64 rcar_atf_boot_args[];
84
85static bool is_hoperun_hihope_rzg2_board(const char *board_name)
86{
87	void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]);
88	bool ret = false;
89
90	if ((fdt_magic(atf_fdt_blob) == FDT_MAGIC) &&
91	    (fdt_node_check_compatible(atf_fdt_blob, 0, board_name) == 0))
92		ret = true;
93
94	return ret;
95}
96
97int board_fit_config_name_match(const char *name)
98{
99	if (is_hoperun_hihope_rzg2_board("hoperun,hihope-rzg2m") &&
100	    !strcmp(name, "r8a774a1-hihope-rzg2m-u-boot"))
101		return 0;
102
103	if (is_hoperun_hihope_rzg2_board("hoperun,hihope-rzg2n") &&
104	    !strcmp(name, "r8a774b1-hihope-rzg2n-u-boot"))
105		return 0;
106
107	if (is_hoperun_hihope_rzg2_board("hoperun,hihope-rzg2h") &&
108	    !strcmp(name, "r8a774e1-hihope-rzg2h-u-boot"))
109		return 0;
110
111	return -1;
112}
113#endif
114