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:
@@ -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 &&
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user