Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/soc/hw_init.c
1476 views
1
/*
2
* Copyright (c) 2018 naehrwert
3
* Copyright (c) 2018-2024 CTCaer
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
#include <string.h>
19
20
#include <soc/hw_init.h>
21
#include <display/di.h>
22
#include <display/vic.h>
23
#include <input/joycon.h>
24
#include <input/touch.h>
25
#include <sec/se.h>
26
#include <sec/se_t210.h>
27
#include <soc/bpmp.h>
28
#include <soc/clock.h>
29
#include <soc/fuse.h>
30
#include <soc/gpio.h>
31
#include <soc/i2c.h>
32
#include <soc/pinmux.h>
33
#include <soc/pmc.h>
34
#include <soc/uart.h>
35
#include <soc/timer.h>
36
#include <soc/t210.h>
37
#include <mem/mc.h>
38
#include <mem/minerva.h>
39
#include <mem/sdram.h>
40
#include <power/bq24193.h>
41
#include <power/max77620.h>
42
#include <power/max7762x.h>
43
#include <power/regulator_5v.h>
44
#include <storage/sd.h>
45
#include <storage/sdmmc.h>
46
#include <thermal/fan.h>
47
#include <thermal/tmp451.h>
48
#include <utils/util.h>
49
50
extern boot_cfg_t b_cfg;
51
extern volatile nyx_storage_t *nyx_str;
52
53
u32 hw_rst_status;
54
u32 hw_rst_reason;
55
56
u32 hw_get_chip_id()
57
{
58
if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01)
59
return GP_HIDREV_MAJOR_T210B01;
60
else
61
return GP_HIDREV_MAJOR_T210;
62
}
63
64
/*
65
* CLK_OSC - 38.4 MHz crystal.
66
* CLK_M - 19.2 MHz (osc/2).
67
* CLK_S - 32.768 KHz (from PMIC).
68
* SCLK - 204MHz init (-> 408MHz -> OC).
69
* HCLK - 204MHz init (-> 408MHz -> OC).
70
* PCLK - 68MHz init (-> 136MHz -> OC/4).
71
*/
72
73
static void _config_oscillators()
74
{
75
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
76
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
77
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
78
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
79
80
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
81
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
82
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
83
PMC(APB_MISC_GP_ASDBGREG) = (PMC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
84
85
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
86
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
87
88
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; // 0x249F = 19200000 * (16 / 32.768 kHz).
89
90
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
91
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
92
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
93
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
94
}
95
96
void hw_config_arbiter(bool reset)
97
{
98
if (reset)
99
{
100
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x0040090;
101
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x12024C2;
102
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x2201209;
103
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320365B;
104
}
105
else
106
{
107
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x12412D1;
108
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x0000000;
109
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x220244A;
110
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320369B;
111
}
112
}
113
114
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
115
static void _config_gpios(bool nx_hoag)
116
{
117
// Clamp inputs when tristated.
118
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
119
120
if (!nx_hoag)
121
{
122
// Turn Joy-Con detect on. (GPIO mode and input logic for UARTB/C TX pins.)
123
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
124
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
125
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
126
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
127
}
128
129
// Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX.
130
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
131
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
132
133
// Configure Joy-Con IsAttached pins. Shared with UARTB/UARTC TX.
134
gpio_direction_input(GPIO_PORT_E, GPIO_PIN_6);
135
gpio_direction_input(GPIO_PORT_H, GPIO_PIN_6);
136
137
pinmux_config_i2c(I2C_1);
138
pinmux_config_i2c(I2C_5);
139
pinmux_config_uart(UART_A);
140
141
// Configure volume up/down as inputs.
142
gpio_direction_input(GPIO_PORT_X, GPIO_PIN_6 | GPIO_PIN_7);
143
144
// Configure HOME as input. (Shared with UARTB RTS).
145
PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
146
gpio_direction_input(GPIO_PORT_Y, GPIO_PIN_1);
147
148
// Power button can be configured for hoag here. Only SKU where it's connected.
149
}
150
151
static void _config_pmc_scratch()
152
{
153
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
154
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset WDT_DURING_BR.
155
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
156
}
157
158
static void _mbist_workaround()
159
{
160
// Make sure Audio clocks are enabled before accessing I2S.
161
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
162
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
163
164
// Set mux output to SOR1 clock switch.
165
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) | 0x8000) & 0xFFFFBFFF;
166
// Enabled PLLD and set csi to PLLD for test pattern generation.
167
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= 0x40800000;
168
169
// Clear per-clock resets for APE/VIC/HOST1X/DISP1.
170
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
171
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = BIT(CLK_X_VIC);
172
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
173
usleep(2);
174
175
// I2S channels to master and disable SLCG.
176
I2S(I2S1_CTRL) |= I2S_CTRL_MASTER_EN;
177
I2S(I2S1_CG) &= ~I2S_CG_SLCG_ENABLE;
178
I2S(I2S2_CTRL) |= I2S_CTRL_MASTER_EN;
179
I2S(I2S2_CG) &= ~I2S_CG_SLCG_ENABLE;
180
I2S(I2S3_CTRL) |= I2S_CTRL_MASTER_EN;
181
I2S(I2S3_CG) &= ~I2S_CG_SLCG_ENABLE;
182
I2S(I2S4_CTRL) |= I2S_CTRL_MASTER_EN;
183
I2S(I2S4_CG) &= ~I2S_CG_SLCG_ENABLE;
184
I2S(I2S5_CTRL) |= I2S_CTRL_MASTER_EN;
185
I2S(I2S5_CG) &= ~I2S_CG_SLCG_ENABLE;
186
187
// Set SLCG overrides.
188
DISPLAY_A(_DIREG(DC_COM_DSC_TOP_CTL)) |= 4; // DSC_SLCG_OVERRIDE.
189
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
190
usleep(2);
191
192
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
193
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
194
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
195
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
196
197
// Enable specific clocks and disable all others.
198
// CLK L Devices.
199
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) =
200
BIT(CLK_H_PMC) |
201
BIT(CLK_H_FUSE);
202
// CLK H Devices.
203
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) =
204
BIT(CLK_L_RTC) |
205
BIT(CLK_L_TMR) |
206
BIT(CLK_L_GPIO) |
207
BIT(CLK_L_BPMP_CACHE_CTRL);
208
// CLK U Devices.
209
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) =
210
BIT(CLK_U_CSITE) |
211
BIT(CLK_U_IRAMA) |
212
BIT(CLK_U_IRAMB) |
213
BIT(CLK_U_IRAMC) |
214
BIT(CLK_U_IRAMD) |
215
BIT(CLK_U_BPMP_CACHE_RAM);
216
// CLK V Devices.
217
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) =
218
BIT(CLK_V_MSELECT) |
219
BIT(CLK_V_APB2APE) |
220
BIT(CLK_V_SPDIF_DOUBLER) |
221
BIT(CLK_V_SE);
222
// CLK W Devices.
223
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) =
224
BIT(CLK_W_PCIERX0) |
225
BIT(CLK_W_PCIERX1) |
226
BIT(CLK_W_PCIERX2) |
227
BIT(CLK_W_PCIERX3) |
228
BIT(CLK_W_PCIERX4) |
229
BIT(CLK_W_PCIERX5) |
230
BIT(CLK_W_ENTROPY) |
231
BIT(CLK_W_MC1);
232
// CLK X Devices.
233
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) =
234
BIT(CLK_X_MC_CAPA) |
235
BIT(CLK_X_MC_CBPA) |
236
BIT(CLK_X_MC_CPU) |
237
BIT(CLK_X_MC_BBC) |
238
BIT(CLK_X_GPU) |
239
BIT(CLK_X_DBGAPB) |
240
BIT(CLK_X_PLLG_REF);
241
// CLK Y Devices.
242
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) =
243
BIT(CLK_Y_MC_CDPA) |
244
BIT(CLK_Y_MC_CCPA);
245
246
// Disable clock gate overrides.
247
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
248
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
249
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
250
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = 0;
251
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE) = 0;
252
253
// Set child clock sources.
254
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
255
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= 0xFFFF3FFF; // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
256
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
257
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
258
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | 0x80000000; // Set clock source to PLLP_OUT.
259
}
260
261
static void _config_se_brom()
262
{
263
// Enable Fuse visibility.
264
clock_enable_fuse(true);
265
266
// Try to set SBK from fuses. If patched, skip.
267
fuse_set_sbk();
268
269
// Lock SSK (although it's not set and unused anyways).
270
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
271
272
// This memset needs to happen here, else TZRAM will behave weirdly later on.
273
memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
274
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
275
276
// Clear SE interrupts.
277
SE(SE_INT_STATUS_REG) = SE_INT_OP_DONE | SE_INT_OUT_DONE | SE_INT_OUT_LL_BUF_WR | SE_INT_IN_DONE | SE_INT_IN_LL_BUF_RD;
278
279
// Save reset reason.
280
hw_rst_status = PMC(APBDEV_PMC_SCRATCH200);
281
hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK;
282
283
// Clear the boot reason to avoid problems later.
284
PMC(APBDEV_PMC_SCRATCH200) = 0;
285
PMC(APBDEV_PMC_RST_STATUS) = PMC_RST_STATUS_POR;
286
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
287
}
288
289
static void _config_regulators(bool tegra_t210, bool nx_hoag)
290
{
291
// Set RTC/AO domain to POR voltage.
292
if (tegra_t210)
293
max7762x_regulator_set_voltage(REGULATOR_LDO4, 1000000);
294
295
// Disable low battery shutdown monitor.
296
max77620_low_battery_monitor_config(false);
297
298
// Power on all relevant rails in case we came out of warmboot. Only keep MEM/MEM_COMP and SDMMC1 states.
299
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_MEM_COMP | PMC_NO_IOPOWER_SDMMC1 | PMC_NO_IOPOWER_MEM;
300
301
// Make sure SDMMC1 IO/Core are powered off.
302
max7762x_regulator_enable(REGULATOR_LDO2, false);
303
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
304
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
305
(void)PMC(APBDEV_PMC_NO_IOPOWER);
306
sd_power_cycle_time_start = get_tmr_ms();
307
308
// Disable backup battery charger.
309
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
310
311
// Set PWR delay for forced shutdown off to 6s.
312
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT));
313
314
if (tegra_t210)
315
{
316
// Configure all Flexible Power Sequencers for MAX77620.
317
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (0 << MAX77620_FPS_EN_SRC_SHIFT));
318
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
319
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
320
max77620_regulator_config_fps(REGULATOR_LDO4);
321
max77620_regulator_config_fps(REGULATOR_LDO8);
322
max77620_regulator_config_fps(REGULATOR_SD0);
323
max77620_regulator_config_fps(REGULATOR_SD1);
324
max77620_regulator_config_fps(REGULATOR_SD3);
325
326
// Set GPIO3 to FPS0 for SYS 3V3 EN. Enabled when FPS0 is enabled.
327
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, (4 << MAX77620_FPS_PU_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT));
328
329
// Set vdd_core voltage to 1.125V.
330
max7762x_regulator_set_voltage(REGULATOR_SD0, 1125000);
331
332
// Power down CPU/GPU regulators after L4T warmboot.
333
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_DISABLE);
334
max77620_config_gpio(6, MAX77620_GPIO_OUTPUT_DISABLE);
335
336
// Set POR configuration.
337
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_POR_CFG);
338
max77621_config_default(REGULATOR_GPU0, MAX77621_CTRL_POR_CFG);
339
}
340
else
341
{
342
// Tegra X1+ set vdd_core voltage to 1.05V.
343
max7762x_regulator_set_voltage(REGULATOR_SD0, 1050000);
344
345
// Power on SD2 regulator for supplying LDO0/1/8.
346
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
347
348
// Set slew rate and enable SD2 regulator.
349
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) |
350
(MAX77620_POWER_MODE_NORMAL << MAX77620_SD_POWER_MODE_SHIFT) |
351
MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
352
353
// Enable LDO8 on HOAG as it also powers I2C1 IO pads.
354
if (nx_hoag)
355
{
356
max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
357
max7762x_regulator_enable(REGULATOR_LDO8, true);
358
}
359
}
360
}
361
362
void hw_init()
363
{
364
// Get Chip ID and SKU.
365
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
366
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
367
368
// Bootrom stuff we skipped by going through rcm.
369
_config_se_brom();
370
//FUSE(FUSE_PRIVATEKEYDISABLE) = 0x11;
371
372
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
373
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
374
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
375
376
// Perform Memory Built-In Self Test WAR if T210.
377
if (tegra_t210)
378
_mbist_workaround();
379
380
// Make sure PLLP_OUT3/4 is set to 408 MHz and enabled.
381
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB) = 0x30003;
382
383
// Enable Security Engine clock.
384
clock_enable_se();
385
386
// Enable Fuse visibility.
387
clock_enable_fuse(true);
388
389
// Disable Fuse programming.
390
fuse_disable_program();
391
392
// Enable clocks to Memory controllers and disable AHB redirect.
393
mc_enable();
394
395
// Initialize counters, CLKM, BPMP and other clocks based on 38.4MHz oscillator.
396
_config_oscillators();
397
398
// Initialize pin configuration.
399
_config_gpios(nx_hoag);
400
401
// Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
402
clock_enable_cl_dvfs();
403
404
// Enable clocks to I2C1 and I2CPWR.
405
clock_enable_i2c(I2C_1);
406
clock_enable_i2c(I2C_5);
407
408
// Enable clock to TZRAM.
409
clock_enable_tzram();
410
411
// Initialize I2C5, mandatory for PMIC.
412
i2c_init(I2C_5);
413
414
// Initialize various regulators based on Erista/Mariko platform.
415
_config_regulators(tegra_t210, nx_hoag);
416
417
// Initialize I2C1 for various power related devices.
418
i2c_init(I2C_1);
419
420
_config_pmc_scratch(); // Missing from 4.x+
421
422
// Set BPMP/SCLK to PLLP_OUT (408MHz).
423
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
424
425
// Power on T210B01 shadow TZRAM and lock the reg.
426
if (!tegra_t210)
427
{
428
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL) &= ~PMC_TZRAM_PWR_CNTRL_SD;
429
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
430
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
431
}
432
433
// Set arbiter.
434
hw_config_arbiter(false);
435
436
// Initialize External memory controller and configure DRAM parameters.
437
sdram_init();
438
439
bpmp_mmu_enable();
440
441
// Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
442
clock_enable_host1x();
443
444
#ifdef DEBUG_UART_PORT
445
// Setup debug uart port.
446
#if (DEBUG_UART_PORT == UART_B)
447
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
448
#elif (DEBUG_UART_PORT == UART_C)
449
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
450
#endif
451
pinmux_config_uart(DEBUG_UART_PORT);
452
clock_enable_uart(DEBUG_UART_PORT);
453
uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE, UART_AO_TX_AO_RX);
454
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
455
#endif
456
}
457
458
void hw_deinit(bool coreboot, u32 bl_magic)
459
{
460
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
461
462
// Scale down BPMP clock.
463
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
464
465
#ifdef BDK_HW_EXTRA_DEINIT
466
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
467
vic_end();
468
tmp451_end();
469
fan_set_duty(0);
470
touch_power_off();
471
jc_deinit();
472
regulator_5v_disable(REGULATOR_5V_ALL);
473
#endif
474
475
// set DRAM clock to 204MHz.
476
minerva_change_freq(FREQ_204);
477
nyx_str->mtc_cfg.init_done = 0;
478
479
// Flush/disable MMU cache.
480
bpmp_mmu_disable();
481
482
// Reset arbiter.
483
hw_config_arbiter(true);
484
485
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
486
if (tegra_t210)
487
{
488
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= BIT(CLK_V_AHUB);
489
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= BIT(CLK_Y_APE);
490
}
491
492
// Do coreboot mitigations.
493
if (coreboot)
494
{
495
msleep(10);
496
497
clock_disable_cl_dvfs();
498
499
// Disable Joy-con detect in order to restore UART TX.
500
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
501
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
502
503
// Reinstate SD controller power.
504
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_SDMMC1;
505
}
506
507
// Seamless display or display power off.
508
switch (bl_magic)
509
{
510
case BL_MAGIC_CRBOOT_SLD:;
511
// Set pwm to 0%, switch to gpio mode and restore pwm duty.
512
u32 brightness = display_get_backlight_brightness();
513
display_backlight_brightness(0, 1000);
514
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_GPIO);
515
display_backlight_brightness(brightness, 0);
516
break;
517
case BL_MAGIC_L4TLDR_SLD:
518
// Do not disable display or backlight at all.
519
break;
520
default:
521
display_end();
522
clock_disable_host1x();
523
}
524
}
525
526