Fusee: Deployed new SDMMC driver in fusee-secondary. All stages boot now.
Fusee: Fixed wrong argument in se.c function. Fusee: Improved timers.
This commit is contained in:
@@ -14,8 +14,6 @@
|
||||
#include "../lib/driver_utils.h"
|
||||
#include "../hwinit/max7762x.h"
|
||||
|
||||
#define SDMMC_BOUNCE_BUFFER_ADDRESS 0x90000000
|
||||
|
||||
static SdmmcLogLevel g_sdmmc_log_level = SDMMC_LOG_NONE;
|
||||
|
||||
void sdmmc_set_log_level(SdmmcLogLevel log_level)
|
||||
@@ -116,7 +114,7 @@ void sdmmc_dump_regs(sdmmc_t *sdmmc)
|
||||
sdmmc_debug(sdmmc, "max_current: 0x%08" PRIX32, sdmmc->regs->max_current);
|
||||
sdmmc_debug(sdmmc, "set_acmd12_error: 0x%04" PRIX16, sdmmc->regs->set_acmd12_error);
|
||||
sdmmc_debug(sdmmc, "set_int_error: 0x%04" PRIX16, sdmmc->regs->set_int_error);
|
||||
sdmmc_debug(sdmmc, "adma_error: 0x%02" PRIX16, sdmmc->regs->adma_error);
|
||||
sdmmc_debug(sdmmc, "adma_error: 0x%02" PRIX8, sdmmc->regs->adma_error);
|
||||
sdmmc_debug(sdmmc, "adma_address: 0x%08" PRIX32, sdmmc->regs->adma_address);
|
||||
sdmmc_debug(sdmmc, "upper_adma_address: 0x%08" PRIX32, sdmmc->regs->upper_adma_address);
|
||||
sdmmc_debug(sdmmc, "preset_for_init: 0x%04" PRIX16, sdmmc->regs->preset_for_init);
|
||||
@@ -700,10 +698,13 @@ static int sdmmc_int_clk_enable(sdmmc_t *sdmmc)
|
||||
|
||||
/* Change to ADMA if requested. */
|
||||
if (sdmmc->use_adma && (sdmmc->regs->capabilities & SDHCI_CAN_DO_ADMA2)) {
|
||||
// TODO: Setting the ADMA flags breaks ADMA...
|
||||
/*
|
||||
if (sdmmc->regs->capabilities & SDHCI_CAN_64BIT)
|
||||
sdmmc->regs->host_control |= SDHCI_CTRL_ADMA64;
|
||||
else
|
||||
sdmmc->regs->host_control |= SDHCI_CTRL_ADMA32;
|
||||
*/
|
||||
}
|
||||
|
||||
/* Set the timeout to be the maximum value. */
|
||||
@@ -1092,7 +1093,7 @@ static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller)
|
||||
sdmmc->is_clk_running = false;
|
||||
sdmmc->is_sd_clk_enabled = false;
|
||||
sdmmc->is_tuning_tap_val_set = false;
|
||||
sdmmc->use_adma = false;
|
||||
sdmmc->use_adma = true;
|
||||
sdmmc->dma_bounce_buf = (uint8_t*)SDMMC_BOUNCE_BUFFER_ADDRESS;
|
||||
sdmmc->tap_val = 0;
|
||||
sdmmc->internal_divider = 0;
|
||||
@@ -1201,13 +1202,23 @@ void sdmmc_finish(sdmmc_t *sdmmc)
|
||||
/* Disable the SD clock. */
|
||||
sdmmc_disable_sd_clock(sdmmc);
|
||||
|
||||
/* Disable SD power. */
|
||||
/* Disable SDMMC power. */
|
||||
sdmmc_select_voltage(sdmmc, SDMMC_VOLTAGE_NONE);
|
||||
|
||||
/* Disable the SD card power. */
|
||||
if (sdmmc->controller == SDMMC_1)
|
||||
{
|
||||
/* Disable GPIO output. */
|
||||
gpio_configure_direction(GPIO_MICROSD_SUPPLY_ENABLE, GPIO_DIRECTION_INPUT);
|
||||
|
||||
/* Power cycle for 100ms without power. */
|
||||
mdelay(100);
|
||||
}
|
||||
|
||||
/* Force a register read to refresh the clock control value. */
|
||||
sdmmc_get_sd_clock_control(sdmmc);
|
||||
|
||||
/* Stop the SD clock. */
|
||||
/* Stop the SDMMC clock. */
|
||||
sdmmc_clk_stop(sdmmc->controller);
|
||||
|
||||
/* Clock is no longer running by now. */
|
||||
@@ -1307,7 +1318,8 @@ static int sdmmc_wait_busy(sdmmc_t *sdmmc)
|
||||
static void sdmmc_intr_enable(sdmmc_t *sdmmc)
|
||||
{
|
||||
/* Set all error bits and enable the relevant interrupts. */
|
||||
sdmmc->regs->int_enable |= (0x017F0000 | (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT));
|
||||
sdmmc->regs->int_enable |= 0x017F0000;
|
||||
sdmmc->regs->int_enable |= (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT);
|
||||
|
||||
/* Refresh status. */
|
||||
sdmmc->regs->int_status = sdmmc->regs->int_status;
|
||||
@@ -1315,11 +1327,15 @@ static void sdmmc_intr_enable(sdmmc_t *sdmmc)
|
||||
|
||||
static void sdmmc_intr_disable(sdmmc_t *sdmmc)
|
||||
{
|
||||
/* Clear the interrupt bits. */
|
||||
sdmmc->regs->int_enable &= ~(0x017F0000 | (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT));
|
||||
/* Clear all error bits and the interrupts. */
|
||||
sdmmc->regs->int_enable &= ~(0x017F0000);
|
||||
sdmmc->regs->int_enable &= ~(TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT);
|
||||
|
||||
/* Refresh status. */
|
||||
sdmmc->regs->int_status = sdmmc->regs->int_status;
|
||||
}
|
||||
|
||||
static bool sdmmc_intr_check_status(sdmmc_t *sdmmc, u16 status_mask)
|
||||
static bool sdmmc_intr_check_status(sdmmc_t *sdmmc, uint16_t status_mask)
|
||||
{
|
||||
bool is_masked = (sdmmc->regs->int_status & status_mask);
|
||||
|
||||
@@ -1353,8 +1369,8 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
|
||||
if (blkcnt >= 0xFFFF)
|
||||
blkcnt = 0xFFFF;
|
||||
|
||||
/* Point to our bounce buffer. */
|
||||
uint32_t dma_base_addr = (uint32_t)sdmmc->dma_bounce_buf;
|
||||
/* Use our bounce buffer for SDMA or the request data buffer for ADMA. */
|
||||
uint32_t dma_base_addr = sdmmc->use_adma ? (uint32_t)req->data : (uint32_t)sdmmc->dma_bounce_buf;
|
||||
|
||||
/* DMA buffer address must be aligned to 4 bytes. */
|
||||
if ((4 - (dma_base_addr & 0x03)) & 0x03)
|
||||
@@ -1408,7 +1424,7 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
|
||||
|
||||
static int sdmmc_dma_update(sdmmc_t *sdmmc)
|
||||
{
|
||||
u16 blkcnt = 0;
|
||||
uint16_t blkcnt = 0;
|
||||
|
||||
/* Loop until all blocks have been consumed. */
|
||||
do
|
||||
@@ -1464,7 +1480,7 @@ static int sdmmc_dma_update(sdmmc_t *sdmmc)
|
||||
|
||||
static void sdmmc_set_cmd_flags(sdmmc_t *sdmmc, sdmmc_command_t *cmd, bool is_dma)
|
||||
{
|
||||
u16 cmd_reg_flags = 0;
|
||||
uint16_t cmd_reg_flags = 0;
|
||||
|
||||
/* Select length flags based on response type. */
|
||||
if (!(cmd->flags & SDMMC_RSP_PRESENT))
|
||||
@@ -1629,8 +1645,8 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If this is a write operation, copy the data into our bounce buffer. */
|
||||
if (!req->is_read)
|
||||
/* If this is a SDMA write operation, copy the data into our bounce buffer. */
|
||||
if (!sdmmc->use_adma && !req->is_read)
|
||||
memcpy((void *)sdmmc->dma_bounce_buf, (void *)req->data, req->blksz * req->num_blocks);
|
||||
}
|
||||
|
||||
@@ -1659,8 +1675,8 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If this is a read operation, copy the data from our bounce buffer. */
|
||||
if (req->is_read)
|
||||
/* If this is a SDMA read operation, copy the data from our bounce buffer. */
|
||||
if (!sdmmc->use_adma && req->is_read)
|
||||
{
|
||||
uint32_t dma_data_size = (sdmmc->regs->dma_address - (uint32_t)sdmmc->dma_bounce_buf);
|
||||
memcpy((void *)req->data, (void *)sdmmc->dma_bounce_buf, dma_data_size);
|
||||
@@ -1853,7 +1869,7 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode)
|
||||
|
||||
void sdmmc_set_tuning_tap_val(sdmmc_t *sdmmc)
|
||||
{
|
||||
sdmmc->tap_val = ((sdmmc->regs->vendor_clock_cntrl & 0xFF0000) >> 16);
|
||||
sdmmc->tap_val = (sdmmc->regs->vendor_clock_cntrl >> 16);
|
||||
sdmmc->is_tuning_tap_val_set = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user