1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2017 Linaro
4 * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
5 */
6
7#include <common.h>
8#include <cpu_func.h>
9#include <dm.h>
10#include <init.h>
11#include <asm/cache.h>
12#include <asm/global_data.h>
13#include <asm/io.h>
14#include <dm/platform_data/serial_pl01x.h>
15#include <asm/arch/hi3798cv200.h>
16#include <asm/armv8/mmu.h>
17#include <linux/bitops.h>
18#include <linux/delay.h>
19
20DECLARE_GLOBAL_DATA_PTR;
21
22static struct mm_region poplar_mem_map[] = {
23	{
24		.virt = 0x0UL,
25		.phys = 0x0UL,
26		.size = 0x80000000UL,
27		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
28			 PTE_BLOCK_INNER_SHARE
29	}, {
30		.virt = 0x80000000UL,
31		.phys = 0x80000000UL,
32		.size = 0x80000000UL,
33		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
34			 PTE_BLOCK_NON_SHARE |
35			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
36	}, {
37		0,
38	}
39};
40
41struct mm_region *mem_map = poplar_mem_map;
42
43#if !CONFIG_IS_ENABLED(OF_CONTROL)
44static const struct pl01x_serial_plat serial_plat = {
45	.base = REG_BASE_UART0,
46	.type = TYPE_PL010,
47	.clock = 75000000,
48};
49
50U_BOOT_DRVINFO(poplar_serial) = {
51	.name = "serial_pl01x",
52	.plat = &serial_plat,
53};
54#endif
55
56int checkboard(void)
57{
58	puts("BOARD: Hisilicon HI3798cv200 Poplar\n");
59
60	return 0;
61}
62
63void reset_cpu(void)
64{
65	psci_system_reset();
66}
67
68int dram_init(void)
69{
70	gd->ram_size = get_ram_size(NULL, 0x80000000);
71
72	return 0;
73}
74
75/*
76 * Some linux kernel versions don't use memory before its load address, so to
77 * be generic we just pretend it isn't there.  In previous uboot versions we
78 * carved the space used by BL31 (runs in DDR on this platfomr) so the PSCI code
79 * could persist in memory and be left alone by the kernel.
80 *
81 * That led to a problem when mapping memory in older kernels.  That PSCI code
82 * now lies in memory below the kernel load offset; it therefore won't be
83 * touched by the kernel, and by not specially reserving it we avoid the mapping
84 * problem as well.
85 *
86 */
87#define KERNEL_TEXT_OFFSET	0x00080000
88
89int dram_init_banksize(void)
90{
91	gd->bd->bi_dram[0].start = KERNEL_TEXT_OFFSET;
92	gd->bd->bi_dram[0].size = gd->ram_size - gd->bd->bi_dram[0].start;
93
94	return 0;
95}
96
97static void usb2_phy_config(void)
98{
99	const u32 config[] = {
100		/* close EOP pre-emphasis. open data pre-emphasis */
101		0xa1001c,
102		/* Rcomp = 150mW, increase DC level */
103		0xa00607,
104		/* keep Rcomp working */
105		0xa10700,
106		/* Icomp = 212mW, increase current drive */
107		0xa00aab,
108		/* EMI fix: rx_active not stay 1 when error packets received */
109		0xa11140,
110		/* Comp mode select */
111		0xa11041,
112		/* adjust eye diagram */
113		0xa0098c,
114		/* adjust eye diagram */
115		0xa10a0a,
116	};
117	int i;
118
119	for (i = 0; i < ARRAY_SIZE(config); i++) {
120		writel(config[i], PERI_CTRL_USB0);
121		clrsetbits_le32(PERI_CTRL_USB0, BIT(21), BIT(20) | BIT(22));
122		udelay(20);
123	}
124}
125
126static void usb2_phy_init(void)
127{
128	/* reset usb2 controller bus/utmi/roothub */
129	setbits_le32(PERI_CRG46, USB2_BUS_SRST_REQ | USB2_UTMI0_SRST_REQ |
130			USB2_HST_PHY_SYST_REQ | USB2_OTG_PHY_SYST_REQ);
131	udelay(200);
132
133	/* reset usb2 phy por/utmi */
134	setbits_le32(PERI_CRG47, USB2_PHY01_SRST_REQ | USB2_PHY01_SRST_TREQ1);
135	udelay(200);
136
137	/* open usb2 ref clk */
138	setbits_le32(PERI_CRG47, USB2_PHY01_REF_CKEN);
139	udelay(300);
140
141	/* cancel usb2 power on reset */
142	clrbits_le32(PERI_CRG47, USB2_PHY01_SRST_REQ);
143	udelay(500);
144
145	usb2_phy_config();
146
147	/* cancel usb2 port reset, wait comp circuit stable */
148	clrbits_le32(PERI_CRG47, USB2_PHY01_SRST_TREQ1);
149	mdelay(10);
150
151	/* open usb2 controller clk */
152	setbits_le32(PERI_CRG46, USB2_BUS_CKEN | USB2_OHCI48M_CKEN |
153			USB2_OHCI12M_CKEN | USB2_OTG_UTMI_CKEN |
154			USB2_HST_PHY_CKEN | USB2_UTMI0_CKEN);
155	udelay(200);
156
157	/* cancel usb2 control reset */
158	clrbits_le32(PERI_CRG46, USB2_BUS_SRST_REQ | USB2_UTMI0_SRST_REQ |
159			USB2_HST_PHY_SYST_REQ | USB2_OTG_PHY_SYST_REQ);
160	udelay(200);
161}
162
163#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
164#include <env.h>
165#include <usb.h>
166#include <usb/dwc2_udc.h>
167#include <g_dnl.h>
168
169static struct dwc2_plat_otg_data poplar_otg_data = {
170	.regs_otg = HIOTG_BASE_ADDR
171};
172
173static void set_usb_to_device(void)
174{
175	setbits_le32(PERI_CTRL_USB3, USB2_2P_CHIPID);
176}
177
178int board_usb_init(int index, enum usb_init_type init)
179{
180	set_usb_to_device();
181	return dwc2_udc_probe(&poplar_otg_data);
182}
183
184int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
185{
186	if (!env_get("serial#"))
187		g_dnl_set_serialnumber("0123456789POPLAR");
188	return 0;
189}
190#endif
191
192int board_init(void)
193{
194	usb2_phy_init();
195
196	return 0;
197}
198