blob: 79a1c92da0a09bb86054621f45c00deb8eeea920 [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
94int checkboard(void)
95{
96 puts("Model: Toradex Apalis TK1 2GB\n");
97
Simon Glassd44a1102023-11-12 19:58:25 -070098 return tdx_checkboard();
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -070099}
100
101#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900102int ft_board_setup(void *blob, struct bd_info *bd)
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700103{
Marcel Ziswiler61c99fe2022-05-21 12:42:46 +0200104 u8 enetaddr[6];
105
106 /* MAC addr */
107 if (eth_env_get_enetaddr("ethaddr", enetaddr)) {
108 int err = fdt_find_and_setprop(blob,
109 "/pcie@1003000/pci@2,0/ethernet@0,0",
110 "local-mac-address", enetaddr, 6, 0);
111
112 /* Older device trees might have used a different node name */
113 if (err < 0)
114 err = fdt_find_and_setprop(blob,
115 "/pcie@1003000/pci@2,0/pcie@0",
116 "local-mac-address", enetaddr, 6, 0);
117
118 if (err >= 0)
119 puts(" MAC address updated...\n");
120 }
121
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700122 return ft_common_board_setup(blob, bd);
123}
124#endif
125
126/*
127 * Routine: pinmux_init
128 * Description: Do individual peripheral pinmux configs
129 */
130void pinmux_init(void)
131{
132 pinmux_clear_tristate_input_clamping();
133
134 gpio_config_table(apalis_tk1_gpio_inits,
135 ARRAY_SIZE(apalis_tk1_gpio_inits));
136
137 pinmux_config_pingrp_table(apalis_tk1_pingrps,
138 ARRAY_SIZE(apalis_tk1_pingrps));
139
140 pinmux_config_drvgrp_table(apalis_tk1_drvgrps,
141 ARRAY_SIZE(apalis_tk1_drvgrps));
142}
143
144#ifdef CONFIG_PCI_TEGRA
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200145/* TODO: Convert to driver model */
146static int as3722_sd_enable(struct udevice *pmic, unsigned int sd)
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700147{
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700148 int err;
149
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200150 if (sd > 6)
151 return -EINVAL;
152
153 err = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700154 if (err) {
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200155 pr_err("failed to update SD control register: %d", err);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700156 return err;
157 }
158
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200159 return 0;
160}
161
162/* TODO: Convert to driver model */
163static int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo)
164{
165 int err;
166 u8 ctrl_reg = AS3722_LDO_CONTROL0;
167
168 if (ldo > 11)
169 return -EINVAL;
170
171 if (ldo > 7) {
172 ctrl_reg = AS3722_LDO_CONTROL1;
173 ldo -= 8;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700174 }
175
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200176 err = pmic_clrsetbits(pmic, ctrl_reg, 0, 1 << ldo);
177 if (err) {
178 pr_err("failed to update LDO control register: %d", err);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700179 return err;
180 }
181
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200182 return 0;
183}
184
185int tegra_pcie_board_init(void)
186{
187 struct udevice *dev;
188 int ret;
189
190 ret = uclass_get_device_by_driver(UCLASS_PMIC,
Simon Glass65130cd2020-12-28 20:34:56 -0700191 DM_DRIVER_GET(pmic_as3722), &dev);
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200192 if (ret) {
193 pr_err("failed to find AS3722 PMIC: %d\n", ret);
194 return ret;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700195 }
196
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200197 ret = as3722_sd_enable(dev, 4);
198 if (ret < 0) {
199 pr_err("failed to enable SD4: %d\n", ret);
200 return ret;
201 }
202
203 ret = as3722_sd_set_voltage(dev, 4, 0x24);
204 if (ret < 0) {
205 pr_err("failed to set SD4 voltage: %d\n", ret);
206 return ret;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700207 }
208
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200209 gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N");
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700210 gpio_request(LAN_RESET_N, "LAN_RESET_N");
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200211 gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
212
213#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
214 gpio_request(PEX_PERST_N, "PEX_PERST_N");
215 gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL");
216#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700217
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200218 return 0;
219}
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700220
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200221void tegra_pcie_board_port_reset(struct tegra_pcie_port *port)
222{
223 int index = tegra_pcie_port_index_of_port(port);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700224
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200225 if (index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */
226 struct udevice *dev;
227 int ret;
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700228
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200229 ret = uclass_get_device_by_driver(UCLASS_PMIC,
Simon Glass65130cd2020-12-28 20:34:56 -0700230 DM_DRIVER_GET(pmic_as3722),
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200231 &dev);
232 if (ret) {
233 debug("%s: Failed to find PMIC\n", __func__);
234 return;
235 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700236
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200237 /* Reset I210 Gigabit Ethernet Controller */
238 gpio_direction_output(LAN_RESET_N, 0);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700239
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200240 /*
241 * Make sure we don't get any back feeding from DEV_OFF_N resp.
242 * LAN_WAKE_N
243 */
244 gpio_direction_output(LAN_DEV_OFF_N, 0);
245 gpio_direction_output(LAN_WAKE_N, 0);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700246
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200247 /* Make sure LDO9 and LDO10 are initially enabled @ 0V */
248 ret = as3722_ldo_enable(dev, 9);
249 if (ret < 0) {
250 pr_err("failed to enable LDO9: %d\n", ret);
251 return;
252 }
253 ret = as3722_ldo_enable(dev, 10);
254 if (ret < 0) {
255 pr_err("failed to enable LDO10: %d\n", ret);
256 return;
257 }
258 ret = as3722_ldo_set_voltage(dev, 9, 0x80);
259 if (ret < 0) {
260 pr_err("failed to set LDO9 voltage: %d\n", ret);
261 return;
262 }
263 ret = as3722_ldo_set_voltage(dev, 10, 0x80);
264 if (ret < 0) {
265 pr_err("failed to set LDO10 voltage: %d\n", ret);
266 return;
267 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700268
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200269 /* Make sure controller gets enabled by disabling DEV_OFF_N */
270 gpio_set_value(LAN_DEV_OFF_N, 1);
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700271
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200272 /*
273 * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype
274 * V1.0A and sample V1.0B and newer modules
275 */
276 ret = as3722_ldo_set_voltage(dev, 9, 0xff);
277 if (ret < 0) {
278 pr_err("failed to set LDO9 voltage: %d\n", ret);
279 return;
280 }
281 ret = as3722_ldo_set_voltage(dev, 10, 0xff);
282 if (ret < 0) {
283 pr_err("failed to set LDO10 voltage: %d\n", ret);
284 return;
285 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700286
Marcel Ziswiler07ce1a62018-05-08 17:34:11 +0200287 /*
288 * Must be asserted for 100 ms after power and clocks are stable
289 */
290 mdelay(100);
291
292 gpio_set_value(LAN_RESET_N, 1);
293 } else if (index == 0) { /* Apalis PCIe */
294#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
295 /*
296 * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis
297 * Evaluation Board
298 */
299 gpio_direction_output(PEX_PERST_N, 0);
300 gpio_direction_output(RESET_MOCI_CTRL, 0);
301
302 /*
303 * Must be asserted for 100 ms after power and clocks are stable
304 */
305 mdelay(100);
306
307 gpio_set_value(PEX_PERST_N, 1);
308 /*
309 * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed
310 * Until 900 us After PEX_PERST# De-assertion
311 */
312 mdelay(1);
313 gpio_set_value(RESET_MOCI_CTRL, 1);
314#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
315 }
Marcel Ziswilerd2b64bd2017-04-01 15:43:16 -0700316}
317#endif /* CONFIG_PCI_TEGRA */
Gerard Salvatella108d7392018-11-19 15:54:10 +0100318
319/*
Igor Opaniukfeb8c0d2019-08-01 11:06:32 +0300320 * Enable/start PWM CPU fan
321 */
322void start_cpu_fan(void)
323{
324 gpio_request(FAN_EN, "FAN_EN");
325 gpio_direction_output(FAN_EN, 1);
326}
327
328/*
Gerard Salvatella108d7392018-11-19 15:54:10 +0100329 * Backlight off before OS handover
330 */
331void board_preboot_os(void)
332{
333 gpio_request(TEGRA_GPIO(BB, 5), "BL_ON");
334 gpio_direction_output(TEGRA_GPIO(BB, 5), 0);
335}