mirror of
https://github.com/Decscots/Lockpick_RCM.git
synced 2024-11-25 16:56:56 +01:00
Merge newer hekate commits
This commit is contained in:
parent
3b797318f5
commit
1bc5c2a667
91
Makefile
91
Makefile
@ -4,56 +4,57 @@ endif
|
|||||||
|
|
||||||
include $(DEVKITARM)/base_rules
|
include $(DEVKITARM)/base_rules
|
||||||
|
|
||||||
IPL_LOAD_ADDR := 0x40003000
|
################################################################################
|
||||||
|
|
||||||
TARGET := Lockpick_RCM
|
IPL_LOAD_ADDR := 0x40003000
|
||||||
LPVERSION_MAJOR := 1
|
LPVERSION_MAJOR := 1
|
||||||
LPVERSION_MINOR := 1
|
LPVERSION_MINOR := 1
|
||||||
LPVERSION_BUGFX := 1
|
LPVERSION_BUGFX := 1
|
||||||
|
|
||||||
BUILD := build
|
################################################################################
|
||||||
OUTPUT := output
|
|
||||||
|
TARGET := Lockpick_RCM
|
||||||
|
BUILDDIR := build
|
||||||
|
OUTPUTDIR := output
|
||||||
SOURCEDIR = source
|
SOURCEDIR = source
|
||||||
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||||
|
|
||||||
OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
|
# Main and graphics.
|
||||||
|
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||||
start.o \
|
start.o \
|
||||||
main.o \
|
main.o heap.o \
|
||||||
keys.o \
|
keys.o \
|
||||||
heap.o \
|
|
||||||
btn.o \
|
|
||||||
clock.o \
|
|
||||||
cluster.o \
|
|
||||||
fuse.o \
|
|
||||||
gpio.o \
|
|
||||||
sept.o \
|
|
||||||
i2c.o \
|
|
||||||
max7762x.o \
|
|
||||||
max17050.o \
|
|
||||||
mc.o \
|
|
||||||
nx_emmc.o \
|
|
||||||
sdmmc.o \
|
|
||||||
sdmmc_driver.o \
|
|
||||||
sdram.o \
|
|
||||||
sdram_lp0.o \
|
|
||||||
util.o \
|
|
||||||
di.o \
|
|
||||||
gfx.o \
|
gfx.o \
|
||||||
pinmux.o \
|
|
||||||
pkg1.o \
|
|
||||||
pkg2.o \
|
|
||||||
se.o \
|
|
||||||
tsec.o \
|
|
||||||
hw_init.o \
|
|
||||||
smmu.o \
|
|
||||||
max77620-rtc.o \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
OBJS += $(addprefix $(BUILD)/$(TARGET)/, \
|
# Hardware.
|
||||||
|
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||||
|
clock.o cluster.o di.o gpio.o i2c.o mc.o sdram.o sdram_lp0.o pinmux.o se.o smmu.o tsec.o \
|
||||||
|
fuse.o \
|
||||||
|
sdmmc.o sdmmc_driver.o \
|
||||||
|
max17050.o max7762x.o max77620-rtc.o \
|
||||||
|
hw_init.o \
|
||||||
|
)
|
||||||
|
|
||||||
|
# Utilities.
|
||||||
|
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||||
|
btn.o util.o \
|
||||||
|
)
|
||||||
|
|
||||||
|
# Horizon.
|
||||||
|
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||||
|
nx_emmc.o \
|
||||||
|
pkg1.o pkg2.o sept.o \
|
||||||
|
)
|
||||||
|
|
||||||
|
# Libraries.
|
||||||
|
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||||
lz.o blz.o \
|
lz.o blz.o \
|
||||||
diskio.o ff.o ffunicode.o ffsystem.o \
|
diskio.o ff.o ffunicode.o ffsystem.o \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||||
CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR) -DLP_VER_BF=$(LPVERSION_BUGFX)
|
CUSTOMDEFINES += -DLP_VER_MJ=$(LPVERSION_MAJOR) -DLP_VER_MN=$(LPVERSION_MINOR) -DLP_VER_BF=$(LPVERSION_BUGFX)
|
||||||
|
|
||||||
@ -63,32 +64,34 @@ LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defs
|
|||||||
|
|
||||||
MODULEDIRS := $(wildcard modules/*)
|
MODULEDIRS := $(wildcard modules/*)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
.PHONY: all clean $(MODULEDIRS)
|
.PHONY: all clean $(MODULEDIRS)
|
||||||
|
|
||||||
all: $(TARGET).bin
|
all: $(TARGET).bin
|
||||||
@echo -n "Payload size is "
|
@echo -n "Payload size is "
|
||||||
@wc -c < $(OUTPUT)/$(TARGET).bin
|
@wc -c < $(OUTPUTDIR)/$(TARGET).bin
|
||||||
@echo "Max size is 126296 Bytes."
|
@echo "Max size is 126296 Bytes."
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf $(OBJS)
|
@rm -rf $(OBJS)
|
||||||
@rm -rf $(BUILD)
|
@rm -rf $(BUILDDIR)
|
||||||
@rm -rf $(OUTPUT)
|
@rm -rf $(OUTPUTDIR)
|
||||||
|
|
||||||
$(MODULEDIRS):
|
$(MODULEDIRS):
|
||||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||||
|
|
||||||
$(TARGET).bin: $(BUILD)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)
|
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS)
|
||||||
$(OBJCOPY) -S -O binary $< $(OUTPUT)/$@
|
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||||
|
|
||||||
$(BUILD)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||||
$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||||
|
|
||||||
$(BUILD)/$(TARGET)/%.o: %.c
|
$(BUILDDIR)/$(TARGET)/%.o: %.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(BUILD)/$(TARGET)/%.o: %.S
|
$(BUILDDIR)/$(TARGET)/%.o: %.S
|
||||||
@mkdir -p "$(BUILD)"
|
@mkdir -p "$(BUILDDIR)"
|
||||||
@mkdir -p "$(BUILD)/$(TARGET)"
|
@mkdir -p "$(BUILDDIR)/$(TARGET)"
|
||||||
@mkdir -p "$(OUTPUT)"
|
@mkdir -p "$(OUTPUTDIR)"
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (C) 2018-2019 CTCaer
|
||||||
* Copyright (c) 2019 shchmue
|
* Copyright (c) 2019 shchmue
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@ -306,7 +306,7 @@ static void _gfx_putn(u32 v, int base, char fill, int fcnt)
|
|||||||
gfx_puts(p);
|
gfx_puts(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx_put_small_sep(gfx_con_t *con)
|
void gfx_put_small_sep()
|
||||||
{
|
{
|
||||||
u8 prevFontSize = gfx_con.fntsz;
|
u8 prevFontSize = gfx_con.fntsz;
|
||||||
gfx_con.fntsz = 8;
|
gfx_con.fntsz = 8;
|
||||||
@ -314,7 +314,7 @@ void gfx_put_small_sep(gfx_con_t *con)
|
|||||||
gfx_con.fntsz = prevFontSize;
|
gfx_con.fntsz = prevFontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx_put_big_sep(gfx_con_t *con)
|
void gfx_put_big_sep()
|
||||||
{
|
{
|
||||||
u8 prevFontSize = gfx_con.fntsz;
|
u8 prevFontSize = gfx_con.fntsz;
|
||||||
gfx_con.fntsz = 16;
|
gfx_con.fntsz = 16;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (C) 2018-2019 CTCaer
|
||||||
* Copyright (C) 2018 M4xw
|
* Copyright (C) 2018 M4xw
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@ -41,8 +41,8 @@ void gfx_hexdump(u32 base, const u8 *buf, u32 len);
|
|||||||
|
|
||||||
void gfx_set_pixel(u32 x, u32 y, u32 color);
|
void gfx_set_pixel(u32 x, u32 y, u32 color);
|
||||||
void gfx_line(int x0, int y0, int x1, int y1, u32 color);
|
void gfx_line(int x0, int y0, int x1, int y1, u32 color);
|
||||||
void gfx_put_small_sep(gfx_con_t *con);
|
void gfx_put_small_sep();
|
||||||
void gfx_put_big_sep(gfx_con_t *con);
|
void gfx_put_big_sep();
|
||||||
void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||||
void gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
void gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||||
void gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
void gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
|
||||||
|
@ -41,11 +41,15 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
|
|||||||
|
|
||||||
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2)
|
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2)
|
||||||
{
|
{
|
||||||
u8 *ptr = pkg2->data;
|
u8 *ptr;
|
||||||
if (pkg2->sec_size[PKG2_SEC_INI1] == 0)
|
// Check for new pkg2 type.
|
||||||
ptr += *(u32 *)(ptr + 0x168);
|
if (!pkg2->sec_size[PKG2_SEC_INI1])
|
||||||
|
{
|
||||||
|
u32 kernel_ini1_off = *(u32 *)(pkg2->data + PKG2_NEWKERN_INI1_START);
|
||||||
|
ptr = pkg2->data + kernel_ini1_off;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ptr += pkg2->sec_size[PKG2_SEC_KERNEL];
|
ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL];
|
||||||
|
|
||||||
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
|
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
|
||||||
ptr += sizeof(pkg2_ini1_t);
|
ptr += sizeof(pkg2_ini1_t);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
* Copyright (C) 2018 CTCaer
|
* Copyright (C) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@ -26,6 +26,8 @@
|
|||||||
#define PKG2_SEC_KERNEL 0
|
#define PKG2_SEC_KERNEL 0
|
||||||
#define PKG2_SEC_INI1 1
|
#define PKG2_SEC_INI1 1
|
||||||
|
|
||||||
|
#define PKG2_NEWKERN_INI1_START 0x168
|
||||||
|
|
||||||
typedef struct _pkg2_hdr_t
|
typedef struct _pkg2_hdr_t
|
||||||
{
|
{
|
||||||
u8 ctr[0x10];
|
u8 ctr[0x10];
|
||||||
|
@ -90,7 +90,7 @@ int reboot_to_sept(const u8 *tsec_fw)
|
|||||||
}
|
}
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
|
||||||
// Save auto boot config to payload, if any.
|
// Save auto boot config to sept payload, if any.
|
||||||
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
||||||
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
|
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
|
||||||
|
|
||||||
@ -125,10 +125,8 @@ int reboot_to_sept(const u8 *tsec_fw)
|
|||||||
|
|
||||||
(*sept)();
|
(*sept)();
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
EPRINTF("Sept payloads not found in sd:/sept!\nPlace appropriate files and try again.");
|
EPRINTF("Sept files not found in sd:/sept!\nPlace appropriate files and try again.");
|
||||||
display_backlight_brightness(100, 1000);
|
display_backlight_brightness(100, 1000);
|
||||||
|
|
||||||
btn_wait();
|
btn_wait();
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
|
|
||||||
extern bool sd_mount();
|
extern bool sd_mount();
|
||||||
extern void sd_unmount();
|
extern void sd_unmount();
|
||||||
extern void *sd_file_read(char *path);
|
|
||||||
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
extern int sd_save_to_file(void *buf, u32 size, const char *filename);
|
||||||
extern void power_off();
|
extern void power_off();
|
||||||
extern void reboot_normal();
|
extern void reboot_normal();
|
||||||
@ -228,7 +227,7 @@ static u32 _sprintf(char *buffer, const char *fmt, ...);
|
|||||||
|
|
||||||
void dump_keys() {
|
void dump_keys() {
|
||||||
display_backlight_brightness(100, 1000);
|
display_backlight_brightness(100, 1000);
|
||||||
gfx_clear_partial_grey(0x1B, 0, 1280);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
|
|
||||||
gfx_printf("[%kLo%kck%kpi%kck%k-R%kCM%k v%d.%d.%d%k]\n\n",
|
gfx_printf("[%kLo%kck%kpi%kck%k-R%kCM%k v%d.%d.%d%k]\n\n",
|
||||||
@ -764,14 +763,14 @@ pkg2_done:
|
|||||||
}
|
}
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
|
||||||
if (f_open(&fp, "emmc:/save/8000000000000043", FA_READ | FA_OPEN_EXISTING) || f_stat("emmc:/save/8000000000000043", &fno)) {
|
if (f_open(&fp, "emmc:/save/8000000000000043", FA_READ | FA_OPEN_EXISTING)) {
|
||||||
EPRINTF("Failed to open ns_appman save.");
|
EPRINTF("Failed to open ns_appman save.");
|
||||||
goto dismount;
|
goto dismount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// locate sd seed
|
// locate sd seed
|
||||||
u8 read_buf[0x20] = {0};
|
u8 read_buf[0x20] = {0};
|
||||||
for (u32 i = 0; i < fno.fsize; i += 0x4000) {
|
for (u32 i = 0; i < f_size(&fp); i += 0x4000) {
|
||||||
if (f_lseek(&fp, i) || f_read(&fp, read_buf, 0x20, &read_bytes) || read_bytes != 0x20)
|
if (f_lseek(&fp, i) || f_read(&fp, read_buf, 0x20, &read_bytes) || read_bytes != 0x20)
|
||||||
break;
|
break;
|
||||||
if (!memcmp(temp_key, read_buf, 0x10)) {
|
if (!memcmp(temp_key, read_buf, 0x10)) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 naehrwert
|
* Copyright (c) 2018 naehrwert
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018 CTCaer
|
* Copyright (c) 2018-2019 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@ -74,27 +74,24 @@ void sd_unmount()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *sd_file_read(char *path)
|
void *sd_file_read(const char *path, u32 *fsize)
|
||||||
{
|
{
|
||||||
FIL fp;
|
FIL fp;
|
||||||
if (f_open(&fp, path, FA_READ) != FR_OK)
|
if (f_open(&fp, path, FA_READ) != FR_OK)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
u32 size = f_size(&fp);
|
u32 size = f_size(&fp);
|
||||||
|
if (fsize)
|
||||||
|
*fsize = size;
|
||||||
|
|
||||||
void *buf = malloc(size);
|
void *buf = malloc(size);
|
||||||
|
|
||||||
u8 *ptr = buf;
|
if (f_read(&fp, buf, size, NULL) != FR_OK)
|
||||||
while (size > 0)
|
|
||||||
{
|
|
||||||
u32 rsize = MIN(size, 512 * 512);
|
|
||||||
if (f_read(&fp, ptr, rsize, NULL) != FR_OK)
|
|
||||||
{
|
{
|
||||||
free(buf);
|
free(buf);
|
||||||
return NULL;
|
f_close(&fp);
|
||||||
}
|
|
||||||
|
|
||||||
ptr += rsize;
|
return NULL;
|
||||||
size -= rsize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
@ -150,8 +147,8 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
|||||||
|
|
||||||
extern void pivot_stack(u32 stack_top);
|
extern void pivot_stack(u32 stack_top);
|
||||||
|
|
||||||
void ipl_main() {
|
void ipl_main()
|
||||||
|
{
|
||||||
config_hw();
|
config_hw();
|
||||||
pivot_stack(IPL_STACK_TOP);
|
pivot_stack(IPL_STACK_TOP);
|
||||||
heap_init(IPL_HEAP_START);
|
heap_init(IPL_HEAP_START);
|
||||||
|
@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
|
||||||
*
|
|
||||||
* 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,
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bq24193.h"
|
|
||||||
#include "../soc/i2c.h"
|
|
||||||
#include "../utils/util.h"
|
|
||||||
|
|
||||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value)
|
|
||||||
{
|
|
||||||
u8 data;
|
|
||||||
|
|
||||||
switch (prop) {
|
|
||||||
case BQ24193_InputVoltageLimit: // Input voltage limit (mV).
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);
|
|
||||||
data = (data & BQ24193_INCONFIG_VINDPM_MASK) >> 3;
|
|
||||||
*value += ((data >> 0) & 1) ? 80 : 0;
|
|
||||||
*value += ((data >> 1) & 1) ? 160 : 0;
|
|
||||||
*value += ((data >> 2) & 1) ? 320 : 0;
|
|
||||||
*value += ((data >> 3) & 1) ? 640 : 0;
|
|
||||||
*value += 3880;
|
|
||||||
break;
|
|
||||||
case BQ24193_InputCurrentLimit: // Input current limit (mA).
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_InputSource);
|
|
||||||
data &= BQ24193_INCONFIG_INLIMIT_MASK;
|
|
||||||
switch (data)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
*value = 100;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
*value = 150;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*value = 500;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
*value = 900;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
*value = 1200;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
*value = 1500;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
*value = 2000;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
*value = 3000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BQ24193_SystemMinimumVoltage: // Minimum system voltage limit (mV).
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_PORConfig);
|
|
||||||
*value = (data & BQ24193_PORCONFIG_SYSMIN_MASK) >> 1;
|
|
||||||
*value *= 100;
|
|
||||||
*value += 3000;
|
|
||||||
break;
|
|
||||||
case BQ24193_FastChargeCurrentLimit: // Fast charge current limit (mA).
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);
|
|
||||||
data = (data & BQ24193_CHRGCURR_ICHG_MASK) >> 2;
|
|
||||||
*value += ((data >> 0) & 1) ? 64 : 0;
|
|
||||||
*value += ((data >> 1) & 1) ? 128 : 0;
|
|
||||||
*value += ((data >> 2) & 1) ? 256 : 0;
|
|
||||||
*value += ((data >> 3) & 1) ? 512 : 0;
|
|
||||||
*value += ((data >> 4) & 1) ? 1024 : 0;
|
|
||||||
*value += ((data >> 5) & 1) ? 2048 : 0;
|
|
||||||
*value += 512;
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgCurr);
|
|
||||||
data &= BQ24193_CHRGCURR_20PCT_MASK;
|
|
||||||
if (data)
|
|
||||||
*value = *value * 20 / 100; // Fast charge current limit is 20%.
|
|
||||||
break;
|
|
||||||
case BQ24193_ChargeVoltageLimit: // Charge voltage limit (mV).
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);
|
|
||||||
data = (data & BQ24193_CHRGVOLT_VREG) >> 2;
|
|
||||||
*value += ((data >> 0) & 1) ? 16 : 0;
|
|
||||||
*value += ((data >> 1) & 1) ? 32 : 0;
|
|
||||||
*value += ((data >> 2) & 1) ? 64 : 0;
|
|
||||||
*value += ((data >> 3) & 1) ? 128 : 0;
|
|
||||||
*value += ((data >> 4) & 1) ? 256 : 0;
|
|
||||||
*value += ((data >> 5) & 1) ? 512 : 0;
|
|
||||||
*value += 3504;
|
|
||||||
break;
|
|
||||||
case BQ24193_RechargeThreshold: // Recharge voltage threshold less than voltage limit (mV).
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgVolt);
|
|
||||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
|
||||||
if (data)
|
|
||||||
*value = 300;
|
|
||||||
else
|
|
||||||
*value = 100;
|
|
||||||
break;
|
|
||||||
case BQ24193_ThermalRegulation: // Thermal regulation threshold (oC).
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_IRCompThermal);
|
|
||||||
data &= BQ24193_IRTHERMAL_THERM_MASK;
|
|
||||||
switch (data)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
*value = 60;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
*value = 80;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*value = 100;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
*value = 120;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BQ24193_ChargeStatus: // 0: Not charging, 1: Pre-charge, 2: Fast charging, 3: Charge termination done
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Status);
|
|
||||||
*value = (data & BQ24193_STATUS_CHRG_MASK) >> 4;
|
|
||||||
break;
|
|
||||||
case BQ24193_TempStatus: // 0: Normal, 2: Warm, 3: Cool, 5: Cold, 6: Hot.
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_FaultReg);
|
|
||||||
*value = data & BQ24193_FAULT_THERM_MASK;
|
|
||||||
break;
|
|
||||||
case BQ24193_DevID: // Dev ID.
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);
|
|
||||||
*value = data & BQ24193_VENDORPART_DEV_MASK;
|
|
||||||
break;
|
|
||||||
case BQ24193_ProductNumber: // Product number.
|
|
||||||
data = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_VendorPart);
|
|
||||||
*value = (data & BQ24193_VENDORPART_PN_MASK) >> 3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bq24193_fake_battery_removal()
|
|
||||||
{
|
|
||||||
u8 value;
|
|
||||||
|
|
||||||
// Disable watchdog to keep BATFET disabled.
|
|
||||||
value = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer);
|
|
||||||
value &= ~BQ24193_CHRGTERM_WATCHDOG_MASK;
|
|
||||||
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_ChrgTermTimer, value);
|
|
||||||
|
|
||||||
// Force BATFET to disabled state. This disconnects the battery from the system.
|
|
||||||
value = i2c_recv_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc);
|
|
||||||
value |= BQ24193_MISC_BATFET_DI_MASK;
|
|
||||||
i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_Misc, value);
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Battery charger driver for Nintendo Switch's TI BQ24193
|
|
||||||
*
|
|
||||||
* 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,
|
|
||||||
* 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 __BQ24193_H_
|
|
||||||
#define __BQ24193_H_
|
|
||||||
|
|
||||||
#define BQ24193_I2C_ADDR 0x6B
|
|
||||||
|
|
||||||
// REG 0 masks.
|
|
||||||
#define BQ24193_INCONFIG_INLIMIT_MASK (7<<0)
|
|
||||||
#define BQ24193_INCONFIG_VINDPM_MASK 0x78
|
|
||||||
#define BQ24193_INCONFIG_HIZ_EN_MASK (1<<7)
|
|
||||||
|
|
||||||
// REG 1 masks.
|
|
||||||
#define BQ24193_PORCONFIG_BOOST_MASK (1<<0)
|
|
||||||
#define BQ24193_PORCONFIG_SYSMIN_MASK (7<<1)
|
|
||||||
#define BQ24193_PORCONFIG_CHGCONFIG_MASK (3<<4)
|
|
||||||
#define BQ24193_PORCONFIG_I2CWATCHDOG_MASK (1<<6)
|
|
||||||
#define BQ24193_PORCONFIG_RESET_MASK (1<<7)
|
|
||||||
|
|
||||||
// REG 2 masks.
|
|
||||||
#define BQ24193_CHRGCURR_20PCT_MASK (1<<0)
|
|
||||||
#define BQ24193_CHRGCURR_ICHG_MASK 0xFC
|
|
||||||
|
|
||||||
// REG 3 masks.
|
|
||||||
#define BQ24193_PRECHRG_ITERM 0x0F
|
|
||||||
#define BQ24193_PRECHRG_IPRECHG 0xF0
|
|
||||||
|
|
||||||
// REG 4 masks.
|
|
||||||
#define BQ24193_CHRGVOLT_VTHRES (1<<0)
|
|
||||||
#define BQ24193_CHRGVOLT_BATTLOW (1<<1)
|
|
||||||
#define BQ24193_CHRGVOLT_VREG 0xFC
|
|
||||||
|
|
||||||
// REG 5 masks.
|
|
||||||
#define BQ24193_CHRGTERM_ISET_MASK (1<<0)
|
|
||||||
#define BQ24193_CHRGTERM_CHGTIMER_MASK (3<<1)
|
|
||||||
#define BQ24193_CHRGTERM_ENTIMER_MASK (1<<3)
|
|
||||||
#define BQ24193_CHRGTERM_WATCHDOG_MASK (3<<4)
|
|
||||||
#define BQ24193_CHRGTERM_TERM_ST_MASK (1<<6)
|
|
||||||
#define BQ24193_CHRGTERM_TERM_EN_MASK (1<<7)
|
|
||||||
|
|
||||||
// REG 6 masks.
|
|
||||||
#define BQ24193_IRTHERMAL_THERM_MASK (3<<0)
|
|
||||||
#define BQ24193_IRTHERMAL_VCLAMP_MASK (7<<2)
|
|
||||||
#define BQ24193_IRTHERMAL_BATTCOMP_MASK (7<<5)
|
|
||||||
|
|
||||||
// REG 7 masks.
|
|
||||||
#define BQ24193_MISC_INT_MASK (3<<0)
|
|
||||||
#define BQ24193_MISC_VSET_MASK (1<<4)
|
|
||||||
#define BQ24193_MISC_BATFET_DI_MASK (1<<5)
|
|
||||||
#define BQ24193_MISC_TMR2X_EN_MASK (1<<6)
|
|
||||||
#define BQ24193_MISC_DPDM_EN_MASK (1<<7)
|
|
||||||
|
|
||||||
// REG 8 masks.
|
|
||||||
#define BQ24193_STATUS_VSYS_MASK (1<<0)
|
|
||||||
#define BQ24193_STATUS_THERM_MASK (1<<1)
|
|
||||||
#define BQ24193_STATUS_PG_MASK (1<<2)
|
|
||||||
#define BQ24193_STATUS_DPM_MASK (1<<3)
|
|
||||||
#define BQ24193_STATUS_CHRG_MASK (3<<4)
|
|
||||||
#define BQ24193_STATUS_VBUS_MASK (3<<6)
|
|
||||||
|
|
||||||
// REG 9 masks.
|
|
||||||
#define BQ24193_FAULT_THERM_MASK (7<<0)
|
|
||||||
#define BQ24193_FAULT_BATT_OVP_MASK (1<<3)
|
|
||||||
#define BQ24193_FAULT_CHARGE_MASK (3<<4)
|
|
||||||
#define BQ24193_FAULT_BOOST_MASK (1<<6)
|
|
||||||
#define BQ24193_FAULT_WATCHDOG_MASK (1<<7)
|
|
||||||
|
|
||||||
// REG A masks.
|
|
||||||
#define BQ24193_VENDORPART_DEV_MASK (3<<0)
|
|
||||||
#define BQ24193_VENDORPART_PN_MASK (7<<3)
|
|
||||||
|
|
||||||
enum BQ24193_reg {
|
|
||||||
BQ24193_InputSource = 0x00,
|
|
||||||
BQ24193_PORConfig = 0x01,
|
|
||||||
BQ24193_ChrgCurr = 0x02,
|
|
||||||
BQ24193_PreChrgTerm = 0x03,
|
|
||||||
BQ24193_ChrgVolt = 0x04,
|
|
||||||
BQ24193_ChrgTermTimer = 0x05,
|
|
||||||
BQ24193_IRCompThermal = 0x06,
|
|
||||||
BQ24193_Misc = 0x07,
|
|
||||||
BQ24193_Status = 0x08,
|
|
||||||
BQ24193_FaultReg = 0x09,
|
|
||||||
BQ24193_VendorPart = 0x0A,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BQ24193_reg_prop {
|
|
||||||
BQ24193_InputVoltageLimit, // REG 0.
|
|
||||||
BQ24193_InputCurrentLimit, // REG 0.
|
|
||||||
BQ24193_SystemMinimumVoltage, // REG 1.
|
|
||||||
BQ24193_FastChargeCurrentLimit, // REG 2.
|
|
||||||
BQ24193_ChargeVoltageLimit, // REG 4.
|
|
||||||
BQ24193_RechargeThreshold, // REG 4.
|
|
||||||
BQ24193_ThermalRegulation, // REG 6.
|
|
||||||
BQ24193_ChargeStatus, // REG 8.
|
|
||||||
BQ24193_TempStatus, // REG 9.
|
|
||||||
BQ24193_DevID, // REG A.
|
|
||||||
BQ24193_ProductNumber, // REG A.
|
|
||||||
};
|
|
||||||
|
|
||||||
int bq24193_get_property(enum BQ24193_reg_prop prop, int *value);
|
|
||||||
void bq24193_fake_battery_removal();
|
|
||||||
|
|
||||||
#endif /* __BQ24193_H_ */
|
|
@ -28,7 +28,7 @@
|
|||||||
#include "../mem/mc.h"
|
#include "../mem/mc.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
/* #include "../gfx/gfx.h" */
|
// #include "../gfx/gfx.h"
|
||||||
|
|
||||||
static int _tsec_dma_wait_idle()
|
static int _tsec_dma_wait_idle()
|
||||||
{
|
{
|
||||||
@ -187,7 +187,8 @@ int tsec_query(u8 *tsec_keys, u8 kb, tsec_ctxt_t *tsec_ctxt)
|
|||||||
{
|
{
|
||||||
smmu_flush_all();
|
smmu_flush_all();
|
||||||
|
|
||||||
if (k != se[SE_KEYTABLE_DATA0_REG_OFFSET / 4]) {
|
if (k != se[SE_KEYTABLE_DATA0_REG_OFFSET / 4])
|
||||||
|
{
|
||||||
k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
|
k = se[SE_KEYTABLE_DATA0_REG_OFFSET / 4];
|
||||||
key[kidx++] = k;
|
key[kidx++] = k;
|
||||||
}
|
}
|
||||||
|
@ -364,10 +364,12 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
|||||||
|
|
||||||
static u32 _clock_sdmmc_table[8] = { 0 };
|
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_source_inner(u32 *pout, u32 id, u32 val)
|
||||||
{
|
{
|
||||||
u32 divisor = 0;
|
u32 divisor = 0;
|
||||||
u32 source = 0;
|
u32 source = PLLP_OUT0;
|
||||||
|
|
||||||
switch (val)
|
switch (val)
|
||||||
{
|
{
|
||||||
@ -414,16 +416,16 @@ static int _clock_sdmmc_config_clock_source_inner(u32 *pout, u32 id, u32 val)
|
|||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case SDMMC_1:
|
case SDMMC_1:
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = source | divisor;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
|
||||||
break;
|
break;
|
||||||
case SDMMC_2:
|
case SDMMC_2:
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = source | divisor;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
|
||||||
break;
|
break;
|
||||||
case SDMMC_3:
|
case SDMMC_3:
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = source | divisor;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
|
||||||
break;
|
break;
|
||||||
case SDMMC_4:
|
case SDMMC_4:
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = source | divisor;
|
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "hw_init.h"
|
#include "hw_init.h"
|
||||||
|
#include "clock.h"
|
||||||
|
#include "fuse.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "i2c.h"
|
||||||
|
#include "pinmux.h"
|
||||||
|
#include "pmc.h"
|
||||||
|
#include "t210.h"
|
||||||
#include "../gfx/di.h"
|
#include "../gfx/di.h"
|
||||||
#include "../mem/mc.h"
|
#include "../mem/mc.h"
|
||||||
#include "../mem/sdram.h"
|
#include "../mem/sdram.h"
|
||||||
@ -25,13 +32,6 @@
|
|||||||
#include "../power/max7762x.h"
|
#include "../power/max7762x.h"
|
||||||
#include "../sec/se.h"
|
#include "../sec/se.h"
|
||||||
#include "../sec/se_t210.h"
|
#include "../sec/se_t210.h"
|
||||||
#include "../soc/clock.h"
|
|
||||||
#include "../soc/fuse.h"
|
|
||||||
#include "../soc/gpio.h"
|
|
||||||
#include "../soc/i2c.h"
|
|
||||||
#include "../soc/pinmux.h"
|
|
||||||
#include "../soc/pmc.h"
|
|
||||||
#include "../soc/t210.h"
|
|
||||||
#include "../storage/sdmmc.h"
|
#include "../storage/sdmmc.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
|
||||||
|
@ -19,13 +19,15 @@
|
|||||||
#include "sdmmc.h"
|
#include "sdmmc.h"
|
||||||
#include "mmc.h"
|
#include "mmc.h"
|
||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
#include "../utils/util.h"
|
#include "../gfx/gfx.h"
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
|
#include "../utils/util.h"
|
||||||
|
|
||||||
/*#include "gfx.h"
|
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||||
#define DPRINTF(...) gfx_printf(__VA_ARGS__)*/
|
|
||||||
#define DPRINTF(...)
|
#define DPRINTF(...)
|
||||||
|
|
||||||
|
extern boot_cfg_t b_cfg;
|
||||||
|
|
||||||
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
|
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
|
||||||
{
|
{
|
||||||
const u32 mask = (size < 32 ? 1 << size : 0) - 1;
|
const u32 mask = (size < 32 ? 1 << size : 0) - 1;
|
||||||
@ -425,7 +427,7 @@ static int _mmc_storage_enable_HS400(sdmmc_storage_t *storage)
|
|||||||
static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type, u32 type)
|
static int _mmc_storage_enable_highspeed(sdmmc_storage_t *storage, u32 card_type, u32 type)
|
||||||
{
|
{
|
||||||
//TODO: this should be a config item.
|
//TODO: this should be a config item.
|
||||||
//---v
|
// --v
|
||||||
if (!1 || sdmmc_get_voltage(storage->sdmmc) != SDMMC_POWER_1_8)
|
if (!1 || sdmmc_get_voltage(storage->sdmmc) != SDMMC_POWER_1_8)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -530,7 +532,9 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
|
|||||||
DPRINTF("[MMC] BKOPS enabled\n");
|
DPRINTF("[MMC] BKOPS enabled\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
DPRINTF("[MMC] BKOPS disabled\n");
|
DPRINTF("[MMC] BKOPS disabled\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
|
if (!_mmc_storage_enable_highspeed(storage, storage->ext_csd.card_type, type))
|
||||||
return 0;
|
return 0;
|
||||||
@ -831,6 +835,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 11:
|
case 11:
|
||||||
|
// Fall through if not supported.
|
||||||
if (buf[13] & SD_MODE_UHS_SDR104)
|
if (buf[13] & SD_MODE_UHS_SDR104)
|
||||||
{
|
{
|
||||||
type = 11;
|
type = 11;
|
||||||
@ -839,7 +844,6 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8
|
|||||||
storage->csd.busspeed = 104;
|
storage->csd.busspeed = 104;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//Fall through.
|
|
||||||
case 10:
|
case 10:
|
||||||
if (buf[13] & SD_MODE_UHS_SDR50)
|
if (buf[13] & SD_MODE_UHS_SDR50)
|
||||||
{
|
{
|
||||||
@ -876,7 +880,7 @@ int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf)
|
|||||||
if (!_sd_storage_switch_get(storage, buf))
|
if (!_sd_storage_switch_get(storage, buf))
|
||||||
return 0;
|
return 0;
|
||||||
//gfx_hexdump(0, (u8 *)buf, 64);
|
//gfx_hexdump(0, (u8 *)buf, 64);
|
||||||
if (!(buf[13] & 2))
|
if (!(buf[13] & SD_MODE_HIGH_SPEED))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!_sd_storage_enable_highspeed(storage, 1, buf))
|
if (!_sd_storage_enable_highspeed(storage, 1, buf))
|
||||||
@ -1011,6 +1015,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
|
|||||||
{
|
{
|
||||||
int is_version_1 = 0;
|
int is_version_1 = 0;
|
||||||
|
|
||||||
|
// Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms.
|
||||||
|
u32 sd_poweroff_time = (u32)get_tmr_ms() - b_cfg.sd_timeoff;
|
||||||
|
if (id == SDMMC_1 && (sd_poweroff_time < 100))
|
||||||
|
msleep(100 - sd_poweroff_time);
|
||||||
|
|
||||||
memset(storage, 0, sizeof(sdmmc_storage_t));
|
memset(storage, 0, sizeof(sdmmc_storage_t));
|
||||||
storage->sdmmc = sdmmc;
|
storage->sdmmc = sdmmc;
|
||||||
|
|
||||||
@ -1103,7 +1112,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
|
|||||||
DPRINTF("[SD] switched to wide bus width\n");
|
DPRINTF("[SD] switched to wide bus width\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
DPRINTF("[SD] SD does not support wide bus width\n");
|
DPRINTF("[SD] SD does not support wide bus width\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (storage->is_low_voltage)
|
if (storage->is_low_voltage)
|
||||||
{
|
{
|
||||||
@ -1129,7 +1140,9 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
|
|||||||
|
|
||||||
// Parse additional card info from sd status.
|
// Parse additional card info from sd status.
|
||||||
if (_sd_storage_get_ssr(storage, buf))
|
if (_sd_storage_get_ssr(storage, buf))
|
||||||
|
{
|
||||||
DPRINTF("[SD] got sd status\n");
|
DPRINTF("[SD] got sd status\n");
|
||||||
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -17,20 +17,22 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "sdmmc.h"
|
|
||||||
#include "../utils/util.h"
|
|
||||||
#include "../soc/clock.h"
|
|
||||||
#include "mmc.h"
|
#include "mmc.h"
|
||||||
|
#include "sdmmc.h"
|
||||||
|
#include "../gfx/gfx.h"
|
||||||
#include "../power/max7762x.h"
|
#include "../power/max7762x.h"
|
||||||
#include "../soc/t210.h"
|
#include "../soc/clock.h"
|
||||||
#include "../soc/pmc.h"
|
|
||||||
#include "../soc/pinmux.h"
|
|
||||||
#include "../soc/gpio.h"
|
#include "../soc/gpio.h"
|
||||||
|
#include "../soc/pinmux.h"
|
||||||
|
#include "../soc/pmc.h"
|
||||||
|
#include "../soc/t210.h"
|
||||||
|
#include "../utils/util.h"
|
||||||
|
|
||||||
/*#include "gfx.h"
|
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||||
#define DPRINTF(...) gfx_printf(__VA_ARGS__)*/
|
|
||||||
#define DPRINTF(...)
|
#define DPRINTF(...)
|
||||||
|
|
||||||
|
extern boot_cfg_t b_cfg;
|
||||||
|
|
||||||
/*! SCMMC controller base addresses. */
|
/*! SCMMC controller base addresses. */
|
||||||
static const u32 _sdmmc_bases[4] = {
|
static const u32 _sdmmc_bases[4] = {
|
||||||
0x700B0000,
|
0x700B0000,
|
||||||
@ -116,7 +118,7 @@ static int _sdmmc_config_ven_ceata_clk(sdmmc_t *sdmmc, u32 id)
|
|||||||
|
|
||||||
if (id == 4)
|
if (id == 4)
|
||||||
sdmmc->regs->venceatactl = (sdmmc->regs->venceatactl & 0xFFFFC0FF) | 0x2800;
|
sdmmc->regs->venceatactl = (sdmmc->regs->venceatactl & 0xFFFFC0FF) | 0x2800;
|
||||||
sdmmc->regs->field_1C0 &= 0xFFFDFFFF;
|
sdmmc->regs->ventunctl0 &= 0xFFFDFFFF;
|
||||||
if (id == 4)
|
if (id == 4)
|
||||||
{
|
{
|
||||||
if (!sdmmc->venclkctl_set)
|
if (!sdmmc->venclkctl_set)
|
||||||
@ -168,11 +170,11 @@ static int _sdmmc_wait_type4(sdmmc_t *sdmmc)
|
|||||||
sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;
|
sdmmc->regs->clkcon |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdmmc->regs->field_1B0 |= 0x80000000;
|
sdmmc->regs->vendllcal |= 0x80000000;
|
||||||
_sdmmc_get_clkcon(sdmmc);
|
_sdmmc_get_clkcon(sdmmc);
|
||||||
|
|
||||||
u32 timeout = get_tmr_ms() + 5;
|
u32 timeout = get_tmr_ms() + 5;
|
||||||
while (sdmmc->regs->field_1B0 & 0x80000000)
|
while (sdmmc->regs->vendllcal & 0x80000000)
|
||||||
{
|
{
|
||||||
if (get_tmr_ms() > timeout)
|
if (get_tmr_ms() > timeout)
|
||||||
{
|
{
|
||||||
@ -182,7 +184,7 @@ static int _sdmmc_wait_type4(sdmmc_t *sdmmc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
timeout = get_tmr_ms() + 10;
|
timeout = get_tmr_ms() + 10;
|
||||||
while (sdmmc->regs->field_1BC & 0x80000000)
|
while (sdmmc->regs->dllcfgstatus & 0x80000000)
|
||||||
{
|
{
|
||||||
if (get_tmr_ms() > timeout)
|
if (get_tmr_ms() > timeout)
|
||||||
{
|
{
|
||||||
@ -561,9 +563,9 @@ int sdmmc_config_tuning(sdmmc_t *sdmmc, u32 type, u32 cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdmmc->regs->field_1C0 = (sdmmc->regs->field_1C0 & 0xFFFF1FFF) | flag;
|
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag;
|
||||||
sdmmc->regs->field_1C0 = (sdmmc->regs->field_1C0 & 0xFFFFE03F) | 0x40;
|
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | 0x40;
|
||||||
sdmmc->regs->field_1C0 |= 0x20000;
|
sdmmc->regs->ventunctl0 |= 0x20000;
|
||||||
sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING;
|
sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING;
|
||||||
|
|
||||||
for (u32 i = 0; i < max; i++)
|
for (u32 i = 0; i < max; i++)
|
||||||
@ -1000,8 +1002,8 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n
|
|||||||
sdmmc->clock_stopped = 0;
|
sdmmc->clock_stopped = 0;
|
||||||
|
|
||||||
//TODO: make this skip-able.
|
//TODO: make this skip-able.
|
||||||
sdmmc->regs->field_1F0 |= 0x80000;
|
sdmmc->regs->iospare |= 0x80000;
|
||||||
sdmmc->regs->field_1AC &= 0xFFFFFFFB;
|
sdmmc->regs->veniotrimctl &= 0xFFFFFFFB;
|
||||||
static const u32 trim_values[] = { 2, 8, 3, 8 };
|
static const u32 trim_values[] = { 2, 8, 3, 8 };
|
||||||
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFF) | (trim_values[sdmmc->id] << 24);
|
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFF) | (trim_values[sdmmc->id] << 24);
|
||||||
sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7;
|
sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & 0xF) | 7;
|
||||||
@ -1036,7 +1038,9 @@ void sdmmc_end(sdmmc_t *sdmmc)
|
|||||||
if (sdmmc->id == SDMMC_1)
|
if (sdmmc->id == SDMMC_1)
|
||||||
{
|
{
|
||||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
||||||
msleep(1); // To power cycle min 1ms without power is needed.
|
max77620_regulator_enable(REGULATOR_LDO2, 0);
|
||||||
|
b_cfg.sd_timeoff = get_tmr_ms(); // Some sandisc U1 cards need 100ms for a power cycle.
|
||||||
|
msleep(1); // To power cycle, min 1ms without power is needed.
|
||||||
}
|
}
|
||||||
|
|
||||||
_sdmmc_get_clkcon(sdmmc);
|
_sdmmc_get_clkcon(sdmmc);
|
||||||
|
@ -115,18 +115,18 @@ typedef struct _t210_sdmmc_t
|
|||||||
vu32 vendebouncecnt;
|
vu32 vendebouncecnt;
|
||||||
vu32 venmiscctl;
|
vu32 venmiscctl;
|
||||||
vu32 res6[34];
|
vu32 res6[34];
|
||||||
vu32 field_1AC;
|
vu32 veniotrimctl;
|
||||||
vu32 field_1B0;
|
vu32 vendllcal;
|
||||||
vu8 res7[8];
|
vu8 res7[8];
|
||||||
vu32 field_1BC;
|
vu32 dllcfgstatus;
|
||||||
vu32 field_1C0;
|
vu32 ventunctl0;
|
||||||
vu32 field_1C4;
|
vu32 field_1C4;
|
||||||
vu8 field_1C8[24];
|
vu8 field_1C8[24];
|
||||||
vu32 sdmemcmppadctl;
|
vu32 sdmemcmppadctl;
|
||||||
vu32 autocalcfg;
|
vu32 autocalcfg;
|
||||||
vu32 autocalintval;
|
vu32 autocalintval;
|
||||||
vu32 autocalsts;
|
vu32 autocalsts;
|
||||||
vu32 field_1F0;
|
vu32 iospare;
|
||||||
} t210_sdmmc_t;
|
} t210_sdmmc_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,7 +80,8 @@ typedef struct __attribute__((__packed__)) _boot_cfg_t
|
|||||||
u8 autoboot;
|
u8 autoboot;
|
||||||
u8 autoboot_list;
|
u8 autoboot_list;
|
||||||
u8 extra_cfg;
|
u8 extra_cfg;
|
||||||
u8 rsvd[128];
|
u32 sd_timeoff;
|
||||||
|
u8 rsvd[124];
|
||||||
} boot_cfg_t;
|
} boot_cfg_t;
|
||||||
|
|
||||||
typedef struct __attribute__((__packed__)) _reloc_meta_t
|
typedef struct __attribute__((__packed__)) _reloc_meta_t
|
||||||
|
@ -106,45 +106,3 @@ void power_off()
|
|||||||
//TODO: we should probably make sure all regulators are powered off properly.
|
//TODO: we should probably make sure all regulators are powered off properly.
|
||||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
|
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CRC32C_POLY 0x82F63B78
|
|
||||||
u32 crc32c(const void *buf, u32 len)
|
|
||||||
{
|
|
||||||
const u8 *cbuf = (const u8 *)buf;
|
|
||||||
u32 crc = 0xFFFFFFFF;
|
|
||||||
while (len--)
|
|
||||||
{
|
|
||||||
crc ^= *cbuf++;
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
crc = crc & 1 ? (crc >> 1) ^ CRC32C_POLY : crc >> 1;
|
|
||||||
}
|
|
||||||
return ~crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len)
|
|
||||||
{
|
|
||||||
u32 len32 = len / 4;
|
|
||||||
|
|
||||||
if (!(len32 % 32))
|
|
||||||
{
|
|
||||||
while (len32)
|
|
||||||
{
|
|
||||||
len32 -= 32;
|
|
||||||
if(buf1[len32] != buf2[len32])
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (len32)
|
|
||||||
{
|
|
||||||
len32 -= 32;
|
|
||||||
if(buf1[len32] != buf2[len32])
|
|
||||||
return 1;
|
|
||||||
if (len32 < 32)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -39,10 +39,5 @@ void reboot_normal();
|
|||||||
void reboot_rcm();
|
void reboot_rcm();
|
||||||
void power_off();
|
void power_off();
|
||||||
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops);
|
||||||
u32 crc32c(const void *buf, u32 len);
|
|
||||||
|
|
||||||
/* This is a faster implementation of memcmp that checks two u32 values */
|
|
||||||
/* every 128 Bytes block. Intented only for Backup and Restore */
|
|
||||||
u32 memcmp32sparse(const u32 *buf1, const u32 *buf2, u32 len);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user