1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2018-2019
4  * NVIDIA Corporation <www.nvidia.com>
5  *
6  */
7 
8 #include <common.h>
9 #include <fdtdec.h>
10 #include <i2c.h>
11 #include <linux/bitops.h>
12 #include <linux/libfdt.h>
13 #include <pca953x.h>
14 #include <asm/arch-tegra/cboot.h>
15 #include <asm/arch/gpio.h>
16 #include <asm/arch/pinmux.h>
17 #include "../p2571/max77620_init.h"
18 
pin_mux_mmc(void)19 void pin_mux_mmc(void)
20 {
21 	struct udevice *dev;
22 	uchar val;
23 	int ret;
24 
25 	/* Turn on MAX77620 LDO2 to 3.3V for SD card power */
26 	debug("%s: Set LDO2 for VDDIO_SDMMC_AP power to 3.3V\n", __func__);
27 	ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev);
28 	if (ret) {
29 		printf("%s: Cannot find MAX77620 I2C chip\n", __func__);
30 		return;
31 	}
32 	/* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
33 	val = 0xF2;
34 	ret = dm_i2c_write(dev, MAX77620_CNFG1_L2_REG, &val, 1);
35 	if (ret)
36 		printf("i2c_write 0 0x3c 0x27 failed: %d\n", ret);
37 
38 	/* Disable LDO4 discharge */
39 	ret = dm_i2c_read(dev, MAX77620_CNFG2_L4_REG, &val, 1);
40 	if (ret) {
41 		printf("i2c_read 0 0x3c 0x2c failed: %d\n", ret);
42 	} else {
43 		val &= ~BIT(1); /* ADE */
44 		ret = dm_i2c_write(dev, MAX77620_CNFG2_L4_REG, &val, 1);
45 		if (ret)
46 			printf("i2c_write 0 0x3c 0x2c failed: %d\n", ret);
47 	}
48 
49 	/* Set MBLPD */
50 	ret = dm_i2c_read(dev, MAX77620_CNFGGLBL1_REG, &val, 1);
51 	if (ret) {
52 		printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret);
53 	} else {
54 		val |= BIT(6); /* MBLPD */
55 		ret = dm_i2c_write(dev, MAX77620_CNFGGLBL1_REG, &val, 1);
56 		if (ret)
57 			printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret);
58 	}
59 }
60 
61 #ifdef CONFIG_PCI_TEGRA
tegra_pcie_board_init(void)62 int tegra_pcie_board_init(void)
63 {
64 	struct udevice *dev;
65 	uchar val;
66 	int ret;
67 
68 	/* Turn on MAX77620 LDO1 to 1.05V for PEX power */
69 	debug("%s: Set LDO1 for PEX power to 1.05V\n", __func__);
70 	ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev);
71 	if (ret) {
72 		printf("%s: Cannot find MAX77620 I2C chip\n", __func__);
73 		return -1;
74 	}
75 	/* 0xCA for 1.05v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
76 	val = 0xCA;
77 	ret = dm_i2c_write(dev, MAX77620_CNFG1_L1_REG, &val, 1);
78 	if (ret)
79 		printf("i2c_write 0 0x3c 0x25 failed: %d\n", ret);
80 
81 	return 0;
82 }
83 #endif /* PCI */
84 
ft_mac_address_setup(void * fdt)85 static void ft_mac_address_setup(void *fdt)
86 {
87 	const void *cboot_fdt = (const void *)cboot_boot_x0;
88 	uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN];
89 	const char *path;
90 	int offset, err;
91 
92 	err = cboot_get_ethaddr(cboot_fdt, local_mac);
93 	if (err < 0)
94 		memset(local_mac, 0, ETH_ALEN);
95 
96 	path = fdt_get_alias(fdt, "ethernet");
97 	if (!path)
98 		return;
99 
100 	debug("ethernet alias found: %s\n", path);
101 
102 	offset = fdt_path_offset(fdt, path);
103 	if (offset < 0) {
104 		printf("ethernet alias points to absent node %s\n", path);
105 		return;
106 	}
107 
108 	if (is_valid_ethaddr(local_mac)) {
109 		err = fdt_setprop(fdt, offset, "local-mac-address", local_mac,
110 				  ETH_ALEN);
111 		if (!err)
112 			debug("Local MAC address set: %pM\n", local_mac);
113 	}
114 
115 	if (eth_env_get_enetaddr("ethaddr", mac)) {
116 		if (memcmp(local_mac, mac, ETH_ALEN) != 0) {
117 			err = fdt_setprop(fdt, offset, "mac-address", mac,
118 					  ETH_ALEN);
119 			if (!err)
120 				debug("MAC address set: %pM\n", mac);
121 		}
122 	}
123 }
124 
ft_copy_carveout(void * dst,const void * src,const char * node)125 static int ft_copy_carveout(void *dst, const void *src, const char *node)
126 {
127 	struct fdt_memory fb;
128 	int err;
129 
130 	err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb);
131 	if (err < 0) {
132 		if (err != -FDT_ERR_NOTFOUND)
133 			printf("failed to get carveout for %s: %d\n", node,
134 			       err);
135 
136 		return err;
137 	}
138 
139 	err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer",
140 				  &fb);
141 	if (err < 0) {
142 		printf("failed to set carveout for %s: %d\n", node, err);
143 		return err;
144 	}
145 
146 	return 0;
147 }
148 
ft_carveout_setup(void * fdt)149 static void ft_carveout_setup(void *fdt)
150 {
151 	const void *cboot_fdt = (const void *)cboot_boot_x0;
152 	static const char * const nodes[] = {
153 		"/host1x@50000000/dc@54200000",
154 		"/host1x@50000000/dc@54240000",
155 	};
156 	unsigned int i;
157 	int err;
158 
159 	for (i = 0; i < ARRAY_SIZE(nodes); i++) {
160 		printf("copying carveout for %s...\n", nodes[i]);
161 
162 		err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]);
163 		if (err < 0) {
164 			if (err != -FDT_ERR_NOTFOUND)
165 				printf("failed to copy carveout for %s: %d\n",
166 				       nodes[i], err);
167 
168 			continue;
169 		}
170 	}
171 }
172 
ft_board_setup(void * fdt,struct bd_info * bd)173 int ft_board_setup(void *fdt, struct bd_info *bd)
174 {
175 	ft_mac_address_setup(fdt);
176 	ft_carveout_setup(fdt);
177 
178 	return 0;
179 }
180