183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2f38f5f4bSMarcel Ziswiler /*
3f1333417SMarcel Ziswiler  * Copyright (c) 2016-2018 Toradex, Inc.
4f38f5f4bSMarcel Ziswiler  */
5f38f5f4bSMarcel Ziswiler 
6f38f5f4bSMarcel Ziswiler #include <common.h>
7f1333417SMarcel Ziswiler #include <dm.h>
8f38f5f4bSMarcel Ziswiler #include <asm/arch-tegra/ap.h>
9f38f5f4bSMarcel Ziswiler #include <asm/gpio.h>
10f38f5f4bSMarcel Ziswiler #include <asm/io.h>
11f38f5f4bSMarcel Ziswiler #include <asm/arch/gpio.h>
12f38f5f4bSMarcel Ziswiler #include <asm/arch/pinmux.h>
13f1333417SMarcel Ziswiler #include <pci_tegra.h>
14f38f5f4bSMarcel Ziswiler #include <power/as3722.h>
15f1333417SMarcel Ziswiler #include <power/pmic.h>
16f38f5f4bSMarcel Ziswiler 
17f38f5f4bSMarcel Ziswiler #include "../common/tdx-common.h"
18f38f5f4bSMarcel Ziswiler #include "pinmux-config-apalis-tk1.h"
19f38f5f4bSMarcel Ziswiler 
20f1333417SMarcel Ziswiler #define LAN_DEV_OFF_N	TEGRA_GPIO(O, 6)
21f38f5f4bSMarcel Ziswiler #define LAN_RESET_N	TEGRA_GPIO(S, 2)
22f1333417SMarcel Ziswiler #define LAN_WAKE_N	TEGRA_GPIO(O, 5)
23f1333417SMarcel Ziswiler #ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
24f1333417SMarcel Ziswiler #define PEX_PERST_N	TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */
25f1333417SMarcel Ziswiler #define RESET_MOCI_CTRL	TEGRA_GPIO(U, 4)
26f1333417SMarcel Ziswiler #endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
27f38f5f4bSMarcel Ziswiler 
arch_misc_init(void)28f38f5f4bSMarcel Ziswiler int arch_misc_init(void)
29f38f5f4bSMarcel Ziswiler {
30f38f5f4bSMarcel Ziswiler 	if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
31f38f5f4bSMarcel Ziswiler 	    NVBOOTTYPE_RECOVERY)
32f38f5f4bSMarcel Ziswiler 		printf("USB recovery mode\n");
33f38f5f4bSMarcel Ziswiler 
34f38f5f4bSMarcel Ziswiler 	return 0;
35f38f5f4bSMarcel Ziswiler }
36f38f5f4bSMarcel Ziswiler 
checkboard(void)37f38f5f4bSMarcel Ziswiler int checkboard(void)
38f38f5f4bSMarcel Ziswiler {
39f38f5f4bSMarcel Ziswiler 	puts("Model: Toradex Apalis TK1 2GB\n");
40f38f5f4bSMarcel Ziswiler 
41f38f5f4bSMarcel Ziswiler 	return 0;
42f38f5f4bSMarcel Ziswiler }
43f38f5f4bSMarcel Ziswiler 
44f38f5f4bSMarcel Ziswiler #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
ft_board_setup(void * blob,bd_t * bd)45f38f5f4bSMarcel Ziswiler int ft_board_setup(void *blob, bd_t *bd)
46f38f5f4bSMarcel Ziswiler {
47f38f5f4bSMarcel Ziswiler 	return ft_common_board_setup(blob, bd);
48f38f5f4bSMarcel Ziswiler }
49f38f5f4bSMarcel Ziswiler #endif
50f38f5f4bSMarcel Ziswiler 
51f38f5f4bSMarcel Ziswiler /*
52f38f5f4bSMarcel Ziswiler  * Routine: pinmux_init
53f38f5f4bSMarcel Ziswiler  * Description: Do individual peripheral pinmux configs
54f38f5f4bSMarcel Ziswiler  */
pinmux_init(void)55f38f5f4bSMarcel Ziswiler void pinmux_init(void)
56f38f5f4bSMarcel Ziswiler {
57f38f5f4bSMarcel Ziswiler 	pinmux_clear_tristate_input_clamping();
58f38f5f4bSMarcel Ziswiler 
59f38f5f4bSMarcel Ziswiler 	gpio_config_table(apalis_tk1_gpio_inits,
60f38f5f4bSMarcel Ziswiler 			  ARRAY_SIZE(apalis_tk1_gpio_inits));
61f38f5f4bSMarcel Ziswiler 
62f38f5f4bSMarcel Ziswiler 	pinmux_config_pingrp_table(apalis_tk1_pingrps,
63f38f5f4bSMarcel Ziswiler 				   ARRAY_SIZE(apalis_tk1_pingrps));
64f38f5f4bSMarcel Ziswiler 
65f38f5f4bSMarcel Ziswiler 	pinmux_config_drvgrp_table(apalis_tk1_drvgrps,
66f38f5f4bSMarcel Ziswiler 				   ARRAY_SIZE(apalis_tk1_drvgrps));
67f38f5f4bSMarcel Ziswiler }
68f38f5f4bSMarcel Ziswiler 
69f38f5f4bSMarcel Ziswiler #ifdef CONFIG_PCI_TEGRA
70f1333417SMarcel Ziswiler /* TODO: Convert to driver model */
as3722_sd_enable(struct udevice * pmic,unsigned int sd)71f1333417SMarcel Ziswiler static int as3722_sd_enable(struct udevice *pmic, unsigned int sd)
72f38f5f4bSMarcel Ziswiler {
73f38f5f4bSMarcel Ziswiler 	int err;
74f38f5f4bSMarcel Ziswiler 
75f1333417SMarcel Ziswiler 	if (sd > 6)
76f1333417SMarcel Ziswiler 		return -EINVAL;
77f1333417SMarcel Ziswiler 
78f1333417SMarcel Ziswiler 	err = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd);
79f38f5f4bSMarcel Ziswiler 	if (err) {
80f1333417SMarcel Ziswiler 		pr_err("failed to update SD control register: %d", err);
81f38f5f4bSMarcel Ziswiler 		return err;
82f38f5f4bSMarcel Ziswiler 	}
83f38f5f4bSMarcel Ziswiler 
84f1333417SMarcel Ziswiler 	return 0;
85f1333417SMarcel Ziswiler }
86f1333417SMarcel Ziswiler 
87f1333417SMarcel Ziswiler /* TODO: Convert to driver model */
as3722_ldo_enable(struct udevice * pmic,unsigned int ldo)88f1333417SMarcel Ziswiler static int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo)
89f1333417SMarcel Ziswiler {
90f1333417SMarcel Ziswiler 	int err;
91f1333417SMarcel Ziswiler 	u8 ctrl_reg = AS3722_LDO_CONTROL0;
92f1333417SMarcel Ziswiler 
93f1333417SMarcel Ziswiler 	if (ldo > 11)
94f1333417SMarcel Ziswiler 		return -EINVAL;
95f1333417SMarcel Ziswiler 
96f1333417SMarcel Ziswiler 	if (ldo > 7) {
97f1333417SMarcel Ziswiler 		ctrl_reg = AS3722_LDO_CONTROL1;
98f1333417SMarcel Ziswiler 		ldo -= 8;
99f1333417SMarcel Ziswiler 	}
100f1333417SMarcel Ziswiler 
101f1333417SMarcel Ziswiler 	err = pmic_clrsetbits(pmic, ctrl_reg, 0, 1 << ldo);
102f1333417SMarcel Ziswiler 	if (err) {
103f1333417SMarcel Ziswiler 		pr_err("failed to update LDO control register: %d", err);
104f38f5f4bSMarcel Ziswiler 		return err;
105f38f5f4bSMarcel Ziswiler 	}
106f38f5f4bSMarcel Ziswiler 
107f1333417SMarcel Ziswiler 	return 0;
108f38f5f4bSMarcel Ziswiler }
109f38f5f4bSMarcel Ziswiler 
tegra_pcie_board_init(void)110f1333417SMarcel Ziswiler int tegra_pcie_board_init(void)
111f1333417SMarcel Ziswiler {
112f1333417SMarcel Ziswiler 	struct udevice *dev;
113f1333417SMarcel Ziswiler 	int ret;
114f1333417SMarcel Ziswiler 
115f1333417SMarcel Ziswiler 	ret = uclass_get_device_by_driver(UCLASS_PMIC,
116f1333417SMarcel Ziswiler 					  DM_GET_DRIVER(pmic_as3722), &dev);
117f1333417SMarcel Ziswiler 	if (ret) {
118f1333417SMarcel Ziswiler 		pr_err("failed to find AS3722 PMIC: %d\n", ret);
119f1333417SMarcel Ziswiler 		return ret;
120f38f5f4bSMarcel Ziswiler 	}
121f38f5f4bSMarcel Ziswiler 
122f1333417SMarcel Ziswiler 	ret = as3722_sd_enable(dev, 4);
123f1333417SMarcel Ziswiler 	if (ret < 0) {
124f1333417SMarcel Ziswiler 		pr_err("failed to enable SD4: %d\n", ret);
125f1333417SMarcel Ziswiler 		return ret;
126f38f5f4bSMarcel Ziswiler 	}
127f1333417SMarcel Ziswiler 
128f1333417SMarcel Ziswiler 	ret = as3722_sd_set_voltage(dev, 4, 0x24);
129f1333417SMarcel Ziswiler 	if (ret < 0) {
130f1333417SMarcel Ziswiler 		pr_err("failed to set SD4 voltage: %d\n", ret);
131f1333417SMarcel Ziswiler 		return ret;
132f1333417SMarcel Ziswiler 	}
133f1333417SMarcel Ziswiler 
134f1333417SMarcel Ziswiler 	gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N");
135f1333417SMarcel Ziswiler 	gpio_request(LAN_RESET_N, "LAN_RESET_N");
136f1333417SMarcel Ziswiler 	gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
137f1333417SMarcel Ziswiler 
138f1333417SMarcel Ziswiler #ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
139f1333417SMarcel Ziswiler 	gpio_request(PEX_PERST_N, "PEX_PERST_N");
140f1333417SMarcel Ziswiler 	gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL");
141f1333417SMarcel Ziswiler #endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
142f1333417SMarcel Ziswiler 
143f1333417SMarcel Ziswiler 	return 0;
144f1333417SMarcel Ziswiler }
145f1333417SMarcel Ziswiler 
tegra_pcie_board_port_reset(struct tegra_pcie_port * port)146f1333417SMarcel Ziswiler void tegra_pcie_board_port_reset(struct tegra_pcie_port *port)
147f1333417SMarcel Ziswiler {
148f1333417SMarcel Ziswiler 	int index = tegra_pcie_port_index_of_port(port);
149f1333417SMarcel Ziswiler 
150f1333417SMarcel Ziswiler 	if (index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */
151f1333417SMarcel Ziswiler 		struct udevice *dev;
152f1333417SMarcel Ziswiler 		int ret;
153f1333417SMarcel Ziswiler 
154f1333417SMarcel Ziswiler 		ret = uclass_get_device_by_driver(UCLASS_PMIC,
155f1333417SMarcel Ziswiler 						  DM_GET_DRIVER(pmic_as3722),
156f1333417SMarcel Ziswiler 						  &dev);
157f1333417SMarcel Ziswiler 		if (ret) {
158f1333417SMarcel Ziswiler 			debug("%s: Failed to find PMIC\n", __func__);
159f1333417SMarcel Ziswiler 			return;
160f1333417SMarcel Ziswiler 		}
161f38f5f4bSMarcel Ziswiler 
162f38f5f4bSMarcel Ziswiler 		/* Reset I210 Gigabit Ethernet Controller */
163f38f5f4bSMarcel Ziswiler 		gpio_direction_output(LAN_RESET_N, 0);
164f38f5f4bSMarcel Ziswiler 
165f38f5f4bSMarcel Ziswiler 		/*
166f1333417SMarcel Ziswiler 		 * Make sure we don't get any back feeding from DEV_OFF_N resp.
167f1333417SMarcel Ziswiler 		 * LAN_WAKE_N
168f38f5f4bSMarcel Ziswiler 		 */
169f1333417SMarcel Ziswiler 		gpio_direction_output(LAN_DEV_OFF_N, 0);
170f1333417SMarcel Ziswiler 		gpio_direction_output(LAN_WAKE_N, 0);
171f38f5f4bSMarcel Ziswiler 
172f38f5f4bSMarcel Ziswiler 		/* Make sure LDO9 and LDO10 are initially enabled @ 0V */
173f1333417SMarcel Ziswiler 		ret = as3722_ldo_enable(dev, 9);
174f1333417SMarcel Ziswiler 		if (ret < 0) {
175f1333417SMarcel Ziswiler 			pr_err("failed to enable LDO9: %d\n", ret);
176f1333417SMarcel Ziswiler 			return;
177f38f5f4bSMarcel Ziswiler 		}
178f1333417SMarcel Ziswiler 		ret = as3722_ldo_enable(dev, 10);
179f1333417SMarcel Ziswiler 		if (ret < 0) {
180f1333417SMarcel Ziswiler 			pr_err("failed to enable LDO10: %d\n", ret);
181f1333417SMarcel Ziswiler 			return;
182f38f5f4bSMarcel Ziswiler 		}
183f1333417SMarcel Ziswiler 		ret = as3722_ldo_set_voltage(dev, 9, 0x80);
184f1333417SMarcel Ziswiler 		if (ret < 0) {
185f1333417SMarcel Ziswiler 			pr_err("failed to set LDO9 voltage: %d\n", ret);
186f1333417SMarcel Ziswiler 			return;
187f38f5f4bSMarcel Ziswiler 		}
188f1333417SMarcel Ziswiler 		ret = as3722_ldo_set_voltage(dev, 10, 0x80);
189f1333417SMarcel Ziswiler 		if (ret < 0) {
190f1333417SMarcel Ziswiler 			pr_err("failed to set LDO10 voltage: %d\n", ret);
191f1333417SMarcel Ziswiler 			return;
192f38f5f4bSMarcel Ziswiler 		}
193f38f5f4bSMarcel Ziswiler 
194f38f5f4bSMarcel Ziswiler 		/* Make sure controller gets enabled by disabling DEV_OFF_N */
195f1333417SMarcel Ziswiler 		gpio_set_value(LAN_DEV_OFF_N, 1);
196f38f5f4bSMarcel Ziswiler 
197f1333417SMarcel Ziswiler 		/*
198f1333417SMarcel Ziswiler 		 * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype
199f1333417SMarcel Ziswiler 		 * V1.0A and sample V1.0B and newer modules
200e3f44f5cSSimon Glass 		 */
201f1333417SMarcel Ziswiler 		ret = as3722_ldo_set_voltage(dev, 9, 0xff);
202f1333417SMarcel Ziswiler 		if (ret < 0) {
203f1333417SMarcel Ziswiler 			pr_err("failed to set LDO9 voltage: %d\n", ret);
204f1333417SMarcel Ziswiler 			return;
205f1333417SMarcel Ziswiler 		}
206f1333417SMarcel Ziswiler 		ret = as3722_ldo_set_voltage(dev, 10, 0xff);
207f1333417SMarcel Ziswiler 		if (ret < 0) {
208f1333417SMarcel Ziswiler 			pr_err("failed to set LDO10 voltage: %d\n", ret);
209f1333417SMarcel Ziswiler 			return;
210f1333417SMarcel Ziswiler 		}
211f38f5f4bSMarcel Ziswiler 
212f1333417SMarcel Ziswiler 		/*
213f1333417SMarcel Ziswiler 		 * Must be asserted for 100 ms after power and clocks are stable
214f1333417SMarcel Ziswiler 		 */
215f38f5f4bSMarcel Ziswiler 		mdelay(100);
216f1333417SMarcel Ziswiler 
217f38f5f4bSMarcel Ziswiler 		gpio_set_value(LAN_RESET_N, 1);
218f1333417SMarcel Ziswiler 	} else if (index == 0) { /* Apalis PCIe */
219f1333417SMarcel Ziswiler #ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
220f1333417SMarcel Ziswiler 		/*
221f1333417SMarcel Ziswiler 		 * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis
222f1333417SMarcel Ziswiler 		 * Evaluation Board
223f1333417SMarcel Ziswiler 		 */
224f38f5f4bSMarcel Ziswiler 		gpio_direction_output(PEX_PERST_N, 0);
225f38f5f4bSMarcel Ziswiler 		gpio_direction_output(RESET_MOCI_CTRL, 0);
226f1333417SMarcel Ziswiler 
227f1333417SMarcel Ziswiler 		/*
228f1333417SMarcel Ziswiler 		 * Must be asserted for 100 ms after power and clocks are stable
229f1333417SMarcel Ziswiler 		 */
230f38f5f4bSMarcel Ziswiler 		mdelay(100);
231f1333417SMarcel Ziswiler 
232f38f5f4bSMarcel Ziswiler 		gpio_set_value(PEX_PERST_N, 1);
233f1333417SMarcel Ziswiler 		/*
234f1333417SMarcel Ziswiler 		 * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed
235f1333417SMarcel Ziswiler 		 * Until 900 us After PEX_PERST# De-assertion
236f1333417SMarcel Ziswiler 		 */
237f38f5f4bSMarcel Ziswiler 		mdelay(1);
238f38f5f4bSMarcel Ziswiler 		gpio_set_value(RESET_MOCI_CTRL, 1);
239f1333417SMarcel Ziswiler #endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
240f1333417SMarcel Ziswiler 	}
241f38f5f4bSMarcel Ziswiler }
242f38f5f4bSMarcel Ziswiler #endif /* CONFIG_PCI_TEGRA */
243*a3c90217SGerard Salvatella 
244*a3c90217SGerard Salvatella /*
245*a3c90217SGerard Salvatella  * Backlight off before OS handover
246*a3c90217SGerard Salvatella  */
board_preboot_os(void)247*a3c90217SGerard Salvatella void board_preboot_os(void)
248*a3c90217SGerard Salvatella {
249*a3c90217SGerard Salvatella 	gpio_request(TEGRA_GPIO(BB, 5), "BL_ON");
250*a3c90217SGerard Salvatella 	gpio_direction_output(TEGRA_GPIO(BB, 5), 0);
251*a3c90217SGerard Salvatella }
252