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:
hexkyz
2018-07-19 21:07:53 +01:00
parent 49ba91a8f3
commit 3db9ce32fa
44 changed files with 5247 additions and 4802 deletions

View File

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