git subrepo pull emummc

subrepo:
  subdir:   "emummc"
  merged:   "5f51fa3b"
upstream:
  origin:   "https://github.com/m4xw/emuMMC"
  branch:   "develop"
  commit:   "5f51fa3b"
git-subrepo:
  version:  "0.4.0"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "5d6aba9"
This commit is contained in:
Michael Scire
2019-06-28 11:36:07 -07:00
parent e871a754a8
commit 3a2bceef8d
40 changed files with 326 additions and 126 deletions

View File

@@ -24,11 +24,13 @@
#include "../utils/types.h"
#include "../utils/util.h"
#include "../utils/fatal.h"
#include "../emuMMC/emummc.h"
#define DPRINTF(...) //fprintf(stdout, __VA_ARGS__)
sdmmc_accessor_t *_current_accessor = NULL;
bool sdmmc_memcpy_buf = false;
extern bool custom_driver;
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
{
@@ -52,25 +54,25 @@ intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned i
char *_buf = (char *)buf;
char *actual_buf_start = _buf;
char *actual_buf_end = &_buf[512 * num_sectors];
char *dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer;
char *dma_buffer_start = _this->parent->dmaBuffers[0].device_addr_buffer;
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size])
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[0].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_EMMC;
dma_buf_idx = 0;
}
else
{
dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size])
dma_buffer_start = _this->parent->dmaBuffers[1].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[1].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_SD;
dma_buf_idx = 1;
}
else
{
dma_buffer_start = _this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer_size])
dma_buffer_start = _this->parent->dmaBuffers[2].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[2].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_GC;
dma_buf_idx = 2;
}
else
{
@@ -86,30 +88,69 @@ intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned i
return admaaddr;
}
int sdmmc_get_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors)
int sdmmc_calculate_dma_index(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors)
{
int dma_buf_idx = 0;
int blkSize = num_sectors * 512;
char *_buf = (char *)buf;
char *actual_buf_start = _buf;
char *actual_buf_end = &_buf[512 * num_sectors];
char *dma_buffer_start = _this->parent->dmaBuffers[0].device_addr_buffer;
if (_this->parent->dmaBuffers[FS_SDMMC_EMMC].device_addr_buffer_size >= blkSize)
if (dma_buffer_start <= _buf && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[0].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_EMMC;
dma_buf_idx = 0;
}
else
{
if (_this->parent->dmaBuffers[FS_SDMMC_SD].device_addr_buffer_size >= blkSize)
dma_buffer_start = _this->parent->dmaBuffers[1].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[1].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_SD;
dma_buf_idx = 1;
}
else
{
if (_this->parent->dmaBuffers[FS_SDMMC_GC].device_addr_buffer_size >= blkSize)
dma_buffer_start = _this->parent->dmaBuffers[2].device_addr_buffer;
if (dma_buffer_start <= actual_buf_start && actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[2].device_addr_buffer_size])
{
dma_buf_idx = FS_SDMMC_GC;
dma_buf_idx = 2;
}
else
{
// If buffer is on a random heap
return -1;
}
}
}
sdmmc_memcpy_buf = false;
return dma_buf_idx;
}
int sdmmc_calculate_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors)
{
int dma_buf_idx = 0;
int blkSize = num_sectors * 512;
if (_this->parent->dmaBuffers[0].device_addr_buffer_size >= blkSize)
{
dma_buf_idx = 0;
}
else
{
if (_this->parent->dmaBuffers[1].device_addr_buffer_size >= blkSize)
{
dma_buf_idx = 1;
}
else
{
if (_this->parent->dmaBuffers[2].device_addr_buffer_size >= blkSize)
{
dma_buf_idx = 2;
}
else
{
// Can't find a fitting buffer
return 0;
}
}
@@ -266,14 +307,112 @@ out:;
return 1;
}
extern _sdmmc_accessor_sd sdmmc_accessor_sd;
extern _sdmmc_accessor_nand sdmmc_accessor_nand;
int sdmmc_storage_read(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);
if (!custom_driver)
{
sdmmc_accessor_t *accessor_sd = sdmmc_accessor_sd();
sdmmc_accessor_t *accessor_nand = sdmmc_accessor_nand();
if (sdmmc_calculate_dma_addr(accessor_sd, buf, num_sectors))
{
return !accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 1);
}
else
{
if (sdmmc_calculate_dma_addr(accessor_nand, buf, num_sectors))
{
// buf is on the nand dma buffer
int original_dma_idx = sdmmc_calculate_dma_index(accessor_nand, buf, num_sectors);
sdmmc_dma_buffer_t *original_dma_buffer = &accessor_nand->parent->dmaBuffers[original_dma_idx];
// Next entry
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors) + 1;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = original_dma_buffer->device_addr_buffer;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = original_dma_buffer->device_addr_buffer_masked;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = original_dma_buffer->device_addr_buffer_size;
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 1);
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = 0;
return !res;
}
else
{
// buf is on a heap
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors);
void *dma_buf = &accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer[0];
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, dma_buf, num_sectors * 512, 1);
memcpy(buf, dma_buf, num_sectors * 512);
return !res;
}
}
}
else
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 0);
}
}
int sdmmc_storage_write(sdmmc_storage_t *storage, u32 sector, u32 num_sectors, void *buf)
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);
if (!custom_driver)
{
sdmmc_accessor_t *accessor_sd = sdmmc_accessor_sd();
sdmmc_accessor_t *accessor_nand = sdmmc_accessor_nand();
if (sdmmc_calculate_dma_addr(accessor_sd, buf, num_sectors))
{
return !accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 0);
}
else
{
if (sdmmc_calculate_dma_addr(accessor_nand, buf, num_sectors))
{
// buf is on the nand dma buffer
int original_dma_idx = sdmmc_calculate_dma_index(accessor_nand, buf, num_sectors);
sdmmc_dma_buffer_t *original_dma_buffer = &accessor_nand->parent->dmaBuffers[original_dma_idx];
// Next entry
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors) + 1;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = original_dma_buffer->device_addr_buffer;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = original_dma_buffer->device_addr_buffer_masked;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = original_dma_buffer->device_addr_buffer_size;
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, buf, num_sectors * 512, 0);
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_masked = 0;
accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer_size = 0;
return !res;
}
else
{
// buf is on a heap
int dma_idx = sdmmc_calculate_fitting_dma_index(accessor_sd, num_sectors);
void *dma_buf = &accessor_sd->parent->dmaBuffers[dma_idx].device_addr_buffer[0];
memcpy(dma_buf, buf, num_sectors * 512);
u64 res = accessor_sd->vtab->read_write(accessor_sd, sector, num_sectors, dma_buf, num_sectors * 512, 0);
return !res;
}
}
}
else
{
return _sdmmc_storage_readwrite(storage, sector, num_sectors, buf, 1);
}
}
/*
@@ -703,7 +842,7 @@ static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, i
if (cond & SD_OCR_CCS)
storage->has_sector_access = 1;
if (false && cond & SD_ROCR_S18A && supports_low_voltage)
if (cond & SD_ROCR_S18A && supports_low_voltage)
{
//The low voltage regulator configuration is valid for SDMMC1 only.
if (storage->sdmmc->id == SDMMC_1 &&

View File

@@ -114,6 +114,7 @@ int sdmmc_storage_set_mmc_partition(sdmmc_storage_t *storage, u32 partition);
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type);
int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors);
int sdmmc_get_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors);
int sdmmc_calculate_dma_index(sdmmc_accessor_t *_this, void *buf, unsigned int num_sectors);
int sdmmc_calculate_fitting_dma_index(sdmmc_accessor_t *_this, unsigned int num_sectors);
#endif

View File

@@ -641,23 +641,6 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
{
if(sdmmc->id == SDMMC_1)
{
static int last_power = SDMMC_POWER_3_3;
if(power == SDMMC_POWER_1_8 && last_power == SDMMC_POWER_3_3)
{
last_power = power = SDMMC_POWER_1_8;
if (!_sdmmc_autocal_config_offset(sdmmc, power))
return;
}
else if(power == SDMMC_POWER_3_3 && last_power == SDMMC_POWER_1_8)
{
last_power = power = SDMMC_POWER_3_3;
if (!_sdmmc_autocal_config_offset(sdmmc, power))
return;
}
}
bool should_enable_sd_clock = false;
if (sdmmc->regs->clkcon & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)
{
@@ -811,7 +794,7 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req)
if (!admaaddr)
{
// buf is on a heap
int dma_idx = sdmmc_get_fitting_dma_index(_current_accessor, blkcnt);
int dma_idx = sdmmc_calculate_fitting_dma_index(_current_accessor, blkcnt);
admaaddr = (u64)&_current_accessor->parent->dmaBuffers[dma_idx].device_addr_buffer_masked[0];
sdmmc->last_dma_idx = dma_idx;
}
@@ -1011,10 +994,13 @@ static int _sdmmc_config_sdmmc1()
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_PULL_UP;
//Make sure SDMMC1 controller is reset.
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, (1 << 12), (1 << 12));
usleep(1000);
//Make sure the SDMMC1 controller is powered.
//PMC(APBDEV_PMC_NO_IOPOWER) &= ~(1 << 12);
//Assume 3.3V SD card voltage.
//PMC(APBDEV_PMC_PWR_DET_VAL) |= (1 << 12);
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_NO_IOPOWER, ~(1 << 12), (1 << 12));
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, (1 << 12), (1 << 12));
//Set enable SD card power.
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN | 1; //GPIO control, pull down.
@@ -1025,10 +1011,10 @@ static int _sdmmc_config_sdmmc1()
usleep(1000);
//Enable SD card power.
//max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
//max77620_regulator_enable(REGULATOR_LDO2, 1);
max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
max77620_regulator_enable(REGULATOR_LDO2, 1);
//usleep(1000);
usleep(1000);
//For good measure.
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = 0x10000000;
@@ -1071,7 +1057,7 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int n
sdmmc->regs->veniotrimctl &= 0xFFFFFFFB;
static const u32 trim_values[] = { 2, 8, 3, 8 };
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 & 0xFFFFFFF0) | 7;
if (!_sdmmc_autocal_config_offset(sdmmc, power))
return 0;
_sdmmc_autocal_execute(sdmmc, power);
@@ -1103,8 +1089,9 @@ void sdmmc_end(sdmmc_t *sdmmc)
if (sdmmc->id == SDMMC_1)
{
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
//max77620_regulator_enable(REGULATOR_LDO2, 0);
msleep(100); // To power cycle min 1ms without power is needed.
msleep(1); // To power cycle min 1ms without power is needed.
max77620_regulator_enable(REGULATOR_LDO2, 0);
msleep(100); // Some extra.
}
_sdmmc_get_clkcon(sdmmc);
@@ -1158,7 +1145,7 @@ int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
_sdmmc_get_clkcon(sdmmc);
max77620_regulator_set_voltage(REGULATOR_LDO2, 1800000);
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~(1 << 12);
smcReadWriteRegister(PMC_BASE + APBDEV_PMC_PWR_DET_VAL, ~(1 << 12), (1 << 12));
_sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8);
_sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8);