mirror of
https://github.com/s1204IT/Lockpick_RCM.git
synced 2024-11-22 17:56:39 +00:00
Merge hekate 5.1.0 changes
This commit is contained in:
parent
cdb29719e4
commit
b3a739592e
46 changed files with 1525 additions and 224 deletions
87
common/memory_map.h
Normal file
87
common/memory_map.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _MEMORY_MAP_H_
|
||||
#define _MEMORY_MAP_H_
|
||||
|
||||
//#define IPL_STACK_TOP 0x4003FF00
|
||||
/* --- BIT/BCT: 0x40000000 - 0x40003000 --- */
|
||||
/* --- IPL: 0x40003000 - 0x40028000 --- */
|
||||
#define IPL_LOAD_ADDR 0x40003000
|
||||
#define IPL_SZ_MAX 0x20000 // 128KB.
|
||||
//#define IRAM_LIB_ADDR 0x4002B000
|
||||
#define SDRAM_PARAMS_ADDR 0x40030000 // SDRAM extraction buffer during sdram init.
|
||||
#define CBFS_DRAM_EN_ADDR 0x4003e000 // u32.
|
||||
|
||||
/* --- DRAM START --- */
|
||||
#define DRAM_START 0x80000000
|
||||
/* Do not write anything in this area */
|
||||
#define NYX_LOAD_ADDR 0x81000000
|
||||
#define NYX_SZ_MAX 0x1000000
|
||||
/* Stack theoretical max: 220MB */
|
||||
#define IPL_STACK_TOP 0x90010000
|
||||
#define IPL_HEAP_START 0x90020000
|
||||
#define IPL_HEAP_SZ 0x24FE0000 // 592MB.
|
||||
/* --- Gap: 0xB5000000 - 0xB5FFFFFF --- */
|
||||
|
||||
// SDMMC DMA buffers
|
||||
#define SDXC_BUF_ALIGNED 0xB6000000
|
||||
#define MIXD_BUF_ALIGNED 0xB7000000
|
||||
#define EMMC_BUF_ALIGNED MIXD_BUF_ALIGNED
|
||||
#define SDMMC_DMA_BUF_SZ 0x1000000 // 16MB (4MB currently used).
|
||||
#define SDMMC_UPPER_BUFFER 0xB8000000
|
||||
#define SDMMC_UP_BUF_SZ 0x8000000 // 128MB.
|
||||
|
||||
// Virtual disk / Chainloader buffers.
|
||||
#define RAM_DISK_ADDR 0xC1000000
|
||||
#define RAM_DISK_SZ 0x20000000
|
||||
//#define DRAM_LIB_ADDR 0xE0000000
|
||||
/* --- Chnldr: 252MB 0xC03C0000 - 0xCFFFFFFF --- */ //! Only used when chainloading.
|
||||
/* --- Gap: 464MB 0xD0000000 - 0xECFFFFFF --- */
|
||||
|
||||
// Nyx buffers.
|
||||
#define NYX_STORAGE_ADDR 0xED000000
|
||||
#define NYX_RES_ADDR 0xEE000000
|
||||
|
||||
// Framebuffer addresses.
|
||||
#define IPL_FB_ADDRESS 0xF0000000
|
||||
#define IPL_FB_SZ 0x384000 // 720 x 1280 x 4.
|
||||
#define LOG_FB_ADDRESS 0xF0400000
|
||||
#define LOG_FB_SZ 0x334000 // 1280 x 656 x 4.
|
||||
#define NYX_FB_ADDRESS 0xF0800000
|
||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||
|
||||
// Nyx LvGL buffers.
|
||||
#define NYX_LV_VDB_ADR 0xF0C00000
|
||||
#define NYX_FB_SZ 0x384000 // 1280 x 720 x 4.
|
||||
#define NYX_LV_MEM_ADR 0xF1000000
|
||||
#define NYX_LV_MEM_SZ 0x8000000
|
||||
|
||||
// NX BIS driver sector cache.
|
||||
#define NX_BIS_CACHE_ADDR 0xF9000000
|
||||
#define NX_BIS_CACHE_SZ 0x8800
|
||||
/* --- Gap: 111MB 0xF9008800 - 0xFFFFFFFF --- */
|
||||
|
||||
// #define EXT_PAYLOAD_ADDR 0xC03C0000
|
||||
// #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
// #define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
||||
|
||||
// NYX
|
||||
// #define EXT_PAYLOAD_ADDR 0xC0000000
|
||||
// #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
// #define COREBOOT_ADDR (0xD0000000 - 0x100000)
|
||||
|
||||
#endif
|
|
@ -20,6 +20,7 @@
|
|||
#include "config.h"
|
||||
#include "ini.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../gfx/tui.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
|
@ -52,3 +53,614 @@ void set_default_configuration()
|
|||
sd_power_cycle_time_start = 0xFFFFFFF;
|
||||
}
|
||||
|
||||
int create_config_entry()
|
||||
{
|
||||
if (!sd_mount())
|
||||
return 1;
|
||||
|
||||
char lbuf[32];
|
||||
FIL fp;
|
||||
bool mainIniFound = false;
|
||||
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||
mainIniFound = true;
|
||||
else
|
||||
{
|
||||
u8 res = f_open(&fp, "bootloader/hekate_ipl.ini", FA_READ);
|
||||
if (res == FR_NO_FILE || res == FR_NO_PATH)
|
||||
{
|
||||
f_mkdir("bootloader");
|
||||
f_mkdir("bootloader/ini");
|
||||
f_mkdir("bootloader/payloads");
|
||||
f_mkdir("bootloader/sys");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!res)
|
||||
f_close(&fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (f_open(&fp, "bootloader/hekate_ipl.ini", FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
|
||||
return 1;
|
||||
// Add config entry.
|
||||
f_puts("[config]\nautoboot=", &fp);
|
||||
itoa(h_cfg.autoboot, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nautoboot_list=", &fp);
|
||||
itoa(h_cfg.autoboot_list, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nbootwait=", &fp);
|
||||
itoa(h_cfg.bootwait, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nverification=", &fp);
|
||||
itoa(h_cfg.verification, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nbacklight=", &fp);
|
||||
itoa(h_cfg.backlight, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nautohosoff=", &fp);
|
||||
itoa(h_cfg.autohosoff, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
f_puts("\nautonogc=", &fp);
|
||||
itoa(h_cfg.autonogc, lbuf, 10);
|
||||
f_puts(lbuf, &fp);
|
||||
if (h_cfg.brand)
|
||||
{
|
||||
f_puts("\nbrand=", &fp);
|
||||
f_puts(h_cfg.brand, &fp);
|
||||
}
|
||||
if (h_cfg.tagline)
|
||||
{
|
||||
f_puts("\ntagline=", &fp);
|
||||
f_puts(h_cfg.tagline, &fp);
|
||||
}
|
||||
f_puts("\n", &fp);
|
||||
|
||||
if (mainIniFound)
|
||||
{
|
||||
// Re-construct existing entries.
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
if (!strcmp(ini_sec->name, "config"))
|
||||
continue;
|
||||
|
||||
switch (ini_sec->type)
|
||||
{
|
||||
case INI_CHOICE: // Re-construct Boot entry [ ].
|
||||
f_puts("[", &fp);
|
||||
f_puts(ini_sec->name, &fp);
|
||||
f_puts("]\n", &fp);
|
||||
// Re-construct boot entry's config.
|
||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
|
||||
{
|
||||
f_puts(kv->key, &fp);
|
||||
f_puts("=", &fp);
|
||||
f_puts(kv->val, &fp);
|
||||
f_puts("\n", &fp);
|
||||
}
|
||||
break;
|
||||
case INI_CAPTION: // Re-construct caption entry { }.
|
||||
f_puts("{", &fp);
|
||||
f_puts(ini_sec->name, &fp);
|
||||
f_puts("}\n", &fp);
|
||||
break;
|
||||
case INI_NEWLINE: // Re-construct cosmetic newline \n.
|
||||
f_puts("\n", &fp);
|
||||
break;
|
||||
case INI_COMMENT: // Re-construct comment entry #.
|
||||
f_puts("#", &fp);
|
||||
f_puts(ini_sec->name, &fp);
|
||||
f_puts("\n", &fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
sd_unmount();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
static void _save_config()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
if (!create_config_entry())
|
||||
gfx_puts("\nConfiguration was saved!\n");
|
||||
else
|
||||
EPRINTF("\nConfiguration saving failed!");
|
||||
gfx_puts("\nPress any key...");
|
||||
}
|
||||
|
||||
static void _config_autoboot_list(void *ent)
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
u32 *temp_autoboot = NULL;
|
||||
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
u8 max_entries = 30;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
|
||||
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries);
|
||||
char *boot_text = (char *)malloc(512 * max_entries);
|
||||
|
||||
for (u32 j = 0; j < max_entries; j++)
|
||||
boot_values[j] = j;
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
if (ini_parse(&ini_sections, "bootloader/ini", true))
|
||||
{
|
||||
// Build configuration menu.
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
u32 i = 2;
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
// Skip other ini entries for autoboot.
|
||||
if (ini_sec->type == INI_CHOICE)
|
||||
{
|
||||
if (!strcmp(ini_sec->name, "config"))
|
||||
continue;
|
||||
|
||||
if (strlen(ini_sec->name) > 510)
|
||||
ments[i].caption = ini_sec->name;
|
||||
else
|
||||
{
|
||||
if (h_cfg.autoboot != (i - 1) || !h_cfg.autoboot_list)
|
||||
boot_text[(i - 1) * 512] = ' ';
|
||||
|
||||
else
|
||||
boot_text[(i - 1) * 512] = '*';
|
||||
strcpy(boot_text + (i - 1) * 512 + 1, ini_sec->name);
|
||||
ments[i].caption = &boot_text[(i - 1) * 512];
|
||||
}
|
||||
ments[i].type = ini_sec->type;
|
||||
ments[i].data = &boot_values[i - 1];
|
||||
i++;
|
||||
|
||||
if ((i - 1) > max_entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&ments[i], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Select an entry to auto boot", 0, 0};
|
||||
temp_autoboot = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_autoboot != NULL)
|
||||
{
|
||||
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||
h_cfg.autoboot_list = 1;
|
||||
_save_config();
|
||||
|
||||
ment_t *tmp = (ment_t *)ent;
|
||||
tmp->data = NULL;
|
||||
}
|
||||
else
|
||||
goto out2;
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists!.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:;
|
||||
btn_wait();
|
||||
out2:;
|
||||
free(ments);
|
||||
free(boot_values);
|
||||
free(boot_text);
|
||||
|
||||
sd_unmount();
|
||||
}
|
||||
|
||||
void config_autoboot()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
u32 *temp_autoboot = NULL;
|
||||
|
||||
LIST_INIT(ini_sections);
|
||||
|
||||
u8 max_entries = 30;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5));
|
||||
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries);
|
||||
char *boot_text = (char *)malloc(512 * max_entries);
|
||||
|
||||
for (u32 j = 0; j < max_entries; j++)
|
||||
boot_values[j] = j;
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||
{
|
||||
// Build configuration menu.
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
ments[2].type = MENT_DATA;
|
||||
if (!h_cfg.autoboot)
|
||||
ments[2].caption = "*Disable";
|
||||
else
|
||||
ments[2].caption = " Disable";
|
||||
ments[2].data = &boot_values[0];
|
||||
|
||||
ments[3].type = MENT_HDLR_RE;
|
||||
if (h_cfg.autoboot_list)
|
||||
ments[3].caption = "*More configs...";
|
||||
else
|
||||
ments[3].caption = " More configs...";
|
||||
ments[3].handler = _config_autoboot_list;
|
||||
ments[3].data = (void *)0xCAFE;
|
||||
|
||||
ments[4].type = MENT_CHGLINE;
|
||||
|
||||
u32 i = 5;
|
||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||
{
|
||||
// Skip other ini entries for autoboot.
|
||||
if (ini_sec->type == INI_CHOICE)
|
||||
{
|
||||
if (!strcmp(ini_sec->name, "config"))
|
||||
continue;
|
||||
|
||||
if (strlen(ini_sec->name) > 510)
|
||||
ments[i].caption = ini_sec->name;
|
||||
else
|
||||
{
|
||||
if (h_cfg.autoboot != (i - 4) || h_cfg.autoboot_list)
|
||||
boot_text[(i - 4) * 512] = ' ';
|
||||
|
||||
else
|
||||
boot_text[(i - 4) * 512] = '*';
|
||||
strcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name);
|
||||
ments[i].caption = &boot_text[(i - 4) * 512];
|
||||
}
|
||||
ments[i].type = ini_sec->type;
|
||||
ments[i].data = &boot_values[i - 4];
|
||||
i++;
|
||||
|
||||
if ((i - 4) > max_entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < 6 && !h_cfg.autoboot_list)
|
||||
{
|
||||
ments[i].type = MENT_CAPTION;
|
||||
ments[i].caption = "No main configurations found...";
|
||||
ments[i].color = 0xFFFFDD00;
|
||||
i++;
|
||||
}
|
||||
|
||||
memset(&ments[i], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Disable or select entry to auto boot", 0, 0};
|
||||
temp_autoboot = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_autoboot != NULL)
|
||||
{
|
||||
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||
h_cfg.autoboot_list = 0;
|
||||
_save_config();
|
||||
}
|
||||
else
|
||||
goto out2;
|
||||
}
|
||||
else
|
||||
{
|
||||
EPRINTF("Could not open 'bootloader/hekate_ipl.ini'.\nMake sure it exists!.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:;
|
||||
btn_wait();
|
||||
out2:;
|
||||
free(ments);
|
||||
free(boot_values);
|
||||
free(boot_text);
|
||||
|
||||
sd_unmount();
|
||||
|
||||
if (temp_autoboot == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
void config_bootdelay()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
u32 delay_entries = 6;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (delay_entries + 3));
|
||||
u32 *delay_values = (u32 *)malloc(sizeof(u32) * delay_entries);
|
||||
char *delay_text = (char *)malloc(32 * delay_entries);
|
||||
|
||||
for (u32 j = 0; j < delay_entries; j++)
|
||||
delay_values[j] = j;
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
ments[2].type = MENT_DATA;
|
||||
if (h_cfg.bootwait)
|
||||
ments[2].caption = " 0 seconds (Bootlogo disabled)";
|
||||
else
|
||||
ments[2].caption = "*0 seconds (Bootlogo disabled)";
|
||||
ments[2].data = &delay_values[0];
|
||||
|
||||
u32 i = 0;
|
||||
for (i = 1; i < delay_entries; i++)
|
||||
{
|
||||
if (h_cfg.bootwait != i)
|
||||
delay_text[i * 32] = ' ';
|
||||
else
|
||||
delay_text[i * 32] = '*';
|
||||
delay_text[i * 32 + 1] = i + '0';
|
||||
strcpy(delay_text + i * 32 + 2, " seconds");
|
||||
|
||||
ments[i + 2].type = MENT_DATA;
|
||||
ments[i + 2].caption = delay_text + i * 32;
|
||||
ments[i + 2].data = &delay_values[i];
|
||||
}
|
||||
|
||||
memset(&ments[i + 2], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Time delay for entering bootloader menu", 0, 0};
|
||||
|
||||
u32 *temp_bootwait = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_bootwait != NULL)
|
||||
{
|
||||
h_cfg.bootwait = *(u32 *)temp_bootwait;
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(delay_values);
|
||||
free(delay_text);
|
||||
|
||||
if (temp_bootwait == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_verification()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
|
||||
u32 *vr_values = (u32 *)malloc(sizeof(u32) * 3);
|
||||
char *vr_text = (char *)malloc(64 * 3);
|
||||
|
||||
for (u32 j = 0; j < 3; j++)
|
||||
{
|
||||
vr_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &vr_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
strcpy(vr_text, " Disable (Fastest - Unsafe)");
|
||||
strcpy(vr_text + 64, " Sparse (Fast - Safe)");
|
||||
strcpy(vr_text + 128, " Full (Slow - Safe)");
|
||||
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (h_cfg.verification != i)
|
||||
vr_text[64 * i] = ' ';
|
||||
else
|
||||
vr_text[64 * i] = '*';
|
||||
ments[2 + i].caption = vr_text + (i * 64);
|
||||
}
|
||||
|
||||
memset(&ments[5], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Backup & Restore verification", 0, 0};
|
||||
|
||||
u32 *temp_verification = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_verification != NULL)
|
||||
{
|
||||
h_cfg.verification = *(u32 *)temp_verification;
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(vr_values);
|
||||
free(vr_text);
|
||||
|
||||
if (temp_verification == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_backlight()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
u32 bri_entries = 11;
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (bri_entries + 3));
|
||||
u32 *bri_values = (u32 *)malloc(sizeof(u32) * bri_entries);
|
||||
char *bri_text = (char *)malloc(8 * bri_entries);
|
||||
|
||||
for (u32 j = 1; j < bri_entries; j++)
|
||||
bri_values[j] = j * 10;
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
u32 i = 0;
|
||||
for (i = 1; i < bri_entries; i++)
|
||||
{
|
||||
if ((h_cfg.backlight / 20) != i)
|
||||
bri_text[i * 32] = ' ';
|
||||
else
|
||||
bri_text[i * 32] = '*';
|
||||
|
||||
if (i < 10)
|
||||
{
|
||||
bri_text[i * 32 + 1] = i + '0';
|
||||
strcpy(bri_text + i * 32 + 2, "0%");
|
||||
}
|
||||
else
|
||||
strcpy(bri_text + i * 32 + 1, "100%");
|
||||
|
||||
ments[i + 1].type = MENT_DATA;
|
||||
ments[i + 1].caption = bri_text + i * 32;
|
||||
ments[i + 1].data = &bri_values[i];
|
||||
}
|
||||
|
||||
memset(&ments[i + 1], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Backlight brightness", 0, 0};
|
||||
|
||||
u32 *temp_backlight = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_backlight != NULL)
|
||||
{
|
||||
h_cfg.backlight = (*(u32 *)temp_backlight) * 2;
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(bri_values);
|
||||
free(bri_text);
|
||||
|
||||
if (temp_backlight == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_auto_hos_poweroff()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
|
||||
u32 *hp_values = (u32 *)malloc(sizeof(u32) * 3);
|
||||
|
||||
for (u32 j = 0; j < 3; j++)
|
||||
{
|
||||
hp_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &hp_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
if (h_cfg.autohosoff == 1)
|
||||
{
|
||||
ments[2].caption = " Disable";
|
||||
ments[3].caption = "*Enable";
|
||||
ments[4].caption = " Enable (No logo)";
|
||||
}
|
||||
else if (h_cfg.autohosoff >= 2)
|
||||
{
|
||||
ments[2].caption = " Disable";
|
||||
ments[3].caption = " Enable";
|
||||
ments[4].caption = "*Enable (No logo)";
|
||||
}
|
||||
else
|
||||
{
|
||||
ments[2].caption = "*Disable";
|
||||
ments[3].caption = " Enable";
|
||||
ments[4].caption = " Enable (No logo)";
|
||||
}
|
||||
|
||||
memset(&ments[5], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "Power off if woke up from HOS", 0, 0};
|
||||
|
||||
u32 *temp_autohosoff = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_autohosoff != NULL)
|
||||
{
|
||||
h_cfg.autohosoff = *(u32 *)temp_autohosoff;
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(hp_values);
|
||||
|
||||
if (temp_autohosoff == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
void config_nogc()
|
||||
{
|
||||
gfx_clear_grey(0x1B);
|
||||
gfx_con_setpos(0, 0);
|
||||
|
||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 5);
|
||||
u32 *cb_values = (u32 *)malloc(sizeof(u32) * 2);
|
||||
|
||||
for (u32 j = 0; j < 2; j++)
|
||||
{
|
||||
cb_values[j] = j;
|
||||
ments[j + 2].type = MENT_DATA;
|
||||
ments[j + 2].data = &cb_values[j];
|
||||
}
|
||||
|
||||
ments[0].type = MENT_BACK;
|
||||
ments[0].caption = "Back";
|
||||
|
||||
ments[1].type = MENT_CHGLINE;
|
||||
|
||||
if (h_cfg.autonogc)
|
||||
{
|
||||
ments[2].caption = " Disable";
|
||||
ments[3].caption = "*Auto";
|
||||
}
|
||||
else
|
||||
{
|
||||
ments[2].caption = "*Disable";
|
||||
ments[3].caption = " Auto";
|
||||
}
|
||||
|
||||
memset(&ments[4], 0, sizeof(ment_t));
|
||||
menu_t menu = {ments, "No Gamecard", 0, 0};
|
||||
|
||||
u32 *temp_nogc = (u32 *)tui_do_menu(&menu);
|
||||
if (temp_nogc != NULL)
|
||||
{
|
||||
h_cfg.autonogc = *(u32 *)temp_nogc;
|
||||
_save_config();
|
||||
}
|
||||
|
||||
free(ments);
|
||||
free(cb_values);
|
||||
|
||||
if (temp_nogc == NULL)
|
||||
return;
|
||||
btn_wait();
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
|
|
@ -46,5 +46,12 @@ typedef enum
|
|||
} hsysmodule_t;
|
||||
|
||||
void set_default_configuration();
|
||||
int create_config_entry();
|
||||
void config_autoboot();
|
||||
void config_bootdelay();
|
||||
void config_verification();
|
||||
void config_backlight();
|
||||
void config_auto_hos_poweroff();
|
||||
void config_nogc();
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -78,7 +78,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
|
||||
char *filename = (char *)malloc(256);
|
||||
|
||||
memcpy(filename, ini_path, pathlen + 1);
|
||||
strcpy(filename, ini_path);
|
||||
|
||||
// Get all ini filenames.
|
||||
if (is_dir)
|
||||
|
@ -89,7 +89,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
free(filename);
|
||||
return 0;
|
||||
}
|
||||
memcpy(filename + pathlen, "/", 2);
|
||||
strcpy(filename + pathlen, "/");
|
||||
pathlen++;
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
|||
{
|
||||
if (filelist[k * 256])
|
||||
{
|
||||
memcpy(filename + pathlen, &filelist[k * 256], strlen(&filelist[k * 256]) + 1);
|
||||
strcpy(filename + pathlen, &filelist[k * 256]);
|
||||
k++;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
|
|
@ -262,11 +262,12 @@ void display_color_screen(u32 color)
|
|||
u32 *display_init_framebuffer()
|
||||
{
|
||||
// Sanitize framebuffer area.
|
||||
memset((u32 *)FB_ADDRESS, 0, 0x3C0000);
|
||||
memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
|
||||
|
||||
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer, 32);
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)FB_ADDRESS;
|
||||
return (u32 *)IPL_FB_ADDRESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -18,10 +18,9 @@
|
|||
#ifndef _DI_H_
|
||||
#define _DI_H_
|
||||
|
||||
#include "../../common/memory_map.h"
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define FB_ADDRESS 0xC0000000
|
||||
|
||||
/*! Display registers. */
|
||||
#define _DIREG(reg) ((reg) * 4)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -128,7 +128,7 @@ static const cfg_op_t _display_config_2[94] = {
|
|||
};
|
||||
|
||||
//DSI Init config.
|
||||
static const cfg_op_t _display_config_3[61] = {
|
||||
static const cfg_op_t _display_config_3[61] = {
|
||||
{DSI_WR_DATA, 0},
|
||||
{DSI_INT_ENABLE, 0},
|
||||
{DSI_INT_STATUS, 0},
|
||||
|
@ -415,7 +415,7 @@ static const cfg_op_t _display_config_11[113] = {
|
|||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{DC_DISP_BACK_PORCH, 0x90048},
|
||||
{DC_DISP_ACTIVE, 0x50002D0},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||
/* End of Display timings */
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
|
@ -548,7 +548,7 @@ static const cfg_op_t cfg_display_framebuffer[32] = {
|
|||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, 0},
|
||||
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
||||
{DC_WINBUF_START_ADDR, FB_ADDRESS}, //Framebuffer address.
|
||||
{DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
|
|
|
@ -139,6 +139,7 @@ int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)
|
|||
memcpy(newKip, &hdr, sizeof(hdr));
|
||||
newKipSize = dstDataPtr-(unsigned char*)(newKip);
|
||||
|
||||
free(ki->kip1);
|
||||
ki->kip1 = newKip;
|
||||
ki->size = newKipSize;
|
||||
|
||||
|
|
|
@ -484,7 +484,6 @@ get_tsec: ;
|
|||
}
|
||||
pkg2_done:
|
||||
if (ki) {
|
||||
free(ki->kip1);
|
||||
free(ki);
|
||||
}
|
||||
free(pkg2);
|
||||
|
|
|
@ -24,15 +24,15 @@
|
|||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../../../common/memory_map.h"
|
||||
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "../../mem/heap.h"
|
||||
#include "../../sec/se.h"
|
||||
#include "../../storage/nx_emmc.h"
|
||||
#include "../../storage/sdmmc.h"
|
||||
|
||||
#define SDMMC_UPPER_BUFFER 0xB8000000
|
||||
#define DRAM_START 0x80000000
|
||||
|
||||
extern sdmmc_storage_t sd_storage;
|
||||
extern sdmmc_storage_t storage;
|
||||
extern emmc_part_t *system_part;
|
||||
|
|
|
@ -49,6 +49,8 @@ static bool sd_mounted;
|
|||
hekate_config h_cfg;
|
||||
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;
|
||||
|
||||
volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
|
||||
|
||||
bool sd_mount()
|
||||
{
|
||||
if (sd_mounted)
|
||||
|
@ -420,7 +422,7 @@ void ipl_main()
|
|||
gfx_con_init();
|
||||
display_backlight_pwm_init();
|
||||
|
||||
bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST);
|
||||
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
||||
|
||||
h_cfg.emummc_force_disable = emummc_load_cfg();
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "../soc/fuse.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
volatile nyx_storage_t *nyx_str = (nyx_storage_t *)0xED000000;
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
void minerva_init()
|
||||
{
|
||||
|
@ -34,8 +34,10 @@ void minerva_init()
|
|||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
|
||||
// Set table to ram.
|
||||
mtc_cfg->mtc_table = NULL;
|
||||
// Set table to nyx storage.
|
||||
mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table;
|
||||
|
||||
mtc_cfg->init_done = MTC_NEW_MAGIC;
|
||||
mtc_cfg->sdram_id = (fuse_read_odm(4) >> 3) & 0x1F;
|
||||
u32 ep_addr = ianos_loader(false, "bootloader/sys/libsys_minerva.bso", DRAM_LIB, (void *)mtc_cfg);
|
||||
minerva_cfg = (void *)ep_addr;
|
||||
|
@ -58,6 +60,15 @@ void minerva_init()
|
|||
minerva_cfg(mtc_cfg, NULL);
|
||||
mtc_cfg->rate_to = 1600000;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
||||
// FSP WAR.
|
||||
mtc_cfg->train_mode = OP_SWITCH;
|
||||
mtc_cfg->rate_to = 800000;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
||||
// Switch to max.
|
||||
mtc_cfg->rate_to = 1600000;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
}
|
||||
|
||||
void minerva_change_freq(minerva_freq_t freq)
|
||||
|
@ -66,7 +77,7 @@ void minerva_change_freq(minerva_freq_t freq)
|
|||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
if (minerva_cfg && (mtc_cfg->rate_from != freq))
|
||||
if (mtc_cfg->rate_from != freq)
|
||||
{
|
||||
mtc_cfg->rate_to = freq;
|
||||
mtc_cfg->train_mode = OP_SWITCH;
|
||||
|
@ -80,7 +91,7 @@ void minerva_periodic_training()
|
|||
return;
|
||||
|
||||
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
|
||||
if (minerva_cfg && mtc_cfg->rate_from == FREQ_1600)
|
||||
if (mtc_cfg->rate_from == FREQ_1600)
|
||||
{
|
||||
mtc_cfg->train_mode = OP_PERIODIC_TRAIN;
|
||||
minerva_cfg(mtc_cfg, NULL);
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
#include "mtc_table.h"
|
||||
#include "../utils/types.h"
|
||||
|
||||
#define EMC_PERIODIC_TRAIN_MS 100
|
||||
#define MTC_INIT_MAGIC 0x3043544D
|
||||
#define MTC_NEW_MAGIC 0x5243544D
|
||||
|
||||
#define EMC_PERIODIC_TRAIN_MS 250
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -35,6 +38,7 @@ typedef struct
|
|||
bool emc_2X_clk_src_is_pllmb;
|
||||
bool fsp_for_src_freq;
|
||||
bool train_ram_patterns;
|
||||
bool init_done;
|
||||
} mtc_config_t;
|
||||
|
||||
enum train_mode_t
|
||||
|
|
|
@ -16,17 +16,18 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "mc.h"
|
||||
#include "emc.h"
|
||||
#include "sdram_param_t210.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../soc/fuse.h"
|
||||
#include "../../common/memory_map.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../power/max7762x.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/fuse.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/pmc.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
#define CONFIG_SDRAM_COMPRESS_CFG
|
||||
|
||||
|
@ -50,19 +51,31 @@ static u32 _get_sdram_id()
|
|||
|
||||
static void _sdram_config(const sdram_params_t *params)
|
||||
{
|
||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = (((4 * params->emc_pmc_scratch1 >> 2) + 0x80000000) ^ 0xFFFF) & 0xC000FFFF;
|
||||
// Program DPD3/DPD4 regs (coldboot path).
|
||||
// Enable sel_dpd on unused pins.
|
||||
u32 dpd_req = (params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x80000000;
|
||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
|
||||
usleep(params->pmc_io_dpd3_req_wait);
|
||||
|
||||
u32 req = (4 * params->emc_pmc_scratch2 >> 2) + 0x80000000;
|
||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req >> 16 << 16) ^ 0x3FFF0000;
|
||||
// Disable e_dpd_vttgen.
|
||||
dpd_req = (params->emc_pmc_scratch2 & 0x3FFFFFFF) | 0x80000000;
|
||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req & 0xFFFF0000) ^ 0x3FFF0000;
|
||||
usleep(params->pmc_io_dpd4_req_wait);
|
||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (req ^ 0xFFFF) & 0xC000FFFF;
|
||||
|
||||
// Disable e_dpd_bg.
|
||||
PMC(APBDEV_PMC_IO_DPD4_REQ) = (dpd_req ^ 0xFFFF) & 0xC000FFFF;
|
||||
usleep(params->pmc_io_dpd4_req_wait);
|
||||
|
||||
PMC(APBDEV_PMC_WEAK_BIAS) = 0;
|
||||
usleep(1);
|
||||
|
||||
// Start clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC1) = params->pllm_setup_control;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) = 0;
|
||||
|
||||
// u32 tmp = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | ((params->pllm_post_divider & 0xFFFF) << 20);
|
||||
// CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = tmp;
|
||||
// CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = tmp | 0x40000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = (params->pllm_feedback_divider << 8) | params->pllm_input_divider | 0x40000000 | ((params->pllm_post_divider & 0xFFFF) << 20);
|
||||
|
||||
u32 wait_end = get_tmr_us() + 300;
|
||||
|
@ -72,24 +85,35 @@ static void _sdram_config(const sdram_params_t *params)
|
|||
goto break_nosleep;
|
||||
}
|
||||
usleep(10);
|
||||
break_nosleep:
|
||||
|
||||
break_nosleep:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = ((params->mc_emem_arb_misc0 >> 11) & 0x10000) | (params->emc_clock_source & 0xFFFEFFFF);
|
||||
if (params->emc_clock_source_dll)
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = params->emc_clock_source_dll;
|
||||
if (params->clear_clock2_mc1)
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_CLR) = 0x40000000;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000;
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001;
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = 0x2000001; // Enable EMC and MEM clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = 0x4000; // Enable EMC_DLL clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = 0x2000001; // Clear EMC and MEM resets.
|
||||
|
||||
// Set pad macros.
|
||||
EMC(EMC_PMACRO_VTTGEN_CTRL_0) = params->emc_pmacro_vttgen_ctrl0;
|
||||
EMC(EMC_PMACRO_VTTGEN_CTRL_1) = params->emc_pmacro_vttgen_ctrl1;
|
||||
EMC(EMC_PMACRO_VTTGEN_CTRL_2) = params->emc_pmacro_vttgen_ctrl2;
|
||||
EMC(EMC_TIMING_CONTROL) = 1;
|
||||
usleep(1);
|
||||
|
||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||
usleep(10); // Ensure the regulators settle.
|
||||
|
||||
// Select EMC write mux.
|
||||
EMC(EMC_DBG) = (params->emc_dbg_write_mux << 1) | params->emc_dbg;
|
||||
|
||||
// Patch 2 using BCT spare variables.
|
||||
if (params->emc_bct_spare2)
|
||||
*(vu32 *)params->emc_bct_spare2 = params->emc_bct_spare3;
|
||||
|
||||
// Program CMD mapping. Required before brick mapping, else
|
||||
// we can't guarantee CK will be differential at all times.
|
||||
EMC(EMC_FBIO_CFG7) = params->emc_fbio_cfg7;
|
||||
EMC(EMC_CMD_MAPPING_CMD0_0) = params->emc_cmd_mapping_cmd0_0;
|
||||
EMC(EMC_CMD_MAPPING_CMD0_1) = params->emc_cmd_mapping_cmd0_1;
|
||||
|
@ -104,25 +128,40 @@ break_nosleep:
|
|||
EMC(EMC_CMD_MAPPING_CMD3_1) = params->emc_cmd_mapping_cmd3_1;
|
||||
EMC(EMC_CMD_MAPPING_CMD3_2) = params->emc_cmd_mapping_cmd3_2;
|
||||
EMC(EMC_CMD_MAPPING_BYTE) = params->emc_cmd_mapping_byte;
|
||||
|
||||
// Program brick mapping.
|
||||
EMC(EMC_PMACRO_BRICK_MAPPING_0) = params->emc_pmacro_brick_mapping0;
|
||||
EMC(EMC_PMACRO_BRICK_MAPPING_1) = params->emc_pmacro_brick_mapping1;
|
||||
EMC(EMC_PMACRO_BRICK_MAPPING_2) = params->emc_pmacro_brick_mapping2;
|
||||
|
||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1120112) | 0x1EED1EED;
|
||||
|
||||
// This is required to do any reads from the pad macros.
|
||||
EMC(EMC_CONFIG_SAMPLE_DELAY) = params->emc_config_sample_delay;
|
||||
|
||||
EMC(EMC_FBIO_CFG8) = params->emc_fbio_cfg8;
|
||||
|
||||
// Set swizzle for Rank 0.
|
||||
EMC(EMC_SWIZZLE_RANK0_BYTE0) = params->emc_swizzle_rank0_byte0;
|
||||
EMC(EMC_SWIZZLE_RANK0_BYTE1) = params->emc_swizzle_rank0_byte1;
|
||||
EMC(EMC_SWIZZLE_RANK0_BYTE2) = params->emc_swizzle_rank0_byte2;
|
||||
EMC(EMC_SWIZZLE_RANK0_BYTE3) = params->emc_swizzle_rank0_byte3;
|
||||
// Set swizzle for Rank 1.
|
||||
EMC(EMC_SWIZZLE_RANK1_BYTE0) = params->emc_swizzle_rank1_byte0;
|
||||
EMC(EMC_SWIZZLE_RANK1_BYTE1) = params->emc_swizzle_rank1_byte1;
|
||||
EMC(EMC_SWIZZLE_RANK1_BYTE2) = params->emc_swizzle_rank1_byte2;
|
||||
EMC(EMC_SWIZZLE_RANK1_BYTE3) = params->emc_swizzle_rank1_byte3;
|
||||
|
||||
// Patch 4 using BCT spare variables.
|
||||
if (params->emc_bct_spare6)
|
||||
*(vu32 *)params->emc_bct_spare6 = params->emc_bct_spare7;
|
||||
|
||||
// Set pad controls.
|
||||
EMC(EMC_XM2COMPPADCTRL) = params->emc_xm2_comp_pad_ctrl;
|
||||
EMC(EMC_XM2COMPPADCTRL2) = params->emc_xm2_comp_pad_ctrl2;
|
||||
EMC(EMC_XM2COMPPADCTRL3) = params->emc_xm2_comp_pad_ctrl3;
|
||||
|
||||
// Program Autocal controls with shadowed register fields.
|
||||
EMC(EMC_AUTO_CAL_CONFIG2) = params->emc_auto_cal_config2;
|
||||
EMC(EMC_AUTO_CAL_CONFIG3) = params->emc_auto_cal_config3;
|
||||
EMC(EMC_AUTO_CAL_CONFIG4) = params->emc_auto_cal_config4;
|
||||
|
@ -130,6 +169,7 @@ break_nosleep:
|
|||
EMC(EMC_AUTO_CAL_CONFIG6) = params->emc_auto_cal_config6;
|
||||
EMC(EMC_AUTO_CAL_CONFIG7) = params->emc_auto_cal_config7;
|
||||
EMC(EMC_AUTO_CAL_CONFIG8) = params->emc_auto_cal_config8;
|
||||
|
||||
EMC(EMC_PMACRO_RX_TERM) = params->emc_pmacro_rx_term;
|
||||
EMC(EMC_PMACRO_DQ_TX_DRV) = params->emc_pmacro_dq_tx_drive;
|
||||
EMC(EMC_PMACRO_CA_TX_DRV) = params->emc_pmacro_ca_tx_drive;
|
||||
|
@ -137,9 +177,11 @@ break_nosleep:
|
|||
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = params->emc_pmacro_auto_cal_common;
|
||||
EMC(EMC_AUTO_CAL_CHANNEL) = params->emc_auto_cal_channel;
|
||||
EMC(EMC_PMACRO_ZCTRL) = params->emc_pmacro_zcrtl;
|
||||
|
||||
EMC(EMC_DLL_CFG_0) = params->emc_dll_cfg0;
|
||||
EMC(EMC_DLL_CFG_1) = params->emc_dll_cfg1;
|
||||
EMC(EMC_CFG_DIG_DLL_1) = params->emc_cfg_dig_dll_1;
|
||||
|
||||
EMC(EMC_DATA_BRLSHFT_0) = params->emc_data_brlshft0;
|
||||
EMC(EMC_DATA_BRLSHFT_1) = params->emc_data_brlshft1;
|
||||
EMC(EMC_DQS_BRLSHFT_0) = params->emc_dqs_brlshft0;
|
||||
|
@ -152,8 +194,10 @@ break_nosleep:
|
|||
EMC(EMC_QUSE_BRLSHFT_1) = params->emc_quse_brlshft1;
|
||||
EMC(EMC_QUSE_BRLSHFT_2) = params->emc_quse_brlshft2;
|
||||
EMC(EMC_QUSE_BRLSHFT_3) = params->emc_quse_brlshft3;
|
||||
|
||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = (params->emc_pmacro_brick_ctrl_rfu1 & 0x1BF01BF) | 0x1E401E40;
|
||||
EMC(EMC_PMACRO_PAD_CFG_CTRL) = params->emc_pmacro_pad_cfg_ctrl;
|
||||
|
||||
EMC(EMC_PMACRO_CMD_BRICK_CTRL_FDPD) = params->emc_pmacro_cmd_brick_ctrl_fdpd;
|
||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2 & 0xFF7FFF7F;
|
||||
EMC(EMC_PMACRO_DATA_BRICK_CTRL_FDPD) = params->emc_pmacro_data_brick_ctrl_fdpd;
|
||||
|
@ -164,6 +208,7 @@ break_nosleep:
|
|||
EMC(EMC_PMACRO_DATA_RX_TERM_MODE) = params->emc_pmacro_data_rx_term_mode;
|
||||
EMC(EMC_PMACRO_CMD_RX_TERM_MODE) = params->emc_pmacro_cmd_rx_term_mode;
|
||||
EMC(EMC_PMACRO_CMD_PAD_TX_CTRL) = params->emc_pmacro_cmd_pad_tx_ctrl;
|
||||
|
||||
EMC(EMC_CFG_3) = params->emc_cfg3;
|
||||
EMC(EMC_PMACRO_TX_PWRD_0) = params->emc_pmacro_tx_pwrd0;
|
||||
EMC(EMC_PMACRO_TX_PWRD_1) = params->emc_pmacro_tx_pwrd1;
|
||||
|
@ -189,6 +234,7 @@ break_nosleep:
|
|||
EMC(EMC_PMACRO_IB_VREF_DQS_0) = params->emc_pmacro_ib_vref_dqs_0;
|
||||
EMC(EMC_PMACRO_IB_VREF_DQS_1) = params->emc_pmacro_ib_vref_dqs_1;
|
||||
EMC(EMC_PMACRO_IB_RXRT) = params->emc_pmacro_ib_rxrt;
|
||||
|
||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_0) = params->emc_pmacro_quse_ddll_rank0_0;
|
||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_1) = params->emc_pmacro_quse_ddll_rank0_1;
|
||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK0_2) = params->emc_pmacro_quse_ddll_rank0_2;
|
||||
|
@ -202,6 +248,7 @@ break_nosleep:
|
|||
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_4) = params->emc_pmacro_quse_ddll_rank1_4;
|
||||
EMC(EMC_PMACRO_QUSE_DDLL_RANK1_5) = params->emc_pmacro_quse_ddll_rank1_5;
|
||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU1) = params->emc_pmacro_brick_ctrl_rfu1;
|
||||
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0) = params->emc_pmacro_ob_ddll_long_dq_rank0_0;
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1) = params->emc_pmacro_ob_ddll_long_dq_rank0_1;
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) = params->emc_pmacro_ob_ddll_long_dq_rank0_2;
|
||||
|
@ -214,6 +261,7 @@ break_nosleep:
|
|||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) = params->emc_pmacro_ob_ddll_long_dq_rank1_3;
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4) = params->emc_pmacro_ob_ddll_long_dq_rank1_4;
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5) = params->emc_pmacro_ob_ddll_long_dq_rank1_5;
|
||||
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0) = params->emc_pmacro_ob_ddll_long_dqs_rank0_0;
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1) = params->emc_pmacro_ob_ddll_long_dqs_rank0_1;
|
||||
EMC(EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2) = params->emc_pmacro_ob_ddll_long_dqs_rank0_2;
|
||||
|
@ -234,6 +282,7 @@ break_nosleep:
|
|||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1) = params->emc_pmacro_ib_ddll_long_dqs_rank1_1;
|
||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) = params->emc_pmacro_ib_ddll_long_dqs_rank1_2;
|
||||
EMC(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) = params->emc_pmacro_ib_ddll_long_dqs_rank1_3;
|
||||
|
||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_0) = params->emc_pmacro_ddll_long_cmd_0;
|
||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_1) = params->emc_pmacro_ddll_long_cmd_1;
|
||||
EMC(EMC_PMACRO_DDLL_LONG_CMD_2) = params->emc_pmacro_ddll_long_cmd_2;
|
||||
|
@ -242,10 +291,17 @@ break_nosleep:
|
|||
EMC(EMC_PMACRO_DDLL_SHORT_CMD_0) = params->emc_pmacro_ddll_short_cmd_0;
|
||||
EMC(EMC_PMACRO_DDLL_SHORT_CMD_1) = params->emc_pmacro_ddll_short_cmd_1;
|
||||
EMC(EMC_PMACRO_DDLL_SHORT_CMD_2) = params->emc_pmacro_ddll_short_cmd_2;
|
||||
|
||||
// Common pad macro (cpm).
|
||||
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = (params->emc_pmacro_common_pad_tx_ctrl & 1) | 0xE;
|
||||
|
||||
// Patch 3 using BCT spare variables.
|
||||
if (params->emc_bct_spare4)
|
||||
*(vu32 *)params->emc_bct_spare4 = params->emc_bct_spare5;
|
||||
EMC(EMC_TIMING_CONTROL) = 1;
|
||||
|
||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||
|
||||
// Initialize MC VPR settings.
|
||||
MC(MC_VIDEO_PROTECT_BOM) = params->mc_video_protect_bom;
|
||||
MC(MC_VIDEO_PROTECT_BOM_ADR_HI) = params->mc_video_protect_bom_adr_hi;
|
||||
MC(MC_VIDEO_PROTECT_SIZE_MB) = params->mc_video_protect_size_mb;
|
||||
|
@ -253,20 +309,32 @@ break_nosleep:
|
|||
MC(MC_VIDEO_PROTECT_VPR_OVERRIDE1) = params->mc_video_protect_vpr_override1;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_0) = params->mc_video_protect_gpu_override0;
|
||||
MC(MC_VIDEO_PROTECT_GPU_OVERRIDE_1) = params->mc_video_protect_gpu_override1;
|
||||
|
||||
// Program SDRAM geometry parameters.
|
||||
MC(MC_EMEM_ADR_CFG) = params->mc_emem_adr_cfg;
|
||||
MC(MC_EMEM_ADR_CFG_DEV0) = params->mc_emem_adr_cfg_dev0;
|
||||
MC(MC_EMEM_ADR_CFG_DEV1) = params->mc_emem_adr_cfg_dev1;
|
||||
MC(MC_EMEM_ADR_CFG_CHANNEL_MASK) = params->mc_emem_adr_cfg_channel_mask;
|
||||
|
||||
// Program bank swizzling.
|
||||
MC(MC_EMEM_ADR_CFG_BANK_MASK_0) = params->mc_emem_adr_cfg_bank_mask0;
|
||||
MC(MC_EMEM_ADR_CFG_BANK_MASK_1) = params->mc_emem_adr_cfg_bank_mask1;
|
||||
MC(MC_EMEM_ADR_CFG_BANK_MASK_2) = params->mc_emem_adr_cfg_bank_mask2;
|
||||
|
||||
// Program external memory aperture (base and size).
|
||||
MC(MC_EMEM_CFG) = params->mc_emem_cfg;
|
||||
|
||||
// Program SEC carveout (base and size).
|
||||
MC(MC_SEC_CARVEOUT_BOM) = params->mc_sec_carveout_bom;
|
||||
MC(MC_SEC_CARVEOUT_ADR_HI) = params->mc_sec_carveout_adr_hi;
|
||||
MC(MC_SEC_CARVEOUT_SIZE_MB) = params->mc_sec_carveout_size_mb;
|
||||
|
||||
// Program MTS carveout (base and size).
|
||||
MC(MC_MTS_CARVEOUT_BOM) = params->mc_mts_carveout_bom;
|
||||
MC(MC_MTS_CARVEOUT_ADR_HI) = params->mc_mts_carveout_adr_hi;
|
||||
MC(MC_MTS_CARVEOUT_SIZE_MB) = params->mc_mts_carveout_size_mb;
|
||||
|
||||
// Program the memory arbiter.
|
||||
MC(MC_EMEM_ARB_CFG) = params->mc_emem_arb_cfg;
|
||||
MC(MC_EMEM_ARB_OUTSTANDING_REQ) = params->mc_emem_arb_outstanding_req;
|
||||
MC(MC_EMEM_ARB_REFPB_HP_CTRL) = params->emc_emem_arb_refpb_hp_ctrl;
|
||||
|
@ -295,21 +363,38 @@ break_nosleep:
|
|||
MC(MC_EMEM_ARB_OVERRIDE_1) = params->mc_emem_arb_override1;
|
||||
MC(MC_EMEM_ARB_RSV) = params->mc_emem_arb_rsv;
|
||||
MC(MC_DA_CONFIG0) = params->mc_da_cfg0;
|
||||
MC(MC_TIMING_CONTROL) = 1;
|
||||
|
||||
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
||||
|
||||
// Program second-level clock enable overrides.
|
||||
MC(MC_CLKEN_OVERRIDE) = params->mc_clken_override;
|
||||
|
||||
// Program statistics gathering.
|
||||
MC(MC_STAT_CONTROL) = params->mc_stat_control;
|
||||
|
||||
// Program SDRAM geometry parameters.
|
||||
EMC(EMC_ADR_CFG) = params->emc_adr_cfg;
|
||||
|
||||
// Program second-level clock enable overrides.
|
||||
EMC(EMC_CLKEN_OVERRIDE) = params->emc_clken_override;
|
||||
|
||||
// Program EMC pad auto calibration.
|
||||
EMC(EMC_PMACRO_AUTOCAL_CFG_0) = params->emc_pmacro_auto_cal_cfg0;
|
||||
EMC(EMC_PMACRO_AUTOCAL_CFG_1) = params->emc_pmacro_auto_cal_cfg1;
|
||||
EMC(EMC_PMACRO_AUTOCAL_CFG_2) = params->emc_pmacro_auto_cal_cfg2;
|
||||
|
||||
EMC(EMC_AUTO_CAL_VREF_SEL_0) = params->emc_auto_cal_vref_sel0;
|
||||
EMC(EMC_AUTO_CAL_VREF_SEL_1) = params->emc_auto_cal_vref_sel1;
|
||||
|
||||
EMC(EMC_AUTO_CAL_INTERVAL) = params->emc_auto_cal_interval;
|
||||
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config;
|
||||
usleep(params->emc_auto_cal_wait);
|
||||
|
||||
// Patch 5 using BCT spare variables.
|
||||
if (params->emc_bct_spare8)
|
||||
*(vu32 *)params->emc_bct_spare8 = params->emc_bct_spare9;
|
||||
|
||||
// Program EMC timing configuration.
|
||||
EMC(EMC_CFG_2) = params->emc_cfg2;
|
||||
EMC(EMC_CFG_PIPE) = params->emc_cfg_pipe;
|
||||
EMC(EMC_CFG_PIPE_1) = params->emc_cfg_pipe1;
|
||||
|
@ -354,9 +439,11 @@ break_nosleep:
|
|||
EMC(EMC_EINPUT_DURATION) = params->emc_einput_duration;
|
||||
EMC(EMC_PUTERM_EXTRA) = params->emc_puterm_extra;
|
||||
EMC(EMC_PUTERM_WIDTH) = params->emc_puterm_width;
|
||||
|
||||
EMC(EMC_PMACRO_COMMON_PAD_TX_CTRL) = params->emc_pmacro_common_pad_tx_ctrl;
|
||||
EMC(EMC_DBG) = params->emc_dbg;
|
||||
EMC(EMC_QRST) = params->emc_qrst;
|
||||
EMC(EMC_ISSUE_QRST) = 1;
|
||||
EMC(EMC_ISSUE_QRST) = 0;
|
||||
EMC(EMC_QSAFE) = params->emc_qsafe;
|
||||
EMC(EMC_RDV) = params->emc_rdv;
|
||||
|
@ -389,6 +476,8 @@ break_nosleep:
|
|||
EMC(EMC_ODT_WRITE) = params->emc_odt_write;
|
||||
EMC(EMC_CFG_DIG_DLL) = params->emc_cfg_dig_dll;
|
||||
EMC(EMC_CFG_DIG_DLL_PERIOD) = params->emc_cfg_dig_dll_period;
|
||||
|
||||
// Don't write CFG_ADR_EN (bit 1) here - lock bit written later.
|
||||
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare & 0xFFFFFFFD;
|
||||
EMC(EMC_CFG_RSV) = params->emc_cfg_rsv;
|
||||
EMC(EMC_PMC_SCRATCH1) = params->emc_pmc_scratch1;
|
||||
|
@ -396,70 +485,104 @@ break_nosleep:
|
|||
EMC(EMC_PMC_SCRATCH3) = params->emc_pmc_scratch3;
|
||||
EMC(EMC_ACPD_CONTROL) = params->emc_acpd_control;
|
||||
EMC(EMC_TXDSRVTTGEN) = params->emc_txdsrvttgen;
|
||||
|
||||
// Set pipe bypass enable bits before sending any DRAM commands.
|
||||
EMC(EMC_CFG) = (params->emc_cfg & 0xE) | 0x3C00000;
|
||||
|
||||
// Patch BootROM.
|
||||
if (params->boot_rom_patch_control & (1 << 31))
|
||||
{
|
||||
*(vu32 *)(APB_MISC_BASE + params->boot_rom_patch_control * 4) = params->boot_rom_patch_data;
|
||||
MC(MC_TIMING_CONTROL) = 1;
|
||||
MC(MC_TIMING_CONTROL) = 1; // Trigger MC timing update.
|
||||
}
|
||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((4 * params->emc_pmc_scratch1 >> 2) + 0x40000000) & 0xCFFF0000;
|
||||
|
||||
// Release SEL_DPD_CMD.
|
||||
PMC(APBDEV_PMC_IO_DPD3_REQ) = ((params->emc_pmc_scratch1 & 0x3FFFFFFF) | 0x40000000) & 0xCFFF0000;
|
||||
usleep(params->pmc_io_dpd3_req_wait);
|
||||
|
||||
// Set autocal interval if not configured.
|
||||
if (!params->emc_auto_cal_interval)
|
||||
EMC(EMC_AUTO_CAL_CONFIG) = params->emc_auto_cal_config | 0x200;
|
||||
|
||||
EMC(EMC_PMACRO_BRICK_CTRL_RFU2) = params->emc_pmacro_brick_ctrl_rfu2;
|
||||
|
||||
// ZQ CAL setup (not actually issuing ZQ CAL now).
|
||||
if (params->emc_zcal_warm_cold_boot_enables & 1)
|
||||
{
|
||||
if (params->memory_type == 2)
|
||||
EMC(EMC_ZCAL_WAIT_CNT) = 8 * params->emc_zcal_wait_cnt;
|
||||
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt << 3;
|
||||
if (params->memory_type == 3)
|
||||
{
|
||||
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
|
||||
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
||||
}
|
||||
}
|
||||
EMC(EMC_TIMING_CONTROL) = 1;
|
||||
|
||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||
usleep(params->emc_timing_control_wait);
|
||||
|
||||
// Deassert HOLD_CKE_LOW.
|
||||
PMC(APBDEV_PMC_DDR_CNTRL) &= 0xFFF8007F;
|
||||
usleep(params->pmc_ddr_ctrl_wait);
|
||||
if (params->memory_type == 2)
|
||||
|
||||
// Set clock enable signal.
|
||||
u32 pin_gpio_cfg = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
|
||||
if (params->memory_type == 2 || params->memory_type == 3)
|
||||
{
|
||||
EMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
|
||||
EMC(EMC_PIN) = pin_gpio_cfg;
|
||||
(void)EMC(EMC_PIN);
|
||||
usleep(params->emc_pin_extra_wait + 200);
|
||||
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;
|
||||
usleep(params->emc_pin_extra_wait + 500);
|
||||
EMC(EMC_PIN) = pin_gpio_cfg | 0x100;
|
||||
(void)EMC(EMC_PIN);
|
||||
}
|
||||
|
||||
if (params->memory_type == 3)
|
||||
{
|
||||
EMC(EMC_PIN) = (params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12);
|
||||
usleep(params->emc_pin_extra_wait + 200);
|
||||
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 256;
|
||||
usleep(params->emc_pin_extra_wait + 2000);
|
||||
}
|
||||
EMC(EMC_PIN) = ((params->emc_pin_gpio_enable << 16) | (params->emc_pin_gpio << 12)) + 0x101;
|
||||
else if (params->memory_type == 2)
|
||||
usleep(params->emc_pin_extra_wait + 500);
|
||||
|
||||
// Enable clock enable signal.
|
||||
EMC(EMC_PIN) = pin_gpio_cfg | 0x101;
|
||||
(void)EMC(EMC_PIN);
|
||||
usleep(params->emc_pin_program_wait);
|
||||
|
||||
// Send NOP (trigger just needs to be non-zero).
|
||||
if (params->memory_type != 3)
|
||||
EMC(EMC_NOP) = (params->emc_dev_select << 30) + 1;
|
||||
|
||||
// On coldboot w/LPDDR2/3, wait 200 uSec after asserting CKE high.
|
||||
if (params->memory_type == 1)
|
||||
usleep(params->emc_pin_extra_wait + 200);
|
||||
|
||||
// Init zq calibration,
|
||||
if (params->memory_type == 3)
|
||||
{
|
||||
// Patch 6 using BCT spare variables.
|
||||
if (params->emc_bct_spare10)
|
||||
*(vu32 *)params->emc_bct_spare10 = params->emc_bct_spare11;
|
||||
|
||||
// Write mode registers.
|
||||
EMC(EMC_MRW2) = params->emc_mrw2;
|
||||
EMC(EMC_MRW) = params->emc_mrw1;
|
||||
EMC(EMC_MRW3) = params->emc_mrw3;
|
||||
EMC(EMC_MRW4) = params->emc_mrw4;
|
||||
EMC(EMC_MRW6) = params->emc_mrw6;
|
||||
EMC(EMC_MRW14) = params->emc_mrw14;
|
||||
|
||||
EMC(EMC_MRW8) = params->emc_mrw8;
|
||||
EMC(EMC_MRW12) = params->emc_mrw12;
|
||||
EMC(EMC_MRW9) = params->emc_mrw9;
|
||||
EMC(EMC_MRW13) = params->emc_mrw13;
|
||||
|
||||
if (params->emc_zcal_warm_cold_boot_enables & 1)
|
||||
{
|
||||
// Issue ZQCAL start, device 0.
|
||||
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0;
|
||||
usleep(params->emc_zcal_init_wait);
|
||||
|
||||
// Issue ZQCAL latch.
|
||||
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev0 ^ 3;
|
||||
// Same for device 1.
|
||||
if (!(params->emc_dev_select & 2))
|
||||
{
|
||||
EMC(EMC_ZQ_CAL) = params->emc_zcal_init_dev1;
|
||||
|
@ -468,42 +591,64 @@ break_nosleep:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set package and DPD pad control.
|
||||
PMC(APBDEV_PMC_DDR_CFG) = params->pmc_ddr_cfg;
|
||||
|
||||
// Start periodic ZQ calibration (LPDDRx only).
|
||||
if (params->memory_type - 1 <= 2)
|
||||
{
|
||||
EMC(EMC_ZCAL_INTERVAL) = params->emc_zcal_interval;
|
||||
EMC(EMC_ZCAL_WAIT_CNT) = params->emc_zcal_wait_cnt;
|
||||
EMC(EMC_ZCAL_MRW_CMD) = params->emc_zcal_mrw_cmd;
|
||||
}
|
||||
|
||||
// Patch 7 using BCT spare variables.
|
||||
if (params->emc_bct_spare12)
|
||||
*(vu32 *)params->emc_bct_spare12 = params->emc_bct_spare13;
|
||||
EMC(EMC_TIMING_CONTROL) = 1;
|
||||
|
||||
EMC(EMC_TIMING_CONTROL) = 1; // Trigger timing update so above writes take place.
|
||||
|
||||
if (params->emc_extra_refresh_num)
|
||||
EMC(EMC_REF) = ((1 << params->emc_extra_refresh_num << 8) - 0xFD) | (params->emc_pin_gpio << 30);
|
||||
EMC(EMC_REF) = (((1 << params->emc_extra_refresh_num) - 1) << 8) | (params->emc_dev_select << 30) | 3;
|
||||
|
||||
// Enable refresh.
|
||||
EMC(EMC_REFCTRL) = params->emc_dev_select | 0x80000000;
|
||||
|
||||
EMC(EMC_DYN_SELF_REF_CONTROL) = params->emc_dyn_self_ref_control;
|
||||
EMC(EMC_CFG_UPDATE) = params->emc_cfg_update;
|
||||
EMC(EMC_CFG) = params->emc_cfg;
|
||||
EMC(EMC_FDPD_CTRL_DQ) = params->emc_fdpd_ctrl_dq;
|
||||
EMC(EMC_FDPD_CTRL_CMD) = params->emc_fdpd_ctrl_cmd;
|
||||
EMC(EMC_SEL_DPD_CTRL) = params->emc_sel_dpd_ctrl;
|
||||
|
||||
// Write addr swizzle lock bit.
|
||||
EMC(EMC_FBIO_SPARE) = params->emc_fbio_spare | 2;
|
||||
EMC(EMC_TIMING_CONTROL) = 1;
|
||||
|
||||
EMC(EMC_TIMING_CONTROL) = 1; // Re-trigger timing to latch power saving functions.
|
||||
|
||||
// Enable EMC pipe clock gating.
|
||||
EMC(EMC_CFG_PIPE_CLK) = params->emc_cfg_pipe_clk;
|
||||
|
||||
// Depending on freqency, enable CMD/CLK fdpd.
|
||||
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = params->emc_fdpd_ctrl_cmd_no_ramp;
|
||||
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | ((params->ahb_arbitration_xbar_ctrl_meminit_done & 0xFFFF) << 16);
|
||||
|
||||
// Enable arbiter.
|
||||
SYSREG(AHB_ARBITRATION_XBAR_CTRL) = (SYSREG(AHB_ARBITRATION_XBAR_CTRL) & 0xFFFEFFFF) | (params->ahb_arbitration_xbar_ctrl_meminit_done << 16);
|
||||
|
||||
// Lock carveouts per BCT cfg.
|
||||
MC(MC_VIDEO_PROTECT_REG_CTRL) = params->mc_video_protect_write_access;
|
||||
MC(MC_SEC_CARVEOUT_REG_CTRL) = params->mc_sec_carveout_protect_write_access;
|
||||
MC(MC_MTS_CARVEOUT_REG_CTRL) = params->mc_mts_carveout_reg_ctrl;
|
||||
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1; //Disable write access to a bunch of EMC registers.
|
||||
|
||||
//Disable write access to a bunch of EMC registers.
|
||||
MC(MC_EMEM_CFG_ACCESS_CTRL) = 1;
|
||||
}
|
||||
|
||||
sdram_params_t *sdram_get_params()
|
||||
{
|
||||
//TODO: sdram_id should be in [0, 7].
|
||||
|
||||
#ifdef CONFIG_SDRAM_COMPRESS_CFG
|
||||
u8 *buf = (u8 *)0x40030000;
|
||||
u8 *buf = (u8 *)SDRAM_PARAMS_ADDR;
|
||||
LZ_Uncompress(_dram_cfg_lz, buf, sizeof(_dram_cfg_lz));
|
||||
return (sdram_params_t *)&buf[sizeof(sdram_params_t) * _get_sdram_id()];
|
||||
#else
|
||||
|
@ -535,7 +680,17 @@ sdram_params_t *sdram_get_params_patched()
|
|||
// Disable Warmboot signature check.
|
||||
sdram_params->boot_rom_patch_control = (1 << 31) | (((IPATCH_BASE + 4) - APB_MISC_BASE) / 4);
|
||||
sdram_params->boot_rom_patch_data = IPATCH_CONFIG(0x10459E, 0x2000);
|
||||
/*
|
||||
// Disable SBK lock.
|
||||
sdram_params->emc_bct_spare8 = (IPATCH_BASE + 7 * 4);
|
||||
sdram_params->emc_bct_spare9 = IPATCH_CONFIG(0x10210E, 0x2000);
|
||||
|
||||
// Disable bootrom read lock.
|
||||
sdram_params->emc_bct_spare10 = (IPATCH_BASE + 10 * 4);
|
||||
sdram_params->emc_bct_spare11 = IPATCH_CONFIG(0x100FDC, 0xF000);
|
||||
sdram_params->emc_bct_spare12 = (IPATCH_BASE + 11 * 4);
|
||||
sdram_params->emc_bct_spare13 = IPATCH_CONFIG(0x100FDE, 0xE320);
|
||||
*/
|
||||
return sdram_params;
|
||||
}
|
||||
|
||||
|
@ -544,16 +699,24 @@ void sdram_init()
|
|||
//TODO: sdram_id should be in [0,4].
|
||||
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
|
||||
|
||||
// Set DRAM voltage.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 0x05);
|
||||
max77620_regulator_set_voltage(REGULATOR_SD1, 1100000); // Set DRAM voltage.
|
||||
max77620_regulator_set_voltage(REGULATOR_SD1, 1100000);
|
||||
|
||||
// VDDP Select.
|
||||
PMC(APBDEV_PMC_VDDP_SEL) = params->pmc_vddp_sel;
|
||||
usleep(params->pmc_vddp_sel_wait);
|
||||
|
||||
// Set DDR pad voltage.
|
||||
PMC(APBDEV_PMC_DDR_PWR) = PMC(APBDEV_PMC_DDR_PWR);
|
||||
|
||||
// Turn on MEM IO Power.
|
||||
PMC(APBDEV_PMC_NO_IOPOWER) = params->pmc_no_io_power;
|
||||
PMC(APBDEV_PMC_REG_SHORT) = params->pmc_reg_short;
|
||||
|
||||
PMC(APBDEV_PMC_DDR_CNTRL) = params->pmc_ddr_ctrl;
|
||||
|
||||
// Patch 1 using BCT spare variables
|
||||
if (params->emc_bct_spare0)
|
||||
*(vu32 *)params->emc_bct_spare0 = params->emc_bct_spare1;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* Copyright (c) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -43,6 +43,9 @@
|
|||
|
||||
#define MAX17050_VMAX_TOLERANCE 50 /* 50 mV */
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
int max17050_get_property(enum MAX17050_reg reg, int *value)
|
||||
{
|
||||
u16 data;
|
||||
|
@ -264,3 +267,5 @@ int max17050_fix_configuration()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
|
@ -2,9 +2,9 @@
|
|||
* Fuel gauge driver for Nintendo Switch's Maxim 17050
|
||||
* Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* Copyright (c) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Defining registers address and its bit definitions of MAX77620 and MAX20024
|
||||
*
|
||||
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2016 NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -19,9 +19,19 @@
|
|||
#define MAX77620_CNFGGLBL1_LBDAC_EN (1 << 7)
|
||||
#define MAX77620_CNFGGLBL1_MPPLD (1 << 6)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST ((1 << 5) | (1 << 4))
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_N (1 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC 0x0E
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_N (1 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_100 (0 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_200 (1 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_300 (2 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBHYST_400 (3 << 4)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_MASK 0x0E
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_2700 (0 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_2800 (1 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_2900 (2 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_3000 (3 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_3100 (4 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_3200 (5 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_3300 (6 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBDAC_3400 (7 << 1)
|
||||
#define MAX77620_CNFGGLBL1_LBRSTEN (1 << 0)
|
||||
|
||||
#define MAX77620_REG_CNFGGLBL2 0x01
|
||||
|
|
|
@ -64,6 +64,16 @@ static const max77620_regulator_t _pmic_regulators[] = {
|
|||
{ REGULATOR_LDO, "ldo8", 0x00, 50000, 800000, 1050000, 1050000, MAX77620_REG_LDO8_CFG, MAX77620_REG_LDO8_CFG2, MAX77620_LDO_VOLT_MASK, MAX77620_LDO_POWER_MODE_MASK, MAX77620_LDO_POWER_MODE_SHIFT, 0x00, MAX77620_REG_FPS_LDO8, 3, 7, 0 }
|
||||
};
|
||||
|
||||
static void _max77620_try_set_reg(u8 reg, u8 val)
|
||||
{
|
||||
u8 tmp;
|
||||
do
|
||||
{
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg, val);
|
||||
tmp = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg);
|
||||
} while (val != tmp);
|
||||
}
|
||||
|
||||
int max77620_regulator_get_status(u32 id)
|
||||
{
|
||||
if (id > REGULATOR_MAX)
|
||||
|
@ -83,7 +93,7 @@ int max77620_regulator_config_fps(u32 id)
|
|||
|
||||
const max77620_regulator_t *reg = &_pmic_regulators[id];
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->fps_addr,
|
||||
_max77620_try_set_reg(reg->fps_addr,
|
||||
(reg->fps_src << MAX77620_FPS_SRC_SHIFT) | (reg->pu_period << MAX77620_FPS_PU_PERIOD_SHIFT) | (reg->pd_period));
|
||||
|
||||
return 1;
|
||||
|
@ -102,7 +112,7 @@ int max77620_regulator_set_voltage(u32 id, u32 mv)
|
|||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
u8 val = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr);
|
||||
val = (val & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);
|
||||
_max77620_try_set_reg(reg->volt_addr, val);
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
|
@ -121,7 +131,7 @@ int max77620_regulator_enable(u32 id, int enable)
|
|||
val = (val & ~reg->enable_mask) | ((MAX77620_POWER_MODE_NORMAL << reg->enable_shift) & reg->enable_mask);
|
||||
else
|
||||
val &= ~reg->enable_mask;
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, addr, val);
|
||||
_max77620_try_set_reg(addr, val);
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
|
@ -139,7 +149,7 @@ int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
|
|||
|
||||
u32 mult = (mv + reg->mv_step - 1 - reg->mv_min) / reg->mv_step;
|
||||
u8 val = ((flags << reg->enable_shift) & ~reg->volt_mask) | (mult & reg->volt_mask);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, reg->volt_addr, val);
|
||||
_max77620_try_set_reg(reg->volt_addr, val);
|
||||
usleep(1000);
|
||||
|
||||
return 1;
|
||||
|
@ -155,11 +165,12 @@ void max77620_config_default()
|
|||
if (_pmic_regulators[i].fps_src != MAX77620_FPS_SRC_NONE)
|
||||
max77620_regulator_enable(i, 1);
|
||||
}
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD_CFG2, 4);
|
||||
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4);
|
||||
}
|
||||
|
||||
void max77620_low_battery_monitor_config()
|
||||
{
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGGLBL1,
|
||||
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_LBHYST_N | MAX77620_CNFGGLBL1_LBDAC_N);
|
||||
_max77620_try_set_reg(MAX77620_REG_CNFGGLBL1,
|
||||
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_MPPLD |
|
||||
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
|
||||
}
|
||||
|
|
|
@ -86,8 +86,8 @@ static int _se_wait()
|
|||
while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET)))
|
||||
;
|
||||
if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) ||
|
||||
SE(SE_STATUS_0) & 3 ||
|
||||
SE(SE_ERR_STATUS_0) != 0)
|
||||
SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN ||
|
||||
SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -111,12 +111,12 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src
|
|||
SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0);
|
||||
SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET);
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op);
|
||||
int res = _se_wait();
|
||||
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -148,9 +148,11 @@ static void _se_aes_ctr_set(void *ctr)
|
|||
|
||||
void se_rsa_acc_ctrl(u32 rs, u32 flags)
|
||||
{
|
||||
if (flags & 0x7F)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = (((flags >> 4) & 4) | (flags & 3)) ^ 7;
|
||||
if (flags & 0x80)
|
||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) =
|
||||
((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) |
|
||||
((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG);
|
||||
if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
||||
SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs);
|
||||
}
|
||||
|
||||
|
@ -216,9 +218,9 @@ int se_rsa_exp_mod(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_siz
|
|||
|
||||
void se_key_acc_ctrl(u32 ks, u32 flags)
|
||||
{
|
||||
if (flags & 0x7F)
|
||||
if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG)
|
||||
SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags;
|
||||
if (flags & 0x80)
|
||||
if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG)
|
||||
SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks);
|
||||
}
|
||||
|
||||
|
@ -424,15 +426,15 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size)
|
|||
int res;
|
||||
// Setup config for SHA256, size = BITS(src_size).
|
||||
SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG);
|
||||
SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_ENABLE;
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3);
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 1) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 2) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 3) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3);
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 1) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 2) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 3) = 0;
|
||||
SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_HASH;
|
||||
SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(src_size << 3);
|
||||
SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(src_size << 3);
|
||||
SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0;
|
||||
SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0;
|
||||
|
||||
// Trigger the operation.
|
||||
res = _se_execute(OP_START, NULL, 0, src, src_size);
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define SE_SECURITY_0 0x000
|
||||
#define SE_KEY_SCHED_READ_SHIFT 3
|
||||
|
||||
#define SE_TZRAM_SECURITY_0 0x004
|
||||
|
||||
#define SE_CONFIG_REG_OFFSET 0x014
|
||||
#define SE_CONFIG_ENC_ALG_SHIFT 12
|
||||
#define SE_CONFIG_DEC_ALG_SHIFT 8
|
||||
|
@ -209,8 +211,12 @@
|
|||
#define SE_INT_OP_DONE(x) (x << SE_INT_OP_DONE_SHIFT)
|
||||
#define SE_INT_ERROR_SHIFT 16
|
||||
#define SE_INT_ERROR(x) (x << SE_INT_ERROR_SHIFT)
|
||||
|
||||
#define SE_STATUS_0 0x800
|
||||
#define SE_STATUS_0_STATE_WAIT_IN 3
|
||||
|
||||
#define SE_ERR_STATUS_0 0x804
|
||||
#define SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR 0
|
||||
|
||||
#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330
|
||||
#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0
|
||||
|
@ -231,11 +237,17 @@
|
|||
#define SE_SPARE_0_REG_OFFSET 0x80c
|
||||
|
||||
#define SE_SHA_CONFIG_REG_OFFSET 0x200
|
||||
#define SHA_INIT_DISABLE 0
|
||||
#define SHA_INIT_ENABLE 1
|
||||
#define SHA_CONTINUE 0
|
||||
#define SHA_INIT_HASH 1
|
||||
|
||||
#define SE_SHA_MSG_LENGTH_REG_OFFSET 0x204
|
||||
#define SE_SHA_MSG_LEFT_REG_OFFSET 0x214
|
||||
#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204
|
||||
#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208
|
||||
#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C
|
||||
#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210
|
||||
#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214
|
||||
#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218
|
||||
#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C
|
||||
#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220
|
||||
|
||||
#define SE_HASH_RESULT_REG_COUNT 16
|
||||
#define SE_HASH_RESULT_REG_OFFSET 0x030
|
||||
|
@ -254,13 +266,24 @@
|
|||
TEGRA_SE_RNG_DT_SIZE)
|
||||
|
||||
#define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16
|
||||
#define TEGRA_SE_RSA512_DIGEST_SIZE 64
|
||||
#define TEGRA_SE_RSA512_DIGEST_SIZE 64
|
||||
#define TEGRA_SE_RSA1024_DIGEST_SIZE 128
|
||||
#define TEGRA_SE_RSA1536_DIGEST_SIZE 192
|
||||
#define TEGRA_SE_RSA2048_DIGEST_SIZE 256
|
||||
|
||||
#define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280
|
||||
#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
||||
|
||||
#define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284
|
||||
#define SE_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0)
|
||||
#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1)
|
||||
#define SE_KEY_TBL_DIS_OIVREAD_FLAG (1 << 2)
|
||||
#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG (1 << 3)
|
||||
#define SE_KEY_TBL_DIS_UIVREAD_FLAG (1 << 4)
|
||||
#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG (1 << 5)
|
||||
#define SE_KEY_TBL_DIS_KEYUSE_FLAG (1 << 6)
|
||||
#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F
|
||||
|
||||
#define SE_KEY_READ_DISABLE_SHIFT 0
|
||||
#define SE_KEY_UPDATE_DISABLE_SHIFT 1
|
||||
|
||||
|
@ -312,7 +335,16 @@
|
|||
#define TEGRA_SE_RSA_KEYSLOT_COUNT 2
|
||||
|
||||
#define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80
|
||||
|
||||
#define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG (1 << 2)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT (1 << 2)
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7
|
||||
#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F
|
||||
|
||||
#define SE_RSA_KEYTABLE_ADDR 0x420
|
||||
#define SE_RSA_KEYTABLE_DATA 0x424
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "../sec/se_t210.h"
|
||||
#include "../soc/bpmp.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/kfuse.h"
|
||||
#include "../soc/smmu.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../mem/heap.h"
|
||||
|
@ -77,6 +78,8 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
clock_enable_sor1();
|
||||
clock_enable_kfuse();
|
||||
|
||||
kfuse_wait_ready();
|
||||
|
||||
//Configure Falcon.
|
||||
TSEC(TSEC_DMACTL) = 0;
|
||||
TSEC(TSEC_IRQMSET) =
|
||||
|
@ -208,7 +211,7 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||
res = -6;
|
||||
smmu_deinit_for_tsec();
|
||||
|
||||
goto out;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
// Give some extra time to make sure PKG1.1 is decrypted.
|
||||
|
@ -278,7 +281,7 @@ out:;
|
|||
clock_disable_sor_safe();
|
||||
clock_disable_tsec();
|
||||
bpmp_mmu_enable();
|
||||
bpmp_clk_rate_set(BPMP_CLK_SUPER_BOOST);
|
||||
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "bpmp.h"
|
||||
#include "clock.h"
|
||||
#include "t210.h"
|
||||
#include "../../common/memory_map.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
#define BPMP_CACHE_CONFIG 0x0
|
||||
|
@ -74,13 +75,13 @@
|
|||
|
||||
bpmp_mmu_entry_t mmu_entries[] =
|
||||
{
|
||||
{ 0x80000000, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
|
||||
{ IPL_LOAD_ADDR, 0x40040000, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
|
||||
{ DRAM_START, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
|
||||
{ IRAM_BASE, 0x4003FFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
|
||||
};
|
||||
|
||||
void bpmp_mmu_maintenance(u32 op)
|
||||
void bpmp_mmu_maintenance(u32 op, bool force)
|
||||
{
|
||||
if (!(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))
|
||||
if (!force && !(BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) & CFG_ENABLE))
|
||||
return;
|
||||
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = INT_CLR_MAINT_DONE;
|
||||
|
@ -132,13 +133,13 @@ void bpmp_mmu_enable()
|
|||
BPMP_CACHE_CTRL(BPMP_CACHE_MMU_CMD) = MMU_CMD_COPY_SHADOW;
|
||||
|
||||
// Invalidate cache.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, true);
|
||||
|
||||
// Enable cache.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = CFG_ENABLE | CFG_FORCE_WRITE_THROUGH | CFG_TAG_CHK_ABRT_ON_ERR;
|
||||
|
||||
// HW bug. Invalidate cache again.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
|
||||
}
|
||||
|
||||
void bpmp_mmu_disable()
|
||||
|
@ -147,21 +148,19 @@ void bpmp_mmu_disable()
|
|||
return;
|
||||
|
||||
// Clean and invalidate cache.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
|
||||
// Disable cache.
|
||||
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
|
||||
|
||||
// HW bug. Invalidate cache again.
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY);
|
||||
}
|
||||
|
||||
const u8 pllc4_divn[] = {
|
||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||
85, // BPMP_CLK_LOW_BOOST: 544MHz 33% - 136MHz APB.
|
||||
90, // BPMP_CLK_MID_BOOST: 576MHz 41% - 144MHz APB.
|
||||
94 // BPMP_CLK_SUPER_BOOST: 602MHz 48% - 150MHz APB.
|
||||
//95 // BPMP_CLK_SUPER_BOOST: 608MHz 49% - 152MHz APB.
|
||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||
90, // BPMP_CLK_SUPER_BOOST: 576MHz 41% - 144MHz APB.
|
||||
92 // BPMP_CLK_HYPER_BOOST: 589MHz 44% - 147MHz APB.
|
||||
// Do not use for public releases!
|
||||
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
||||
};
|
||||
|
||||
bpmp_freq_t bpmp_clock_set = BPMP_CLK_NORMAL;
|
||||
|
|
|
@ -36,13 +36,16 @@ typedef struct _bpmp_mmu_entry_t
|
|||
typedef enum
|
||||
{
|
||||
BPMP_CLK_NORMAL, // 408MHz 0% - 136MHz APB.
|
||||
BPMP_CLK_LOW_BOOST, // 544MHz 33% - 136MHz APB.
|
||||
BPMP_CLK_MID_BOOST, // 576MHz 41% - 144MHz APB.
|
||||
BPMP_CLK_SUPER_BOOST, // 608MHz 49% - 152MHz APB.
|
||||
BPMP_CLK_HIGH_BOOST, // 544MHz 33% - 136MHz APB.
|
||||
BPMP_CLK_SUPER_BOOST, // 576MHz 41% - 144MHz APB.
|
||||
BPMP_CLK_HYPER_BOOST, // 589MHz 44% - 147MHz APB.
|
||||
//BPMP_CLK_DEV_BOOST, // 608MHz 49% - 152MHz APB.
|
||||
BPMP_CLK_MAX
|
||||
} bpmp_freq_t;
|
||||
|
||||
void bpmp_mmu_maintenance(u32 op);
|
||||
#define BPMP_CLK_DEFAULT_BOOST BPMP_CLK_HYPER_BOOST
|
||||
|
||||
void bpmp_mmu_maintenance(u32 op, bool force);
|
||||
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
|
||||
void bpmp_mmu_enable();
|
||||
void bpmp_mmu_disable();
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/kfuse.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
#include "../storage/sdmmc.h"
|
||||
|
@ -30,13 +29,14 @@ static const clock_t _clock_uart[] = {
|
|||
/* UART E */ { CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, 20, 0, 2 }
|
||||
};
|
||||
|
||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0 FM_DIV: 26.
|
||||
static const clock_t _clock_i2c[] = {
|
||||
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 12, 6, 0 }, // 0, 19 }, // 100KHz
|
||||
/* I2C2 */ { 0 },
|
||||
/* I2C3 */ { 0 },
|
||||
/* I2C4 */ { 0 },
|
||||
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 15, 6, 0 }, // 0, 4 }, // 400KHz
|
||||
/* I2C6 */ { 0 }
|
||||
/* I2C1 */ { CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, 12, 0, 19 }, //20.4MHz -> 100KHz
|
||||
/* I2C2 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, 22, 0, 4 }, //81.6MHz -> 400KHz
|
||||
/* I2C3 */ { CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, 3, 0, 4 }, //81.6MHz -> 400KHz
|
||||
/* I2C4 */ { CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, 7, 0, 19 }, //20.4MHz -> 100KHz
|
||||
/* I2C5 */ { CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, 15, 0, 4 }, //81.6MHz -> 400KHz
|
||||
/* I2C6 */ { CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, 6, 0, 19 } //20.4MHz -> 100KHz
|
||||
};
|
||||
|
||||
static clock_t _clock_se = {
|
||||
|
@ -74,7 +74,7 @@ static clock_t _clock_coresight = {
|
|||
};
|
||||
|
||||
static clock_t _clock_pwm = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, 17, 6, 4 // Freference: 6.2MHz.
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, 17, 6, 4 // Fref: 6.2MHz.
|
||||
};
|
||||
|
||||
void clock_enable(const clock_t *clk)
|
||||
|
@ -88,6 +88,8 @@ void clock_enable(const clock_t *clk)
|
|||
CLOCK(clk->source) = clk->clk_div | (clk->clk_src << 29);
|
||||
// Enable.
|
||||
CLOCK(clk->enable) = (CLOCK(clk->enable) & ~(1 << clk->index)) | (1 << clk->index);
|
||||
usleep(2);
|
||||
|
||||
// Take clock off reset.
|
||||
CLOCK(clk->reset) &= ~(1 << clk->index);
|
||||
}
|
||||
|
@ -189,7 +191,6 @@ void clock_enable_kfuse()
|
|||
usleep(10);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_H) &= 0xFFFFFEFF;
|
||||
usleep(20);
|
||||
kfuse_wait_ready();
|
||||
}
|
||||
|
||||
void clock_disable_kfuse()
|
||||
|
@ -368,7 +369,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
|||
static u32 _clock_sdmmc_table[8] = { 0 };
|
||||
|
||||
#define PLLP_OUT0 0x0
|
||||
static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pout, u32 id, u32 val)
|
||||
{
|
||||
u32 divisor = 0;
|
||||
u32 source = PLLP_OUT0;
|
||||
|
@ -416,6 +417,7 @@ static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
|
|||
_clock_sdmmc_table[2 * id] = val;
|
||||
_clock_sdmmc_table[2 * id + 1] = *pout;
|
||||
|
||||
// Set SDMMC clock.
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
|
@ -446,15 +448,16 @@ void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val)
|
|||
int is_enabled = _clock_sdmmc_is_enabled(id);
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_config_clock_source_inner(pout, id, val);
|
||||
_clock_sdmmc_config_clock_host(pout, id, val);
|
||||
if (is_enabled)
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
}
|
||||
|
||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type)
|
||||
void clock_sdmmc_get_card_clock_div(u32 *pout, u16 *pdivisor, u32 type)
|
||||
{
|
||||
// Get Card clock divisor.
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
|
@ -515,7 +518,7 @@ void clock_sdmmc_enable(u32 id, u32 val)
|
|||
if (_clock_sdmmc_is_enabled(id))
|
||||
_clock_sdmmc_clear_enable(id);
|
||||
_clock_sdmmc_set_reset(id);
|
||||
_clock_sdmmc_config_clock_source_inner(&div, id, val);
|
||||
_clock_sdmmc_config_clock_host(&div, id, val);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
usleep((100000 + div - 1) / div);
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SYS 0x400
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SOR1 0x410
|
||||
#define CLK_RST_CONTROLLER_CLK_SOURCE_SE 0x42C
|
||||
#define CLK_RST_CONTROLLER_RST_DEV_V_CLR 0x434
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_SET 0x440
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_V_CLR 0x444
|
||||
#define CLK_RST_CONTROLLER_CLK_ENB_W_SET 0x448
|
||||
|
@ -181,7 +182,7 @@ void clock_disable_coresight();
|
|||
void clock_enable_pwm();
|
||||
void clock_disable_pwm();
|
||||
void clock_sdmmc_config_clock_source(u32 *pout, u32 id, u32 val);
|
||||
void clock_sdmmc_get_params(u32 *pout, u16 *pdivisor, u32 type);
|
||||
void clock_sdmmc_get_card_clock_div(u32 *pout, u16 *pdivisor, u32 type);
|
||||
int clock_sdmmc_is_not_reset_and_enabled(u32 id);
|
||||
void clock_sdmmc_enable(u32 id, u32 val);
|
||||
void clock_sdmmc_disable(u32 id);
|
||||
|
|
|
@ -80,9 +80,9 @@ void cluster_boot_cpu0(u32 entry)
|
|||
|
||||
_cluster_enable_power();
|
||||
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000))
|
||||
if (!(CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) & 0x40000000)) // PLLX_ENABLE.
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_MISC_3) &= 0xFFFFFFF7; // Disable IDDQ.
|
||||
usleep(2);
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x80404E02;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLX_BASE) = 0x404E02;
|
||||
|
@ -127,6 +127,9 @@ void cluster_boot_cpu0(u32 entry)
|
|||
SB(SB_CSR) = SB_CSR_NS_RST_VEC_WR_DIS;
|
||||
(void)SB(SB_CSR);
|
||||
|
||||
// Tighten up the security aperture.
|
||||
// MC(MC_TZ_SECURITY_CTRL) = 1;
|
||||
|
||||
// Clear MSELECT reset.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEVICES_V) &= 0xFFFFFFF7;
|
||||
// Clear NONCPU reset.
|
||||
|
|
|
@ -22,6 +22,34 @@
|
|||
#include "../soc/fuse.h"
|
||||
#include "../soc/t210.h"
|
||||
|
||||
#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
|
||||
|
||||
static const u32 evp_thunk_template[] = {
|
||||
0xe92d0007, // STMFD SP!, {R0-R2}
|
||||
0xe1a0200e, // MOV R2, LR
|
||||
0xe2422002, // SUB R2, R2, #2
|
||||
0xe5922000, // LDR R2, [R2]
|
||||
0xe20220ff, // AND R2, R2, #0xFF
|
||||
0xe1a02082, // MOV R2, R2,LSL#1
|
||||
0xe59f001c, // LDR R0, =evp_thunk_template
|
||||
0xe59f101c, // LDR R1, =thunk_end
|
||||
0xe0411000, // SUB R1, R1, R0
|
||||
0xe59f0018, // LDR R0, =iram_evp_thunks
|
||||
0xe0800001, // ADD R0, R0, R1
|
||||
0xe0822000, // ADD R2, R2, R0
|
||||
0xe3822001, // ORR R2, R2, #1
|
||||
0xe8bd0003, // LDMFD SP!, {R0,R1}
|
||||
0xe12fff12, // BX R2
|
||||
0x001007b0, // off_1007EC DCD evp_thunk_template
|
||||
0x001007f8, // off_1007F0 DCD thunk_end
|
||||
0x40004c30, // off_1007F4 DCD iram_evp_thunks
|
||||
// thunk_end is here
|
||||
};
|
||||
static const u32 evp_thunk_template_len = sizeof(evp_thunk_template);
|
||||
|
||||
// treated as 12bit values
|
||||
static const u32 hash_vals[] = {1, 2, 4, 8, 0, 3, 5, 6, 7, 9, 10, 11};
|
||||
|
||||
void fuse_disable_program()
|
||||
{
|
||||
FUSE(FUSE_DISABLEREGPROGRAM) = 1;
|
||||
|
@ -31,3 +59,291 @@ u32 fuse_read_odm(u32 idx)
|
|||
{
|
||||
return FUSE(FUSE_RESERVED_ODMX(idx));
|
||||
}
|
||||
|
||||
void fuse_wait_idle()
|
||||
{
|
||||
u32 ctrl;
|
||||
do
|
||||
{
|
||||
ctrl = FUSE(FUSE_CTRL);
|
||||
} while (((ctrl >> 16) & 0x1f) != 4);
|
||||
}
|
||||
|
||||
u32 fuse_read(u32 addr)
|
||||
{
|
||||
FUSE(FUSE_ADDR) = addr;
|
||||
FUSE(FUSE_CTRL) = (FUSE(FUSE_ADDR) & ~FUSE_CMD_MASK) | FUSE_READ;
|
||||
fuse_wait_idle();
|
||||
return FUSE(FUSE_RDATA);
|
||||
}
|
||||
|
||||
void fuse_read_array(u32 *words)
|
||||
{
|
||||
for (u32 i = 0; i < 192; i++)
|
||||
words[i] = fuse_read(i);
|
||||
}
|
||||
|
||||
static u32 _parity32_even(u32 *words, u32 count)
|
||||
{
|
||||
u32 acc = words[0];
|
||||
for (u32 i = 1; i < count; i++)
|
||||
{
|
||||
acc ^= words[i];
|
||||
}
|
||||
u32 lo = ((acc & 0xffff) ^ (acc >> 16)) & 0xff;
|
||||
u32 hi = ((acc & 0xffff) ^ (acc >> 16)) >> 8;
|
||||
u32 x = hi ^ lo;
|
||||
lo = ((x & 0xf) ^ (x >> 4)) & 3;
|
||||
hi = ((x & 0xf) ^ (x >> 4)) >> 2;
|
||||
x = hi ^ lo;
|
||||
|
||||
return (x & 1) ^ (x >> 1);
|
||||
}
|
||||
|
||||
static int _patch_hash_one(u32 *word)
|
||||
{
|
||||
u32 bits20_31 = *word & 0xfff00000;
|
||||
u32 parity_bit = _parity32_even(&bits20_31, 1);
|
||||
u32 hash = 0;
|
||||
for (u32 i = 0; i < 12; i++)
|
||||
{
|
||||
if (*word & (1 << (20 + i)))
|
||||
{
|
||||
hash ^= hash_vals[i];
|
||||
}
|
||||
}
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*word ^= 1 << 24;
|
||||
return 1;
|
||||
}
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
for (u32 i = 0; i < ARRAYSIZE(hash_vals); i++)
|
||||
{
|
||||
if (hash_vals[i] == hash)
|
||||
{
|
||||
*word ^= 1 << (20 + i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int _patch_hash_multi(u32 *words, u32 count)
|
||||
{
|
||||
u32 parity_bit = _parity32_even(words, count);
|
||||
u32 bits0_14 = words[0] & 0x7fff;
|
||||
u32 bit15 = words[0] & 0x8000;
|
||||
u32 bits16_19 = words[0] & 0xf0000;
|
||||
|
||||
u32 hash = 0;
|
||||
words[0] = bits16_19;
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
u32 w = words[i];
|
||||
if (w)
|
||||
{
|
||||
for (u32 bitpos = 0; bitpos < 32; bitpos++)
|
||||
{
|
||||
if ((w >> bitpos) & 1)
|
||||
{
|
||||
hash ^= 0x4000 + i * 32 + bitpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hash ^= bits0_14;
|
||||
// stupid but this is what original code does.
|
||||
// equivalent to original words[0] &= 0xfff00000
|
||||
words[0] = bits16_19 ^ bit15 ^ bits0_14;
|
||||
|
||||
if (hash == 0)
|
||||
{
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
words[0] ^= 0x8000;
|
||||
return 1;
|
||||
}
|
||||
if (parity_bit == 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
u32 bitcount = hash - 0x4000;
|
||||
if (bitcount < 16 || bitcount >= count * 32)
|
||||
{
|
||||
u32 num_set = 0;
|
||||
for (u32 bitpos = 0; bitpos < 15; bitpos++)
|
||||
{
|
||||
if ((hash >> bitpos) & 1)
|
||||
{
|
||||
num_set++;
|
||||
}
|
||||
}
|
||||
if (num_set != 1)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
words[0] ^= hash;
|
||||
return 1;
|
||||
}
|
||||
words[bitcount / 32] ^= 1 << (hash & 0x1f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value))
|
||||
{
|
||||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0 = 0;
|
||||
u32 total_read = 0;
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAYSIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
words[i] = fuse_read(word_addr--);
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
if (ipatch_count)
|
||||
{
|
||||
for (u32 i = 0; i < ipatch_count; i++)
|
||||
{
|
||||
u32 word = words[i + 1];
|
||||
u32 addr = (word >> 16) * 2;
|
||||
u32 data = word & 0xFFFF;
|
||||
|
||||
ipatch(addr, data);
|
||||
}
|
||||
}
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len)
|
||||
{
|
||||
u32 words[80];
|
||||
u32 word_count;
|
||||
u32 word_addr;
|
||||
u32 word0 = 0;
|
||||
u32 total_read = 0;
|
||||
int evp_thunk_written = 0;
|
||||
void *evp_thunk_dst_addr = 0;
|
||||
|
||||
memset(iram_evp_thunks, 0, *iram_evp_thunks_len);
|
||||
|
||||
word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE);
|
||||
word_count &= 0x7F;
|
||||
word_addr = 191;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
total_read += word_count;
|
||||
if (total_read >= ARRAYSIZE(words))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < word_count; i++)
|
||||
words[i] = fuse_read(word_addr--);
|
||||
|
||||
word0 = words[0];
|
||||
if (_patch_hash_multi(words, word_count) >= 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
u32 ipatch_count = (words[0] >> 16) & 0xF;
|
||||
u32 insn_count = word_count - ipatch_count - 1;
|
||||
if (insn_count)
|
||||
{
|
||||
if (!evp_thunk_written)
|
||||
{
|
||||
evp_thunk_dst_addr = (void *)iram_evp_thunks;
|
||||
|
||||
memcpy(evp_thunk_dst_addr, (void *)evp_thunk_template, evp_thunk_template_len);
|
||||
evp_thunk_dst_addr += evp_thunk_template_len;
|
||||
evp_thunk_written = 1;
|
||||
*iram_evp_thunks_len = evp_thunk_template_len;
|
||||
|
||||
//write32(TEGRA_EXCEPTION_VECTORS_BASE + 0x208, iram_evp_thunks);
|
||||
}
|
||||
|
||||
u32 thunk_patch_len = insn_count * sizeof(u32);
|
||||
memcpy(evp_thunk_dst_addr, &words[ipatch_count + 1], thunk_patch_len);
|
||||
evp_thunk_dst_addr += thunk_patch_len;
|
||||
*iram_evp_thunks_len += thunk_patch_len;
|
||||
}
|
||||
words[0] = word0;
|
||||
if ((word0 >> 25) == 0)
|
||||
break;
|
||||
if (_patch_hash_one(&word0) >= 2)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fuse_check_patched_rcm()
|
||||
{
|
||||
// Check if XUSB in use.
|
||||
if (FUSE(FUSE_RESERVED_SW) & (1<<7))
|
||||
return true;
|
||||
|
||||
// Check if RCM is ipatched.
|
||||
u32 word_count = FUSE(FUSE_FIRST_BOOTROM_PATCH_SIZE) & 0x7F;
|
||||
u32 word_addr = 191;
|
||||
|
||||
while (word_count)
|
||||
{
|
||||
u32 word0 = fuse_read(word_addr);
|
||||
u32 ipatch_count = (word0 >> 16) & 0xF;
|
||||
|
||||
for (u32 i = 0; i < ipatch_count; i++)
|
||||
{
|
||||
u32 word = fuse_read(word_addr - (i + 1));
|
||||
u32 addr = (word >> 16) * 2;
|
||||
if (addr == 0x769A)
|
||||
return true;
|
||||
}
|
||||
|
||||
word_addr -= word_count;
|
||||
word_count = word0 >> 25;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#define FUSE_PRIVATE_KEY3 0x1B0
|
||||
#define FUSE_PRIVATE_KEY4 0x1B4
|
||||
#define FUSE_RESERVED_SW 0x1C0
|
||||
#define FUSE_SKU_DIRECT_CONFIG 0x1F4
|
||||
#define FUSE_OPT_VENDOR_CODE 0x200
|
||||
#define FUSE_OPT_FAB_CODE 0x204
|
||||
#define FUSE_OPT_LOT_CODE_0 0x208
|
||||
|
@ -74,5 +75,10 @@
|
|||
|
||||
void fuse_disable_program();
|
||||
u32 fuse_read_odm(u32 idx);
|
||||
void fuse_wait_idle();
|
||||
int fuse_read_ipatch(void (*ipatch)(u32 offset, u32 value));
|
||||
int fuse_read_evp_thunk(u32 *iram_evp_thunks, u32 *iram_evp_thunks_len);
|
||||
void fuse_read_array(u32 *words);
|
||||
bool fuse_check_patched_rcm();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -219,7 +219,7 @@ void _config_regulators()
|
|||
{
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
|
||||
(1 << 6) | (1 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
||||
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
|
||||
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
|
||||
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
|
||||
|
@ -257,7 +257,7 @@ void _config_regulators()
|
|||
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
|
||||
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
|
||||
|
||||
// Disable low battery shutdown monitor.
|
||||
// Enable low battery shutdown monitor for < 2800mV.
|
||||
max77620_low_battery_monitor_config();
|
||||
}
|
||||
|
||||
|
@ -274,6 +274,7 @@ void config_hw()
|
|||
|
||||
// Enable fuse clock.
|
||||
clock_enable_fuse(true);
|
||||
|
||||
// Disable fuse programming.
|
||||
fuse_disable_program();
|
||||
|
||||
|
|
|
@ -17,7 +17,21 @@
|
|||
#include "../soc/kfuse.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("Os")
|
||||
|
||||
int kfuse_wait_ready()
|
||||
{
|
||||
// Wait for KFUSE to finish init and verification of data.
|
||||
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
|
||||
;
|
||||
|
||||
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kfuse_read(u32 *buf)
|
||||
{
|
||||
|
@ -25,10 +39,7 @@ int kfuse_read(u32 *buf)
|
|||
|
||||
clock_enable_kfuse();
|
||||
|
||||
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
|
||||
;
|
||||
|
||||
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
|
||||
if (!kfuse_wait_ready())
|
||||
goto out;
|
||||
|
||||
KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC;
|
||||
|
@ -42,16 +53,4 @@ out:;
|
|||
return res;
|
||||
}
|
||||
|
||||
int kfuse_wait_ready()
|
||||
{
|
||||
// Wait for KFUSE to finish init and verification of data.
|
||||
while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE))
|
||||
{
|
||||
usleep(500);
|
||||
}
|
||||
|
||||
if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#define KFUSE_NUM_WORDS 144
|
||||
|
||||
int kfuse_read(u32 *buf);
|
||||
int kfuse_wait_ready();
|
||||
int kfuse_read(u32 *buf);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -106,7 +106,7 @@ bool smmu_is_used()
|
|||
|
||||
void smmu_exit()
|
||||
{
|
||||
*(uint32_t *)(smmu_payload + 0x14) = _NOP();
|
||||
*(u32 *)(smmu_payload + 0x14) = _NOP();
|
||||
}
|
||||
|
||||
u32 *smmu_init_domain4(u32 dev_base, u32 asid)
|
||||
|
|
|
@ -108,6 +108,14 @@
|
|||
|
||||
/*! EVP registers. */
|
||||
#define EVP_CPU_RESET_VECTOR 0x100
|
||||
#define EVP_COP_RESET_VECTOR 0x200
|
||||
#define EVP_COP_UNDEF_VECTOR 0x204
|
||||
#define EVP_COP_SWI_VECTOR 0x208
|
||||
#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
|
||||
#define EVP_COP_DATA_ABORT_VECTOR 0x210
|
||||
#define EVP_COP_RSVD_VECTOR 0x214
|
||||
#define EVP_COP_IRQ_VECTOR 0x218
|
||||
#define EVP_COP_FIQ_VECTOR 0x21C
|
||||
|
||||
/*! Misc registers. */
|
||||
#define APB_MISC_PP_STRAPPING_OPT_A 0x08
|
||||
|
@ -208,7 +216,7 @@
|
|||
#define HALT_COP_JTAG (1 << 28)
|
||||
#define HALT_COP_WAIT_EVENT (1 << 30)
|
||||
#define HALT_COP_WAIT_IRQ (1 << 31)
|
||||
#define HALT_COP_MAX_CNT 0xFF
|
||||
#define HALT_COP_MAX_CNT 0xFF
|
||||
#define FLOW_CTLR_HALT_CPU0_EVENTS 0x0
|
||||
#define FLOW_CTLR_HALT_CPU1_EVENTS 0x14
|
||||
#define FLOW_CTLR_HALT_CPU2_EVENTS 0x1C
|
||||
|
|
|
@ -36,9 +36,9 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
|
|||
part->lba_end = ent->lba_end;
|
||||
part->attrs = ent->attrs;
|
||||
|
||||
//HACK
|
||||
for (u32 j = 0; j < 36; j++)
|
||||
part->name[j] = ent->name[j];
|
||||
// ASCII conversion. Copy only the LSByte of the UTF-16LE name.
|
||||
for (u32 i = 0; i < 36; i++)
|
||||
part->name[i] = ent->name[i];
|
||||
part->name[36] = 0;
|
||||
|
||||
list_append(gpt, &part->link);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* include/linux/mmc/sd.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2005-2007 Pierre Ossman, All Rights Reserved.
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -40,7 +40,9 @@
|
|||
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
|
||||
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
|
||||
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
|
||||
#define SD_OCR_VDD_27_34 (0x7F << 15) /* VDD voltage 2.7 ~ 3.4 */
|
||||
#define SD_OCR_VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
|
||||
#define SD_OCR_VDD_18 (1 << 7) /* VDD voltage 1.8 */
|
||||
|
||||
/*
|
||||
* SD_SWITCH argument format:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -19,6 +19,7 @@
|
|||
#include "sdmmc.h"
|
||||
#include "mmc.h"
|
||||
#include "sd.h"
|
||||
#include "../../common/memory_map.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../utils/util.h"
|
||||
|
@ -220,10 +221,10 @@ static int _mmc_storage_get_op_cond_inner(sdmmc_storage_t *storage, u32 *pout, u
|
|||
switch (power)
|
||||
{
|
||||
case SDMMC_POWER_1_8:
|
||||
arg = 0x40000080; //Sector access, voltage.
|
||||
arg = SD_OCR_CCS | SD_OCR_VDD_18;
|
||||
break;
|
||||
case SDMMC_POWER_3_3:
|
||||
arg = 0x403F8000; //Sector access, voltage.
|
||||
arg = SD_OCR_CCS | SD_OCR_VDD_27_34;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -248,7 +249,7 @@ static int _mmc_storage_get_op_cond(sdmmc_storage_t *storage, u32 power)
|
|||
|
||||
if (cond & MMC_CARD_BUSY)
|
||||
{
|
||||
if (cond & 0x40000000)
|
||||
if (cond & SD_OCR_CCS)
|
||||
storage->has_sector_access = 1;
|
||||
|
||||
return 1;
|
||||
|
@ -569,7 +570,7 @@ DPRINTF("[MMC] BKOPS disabled\n");
|
|||
|
||||
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
|
||||
return 0;
|
||||
DPRINTF("[MMC] succesfully switched to highspeed mode\n");
|
||||
DPRINTF("[MMC] succesfully switched to HS mode\n");
|
||||
|
||||
sdmmc_sd_clock_ctrl(storage->sdmmc, 1);
|
||||
|
||||
|
@ -819,17 +820,17 @@ void _sd_storage_set_current_limit(sdmmc_storage_t *storage, u8 *buf)
|
|||
switch (pwr)
|
||||
{
|
||||
case SD_SET_CURRENT_LIMIT_800:
|
||||
DPRINTF("[SD] Power limit raised to 800mA\n");
|
||||
DPRINTF("[SD] power limit raised to 800mA\n");
|
||||
break;
|
||||
case SD_SET_CURRENT_LIMIT_600:
|
||||
DPRINTF("[SD] Power limit raised to 600mA\n");
|
||||
DPRINTF("[SD] power limit raised to 600mA\n");
|
||||
break;
|
||||
case SD_SET_CURRENT_LIMIT_400:
|
||||
DPRINTF("[SD] Power limit raised to 800mA\n");
|
||||
DPRINTF("[SD] power limit raised to 800mA\n");
|
||||
break;
|
||||
default:
|
||||
case SD_SET_CURRENT_LIMIT_200:
|
||||
DPRINTF("[SD] Power limit defaulted to 200mA\n");
|
||||
DPRINTF("[SD] power limit defaulted to 200mA\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -857,7 +858,7 @@ DPRINTF("[SD] SD supports selected (U)HS mode\n");
|
|||
return 1;
|
||||
}
|
||||
|
||||
int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
|
||||
int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf)
|
||||
{
|
||||
// Try to raise the current limit to let the card perform better.
|
||||
_sd_storage_set_current_limit(storage, buf);
|
||||
|
@ -878,7 +879,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8
|
|||
{
|
||||
type = 11;
|
||||
hs_type = UHS_SDR104_BUS_SPEED;
|
||||
DPRINTF("[SD] Bus speed set to SDR104\n");
|
||||
DPRINTF("[SD] bus speed set to SDR104\n");
|
||||
storage->csd.busspeed = 104;
|
||||
break;
|
||||
}
|
||||
|
@ -887,7 +888,7 @@ DPRINTF("[SD] Bus speed set to SDR104\n");
|
|||
{
|
||||
type = 10;
|
||||
hs_type = UHS_SDR50_BUS_SPEED;
|
||||
DPRINTF("[SD] Bus speed set to SDR50\n");
|
||||
DPRINTF("[SD] bus speed set to SDR50\n");
|
||||
storage->csd.busspeed = 50;
|
||||
break;
|
||||
}
|
||||
|
@ -896,7 +897,7 @@ DPRINTF("[SD] Bus speed set to SDR50\n");
|
|||
return 0;
|
||||
type = 8;
|
||||
hs_type = UHS_SDR12_BUS_SPEED;
|
||||
DPRINTF("[SD] Bus speed set to SDR12\n");
|
||||
DPRINTF("[SD] bus speed set to SDR12\n");
|
||||
storage->csd.busspeed = 12;
|
||||
break;
|
||||
default:
|
||||
|
@ -916,7 +917,7 @@ DPRINTF("[SD] config tuning\n");
|
|||
return _sdmmc_storage_check_status(storage);
|
||||
}
|
||||
|
||||
int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf)
|
||||
int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf)
|
||||
{
|
||||
if (!_sd_storage_switch_get(storage, buf))
|
||||
return 0;
|
||||
|
@ -1064,8 +1065,9 @@ void sdmmc_storage_init_wait_sd()
|
|||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type)
|
||||
{
|
||||
int is_version_1 = 0;
|
||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||
|
||||
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||
// Some cards (SanDisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||
sdmmc_storage_init_wait_sd();
|
||||
|
||||
memset(storage, 0, sizeof(sdmmc_storage_t));
|
||||
|
@ -1138,12 +1140,8 @@ DPRINTF("[SD] set blocklen to 512\n");
|
|||
return 0;
|
||||
DPRINTF("[SD] cleared card detect\n");
|
||||
|
||||
u8 *buf = (u8 *)malloc(512);
|
||||
if (!_sd_storage_get_scr(storage, buf))
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//gfx_hexdump(0, storage->raw_scr, 8);
|
||||
DPRINTF("[SD] got scr\n");
|
||||
|
@ -1152,10 +1150,8 @@ DPRINTF("[SD] got scr\n");
|
|||
if (bus_width == SDMMC_BUS_WIDTH_4 && (storage->scr.bus_widths & 4) && (storage->scr.sda_vsn & 0xF))
|
||||
{
|
||||
if (!_sd_storage_execute_app_cmd_type1(storage, &tmp, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, 0, R1_STATE_TRAN))
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdmmc_set_bus_width(storage->sdmmc, SDMMC_BUS_WIDTH_4);
|
||||
DPRINTF("[SD] switched to wide bus width\n");
|
||||
}
|
||||
|
@ -1166,20 +1162,15 @@ DPRINTF("[SD] SD does not support wide bus width\n");
|
|||
|
||||
if (storage->is_low_voltage)
|
||||
{
|
||||
if (!_sd_storage_enable_highspeed_low_volt(storage, type, buf))
|
||||
{
|
||||
free(buf);
|
||||
if (!_sd_storage_enable_uhs_low_volt(storage, type, buf))
|
||||
return 0;
|
||||
}
|
||||
DPRINTF("[SD] enabled UHS\n");
|
||||
}
|
||||
else if (type != 6 && (storage->scr.sda_vsn & 0xF) != 0)
|
||||
{
|
||||
if (!_sd_storage_enable_highspeed_high_volt(storage, buf))
|
||||
{
|
||||
free(buf);
|
||||
if (!_sd_storage_enable_hs_high_volt(storage, buf))
|
||||
return 0;
|
||||
}
|
||||
|
||||
DPRINTF("[SD] enabled HS\n");
|
||||
storage->csd.busspeed = 25;
|
||||
}
|
||||
|
@ -1192,7 +1183,6 @@ DPRINTF("[SD] enabled HS\n");
|
|||
DPRINTF("[SD] got sd status\n");
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
|
|
@ -252,7 +252,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
|
|||
|
||||
u32 tmp;
|
||||
u16 divisor;
|
||||
clock_sdmmc_get_params(&tmp, &divisor, type);
|
||||
clock_sdmmc_get_card_clock_div(&tmp, &divisor, type);
|
||||
clock_sdmmc_config_clock_source(&tmp, sdmmc->id, tmp);
|
||||
sdmmc->divisor = (tmp + divisor - 1) / divisor;
|
||||
|
||||
|
@ -722,7 +722,7 @@ static int _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
|
|||
sdmmc->regs->norintsts = norintsts & mask;
|
||||
return SDMMC_MASKINT_MASKED;
|
||||
}
|
||||
|
||||
|
||||
return SDMMC_MASKINT_NOERROR;
|
||||
}
|
||||
|
||||
|
@ -767,7 +767,7 @@ static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp)
|
|||
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
|
||||
_sdmmc_cache_rsp(sdmmc, rsp, 4, SDMMC_RSP_TYPE_1);
|
||||
|
||||
return _sdmmc_wait_prnsts_type1(sdmmc);
|
||||
|
@ -830,7 +830,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
|
|||
trnmode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
|
||||
if (req->is_auto_cmd12)
|
||||
trnmode = (trnmode & 0xFFF3) | TEGRA_MMC_TRNMOD_AUTO_CMD12;
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
sdmmc->regs->trnmod = trnmode;
|
||||
|
||||
return 1;
|
||||
|
@ -855,7 +855,7 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc)
|
|||
break;
|
||||
if (intr & TEGRA_MMC_NORINTSTS_XFER_COMPLETE)
|
||||
{
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY);
|
||||
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false);
|
||||
return 1; // Transfer complete.
|
||||
}
|
||||
if (intr & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT)
|
||||
|
@ -901,7 +901,7 @@ static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_
|
|||
_sdmmc_parse_cmdbuf(sdmmc, cmd, is_data_present);
|
||||
|
||||
int res = _sdmmc_wait_request(sdmmc);
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", res,
|
||||
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", res,
|
||||
sdmmc->regs->rspreg0, sdmmc->regs->rspreg1, sdmmc->regs->rspreg2, sdmmc->regs->rspreg3);
|
||||
if (res)
|
||||
{
|
||||
|
@ -943,7 +943,7 @@ static int _sdmmc_config_sdmmc1()
|
|||
gpio_output_enable(GPIO_PORT_Z, GPIO_PIN_1, GPIO_OUTPUT_DISABLE);
|
||||
usleep(100);
|
||||
|
||||
// Check if SD card is inserted.
|
||||
// Check if SD card is inserted.
|
||||
if(!!gpio_read(GPIO_PORT_Z, GPIO_PIN_1))
|
||||
return 0;
|
||||
|
||||
|
@ -1015,7 +1015,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n
|
|||
|
||||
u32 clock;
|
||||
u16 divisor;
|
||||
clock_sdmmc_get_params(&clock, &divisor, type);
|
||||
clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
|
||||
clock_sdmmc_enable(id, clock);
|
||||
|
||||
sdmmc->clock_stopped = 0;
|
||||
|
@ -1055,7 +1055,7 @@ void sdmmc_end(sdmmc_t *sdmmc)
|
|||
if (!sdmmc->clock_stopped)
|
||||
{
|
||||
_sdmmc_sd_clock_disable(sdmmc);
|
||||
// Disable SDMMC power.
|
||||
// Disable SDMMC power.
|
||||
_sdmmc_set_voltage(sdmmc, SDMMC_POWER_OFF);
|
||||
|
||||
// Disable SD card power.
|
||||
|
@ -1134,7 +1134,7 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
|
|||
_sdmmc_set_voltage(sdmmc, SDMMC_POWER_1_8);
|
||||
_sdmmc_get_clkcon(sdmmc);
|
||||
msleep(5);
|
||||
|
||||
|
||||
if (sdmmc->regs->hostctl2 & SDHCI_CTRL_VDD_180)
|
||||
{
|
||||
sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -61,16 +61,25 @@ u8 btn_wait()
|
|||
|
||||
u8 btn_wait_timeout(u32 time_ms, u8 mask)
|
||||
{
|
||||
u8 single_button = mask & BTN_SINGLE;
|
||||
mask &= ~BTN_SINGLE;
|
||||
|
||||
u32 timeout = get_tmr_ms() + time_ms;
|
||||
u8 res = btn_read() & mask;
|
||||
u8 res = btn_read();
|
||||
|
||||
while (get_tmr_ms() < timeout)
|
||||
{
|
||||
if (res == mask)
|
||||
break;
|
||||
if ((res & mask) == mask)
|
||||
{
|
||||
if (single_button && (res & ~mask)) // Undesired button detected.
|
||||
res = btn_read();
|
||||
else
|
||||
return (res & mask);
|
||||
}
|
||||
else
|
||||
res = btn_read() & mask;
|
||||
res = btn_read();
|
||||
};
|
||||
|
||||
return res;
|
||||
// Timed out.
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -23,6 +23,7 @@
|
|||
#define BTN_POWER (1 << 0)
|
||||
#define BTN_VOL_DOWN (1 << 1)
|
||||
#define BTN_VOL_UP (1 << 2)
|
||||
#define BTN_SINGLE (1 << 7)
|
||||
|
||||
u8 btn_read();
|
||||
u8 btn_wait();
|
||||
|
|
|
@ -42,7 +42,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
|
|||
break;
|
||||
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||
{
|
||||
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
||||
strcpy(dir_entries + (k * 256), fno.fname);
|
||||
k++;
|
||||
if (k > (max_entries - 1))
|
||||
break;
|
||||
|
@ -56,7 +56,7 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
|
|||
{
|
||||
if (!(fno.fattrib & AM_DIR) && (fno.fname[0] != '.') && (includeHiddenFiles || !(fno.fattrib & AM_HID)))
|
||||
{
|
||||
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
||||
strcpy(dir_entries + (k * 256), fno.fname);
|
||||
k++;
|
||||
if (k > (max_entries - 1))
|
||||
break;
|
||||
|
@ -81,9 +81,9 @@ char *dirlist(const char *directory, const char *pattern, bool includeHiddenFile
|
|||
{
|
||||
if (strcmp(&dir_entries[i * 256], &dir_entries[j * 256]) > 0)
|
||||
{
|
||||
memcpy(temp, &dir_entries[i * 256], strlen(&dir_entries[i * 256]) + 1);
|
||||
memcpy(&dir_entries[i * 256], &dir_entries[j * 256], strlen(&dir_entries[j * 256]) + 1);
|
||||
memcpy(&dir_entries[j * 256], temp, strlen(temp) + 1);
|
||||
strcpy(temp, &dir_entries[i * 256]);
|
||||
strcpy(&dir_entries[i * 256], &dir_entries[j * 256]);
|
||||
strcpy(&dir_entries[j * 256], temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define NULL ((void *)0)
|
||||
|
||||
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
|
||||
#define ALIGN_DOWN(x, a) (((x) - ((a) - 1)) & ~((a) - 1))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "util.h"
|
||||
#include "../gfx/di.h"
|
||||
#include "../mem/minerva.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../rtc/max77620-rtc.h"
|
||||
#include "../soc/bpmp.h"
|
||||
|
@ -26,6 +27,8 @@
|
|||
|
||||
#define USE_RTC_TIMER
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
extern void sd_unmount();
|
||||
|
||||
u32 get_tmr_s()
|
||||
|
@ -100,6 +103,8 @@ void reboot_normal()
|
|||
sd_unmount();
|
||||
display_end();
|
||||
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
|
||||
panic(0x21); // Bypass fuse programming in package1.
|
||||
}
|
||||
|
||||
|
@ -110,6 +115,8 @@ void reboot_rcm()
|
|||
sd_unmount();
|
||||
display_end();
|
||||
|
||||
nyx_str->mtc_cfg.init_done = 0;
|
||||
|
||||
PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm.
|
||||
PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (C) 2018 CTCaer
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -21,6 +21,9 @@
|
|||
#include "types.h"
|
||||
#include "../mem/minerva.h"
|
||||
|
||||
#define NYX_CFG_DUMP (1 << 7)
|
||||
#define NYX_CFG_MINERVA (1 << 8)
|
||||
|
||||
#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \
|
||||
((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000))
|
||||
|
||||
|
|
Loading…
Reference in a new issue