blob: 8334c9bb3765fc439998049af10e0cab19cd3e42 [file] [log] [blame]
Marcel Ziswiler36a439d2022-02-07 11:54:13 +01001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright 2022 Toradex
4 */
5
6#include <common.h>
7#include <asm/arch/clock.h>
8#include <asm/arch/imx8mp_pins.h>
9#include <asm/arch/sys_proto.h>
10#include <asm-generic/gpio.h>
11#include <asm/global_data.h>
12#include <asm/mach-imx/gpio.h>
13#include <asm/mach-imx/iomux-v3.h>
14#include <errno.h>
15#include <env.h>
16#include <init.h>
17#include <linux/delay.h>
18#include <micrel.h>
19#include <miiphy.h>
20#include <netdev.h>
21
22#include "../common/tdx-cfg-block.h"
23
24DECLARE_GLOBAL_DATA_PTR;
25
26#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1)
27#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE)
28
29/* Verdin UART_3, Console/Debug UART */
30static const iomux_v3_cfg_t uart_pads[] = {
31 MX8MP_PAD_UART3_RXD__UART3_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
32 MX8MP_PAD_UART3_TXD__UART3_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
33};
34
35static const iomux_v3_cfg_t wdog_pads[] = {
36 MX8MP_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL),
37};
38
39int board_early_init_f(void)
40{
41 struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
42
43 imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
44
45 set_wdog_reset(wdog);
46
47 imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
48
49 init_uart_clk(2);
50
51 return 0;
52}
53
54static void setup_fec(void)
55{
56 struct iomuxc_gpr_base_regs *gpr =
57 (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
58
59 /* Enable RGMII TX clk output */
60 setbits_le32(&gpr->gpr[1], BIT(22));
61}
62
63static int setup_eqos(void)
64{
65 struct iomuxc_gpr_base_regs *gpr =
66 (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
67
68 /* set INTF as RGMII, enable RGMII TXC clock */
69 clrsetbits_le32(&gpr->gpr[1],
70 IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK, BIT(16));
71 setbits_le32(&gpr->gpr[1], BIT(19) | BIT(21));
72
73 return set_clk_eqos(ENET_125MHZ);
74}
75
76#if IS_ENABLED(CONFIG_NET)
77int board_phy_config(struct phy_device *phydev)
78{
79 if (phydev->drv->config)
80 phydev->drv->config(phydev);
81 return 0;
82}
83#endif
84
85int board_init(void)
86{
87 int ret = 0;
88
89 if (IS_ENABLED(CONFIG_FEC_MXC))
90 setup_fec();
91
92 if (IS_ENABLED(CONFIG_DWC_ETH_QOS))
93 ret = setup_eqos();
94
95 return ret;
96}
97
98static void select_dt_from_module_version(void)
99{
100 char variant[32];
101 char *env_variant = env_get("variant");
102 int is_wifi = 0;
103
104 if (IS_ENABLED(CONFIG_TDX_CFG_BLOCK)) {
105 /*
106 * If we have a valid config block and it says we are a module with
107 * Wi-Fi/Bluetooth make sure we use the -wifi device tree.
108 */
109 is_wifi = (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_WIFI_BT_IT) ||
110 (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_2GB_WIFI_BT_IT) ||
111 (tdx_hw_tag.prodid == VERDIN_IMX8MPQ_8GB_WIFI_BT);
112 }
113
114 if (is_wifi)
115 strlcpy(&variant[0], "wifi", sizeof(variant));
116 else
117 strlcpy(&variant[0], "nonwifi", sizeof(variant));
118
119 if (strcmp(variant, env_variant)) {
120 printf("Setting variant to %s\n", variant);
121 env_set("variant", variant);
122
123 if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE))
124 env_save();
125 }
126}
127
128int board_late_init(void)
129{
130 select_dt_from_module_version();
131
132 return 0;
133}
134
135#if IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_OF_BOARD_SETUP)
136int ft_board_setup(void *blob, struct bd_info *bd)
137{
138 return 0;
139}
140#endif