Merge newer hekate commits

This commit is contained in:
shchmue 2019-05-11 17:51:44 -04:00
parent 3b797318f5
commit 1bc5c2a667
19 changed files with 155 additions and 459 deletions

View file

@ -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 $@

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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];

View file

@ -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();

View file

@ -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)) {

View file

@ -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,32 +74,29 @@ 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);
void *buf = malloc(size); if (fsize)
*fsize = size;
u8 *ptr = buf; void *buf = malloc(size);
while (size > 0)
{
u32 rsize = MIN(size, 512 * 512);
if (f_read(&fp, ptr, rsize, NULL) != FR_OK)
{
free(buf);
return NULL;
}
ptr += rsize; if (f_read(&fp, buf, size, NULL) != FR_OK)
size -= rsize; {
} free(buf);
f_close(&fp);
f_close(&fp); return NULL;
}
return buf; f_close(&fp);
return buf;
} }
int sd_save_to_file(void *buf, u32 size, const char *filename) int sd_save_to_file(void *buf, u32 size, const char *filename)
@ -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);

View file

@ -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);
}

View file

@ -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_ */

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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"

View file

@ -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;
@ -704,7 +708,7 @@ int _sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf)
u32 tmp = 0; u32 tmp = 0;
sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1); sdmmc_get_rsp(storage->sdmmc, &tmp, 4, SDMMC_RSP_TYPE_1);
//Prepare buffer for unstuff_bits //Prepare buffer for unstuff_bits
for (int i = 0; i < 8; i+=4) for (int i = 0; i < 8; i+=4)
{ {
storage->raw_scr[i + 3] = buf[i]; storage->raw_scr[i + 3] = buf[i];
@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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