1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2017 NXP Semiconductors
4 */
5
6#include <init.h>
7#include <net.h>
8#include <asm/arch/clock.h>
9#include <asm/arch/crm_regs.h>
10#include <asm/arch/imx-regs.h>
11#include <asm/arch/mx7-pins.h>
12#include <asm/arch/sys_proto.h>
13#include <asm/global_data.h>
14#include <asm/gpio.h>
15#include <asm/mach-imx/iomux-v3.h>
16#include <asm/mach-imx/boot_mode.h>
17#include <asm/io.h>
18#include <common.h>
19#include <miiphy.h>
20#include <power/pmic.h>
21#include <power/pfuze3000_pmic.h>
22#include "../../freescale/common/pfuze.h"
23
24DECLARE_GLOBAL_DATA_PTR;
25
26#define UART_PAD_CTRL  (PAD_CTL_DSE_3P3V_49OHM | \
27	PAD_CTL_PUS_PU100KOHM | PAD_CTL_HYS)
28
29#define PICO_MMC0 0
30#define PICO_MMC0_BLK 2
31#define PICO_MMC1 1
32#define PICO_MMC1_BLK 0
33
34int dram_init(void)
35{
36	gd->ram_size = imx_ddr_size();
37
38	/* Subtract the defined OPTEE runtime firmware length */
39#ifdef CONFIG_OPTEE_TZDRAM_SIZE
40		gd->ram_size -= CONFIG_OPTEE_TZDRAM_SIZE;
41#endif
42
43	return 0;
44}
45
46#if CONFIG_IS_ENABLED(DM_PMIC)
47int power_init_board(void)
48{
49	struct udevice *dev;
50	int reg, rev_id;
51	int ret;
52
53	ret = pmic_get("pfuze3000@8", &dev);
54	if (ret == -ENODEV)
55		return 0;
56	if (ret != 0)
57		return ret;
58
59	reg = pmic_reg_read(dev, PFUZE3000_DEVICEID);
60	rev_id = pmic_reg_read(dev, PFUZE3000_REVID);
61	printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id);
62
63	/* disable Low Power Mode during standby mode */
64	reg = pmic_reg_read(dev, PFUZE3000_LDOGCTL);
65	reg |= 0x1;
66	pmic_reg_write(dev, PFUZE3000_LDOGCTL, reg);
67
68	/* SW1A/1B mode set to APS/APS */
69	reg = 0x8;
70	pmic_reg_write(dev, PFUZE3000_SW1AMODE, reg);
71	pmic_reg_write(dev, PFUZE3000_SW1BMODE, reg);
72
73	/* SW1A/1B standby voltage set to 1.025V */
74	reg = 0xd;
75	pmic_reg_write(dev, PFUZE3000_SW1ASTBY, reg);
76	pmic_reg_write(dev, PFUZE3000_SW1BSTBY, reg);
77
78	/* decrease SW1B normal voltage to 0.975V */
79	reg = pmic_reg_read(dev, PFUZE3000_SW1BVOLT);
80	reg &= ~0x1f;
81	reg |= PFUZE3000_SW1AB_SETP(975);
82	pmic_reg_write(dev, PFUZE3000_SW1BVOLT, reg);
83
84	return 0;
85}
86#endif
87
88static iomux_v3_cfg_t const wdog_pads[] = {
89	MX7D_PAD_GPIO1_IO00__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL),
90};
91
92static iomux_v3_cfg_t const uart5_pads[] = {
93	MX7D_PAD_I2C4_SCL__UART5_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
94	MX7D_PAD_I2C4_SDA__UART5_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
95};
96
97#ifdef CONFIG_FEC_MXC
98static int setup_fec(void)
99{
100	struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs
101		= (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
102
103	/* Use 125M anatop REF_CLK1 for ENET1, clear gpr1[13], gpr1[17] */
104	clrsetbits_le32(&iomuxc_gpr_regs->gpr[1],
105			(IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK |
106			IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0);
107
108	return set_clk_enet(ENET_125MHZ);
109}
110#endif
111
112static void setup_iomux_uart(void)
113{
114	imx_iomux_v3_setup_multiple_pads(uart5_pads, ARRAY_SIZE(uart5_pads));
115}
116
117int board_early_init_f(void)
118{
119	setup_iomux_uart();
120
121	return 0;
122}
123
124#ifdef CONFIG_VIDEO
125void setup_lcd(void)
126{
127	gpio_request(IMX_GPIO_NR(1, 11), "lcd_brightness");
128	gpio_request(IMX_GPIO_NR(1, 6), "lcd_enable");
129	/* Set Brightness to high */
130	gpio_direction_output(IMX_GPIO_NR(1, 11) , 1);
131	/* Set LCD enable to high */
132	gpio_direction_output(IMX_GPIO_NR(1, 6) , 1);
133}
134#endif
135
136int board_init(void)
137{
138	/* address of boot parameters */
139	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
140
141#ifdef CONFIG_VIDEO
142	setup_lcd();
143#endif
144#ifdef CONFIG_FEC_MXC
145	setup_fec();
146#endif
147
148	return 0;
149}
150
151int board_late_init(void)
152{
153	struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
154
155	imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
156
157	set_wdog_reset(wdog);
158
159#if CONFIG_IS_ENABLED(FSL_ESDHC_IMX)
160#if CONFIG_IS_ENABLED(ENV_IS_IN_MMC) || CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
161	board_late_mmc_env_init();
162#endif /* CONFIG_ENV_IS_IN_MMC or CONFIG_ENV_IS_NOWHERE */
163#endif
164
165	/*
166	 * Do not assert internal WDOG_RESET_B_DEB(controlled by bit 4),
167	 * since we use PMIC_PWRON to reset the board.
168	 */
169	clrsetbits_le16(&wdog->wcr, 0, 0x10);
170
171	return 0;
172}
173
174int checkboard(void)
175{
176	puts("Board: i.MX7D PICOSOM\n");
177
178	return 0;
179}
180
181static iomux_v3_cfg_t const usb_otg2_pads[] = {
182	MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
183};
184
185int board_ehci_hcd_init(int port)
186{
187	switch (port) {
188	case 0:
189		break;
190	case 1:
191		imx_iomux_v3_setup_multiple_pads(usb_otg2_pads,
192						 ARRAY_SIZE(usb_otg2_pads));
193		break;
194	default:
195		return -EINVAL;
196	}
197	return 0;
198}
199
200#if CONFIG_IS_ENABLED(FSL_ESDHC_IMX)
201#if CONFIG_IS_ENABLED(ENV_IS_IN_MMC) || CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
202int board_mmc_get_env_dev(int devno)
203{
204	int dev_env = 0;
205
206	switch (get_boot_device()) {
207	case SD3_BOOT:
208	case MMC3_BOOT:
209		env_set("bootdev", "MMC3");
210		dev_env = PICO_MMC0;
211		break;
212	case SD1_BOOT:
213		env_set("bootdev", "SD1");
214		dev_env = PICO_MMC1;
215		break;
216	default:
217		printf("Wrong boot device!");
218	}
219
220	return dev_env;
221}
222
223int mmc_map_to_kernel_blk(int dev_no)
224{
225	int blk_no = 0;
226
227	switch (dev_no) {
228	case PICO_MMC0:
229		blk_no = PICO_MMC0_BLK;
230		break;
231	case PICO_MMC1:
232		blk_no = PICO_MMC1_BLK;
233		break;
234	default:
235		printf("Invalid MMC device!");
236	}
237
238	return blk_no;
239}
240#endif
241
242#if CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
243int mmc_get_env_dev(void)
244{
245	return board_mmc_get_env_dev(0);
246}
247#endif
248#endif /* CONFIG_FSL_ESDHC_IMX */
249