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