Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/soc/hw_init.c
3694 views
1
/*
2
* Copyright (c) 2018 naehrwert
3
* Copyright (c) 2018-2026 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
u32 hw_rst_status;
51
u32 hw_rst_reason;
52
53
u32 hw_get_chip_id()
54
{
55
if (((APB_MISC(APB_MISC_GP_HIDREV) >> 4) & 0xF) >= GP_HIDREV_MAJOR_T210B01)
56
return GP_HIDREV_MAJOR_T210B01;
57
else
58
return GP_HIDREV_MAJOR_T210;
59
}
60
61
/*
62
* CLK_OSC - 38.4 MHz crystal.
63
* CLK_M - 19.2 MHz (osc/2).
64
* CLK_S - 32.768 KHz (from PMIC).
65
* SCLK - 204MHz init (-> 408MHz -> OC).
66
* HCLK - 204MHz init (-> 408MHz -> OC).
67
* PCLK - 68MHz init (-> 136MHz -> OC/4).
68
*/
69
70
static void _config_oscillators()
71
{
72
CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) = (CLOCK(CLK_RST_CONTROLLER_SPARE_REG0) & 0xFFFFFFF3) | 4; // Set CLK_M_DIVISOR to 2.
73
SYSCTR0(SYSCTR0_CNTFID0) = 19200000; // Set counter frequency.
74
TMR(TIMERUS_USEC_CFG) = 0x45F; // For 19.2MHz clk_m.
75
CLOCK(CLK_RST_CONTROLLER_OSC_CTRL) = 0x50000071; // Set OSC to 38.4MHz and drive strength.
76
77
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFFFFF81) | 0xE; // Set LP0 OSC drive strength.
78
PMC(APBDEV_PMC_OSC_EDPD_OVER) = (PMC(APBDEV_PMC_OSC_EDPD_OVER) & 0xFFBFFFFF) | PMC_OSC_EDPD_OVER_OSC_CTRL_OVER;
79
PMC(APBDEV_PMC_CNTRL2) = (PMC(APBDEV_PMC_CNTRL2) & 0xFFFFEFFF) | PMC_CNTRL2_HOLD_CKE_LOW_EN;
80
APB_MISC(APB_MISC_GP_ASDBGREG) = (APB_MISC(APB_MISC_GP_ASDBGREG) & 0xFCFFFFFF) | (2 << 24); // CFG2TMC_RAM_SVOP_PDP.
81
82
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
83
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) &= 0xBFFFFFFF; // PLLMB disable.
84
85
PMC(APBDEV_PMC_TSC_MULT) = (PMC(APBDEV_PMC_TSC_MULT) & 0xFFFF0000) | 0x249F; // 0x249F = 19200000 * (16 / 32.768 kHz).
86
87
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set BPMP/SCLK div to 1.
88
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set BPMP/SCLK source to Run and PLLP_OUT2 (204MHz).
89
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
90
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
91
}
92
93
void hw_config_arbiter(bool reset)
94
{
95
if (reset)
96
{
97
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x0040090;
98
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x12024C2;
99
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x2201209;
100
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320365B;
101
}
102
else
103
{
104
ARB_PRI(ARB_PRIO_CPU_PRIORITY) = 0x12412D1;
105
ARB_PRI(ARB_PRIO_COP_PRIORITY) = 0x0000000;
106
ARB_PRI(ARB_PRIO_VCP_PRIORITY) = 0x220244A;
107
ARB_PRI(ARB_PRIO_DMA_PRIORITY) = 0x320369B;
108
}
109
}
110
111
// The uart is skipped for Copper, Hoag and Calcio. Used in Icosa, Iowa and Aula.
112
static void _config_gpios(bool nx_hoag)
113
{
114
// Clamp inputs when tristated.
115
APB_MISC(APB_MISC_PP_PINMUX_GLOBAL) = 0;
116
117
if (!nx_hoag)
118
{
119
// Turn Joy-Con detect on. (GPIO mode and input logic for UARTB/C TX pins.)
120
PINMUX_AUX(PINMUX_AUX_UART2_TX) = 0;
121
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
122
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
123
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
124
}
125
126
// Set Joy-Con IsAttached pinmux. Shared with UARTB/UARTC TX.
127
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
128
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
129
130
// Configure Joy-Con IsAttached pins. Shared with UARTB/UARTC TX.
131
gpio_direction_input(GPIO_PORT_E, GPIO_PIN_6);
132
gpio_direction_input(GPIO_PORT_H, GPIO_PIN_6);
133
134
pinmux_config_i2c(I2C_1);
135
pinmux_config_i2c(I2C_5);
136
pinmux_config_uart(UART_A);
137
138
// Configure volume up/down as inputs.
139
gpio_direction_input(GPIO_PORT_X, GPIO_PIN_6 | GPIO_PIN_7);
140
141
// Configure HOME as input. (Shared with UARTB RTS).
142
PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
143
gpio_direction_input(GPIO_PORT_Y, GPIO_PIN_1);
144
145
// Power button can be configured for hoag here. Only SKU where it's connected.
146
}
147
148
static void _config_pmc_scratch()
149
{
150
PMC(APBDEV_PMC_SCRATCH20) &= 0xFFF3FFFF; // Unset Debug console from Customer Option.
151
PMC(APBDEV_PMC_SCRATCH190) &= 0xFFFFFFFE; // Unset WDT_DURING_BR.
152
PMC(APBDEV_PMC_SECURE_SCRATCH21) |= PMC_FUSE_PRIVATEKEYDISABLE_TZ_STICKY_BIT;
153
}
154
155
static void _mbist_workaround_bl()
156
{
157
/*
158
* DFT MBIST HW Errata for T210.
159
* RAM Data corruption observed when MBIST_EN from DFT (Tegra X1 Si Errata)
160
*
161
* The MBIST_EN signals from the DFT logic can impact the functional logic of
162
* internal rams after power-on since they are driven by non-resetable flops.
163
* That can be worked around by enabling and then disabling the related clocks.
164
*
165
* The bootrom patches, already handle the LVL2 SLCG war by enabling all clocks
166
* and all LVL2 CLK overrides (power saving disable).
167
* The Bootloader then handles the IP block SLCG part and also restores the
168
* state for the clocks/lvl2 slcg.
169
* After these, per domain MBIST WAR is needed every time a domain gets
170
* unpowergated if it was previously powergated.
171
*
172
* Affected power domains: all except IRAM and CCPLEX.
173
*/
174
175
// Set mux output to SOR1 clock switch (for VI).
176
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) & ~BIT(14)) | BIT(15);
177
// Enable PLLD and set csi to PLLD for test pattern generation (for VI).
178
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) |= PLL_BASE_ENABLE | BIT(23);
179
180
// Make sure Audio clocks are enabled before accessing I2S.
181
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
182
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
183
184
// Clear per-clock resets for APE/VIC/HOST1X/DISP1.
185
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_CLR) = BIT(CLK_Y_APE);
186
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_CLR) = BIT(CLK_X_VIC);
187
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
188
usleep(2);
189
190
// Set I2S to master to enable clocks and set SLCG overrides.
191
for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
192
{
193
I2S(I2S_CTRL + (i2s_idx << 8u)) |= I2S_CTRL_MASTER_EN;
194
I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_DISABLE;
195
}
196
// Set SLCG overrides for DISPA and VIC.
197
DISPLAY_A(DC_COM_DSC_TOP_CTL) |= BIT(2); // DSC_SLCG_OVERRIDE.
198
VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0xFFFFFFFF;
199
200
// Wait a bit for MBIST_EN to get unstuck (1 cycle min).
201
usleep(2);
202
203
// Reset SLCG to automatic mode.
204
// for (u32 i2s_idx = 0; i2s_idx < 5; i2s_idx++)
205
// I2S(I2S_CG + (i2s_idx << 8u)) = I2S_CG_SLCG_ENABLE;
206
// DISPLAY_A(DC_COM_DSC_TOP_CTL) &= ~BIT(2); // DSC_SLCG_OVERRIDE.
207
// VIC(VIC_THI_SLCG_OVERRIDE_LOW_A) = 0;
208
209
// Set per-clock reset for APE/VIC/HOST1X/DISP1.
210
CLOCK(CLK_RST_CONTROLLER_RST_DEV_Y_SET) = BIT(CLK_Y_APE);
211
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
212
CLOCK(CLK_RST_CONTROLLER_RST_DEV_X_SET) = BIT(CLK_X_VIC);
213
214
// Disable all unneeded clocks that were enabled in bootrom.
215
// CLK L Devices.
216
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = BIT(CLK_H_PMC) |
217
BIT(CLK_H_FUSE);
218
// CLK H Devices.
219
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = BIT(CLK_L_RTC) |
220
BIT(CLK_L_TMR) |
221
BIT(CLK_L_GPIO) |
222
BIT(CLK_L_BPMP_CACHE_CTRL);
223
// CLK U Devices.
224
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = BIT(CLK_U_CSITE) |
225
BIT(CLK_U_IRAMA) |
226
BIT(CLK_U_IRAMB) |
227
BIT(CLK_U_IRAMC) |
228
BIT(CLK_U_IRAMD) |
229
BIT(CLK_U_BPMP_CACHE_RAM);
230
// CLK V Devices.
231
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = BIT(CLK_V_MSELECT) |
232
BIT(CLK_V_APB2APE) |
233
BIT(CLK_V_SPDIF_DOUBLER) |
234
BIT(CLK_V_SE);
235
// CLK W Devices.
236
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = BIT(CLK_W_PCIERX0) |
237
BIT(CLK_W_PCIERX1) |
238
BIT(CLK_W_PCIERX2) |
239
BIT(CLK_W_PCIERX3) |
240
BIT(CLK_W_PCIERX4) |
241
BIT(CLK_W_PCIERX5) |
242
BIT(CLK_W_ENTROPY) |
243
BIT(CLK_W_MC1);
244
// CLK X Devices.
245
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X) = BIT(CLK_X_MC_CAPA) |
246
BIT(CLK_X_MC_CBPA) |
247
BIT(CLK_X_MC_CPU) |
248
BIT(CLK_X_MC_BBC) |
249
BIT(CLK_X_GPU) |
250
BIT(CLK_X_DBGAPB) |
251
BIT(CLK_X_PLLG_REF);
252
// CLK Y Devices.
253
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) = BIT(CLK_Y_MC_CDPA) |
254
BIT(CLK_Y_MC_CCPA);
255
256
// Reset clock gate overrides to automatic mode.
257
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRA) = 0;
258
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB) = 0;
259
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRC) = 0;
260
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD) = 0;
261
CLOCK(CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRE) = 0;
262
263
// Set child clock sources.
264
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) &= 0x1F7FFFFF; // Disable PLLD and set reference clock and csi clock.
265
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SOR1) &= ~(BIT(15) | BIT(14)); // Set SOR1 to automatic muxing of safe clock (24MHz) or SOR1 clk switch.
266
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_VI) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
267
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
268
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_NVENC) & 0x1FFFFFFF) | (4 << 29u); // Set clock source to PLLP_OUT.
269
}
270
271
static void _config_se_brom()
272
{
273
// Enable Fuse visibility.
274
clock_enable_fuse(true);
275
276
// Try to set SBK from fuses. If patched, skip.
277
fuse_set_sbk();
278
279
// Make SBK unreadable.
280
//FUSE(FUSE_PRIVATEKEYDISABLE) = FUSE_PRIVKEY_TZ_STICKY_BIT | FUSE_PRIVKEY_DISABLE;
281
282
// Lock SSK (although it's not set and unused anyways).
283
// se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEYREAD_FLAG);
284
285
// This memset needs to happen here, else TZRAM will behave weirdly later on.
286
memset((void *)TZRAM_BASE, 0, TZRAM_SIZE);
287
PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE;
288
289
// Clear SE interrupts.
290
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;
291
292
// Save reset reason.
293
hw_rst_status = PMC(APBDEV_PMC_SCRATCH200);
294
hw_rst_reason = PMC(APBDEV_PMC_RST_STATUS) & PMC_RST_STATUS_MASK;
295
296
// Clear the boot reason to avoid problems later.
297
PMC(APBDEV_PMC_SCRATCH200) = 0;
298
PMC(APBDEV_PMC_RST_STATUS) = PMC_RST_STATUS_POR;
299
APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) = (APB_MISC(APB_MISC_PP_STRAPPING_OPT_A) & 0xF0) | (7 << 10);
300
}
301
302
static void _config_regulators(bool tegra_t210, bool nx_hoag)
303
{
304
// Set RTC/AO domain to POR voltage.
305
if (tegra_t210)
306
max7762x_regulator_set_voltage(REGULATOR_LDO4, 1000000);
307
308
// Disable low battery shutdown monitor.
309
max77620_low_battery_monitor_config(false);
310
311
// Power on all relevant rails in case we came out of warmboot. Only keep MEM/MEM_COMP and SDMMC1 states.
312
PMC(APBDEV_PMC_NO_IOPOWER) &= PMC_NO_IOPOWER_MEM_COMP | PMC_NO_IOPOWER_SDMMC1 | PMC_NO_IOPOWER_MEM;
313
314
// Make sure SDMMC1 IO/Core are powered off.
315
max7762x_regulator_enable(REGULATOR_LDO2, false);
316
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
317
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
318
(void)PMC(APBDEV_PMC_NO_IOPOWER);
319
sd_power_cycle_time_start = get_tmr_ms();
320
321
// Disable backup battery charger.
322
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
323
324
// Set PWR delay for forced shutdown off to 6s.
325
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_RSVD | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT));
326
327
if (tegra_t210)
328
{
329
// Configure all Flexible Power Sequencers for MAX77620.
330
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (0 << MAX77620_FPS_EN_SRC_SHIFT));
331
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (1 << MAX77620_FPS_EN_SRC_SHIFT));
332
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG2, (7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
333
max77620_regulator_config_fps(REGULATOR_LDO4);
334
max77620_regulator_config_fps(REGULATOR_LDO8);
335
max77620_regulator_config_fps(REGULATOR_SD0);
336
max77620_regulator_config_fps(REGULATOR_SD1);
337
max77620_regulator_config_fps(REGULATOR_SD3);
338
339
// Set GPIO3 to FPS0 for SYS 3V3 EN. Enabled when FPS0 is enabled.
340
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3, (4 << MAX77620_FPS_PU_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT));
341
342
// Set vdd_core voltage to 1.125V.
343
max7762x_regulator_set_voltage(REGULATOR_SD0, 1125000);
344
345
// Power down CPU/GPU regulators after L4T warmboot.
346
max77620_config_gpio(5, MAX77620_GPIO_OUTPUT_DISABLE);
347
max77620_config_gpio(6, MAX77620_GPIO_OUTPUT_DISABLE);
348
349
// Set POR configuration.
350
max77621_config_default(REGULATOR_CPU0, MAX77621_CTRL_POR_CFG);
351
max77621_config_default(REGULATOR_GPU0, MAX77621_CTRL_POR_CFG);
352
}
353
else
354
{
355
// Tegra X1+ set vdd_core voltage to 1.05V.
356
max7762x_regulator_set_voltage(REGULATOR_SD0, 1050000);
357
358
// Power on SD2 regulator for supplying LDO0/1/8.
359
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
360
361
// Set slew rate and enable SD2 regulator.
362
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) |
363
(MAX77620_POWER_MODE_NORMAL << MAX77620_SD_POWER_MODE_SHIFT) |
364
MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
365
366
// Enable LDO8 on HOAG as it also powers I2C1 IO pads.
367
if (nx_hoag)
368
{
369
max7762x_regulator_set_voltage(REGULATOR_LDO8, 2800000);
370
max7762x_regulator_enable(REGULATOR_LDO8, true);
371
}
372
}
373
}
374
375
void hw_init()
376
{
377
// Get Chip ID and SKU.
378
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
379
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
380
381
// Bootrom stuff we might skipped by going through rcm.
382
_config_se_brom();
383
384
// Unset APB2JTAG_OVERRIDE_EN and OBS_OVERRIDE_EN.
385
SYSREG(AHB_AHB_SPARE_REG) &= 0xFFFFFF9F;
386
PMC(APBDEV_PMC_SCRATCH49) &= 0xFFFFFFFC;
387
388
// Perform the bootloader part of the Memory Built-In Self Test WAR if T210.
389
if (tegra_t210)
390
_mbist_workaround_bl();
391
392
// Make sure PLLP_OUT3/4 is set to 408 MHz and enabled.
393
CLOCK(CLK_RST_CONTROLLER_PLLP_OUTB) = 0x30003;
394
395
// Enable Security Engine clock.
396
clock_enable_se();
397
398
// Enable Fuse visibility.
399
clock_enable_fuse(true);
400
401
// Disable Fuse programming.
402
fuse_disable_program();
403
404
// Enable clocks to Memory controllers and disable AHB redirect.
405
mc_enable();
406
407
// Initialize counters, CLKM, BPMP and other clocks based on 38.4MHz oscillator.
408
_config_oscillators();
409
410
// Initialize pin configuration.
411
_config_gpios(nx_hoag);
412
413
// Enable CL-DVFS clock unconditionally to avoid issues with I2C5 sharing.
414
clock_enable_cl_dvfs();
415
416
// Enable clocks to I2C1 and I2CPWR.
417
clock_enable_i2c(I2C_1);
418
clock_enable_i2c(I2C_5);
419
420
// Enable clock to TZRAM.
421
clock_enable_tzram();
422
423
// Initialize I2C5, mandatory for PMIC.
424
i2c_init(I2C_5);
425
426
// Initialize various regulators based on Erista/Mariko platform.
427
_config_regulators(tegra_t210, nx_hoag);
428
429
// Initialize I2C1 for various power related devices.
430
i2c_init(I2C_1);
431
432
_config_pmc_scratch(); // Missing from 4.x+
433
434
// Set BPMP/SCLK to PLLP_OUT (408MHz).
435
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333;
436
437
// Disable T210B01 TZRAM power-gating and lock the reg.
438
if (!tegra_t210)
439
{
440
// This is not actually needed since it's done by bootrom. The read locks are extra.
441
PMC(APBDEV_PMC_TZRAM_PWR_CNTRL_B01) &= ~PMC_TZRAM_PWR_CNTRL_SD;
442
PMC(APBDEV_PMC_TZRAM_NON_SEC_DISABLE_B01) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
443
PMC(APBDEV_PMC_TZRAM_SEC_DISABLE_B01) = PMC_TZRAM_DISABLE_REG_WRITE | PMC_TZRAM_DISABLE_REG_READ;
444
}
445
446
// Set arbiter.
447
hw_config_arbiter(false);
448
449
// Initialize External memory controller and configure DRAM parameters.
450
sdram_init();
451
452
bpmp_mmu_enable();
453
454
// Enable HOST1X used by every display module (DC, VIC, NVDEC, NVENC, TSEC, etc).
455
clock_enable_host1x();
456
457
#ifdef DEBUG_UART_PORT
458
// Setup debug uart port.
459
#if (DEBUG_UART_PORT == UART_B)
460
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
461
#elif (DEBUG_UART_PORT == UART_C)
462
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
463
#endif
464
pinmux_config_uart(DEBUG_UART_PORT);
465
clock_enable_uart(DEBUG_UART_PORT);
466
uart_init(DEBUG_UART_PORT, DEBUG_UART_BAUDRATE, UART_AO_TX_AO_RX);
467
uart_invert(DEBUG_UART_PORT, DEBUG_UART_INVERT, UART_INVERT_TXD);
468
#endif
469
}
470
471
void hw_deinit(bool keep_display)
472
{
473
// Seamless display or display power off.
474
if (!keep_display)
475
{
476
display_end();
477
clock_disable_host1x();
478
}
479
480
// Scale down BPMP clock.
481
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
482
483
#ifdef BDK_HW_EXTRA_DEINIT
484
// Disable temperature sensor, touchscreen, 5V regulators, Joy-Con and VIC.
485
vic_end();
486
tmp451_end();
487
fan_set_duty(0);
488
touch_power_off();
489
jc_deinit();
490
regulator_5v_disable(REGULATOR_5V_ALL);
491
#endif
492
493
// Set DRAM clock to 204MHz.
494
minerva_deinit();
495
496
// Flush/disable MMU cache.
497
bpmp_mmu_disable();
498
499
// Reset arbiter.
500
hw_config_arbiter(true);
501
502
// Re-enable clocks to Audio Processing Engine as a workaround to rerunning mbist war.
503
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210)
504
{
505
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_V_SET) = BIT(CLK_V_AHUB);
506
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_APE);
507
}
508
}
509
510