blob: a08e00dd87cb356f3939ea92ccae7e4da0467caf [file] [log] [blame]
Svyatoslav Ryhelfcb1d912023-06-30 10:29:05 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2010-2013
4 * NVIDIA Corporation <www.nvidia.com>
5 *
6 * (C) Copyright 2022
7 * Svyatoslav Ryhel <clamor95@gmail.com>
8 */
9
10#include <common.h>
11#include <dm.h>
Svyatoslav Ryhelfcb1d912023-06-30 10:29:05 +030012#include <fdt_support.h>
13#include <i2c.h>
14#include <log.h>
15#include <asm/arch/pinmux.h>
16#include <asm/arch/clock.h>
17#include <asm/arch/gpio.h>
18#include <asm/arch/tegra.h>
19#include <asm/arch-tegra/fuse.h>
20#include <asm/gpio.h>
21#include <linux/delay.h>
22#include "pinmux-config-x3.h"
23
24#define MAX77663_I2C_ADDR 0x1C
25
26#define MAX77663_REG_SD2 0x18
27#define MAX77663_REG_LDO2 0x27
28#define MAX77663_REG_LDO3 0x29
29#define MAX77663_REG_LDO5 0x2D
30#define MAX77663_REG_ONOFF_CFG1 0x41
31#define ONOFF_PWR_OFF BIT(1)
32
33#ifdef CONFIG_CMD_POWEROFF
34int do_poweroff(struct cmd_tbl *cmdtp, int flag,
35 int argc, char *const argv[])
36{
37 struct udevice *dev;
38 uchar data_buffer[1];
39 int ret;
40
41 ret = i2c_get_chip_for_busnum(0, MAX77663_I2C_ADDR, 1, &dev);
42 if (ret) {
43 log_debug("cannot find PMIC I2C chip\n");
44 return 0;
45 }
46
47 ret = dm_i2c_read(dev, MAX77663_REG_ONOFF_CFG1, data_buffer, 1);
48 if (ret)
49 return ret;
50
51 data_buffer[0] |= ONOFF_PWR_OFF;
52
53 ret = dm_i2c_write(dev, MAX77663_REG_ONOFF_CFG1, data_buffer, 1);
54 if (ret)
55 return ret;
56
57 /* wait some time and then print error */
58 mdelay(5000);
59
60 printf("Failed to power off!!!\n");
61 return 1;
62}
63#endif
64
65/*
66 * Routine: pinmux_init
67 * Description: Do individual peripheral pinmux configs
68 */
69void pinmux_init(void)
70{
71 pinmux_config_pingrp_table(tegra3_x3_pinmux_common,
72 ARRAY_SIZE(tegra3_x3_pinmux_common));
73
74#ifdef CONFIG_DEVICE_P880
75 pinmux_config_pingrp_table(tegra3_p880_pinmux,
76 ARRAY_SIZE(tegra3_p880_pinmux));
77#endif
78
79#ifdef CONFIG_DEVICE_P895
80 pinmux_config_pingrp_table(tegra3_p895_pinmux,
81 ARRAY_SIZE(tegra3_p895_pinmux));
82#endif
83}
84
85#ifdef CONFIG_MMC_SDHCI_TEGRA
86static void max77663_voltage_init(void)
87{
88 struct udevice *dev;
89 int ret;
90
91 ret = i2c_get_chip_for_busnum(0, MAX77663_I2C_ADDR, 1, &dev);
92 if (ret) {
93 log_debug("cannot find PMIC I2C chip\n");
94 return;
95 }
96
97 /* 0x60 for 1.8v, bit7:0 = voltage */
98 ret = dm_i2c_reg_write(dev, MAX77663_REG_SD2, 0x60);
99 if (ret)
100 log_debug("vdd_1v8_vio set failed: %d\n", ret);
101
102 /* 0xF2 for 3.30v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
103 ret = dm_i2c_reg_write(dev, MAX77663_REG_LDO2, 0xF2);
104 if (ret)
105 log_debug("avdd_usb set failed: %d\n", ret);
106
107 /* 0xEC for 3.00v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
108 ret = dm_i2c_reg_write(dev, MAX77663_REG_LDO3, 0xEC);
109 if (ret)
110 log_debug("vdd_usd set failed: %d\n", ret);
111
112 /* 0xE9 for 2.85v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
113 ret = dm_i2c_reg_write(dev, MAX77663_REG_LDO5, 0xE9);
114 if (ret)
115 log_debug("vcore_emmc set failed: %d\n", ret);
116}
117
118/*
119 * Routine: pin_mux_mmc
120 * Description: setup the MMC muxes, power rails, etc.
121 */
122void pin_mux_mmc(void)
123{
124 /* Bring up uSD and eMMC power */
125 max77663_voltage_init();
126}
127#endif /* MMC */
128
129int nvidia_board_init(void)
130{
131 /* Set up panel bridge clocks */
132 clock_start_periph_pll(PERIPH_ID_EXTPERIPH3, CLOCK_ID_PERIPH,
133 24 * 1000000);
134 clock_external_output(3);
135
136 return 0;
137}
138
139#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
140int ft_board_setup(void *blob, struct bd_info *bd)
141{
142 /* First 3 bytes refer to LG vendor */
143 u8 btmacaddr[6] = { 0x00, 0x00, 0x00, 0xD0, 0xC9, 0x88 };
144
145 /* Generate device 3 bytes based on chip sd */
146 u64 bt_device = tegra_chip_uid() >> 24ull;
147
148 btmacaddr[0] = (bt_device >> 1 & 0x0F) |
149 (bt_device >> 5 & 0xF0);
150 btmacaddr[1] = (bt_device >> 11 & 0x0F) |
151 (bt_device >> 17 & 0xF0);
152 btmacaddr[2] = (bt_device >> 23 & 0x0F) |
153 (bt_device >> 29 & 0xF0);
154
155 /* Set BT MAC address */
156 fdt_find_and_setprop(blob, "/serial@70006200/bluetooth",
157 "local-bd-address", btmacaddr, 6, 1);
158
159 /* Remove TrustZone nodes */
160 fdt_del_node_and_alias(blob, "/firmware");
161 fdt_del_node_and_alias(blob, "/reserved-memory/trustzone@bfe00000");
162
163 return 0;
164}
165#endif