3d8038164662c5532ed9fde7eb3ca94e57a1ad9a
[oweals/u-boot.git] / board / toradex / apalis-tk1 / apalis-tk1.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2016-2018 Toradex, Inc.
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <env.h>
9 #include <init.h>
10 #include <log.h>
11 #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>
16 #include <env_internal.h>
17 #include <pci_tegra.h>
18 #include <power/as3722.h>
19 #include <power/pmic.h>
20
21 #include "../common/tdx-common.h"
22 #include "pinmux-config-apalis-tk1.h"
23
24 #define LAN_DEV_OFF_N   TEGRA_GPIO(O, 6)
25 #define LAN_RESET_N     TEGRA_GPIO(S, 2)
26 #define FAN_EN          TEGRA_GPIO(DD, 2)
27 #define LAN_WAKE_N      TEGRA_GPIO(O, 5)
28 #ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
29 #define PEX_PERST_N     TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */
30 #define RESET_MOCI_CTRL TEGRA_GPIO(U, 4)
31 #endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
32 #define VCC_USBH        TEGRA_GPIO(T, 6)
33 #define VCC_USBH_V1_0   TEGRA_GPIO(N, 5)
34 #define VCC_USBO1       TEGRA_GPIO(T, 5)
35 #define VCC_USBO1_V1_0  TEGRA_GPIO(N, 4)
36
37 int arch_misc_init(void)
38 {
39         if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) ==
40             NVBOOTTYPE_RECOVERY)
41                 printf("USB recovery mode\n");
42
43         /* PCB Version Indication: V1.2 and later have GPIO_PV0 wired to GND */
44         gpio_request(TEGRA_GPIO(V, 0), "PCB Version Indication");
45         gpio_direction_input(TEGRA_GPIO(V, 0));
46         if (gpio_get_value(TEGRA_GPIO(V, 0))) {
47                 /*
48                  * if using the default device tree for new V1.2 and later HW,
49                  * use version for older V1.0 and V1.1 HW
50                  */
51                 char *fdt_env = env_get("fdt_module");
52
53                 if (fdt_env && !strcmp(FDT_MODULE, fdt_env)) {
54                         env_set("fdt_module", FDT_MODULE_V1_0);
55                         printf("patching fdt_module to " FDT_MODULE_V1_0
56                                " for older V1.0 and V1.1 HW\n");
57 #ifndef CONFIG_ENV_IS_NOWHERE
58                         env_save();
59 #endif
60                 }
61
62                 /* activate USB power enable GPIOs */
63                 gpio_request(VCC_USBH_V1_0, "VCC_USBH");
64                 gpio_direction_output(VCC_USBH_V1_0, 1);
65                 gpio_request(VCC_USBO1_V1_0, "VCC_USBO1");
66                 gpio_direction_output(VCC_USBO1_V1_0, 1);
67         } else {
68                 /* activate USB power enable GPIOs */
69                 gpio_request(VCC_USBH, "VCC_USBH");
70                 gpio_direction_output(VCC_USBH, 1);
71                 gpio_request(VCC_USBO1, "VCC_USBO1");
72                 gpio_direction_output(VCC_USBO1, 1);
73         }
74
75         return 0;
76 }
77
78 int checkboard(void)
79 {
80         puts("Model: Toradex Apalis TK1 2GB\n");
81
82         return 0;
83 }
84
85 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
86 int ft_board_setup(void *blob, bd_t *bd)
87 {
88         return ft_common_board_setup(blob, bd);
89 }
90 #endif
91
92 /*
93  * Routine: pinmux_init
94  * Description: Do individual peripheral pinmux configs
95  */
96 void pinmux_init(void)
97 {
98         pinmux_clear_tristate_input_clamping();
99
100         gpio_config_table(apalis_tk1_gpio_inits,
101                           ARRAY_SIZE(apalis_tk1_gpio_inits));
102
103         pinmux_config_pingrp_table(apalis_tk1_pingrps,
104                                    ARRAY_SIZE(apalis_tk1_pingrps));
105
106         pinmux_config_drvgrp_table(apalis_tk1_drvgrps,
107                                    ARRAY_SIZE(apalis_tk1_drvgrps));
108 }
109
110 #ifdef CONFIG_PCI_TEGRA
111 /* TODO: Convert to driver model */
112 static int as3722_sd_enable(struct udevice *pmic, unsigned int sd)
113 {
114         int err;
115
116         if (sd > 6)
117                 return -EINVAL;
118
119         err = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd);
120         if (err) {
121                 pr_err("failed to update SD control register: %d", err);
122                 return err;
123         }
124
125         return 0;
126 }
127
128 /* TODO: Convert to driver model */
129 static int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo)
130 {
131         int err;
132         u8 ctrl_reg = AS3722_LDO_CONTROL0;
133
134         if (ldo > 11)
135                 return -EINVAL;
136
137         if (ldo > 7) {
138                 ctrl_reg = AS3722_LDO_CONTROL1;
139                 ldo -= 8;
140         }
141
142         err = pmic_clrsetbits(pmic, ctrl_reg, 0, 1 << ldo);
143         if (err) {
144                 pr_err("failed to update LDO control register: %d", err);
145                 return err;
146         }
147
148         return 0;
149 }
150
151 int tegra_pcie_board_init(void)
152 {
153         struct udevice *dev;
154         int ret;
155
156         ret = uclass_get_device_by_driver(UCLASS_PMIC,
157                                           DM_GET_DRIVER(pmic_as3722), &dev);
158         if (ret) {
159                 pr_err("failed to find AS3722 PMIC: %d\n", ret);
160                 return ret;
161         }
162
163         ret = as3722_sd_enable(dev, 4);
164         if (ret < 0) {
165                 pr_err("failed to enable SD4: %d\n", ret);
166                 return ret;
167         }
168
169         ret = as3722_sd_set_voltage(dev, 4, 0x24);
170         if (ret < 0) {
171                 pr_err("failed to set SD4 voltage: %d\n", ret);
172                 return ret;
173         }
174
175         gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N");
176         gpio_request(LAN_RESET_N, "LAN_RESET_N");
177         gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
178
179 #ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
180         gpio_request(PEX_PERST_N, "PEX_PERST_N");
181         gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL");
182 #endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
183
184         return 0;
185 }
186
187 void tegra_pcie_board_port_reset(struct tegra_pcie_port *port)
188 {
189         int index = tegra_pcie_port_index_of_port(port);
190
191         if (index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */
192                 struct udevice *dev;
193                 int ret;
194
195                 ret = uclass_get_device_by_driver(UCLASS_PMIC,
196                                                   DM_GET_DRIVER(pmic_as3722),
197                                                   &dev);
198                 if (ret) {
199                         debug("%s: Failed to find PMIC\n", __func__);
200                         return;
201                 }
202
203                 /* Reset I210 Gigabit Ethernet Controller */
204                 gpio_direction_output(LAN_RESET_N, 0);
205
206                 /*
207                  * Make sure we don't get any back feeding from DEV_OFF_N resp.
208                  * LAN_WAKE_N
209                  */
210                 gpio_direction_output(LAN_DEV_OFF_N, 0);
211                 gpio_direction_output(LAN_WAKE_N, 0);
212
213                 /* Make sure LDO9 and LDO10 are initially enabled @ 0V */
214                 ret = as3722_ldo_enable(dev, 9);
215                 if (ret < 0) {
216                         pr_err("failed to enable LDO9: %d\n", ret);
217                         return;
218                 }
219                 ret = as3722_ldo_enable(dev, 10);
220                 if (ret < 0) {
221                         pr_err("failed to enable LDO10: %d\n", ret);
222                         return;
223                 }
224                 ret = as3722_ldo_set_voltage(dev, 9, 0x80);
225                 if (ret < 0) {
226                         pr_err("failed to set LDO9 voltage: %d\n", ret);
227                         return;
228                 }
229                 ret = as3722_ldo_set_voltage(dev, 10, 0x80);
230                 if (ret < 0) {
231                         pr_err("failed to set LDO10 voltage: %d\n", ret);
232                         return;
233                 }
234
235                 /* Make sure controller gets enabled by disabling DEV_OFF_N */
236                 gpio_set_value(LAN_DEV_OFF_N, 1);
237
238                 /*
239                  * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype
240                  * V1.0A and sample V1.0B and newer modules
241                  */
242                 ret = as3722_ldo_set_voltage(dev, 9, 0xff);
243                 if (ret < 0) {
244                         pr_err("failed to set LDO9 voltage: %d\n", ret);
245                         return;
246                 }
247                 ret = as3722_ldo_set_voltage(dev, 10, 0xff);
248                 if (ret < 0) {
249                         pr_err("failed to set LDO10 voltage: %d\n", ret);
250                         return;
251                 }
252
253                 /*
254                  * Must be asserted for 100 ms after power and clocks are stable
255                  */
256                 mdelay(100);
257
258                 gpio_set_value(LAN_RESET_N, 1);
259         } else if (index == 0) { /* Apalis PCIe */
260 #ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT
261                 /*
262                  * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis
263                  * Evaluation Board
264                  */
265                 gpio_direction_output(PEX_PERST_N, 0);
266                 gpio_direction_output(RESET_MOCI_CTRL, 0);
267
268                 /*
269                  * Must be asserted for 100 ms after power and clocks are stable
270                  */
271                 mdelay(100);
272
273                 gpio_set_value(PEX_PERST_N, 1);
274                 /*
275                  * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed
276                  * Until 900 us After PEX_PERST# De-assertion
277                  */
278                 mdelay(1);
279                 gpio_set_value(RESET_MOCI_CTRL, 1);
280 #endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */
281         }
282 }
283 #endif /* CONFIG_PCI_TEGRA */
284
285 /*
286  * Enable/start PWM CPU fan
287  */
288 void start_cpu_fan(void)
289 {
290         gpio_request(FAN_EN, "FAN_EN");
291         gpio_direction_output(FAN_EN, 1);
292 }
293
294 /*
295  * Backlight off before OS handover
296  */
297 void board_preboot_os(void)
298 {
299         gpio_request(TEGRA_GPIO(BB, 5), "BL_ON");
300         gpio_direction_output(TEGRA_GPIO(BB, 5), 0);
301 }