blob: ee87d9f4145f30162a56e5b4f2bb5cb9e8e4b8d7 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -07002/*
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +02003 * Copyright (c) 2016-2018 Toradex, Inc.
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -07004 */
5
6#include <common.h>
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +02007#include <dm.h>
Simon Glassed38aef2020-05-10 11:40:03 -06008#include <env.h>
Simon Glass97589732020-05-10 11:40:02 -06009#include <init.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070011#include <asm/arch-tegra/ap.h>
12#include <asm/gpio.h>
13#include <asm/io.h>
14#include <asm/arch/gpio.h>
15#include <asm/arch/pinmux.h>
Simon Glass9d1f6192019-08-02 09:44:25 -060016#include <env_internal.h>
Marcel Ziswiler61c99fe2022-05-21 12:42:46 +020017#include <fdt_support.h>
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +020018#include <pci_tegra.h>
Simon Glassdbd79542020-05-10 11:40:11 -060019#include <linux/delay.h>
Simon Glassbdd5f812023-09-14 18:21:46 -060020#include <linux/printk.h>
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070021#include <power/as3722.h>
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +020022#include <power/pmic.h>
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070023
24#include "../common/tdx-common.h"
25#include "pinmux-config-apalis-tk1.h"
26
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +020027#define LAN_DEV_OFF_N TEGRA_GPIO(O, 6)
28#define LAN_RESET_N TEGRA_GPIO(S, 2)
Igor Opaniukfeb8c0d2019-08-01 11:06:32 +030029#define FAN_EN TEGRA_GPIO(DD, 2)
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +020030#define LAN_WAKE_N TEGRA_GPIO(O, 5)
31#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
32#define PEX_PERST_N TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */
33#define RESET_MOCI_CTRL TEGRA_GPIO(U, 4)
34#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
Marcel Ziswiler46eb7292019-08-09 13:21:46 +030035#define VCC_USBH TEGRA_GPIO(T, 6)
36#define VCC_USBH_V1_0 TEGRA_GPIO(N, 5)
37#define VCC_USBO1 TEGRA_GPIO(T, 5)
38#define VCC_USBO1_V1_0 TEGRA_GPIO(N, 4)
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070039
40int arch_misc_init(void)
41{
42 if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
Marcel Ziswiler55fb0572021-08-11 15:12:56 +020043 NVBOOTTYPE_RECOVERY) {
44 printf("USB recovery mode, attempting to boot Toradex Easy "
45 "Installer\n");
46 env_set("bootdelay", "-2");
47 env_set("defargs", "pcie_aspm=off user_debug=30");
48 env_set("fdt_high", "");
49 env_set("initrd_high", "");
50
51 env_set("setup", "env set setupargs igb_mac=${ethaddr} "
52 "consoleblank=0 no_console_suspend=1 "
53 "console=${console},${baudrate}n8 ${memargs}");
54 env_set("teziargs", "rootfstype=squashfs root=/dev/ram quiet "
55 "autoinstall");
56 env_set("vidargs", "video=HDMI-A-1:640x480-16@60D");
57 env_set("bootcmd", "run setup; env set bootargs ${defargs} "
58 "${setupargs} ${vidargs} ${teziargs}; bootm 0x80208000"
59 "#config@${soc}-${fdt_module}-${fdt_board}.dtb");
60 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070061
Marcel Ziswiler46eb7292019-08-09 13:21:46 +030062 /* PCB Version Indication: V1.2 and later have GPIO_PV0 wired to GND */
63 gpio_request(TEGRA_GPIO(V, 0), "PCB Version Indication");
64 gpio_direction_input(TEGRA_GPIO(V, 0));
65 if (gpio_get_value(TEGRA_GPIO(V, 0))) {
66 /*
67 * if using the default device tree for new V1.2 and later HW,
68 * use version for older V1.0 and V1.1 HW
69 */
70 char *fdt_env = env_get("fdt_module");
71
72 if (fdt_env && !strcmp(FDT_MODULE, fdt_env)) {
73 env_set("fdt_module", FDT_MODULE_V1_0);
74 printf("patching fdt_module to " FDT_MODULE_V1_0
75 " for older V1.0 and V1.1 HW\n");
Marcel Ziswiler46eb7292019-08-09 13:21:46 +030076 }
77
78 /* activate USB power enable GPIOs */
79 gpio_request(VCC_USBH_V1_0, "VCC_USBH");
80 gpio_direction_output(VCC_USBH_V1_0, 1);
81 gpio_request(VCC_USBO1_V1_0, "VCC_USBO1");
82 gpio_direction_output(VCC_USBO1_V1_0, 1);
83 } else {
84 /* activate USB power enable GPIOs */
85 gpio_request(VCC_USBH, "VCC_USBH");
86 gpio_direction_output(VCC_USBH, 1);
87 gpio_request(VCC_USBO1, "VCC_USBO1");
88 gpio_direction_output(VCC_USBO1, 1);
89 }
90
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070091 return 0;
92}
93
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070094#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +090095int ft_board_setup(void *blob, struct bd_info *bd)
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070096{
Marcel Ziswiler61c99fe2022-05-21 12:42:46 +020097 u8 enetaddr[6];
98
99 /* MAC addr */
100 if (eth_env_get_enetaddr("ethaddr", enetaddr)) {
101 int err = fdt_find_and_setprop(blob,
102 "/pcie@1003000/pci@2,0/ethernet@0,0",
103 "local-mac-address", enetaddr, 6, 0);
104
105 /* Older device trees might have used a different node name */
106 if (err < 0)
107 err = fdt_find_and_setprop(blob,
108 "/pcie@1003000/pci@2,0/pcie@0",
109 "local-mac-address", enetaddr, 6, 0);
110
111 if (err >= 0)
112 puts(" MAC address updated...\n");
113 }
114
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700115 return ft_common_board_setup(blob, bd);
116}
117#endif
118
119/*
120 * Routine: pinmux_init
121 * Description: Do individual peripheral pinmux configs
122 */
123void pinmux_init(void)
124{
125 pinmux_clear_tristate_input_clamping();
126
127 gpio_config_table(apalis_tk1_gpio_inits,
128 ARRAY_SIZE(apalis_tk1_gpio_inits));
129
130 pinmux_config_pingrp_table(apalis_tk1_pingrps,
131 ARRAY_SIZE(apalis_tk1_pingrps));
132
133 pinmux_config_drvgrp_table(apalis_tk1_drvgrps,
134 ARRAY_SIZE(apalis_tk1_drvgrps));
135}
136
137#ifdef CONFIG_PCI_TEGRA
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200138/* TODO: Convert to driver model */
139static int as3722_sd_enable(struct udevice *pmic, unsigned int sd)
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700140{
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700141 int err;
142
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200143 if (sd > 6)
144 return -EINVAL;
145
146 err = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700147 if (err) {
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200148 pr_err("failed to update SD control register: %d", err);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700149 return err;
150 }
151
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200152 return 0;
153}
154
155/* TODO: Convert to driver model */
156static int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo)
157{
158 int err;
159 u8 ctrl_reg = AS3722_LDO_CONTROL0;
160
161 if (ldo > 11)
162 return -EINVAL;
163
164 if (ldo > 7) {
165 ctrl_reg = AS3722_LDO_CONTROL1;
166 ldo -= 8;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700167 }
168
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200169 err = pmic_clrsetbits(pmic, ctrl_reg, 0, 1 << ldo);
170 if (err) {
171 pr_err("failed to update LDO control register: %d", err);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700172 return err;
173 }
174
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200175 return 0;
176}
177
178int tegra_pcie_board_init(void)
179{
180 struct udevice *dev;
181 int ret;
182
183 ret = uclass_get_device_by_driver(UCLASS_PMIC,
Simon Glass65130cd2020-12-28 20:34:56 -0700184 DM_DRIVER_GET(pmic_as3722), &dev);
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200185 if (ret) {
186 pr_err("failed to find AS3722 PMIC: %d\n", ret);
187 return ret;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700188 }
189
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200190 ret = as3722_sd_enable(dev, 4);
191 if (ret < 0) {
192 pr_err("failed to enable SD4: %d\n", ret);
193 return ret;
194 }
195
196 ret = as3722_sd_set_voltage(dev, 4, 0x24);
197 if (ret < 0) {
198 pr_err("failed to set SD4 voltage: %d\n", ret);
199 return ret;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700200 }
201
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200202 gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N");
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700203 gpio_request(LAN_RESET_N, "LAN_RESET_N");
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200204 gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
205
206#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
207 gpio_request(PEX_PERST_N, "PEX_PERST_N");
208 gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL");
209#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700210
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200211 return 0;
212}
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700213
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200214void tegra_pcie_board_port_reset(struct tegra_pcie_port *port)
215{
216 int index = tegra_pcie_port_index_of_port(port);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700217
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200218 if (index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */
219 struct udevice *dev;
220 int ret;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700221
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200222 ret = uclass_get_device_by_driver(UCLASS_PMIC,
Simon Glass65130cd2020-12-28 20:34:56 -0700223 DM_DRIVER_GET(pmic_as3722),
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200224 &dev);
225 if (ret) {
226 debug("%s: Failed to find PMIC\n", __func__);
227 return;
228 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700229
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200230 /* Reset I210 Gigabit Ethernet Controller */
231 gpio_direction_output(LAN_RESET_N, 0);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700232
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200233 /*
234 * Make sure we don't get any back feeding from DEV_OFF_N resp.
235 * LAN_WAKE_N
236 */
237 gpio_direction_output(LAN_DEV_OFF_N, 0);
238 gpio_direction_output(LAN_WAKE_N, 0);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700239
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200240 /* Make sure LDO9 and LDO10 are initially enabled @ 0V */
241 ret = as3722_ldo_enable(dev, 9);
242 if (ret < 0) {
243 pr_err("failed to enable LDO9: %d\n", ret);
244 return;
245 }
246 ret = as3722_ldo_enable(dev, 10);
247 if (ret < 0) {
248 pr_err("failed to enable LDO10: %d\n", ret);
249 return;
250 }
251 ret = as3722_ldo_set_voltage(dev, 9, 0x80);
252 if (ret < 0) {
253 pr_err("failed to set LDO9 voltage: %d\n", ret);
254 return;
255 }
256 ret = as3722_ldo_set_voltage(dev, 10, 0x80);
257 if (ret < 0) {
258 pr_err("failed to set LDO10 voltage: %d\n", ret);
259 return;
260 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700261
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200262 /* Make sure controller gets enabled by disabling DEV_OFF_N */
263 gpio_set_value(LAN_DEV_OFF_N, 1);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700264
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200265 /*
266 * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype
267 * V1.0A and sample V1.0B and newer modules
268 */
269 ret = as3722_ldo_set_voltage(dev, 9, 0xff);
270 if (ret < 0) {
271 pr_err("failed to set LDO9 voltage: %d\n", ret);
272 return;
273 }
274 ret = as3722_ldo_set_voltage(dev, 10, 0xff);
275 if (ret < 0) {
276 pr_err("failed to set LDO10 voltage: %d\n", ret);
277 return;
278 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700279
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200280 /*
281 * Must be asserted for 100 ms after power and clocks are stable
282 */
283 mdelay(100);
284
285 gpio_set_value(LAN_RESET_N, 1);
286 } else if (index == 0) { /* Apalis PCIe */
287#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
288 /*
289 * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis
290 * Evaluation Board
291 */
292 gpio_direction_output(PEX_PERST_N, 0);
293 gpio_direction_output(RESET_MOCI_CTRL, 0);
294
295 /*
296 * Must be asserted for 100 ms after power and clocks are stable
297 */
298 mdelay(100);
299
300 gpio_set_value(PEX_PERST_N, 1);
301 /*
302 * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed
303 * Until 900 us After PEX_PERST# De-assertion
304 */
305 mdelay(1);
306 gpio_set_value(RESET_MOCI_CTRL, 1);
307#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
308 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700309}
310#endif /* CONFIG_PCI_TEGRA */
Gerard Salvatella108d7392018-11-19 15:54:10 +0100311
312/*
Igor Opaniukfeb8c0d2019-08-01 11:06:32 +0300313 * Enable/start PWM CPU fan
314 */
315void start_cpu_fan(void)
316{
317 gpio_request(FAN_EN, "FAN_EN");
318 gpio_direction_output(FAN_EN, 1);
319}
320
321/*
Gerard Salvatella108d7392018-11-19 15:54:10 +0100322 * Backlight off before OS handover
323 */
324void board_preboot_os(void)
325{
326 gpio_request(TEGRA_GPIO(BB, 5), "BL_ON");
327 gpio_direction_output(TEGRA_GPIO(BB, 5), 0);
328}