summaryrefslogtreecommitdiff
path: root/board/lg/x3-t30/x3-t30.c
blob: 594563cf52de702f7139cad5e4efb0e1a5e05ea2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// SPDX-License-Identifier: GPL-2.0+
/*
 *  (C) Copyright 2010-2013
 *  NVIDIA Corporation <www.nvidia.com>
 *
 *  (C) Copyright 2022
 *  Svyatoslav Ryhel <clamor95@gmail.com>
 */

#include <common.h>
#include <dm.h>
#include <env.h>
#include <fdt_support.h>
#include <i2c.h>
#include <log.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
#include <asm/arch/tegra.h>
#include <asm/arch-tegra/fuse.h>
#include <asm/gpio.h>
#include <linux/delay.h>
#include "pinmux-config-x3.h"

#define MAX77663_I2C_ADDR		0x1C

#define MAX77663_REG_SD2		0x18
#define MAX77663_REG_LDO2		0x27
#define MAX77663_REG_LDO3		0x29
#define MAX77663_REG_LDO5		0x2D
#define MAX77663_REG_ONOFF_CFG1		0x41
#define   ONOFF_PWR_OFF			BIT(1)

#ifdef CONFIG_CMD_POWEROFF
int do_poweroff(struct cmd_tbl *cmdtp, int flag,
		int argc, char *const argv[])
{
	struct udevice *dev;
	uchar data_buffer[1];
	int ret;

	ret = i2c_get_chip_for_busnum(0, MAX77663_I2C_ADDR, 1, &dev);
	if (ret) {
		log_debug("cannot find PMIC I2C chip\n");
		return 0;
	}

	ret = dm_i2c_read(dev, MAX77663_REG_ONOFF_CFG1, data_buffer, 1);
	if (ret)
		return ret;

	data_buffer[0] |= ONOFF_PWR_OFF;

	ret = dm_i2c_write(dev, MAX77663_REG_ONOFF_CFG1, data_buffer, 1);
	if (ret)
		return ret;

	/* wait some time and then print error */
	mdelay(5000);

	printf("Failed to power off!!!\n");
	return 1;
}
#endif

/*
 * Routine: pinmux_init
 * Description: Do individual peripheral pinmux configs
 */
void pinmux_init(void)
{
	pinmux_config_pingrp_table(tegra3_x3_pinmux_common,
		ARRAY_SIZE(tegra3_x3_pinmux_common));

#ifdef CONFIG_DEVICE_P880
	pinmux_config_pingrp_table(tegra3_p880_pinmux,
		ARRAY_SIZE(tegra3_p880_pinmux));
#endif

#ifdef CONFIG_DEVICE_P895
	pinmux_config_pingrp_table(tegra3_p895_pinmux,
		ARRAY_SIZE(tegra3_p895_pinmux));
#endif
}

#ifdef CONFIG_MMC_SDHCI_TEGRA
static void max77663_voltage_init(void)
{
	struct udevice *dev;
	int ret;

	ret = i2c_get_chip_for_busnum(0, MAX77663_I2C_ADDR, 1, &dev);
	if (ret) {
		log_debug("cannot find PMIC I2C chip\n");
		return;
	}

	/* 0x60 for 1.8v, bit7:0 = voltage */
	ret = dm_i2c_reg_write(dev, MAX77663_REG_SD2, 0x60);
	if (ret)
		log_debug("vdd_1v8_vio set failed: %d\n", ret);

	/* 0xF2 for 3.30v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
	ret = dm_i2c_reg_write(dev, MAX77663_REG_LDO2, 0xF2);
	if (ret)
		log_debug("avdd_usb set failed: %d\n", ret);

	/* 0xEC for 3.00v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
	ret = dm_i2c_reg_write(dev, MAX77663_REG_LDO3, 0xEC);
	if (ret)
		log_debug("vdd_usd set failed: %d\n", ret);

	/* 0xE9 for 2.85v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
	ret = dm_i2c_reg_write(dev, MAX77663_REG_LDO5, 0xE9);
	if (ret)
		log_debug("vcore_emmc set failed: %d\n", ret);
}

/*
 * Routine: pin_mux_mmc
 * Description: setup the MMC muxes, power rails, etc.
 */
void pin_mux_mmc(void)
{
	/* Bring up uSD and eMMC power */
	max77663_voltage_init();
}
#endif	/* MMC */

int nvidia_board_init(void)
{
	/* Set up panel bridge clocks */
	clock_start_periph_pll(PERIPH_ID_EXTPERIPH3, CLOCK_ID_PERIPH,
			       24 * 1000000);
	clock_external_output(3);

	return 0;
}

#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
int ft_board_setup(void *blob, struct bd_info *bd)
{
	/* First 3 bytes refer to LG vendor */
	u8 btmacaddr[6] = { 0x00, 0x00, 0x00, 0xD0, 0xC9, 0x88 };

	/* Generate device 3 bytes based on chip sd */
	u64 bt_device = tegra_chip_uid() >> 24ull;

	btmacaddr[0] =  (bt_device >> 1 & 0x0F) |
			(bt_device >> 5 & 0xF0);
	btmacaddr[1] =  (bt_device >> 11 & 0x0F) |
			(bt_device >> 17 & 0xF0);
	btmacaddr[2] =  (bt_device >> 23 & 0x0F) |
			(bt_device >> 29 & 0xF0);

	/* Set BT MAC address */
	fdt_find_and_setprop(blob, "/serial@70006200/bluetooth",
			     "local-bd-address", btmacaddr, 6, 1);

	/* Remove TrustZone nodes */
	fdt_del_node_and_alias(blob, "/firmware");
	fdt_del_node_and_alias(blob, "/reserved-memory/trustzone@bfe00000");

	return 0;
}
#endif

void nvidia_board_late_init(void)
{
	char serialno_str[17];

	/* Set chip id as serialno */
	sprintf(serialno_str, "%016llx", tegra_chip_uid());
	env_set("serial#", serialno_str);
	env_set("platform", "Tegra 3 T30");
}