diff --git a/fusee/common/fatfs/diskio.c b/fusee/common/fatfs/diskio.c
index 43c6f08b8..4509e61f1 100644
--- a/fusee/common/fatfs/diskio.c
+++ b/fusee/common/fatfs/diskio.c
@@ -14,7 +14,7 @@
#include "ffconf.h"
#if defined(FUSEE_STAGE1_SRC)
-#include "../../../fusee/fusee-primary/src/fs_utils.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/fs_utils.h"
#elif defined(FUSEE_STAGE2_SRC)
#include "../../../fusee/fusee-secondary/src/device_partition.h"
#elif defined(SEPT_STAGE2_SRC)
@@ -63,7 +63,7 @@ DSTATUS disk_initialize (
return STA_NODISK;
else if (devpart->initializer)
return devpart->initializer(devpart) ? STA_NOINIT : RES_OK;
- else
+ else
return RES_OK;
#else
return RES_OK;
diff --git a/fusee/common/sdmmc/sdmmc.c b/fusee/common/sdmmc/sdmmc.c
index 0945f3023..2385c58e1 100644
--- a/fusee/common/sdmmc/sdmmc.c
+++ b/fusee/common/sdmmc/sdmmc.c
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#include
#include
#include
@@ -27,7 +27,7 @@
#include "sd.h"
#if defined(FUSEE_STAGE1_SRC)
-#include "../../../fusee/fusee-primary/src/timers.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/timers.h"
#elif defined(FUSEE_STAGE2_SRC)
#include "../../../fusee/fusee-secondary/src/timers.h"
#elif defined(SEPT_STAGE2_SRC)
@@ -81,31 +81,31 @@ static bool is_sdmmc_device_r1_error(uint32_t status)
}
static int sdmmc_device_send_r1_cmd(sdmmc_device_t *device, uint32_t opcode, uint32_t arg, bool is_busy, uint32_t resp_mask, uint32_t resp_state)
-{
+{
sdmmc_command_t cmd = {};
-
+
cmd.opcode = opcode;
cmd.arg = arg;
cmd.flags = (is_busy ? SDMMC_RSP_R1B : SDMMC_RSP_R1);
-
+
/* Try to send the command. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0))
return 0;
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp))
return 0;
-
+
/* Mask the response, if necessary. */
if (resp_mask)
resp &= ~(resp_mask);
-
+
/* We got an error state. */
- if (is_sdmmc_device_r1_error(resp))
+ if (is_sdmmc_device_r1_error(resp))
return 0;
-
+
/* We need to check for the desired state. */
if (resp_state != 0xFFFFFFFF)
{
@@ -113,14 +113,14 @@ static int sdmmc_device_send_r1_cmd(sdmmc_device_t *device, uint32_t opcode, uin
if (R1_CURRENT_STATE(resp) != resp_state)
return 0;
}
-
+
return 1;
}
static int sdmmc_device_go_idle(sdmmc_device_t *device)
{
sdmmc_command_t cmd = {};
-
+
cmd.opcode = MMC_GO_IDLE_STATE;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_NONE;
@@ -131,7 +131,7 @@ static int sdmmc_device_go_idle(sdmmc_device_t *device)
static int sdmmc_device_send_cid(sdmmc_device_t *device, uint32_t *cid)
{
sdmmc_command_t cmd = {};
-
+
cmd.opcode = MMC_ALL_SEND_CID;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_R2;
@@ -139,7 +139,7 @@ static int sdmmc_device_send_cid(sdmmc_device_t *device, uint32_t *cid)
/* Try to send the command. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0))
return 0;
-
+
/* Try to load back the response. */
return sdmmc_load_response(device->sdmmc, SDMMC_RSP_R2, cid);
}
@@ -147,7 +147,7 @@ static int sdmmc_device_send_cid(sdmmc_device_t *device, uint32_t *cid)
static int sdmmc_device_send_csd(sdmmc_device_t *device, uint32_t *csd)
{
sdmmc_command_t cmd = {};
-
+
cmd.opcode = MMC_SEND_CSD;
cmd.arg = (device->rca << 16);
cmd.flags = SDMMC_RSP_R2;
@@ -155,25 +155,25 @@ static int sdmmc_device_send_csd(sdmmc_device_t *device, uint32_t *csd)
/* Try to send the command. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0))
return 0;
-
+
/* Try to load back the response. */
return sdmmc_load_response(device->sdmmc, SDMMC_RSP_R2, csd);
}
static int sdmmc_device_select_card(sdmmc_device_t *device)
-{
+{
/* Try to send the command. */
return sdmmc_device_send_r1_cmd(device, MMC_SELECT_CARD, (device->rca << 16), true, 0, 0xFFFFFFFF);
}
static int sdmmc_device_set_blocklen(sdmmc_device_t *device, uint32_t blocklen)
-{
+{
/* Try to send the command. */
return sdmmc_device_send_r1_cmd(device, MMC_SET_BLOCKLEN, blocklen, false, 0, R1_STATE_TRAN);
}
static int sdmmc_device_send_status(sdmmc_device_t *device)
-{
+{
/* Try to send the command. */
return sdmmc_device_send_r1_cmd(device, MMC_SEND_STATUS, (device->rca << 16), false, 0, R1_STATE_TRAN);
}
@@ -181,21 +181,21 @@ static int sdmmc_device_send_status(sdmmc_device_t *device)
static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data, bool is_read)
{
uint8_t *buf = (uint8_t *)data;
-
+
sdmmc_command_t cmd = {};
sdmmc_request_t req = {};
-
+
while (num_sectors)
{
uint32_t num_blocks_out = 0;
uint32_t num_retries = 10;
-
+
for (; num_retries > 0; num_retries--)
{
cmd.opcode = is_read ? MMC_READ_MULTIPLE_BLOCK : MMC_WRITE_MULTIPLE_BLOCK;
cmd.arg = sector;
cmd.flags = SDMMC_RSP_R1;
-
+
req.data = buf;
req.blksz = 512;
req.num_blocks = num_sectors;
@@ -208,7 +208,7 @@ static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num
{
/* Abort the transmission. */
sdmmc_abort(device->sdmmc, MMC_STOP_TRANSMISSION);
-
+
/* Peek the SD card's status. */
sdmmc_device_send_status(device);
@@ -218,17 +218,17 @@ static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num
else
break;
}
-
+
/* Failed to read/write on all attempts. */
if (!num_retries)
return 0;
-
+
/* Advance to next sector. */
sector += num_blocks_out;
num_sectors -= num_blocks_out;
buf += (512 * num_blocks_out);
}
-
+
return 1;
}
@@ -247,7 +247,7 @@ int sdmmc_device_finish(sdmmc_device_t *device)
/* Place the device in idle state. */
if (!sdmmc_device_go_idle(device))
return 0;
-
+
/* Terminate the device. */
sdmmc_finish(device->sdmmc);
return 1;
@@ -335,7 +335,7 @@ static int sdmmc_sd_decode_csd(sdmmc_device_t *device, uint32_t *csd)
default:
return 0;
}
-
+
return 1;
}
@@ -343,7 +343,7 @@ static int sdmmc_sd_decode_scr(sdmmc_device_t *device, uint8_t *scr)
{
uint8_t tmp[8];
uint32_t resp[4];
-
+
/* This must be swapped. */
for (int i = 0; i < 8; i += 4)
{
@@ -358,14 +358,14 @@ static int sdmmc_sd_decode_scr(sdmmc_device_t *device, uint8_t *scr)
device->scr.sda_vsn = UNSTUFF_BITS(resp, 56, 4);
device->scr.bus_widths = UNSTUFF_BITS(resp, 48, 4);
-
+
/* Check if Physical Layer Spec v3.0 is supported. */
if (device->scr.sda_vsn == SD_SCR_SPEC_VER_2)
device->scr.sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
if (device->scr.sda_spec3)
device->scr.cmds = UNSTUFF_BITS(resp, 32, 2);
-
+
/* Unknown SCR structure version. */
if (UNSTUFF_BITS(resp, 60, 4))
return 0;
@@ -378,7 +378,7 @@ static void sdmmc_sd_decode_ssr(sdmmc_device_t *device, uint8_t *ssr)
uint8_t tmp[64];
uint32_t resp1[4];
uint32_t resp2[4];
-
+
/* This must be swapped. */
for (int i = 0; i < 64; i += 4)
{
@@ -396,15 +396,15 @@ static void sdmmc_sd_decode_ssr(sdmmc_device_t *device, uint8_t *ssr)
resp2[2] = *(uint32_t *)&tmp[24];
resp2[1] = *(uint32_t *)&tmp[20];
resp2[0] = *(uint32_t *)&tmp[16];
-
+
device->ssr.dat_bus_width = ((UNSTUFF_BITS(resp1, 126, 2) & SD_BUS_WIDTH_4) ? 4 : 1);
device->ssr.speed_class = UNSTUFF_BITS(resp1, 56, 8);
-
+
if (device->ssr.speed_class < 4)
device->ssr.speed_class <<= 1;
else if (device->ssr.speed_class == 4)
device->ssr.speed_class = 10;
-
+
device->ssr.uhs_speed_grade = UNSTUFF_BITS(resp1, 12, 4);
device->ssr.video_speed_class = UNSTUFF_BITS(resp1, 0, 8);
device->ssr.app_perf_class = UNSTUFF_BITS(resp2, 80, 4);
@@ -415,50 +415,50 @@ static int sdmmc_sd_send_app_cmd(sdmmc_device_t *device, sdmmc_command_t *cmd, s
/* Try to send the APP command. */
if (!sdmmc_device_send_r1_cmd(device, MMC_APP_CMD, (device->rca << 16), false, resp_mask, resp_state))
return 0;
-
+
/* Send the actual command. */
if (!sdmmc_send_cmd(device->sdmmc, cmd, req, 0))
return 0;
-
+
return 1;
}
static int sdmmc_sd_send_if_cond(sdmmc_device_t *device, bool *is_sd_ver2)
{
sdmmc_command_t cmd = {};
-
+
cmd.opcode = SD_SEND_IF_COND;
/* We set the bit if the host supports voltages between 2.7 and 3.6 V */
cmd.arg = 0x1AA;
cmd.flags = SDMMC_RSP_R7;
-
+
/* Command failed, this means SD Card is not version 2. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0))
{
*is_sd_ver2 = false;
return 1;
}
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R7, &resp))
return 0;
-
+
/* Check if we got a valid response. */
if ((resp & 0xFF) == 0xAA)
{
*is_sd_ver2 = true;
return 1;
}
-
+
return 0;
}
static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool is_uhs_en)
{
sdmmc_command_t cmd = {};
-
+
/* Program a large timeout. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -467,32 +467,32 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
{
/* Set this since most cards do not answer if some reserved bits in the OCR are set. */
uint32_t arg = SD_OCR_VDD_32_33;
-
+
/* Request support for SDXC power control and SDHC block mode cards. */
if (is_sd_ver2)
{
arg |= SD_OCR_XPC;
arg |= SD_OCR_CCS;
}
-
+
/* Request support 1.8V switching. */
if (is_uhs_en)
arg |= SD_OCR_S18R;
-
+
cmd.opcode = SD_APP_OP_COND;
cmd.arg = arg;
cmd.flags = SDMMC_RSP_R3;
-
+
/* Try to send the command. */
if (!sdmmc_sd_send_app_cmd(device, &cmd, 0, is_sd_ver2 ? 0 : 0x400000, 0xFFFFFFFF))
return 0;
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R3, &resp))
return 0;
-
+
/* Card Power up bit is set. */
if (resp & MMC_CARD_BUSY)
{
@@ -509,10 +509,10 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
/* Failed to issue voltage switching command. */
if (!sdmmc_device_send_r1_cmd(device, SD_SWITCH_VOLTAGE, 0, false, 0, R1_STATE_READY))
return 0;
-
+
/* Delay a bit before asking for the voltage switch. */
mdelay(100);
-
+
/* Tell the driver to switch the voltage. */
if (!sdmmc_switch_voltage(device->sdmmc))
return 0;
@@ -524,10 +524,10 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
return 1;
}
-
+
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 2000000);
-
+
/* Delay for a minimum of 10 milliseconds. */
mdelay(10);
}
@@ -538,11 +538,11 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i
static int sdmmc_sd_send_relative_addr(sdmmc_device_t *device)
{
sdmmc_command_t cmd = {};
-
+
cmd.opcode = SD_SEND_RELATIVE_ADDR;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_R6;
-
+
/* Program a large timeout. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -552,27 +552,27 @@ static int sdmmc_sd_send_relative_addr(sdmmc_device_t *device)
/* Try to send the command. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0))
return 0;
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R6, &resp))
return 0;
-
+
/* Save the RCA. */
if (resp >> 16)
{
device->rca = (resp >> 16);
return 1;
}
-
+
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 2000000);
-
+
/* Delay for an appropriate period. */
udelay(1000);
}
-
+
return 0;
}
@@ -580,28 +580,28 @@ static int sdmmc_sd_send_scr(sdmmc_device_t *device, uint8_t *scr)
{
sdmmc_command_t cmd = {};
sdmmc_request_t req = {};
-
+
cmd.opcode = SD_APP_SEND_SCR;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_R1;
-
+
req.data = scr;
req.blksz = 8;
req.num_blocks = 1;
req.is_read = true;
req.is_multi_block = false;
req.is_auto_cmd12 = false;
-
+
/* Try to send the APP command. */
if (!sdmmc_sd_send_app_cmd(device, &cmd, &req, 0, R1_STATE_TRAN))
return 0;
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp))
- return 0;
-
+ return 0;
+
/* Evaluate the response. */
if (is_sdmmc_device_r1_error(resp))
return 0;
@@ -610,21 +610,21 @@ static int sdmmc_sd_send_scr(sdmmc_device_t *device, uint8_t *scr)
}
static int sdmmc_sd_set_clr_card_detect(sdmmc_device_t *device)
-{
+{
/* Try to send the APP command. */
if (!sdmmc_device_send_r1_cmd(device, MMC_APP_CMD, (device->rca << 16), false, 0, R1_STATE_TRAN))
return 0;
-
+
/* Try to send the command. */
return sdmmc_device_send_r1_cmd(device, SD_APP_SET_CLR_CARD_DETECT, 0, false, 0, R1_STATE_TRAN);
}
static int sdmmc_sd_set_bus_width(sdmmc_device_t *device)
-{
+{
/* Try to send the APP command. */
if (!sdmmc_device_send_r1_cmd(device, MMC_APP_CMD, (device->rca << 16), false, 0, R1_STATE_TRAN))
return 0;
-
+
/* Try to send the command. */
return sdmmc_device_send_r1_cmd(device, SD_APP_SET_BUS_WIDTH, SD_BUS_WIDTH_4, false, 0, R1_STATE_TRAN);
}
@@ -633,30 +633,30 @@ static int sdmmc_sd_switch(sdmmc_device_t *device, uint32_t mode, uint32_t group
{
sdmmc_command_t cmd = {};
sdmmc_request_t req = {};
-
+
cmd.opcode = SD_SWITCH;
cmd.arg = ((mode << 31) | 0x00FFFFFF);
cmd.arg &= ~(0xF << (group * 4));
cmd.arg |= (value << (group * 4));
cmd.flags = SDMMC_RSP_R1;
-
+
req.data = data;
req.blksz = 64;
req.num_blocks = 1;
req.is_read = true;
req.is_multi_block = false;
req.is_auto_cmd12 = false;
-
+
/* Try to send the command. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, &req, 0))
return 0;
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp))
- return 0;
-
+ return 0;
+
/* Evaluate the response. */
if (is_sdmmc_device_r1_error(resp))
return 0;
@@ -668,21 +668,21 @@ static int sdmmc_sd_set_current_limit(sdmmc_device_t *device, uint8_t *status)
{
/* Start with the highest possible limit. */
int32_t current_limit = SD_SET_CURRENT_LIMIT_800;
-
+
/* Try each limit. */
while (current_limit > SD_SET_CURRENT_NO_CHANGE)
{
/* Switch the current limit. */
if (!sdmmc_sd_switch(device, SD_SWITCH_SET, 3, current_limit, status))
return 0;
-
+
/* Current limit was set successfully. */
if (((status[15] >> 4) & 0x0F) == current_limit)
break;
-
+
current_limit--;
}
-
+
return 1;
}
@@ -693,7 +693,7 @@ static int sdmmc_sd_switch_hs(sdmmc_device_t *device, uint32_t type, uint8_t *st
return 0;
uint32_t res_type = (status[16] & 0xF);
-
+
/* This high-speed mode type is not supported. */
if (res_type != type)
return 0;
@@ -713,7 +713,7 @@ static int sdmmc_sd_switch_hs(sdmmc_device_t *device, uint32_t type, uint8_t *st
}
static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status)
-{
+{
/* Adjust the current limit. */
if (!sdmmc_sd_set_current_limit(device, status))
return 0;
@@ -771,8 +771,8 @@ static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status)
}
else
return 0;
-
-
+
+
/* Peek the SD card's status. */
return sdmmc_device_send_status(device);
}
@@ -782,18 +782,18 @@ static int sdmmc_sd_switch_hs_high(sdmmc_device_t *device, uint8_t *status)
/* Get the supported high-speed type. */
if (!sdmmc_sd_switch(device, 0, 0, 0xF, status))
return 0;
-
+
/* High-speed is supported. */
if (status[13] & 2)
{
/* Switch to high-speed. */
if (!sdmmc_sd_switch_hs(device, SDHCI_CTRL_UHS_SDR25, status))
return 0;
-
+
/* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR25))
return 0;
-
+
/* Peek the SD card's status. */
return sdmmc_device_send_status(device);
}
@@ -806,28 +806,28 @@ static int sdmmc_sd_status(sdmmc_device_t *device, uint8_t *ssr)
{
sdmmc_command_t cmd = {};
sdmmc_request_t req = {};
-
+
cmd.opcode = SD_APP_SD_STATUS;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_R1;
-
+
req.data = ssr;
req.blksz = 64;
req.num_blocks = 1;
req.is_read = true;
req.is_multi_block = false;
req.is_auto_cmd12 = false;
-
+
/* Try to send the APP command. */
if (!sdmmc_sd_send_app_cmd(device, &cmd, &req, 0, R1_STATE_TRAN))
return 0;
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp))
- return 0;
-
+ return 0;
+
/* Evaluate the response. */
if (is_sdmmc_device_r1_error(resp))
return 0;
@@ -843,22 +843,22 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
uint8_t scr[8] = {0};
uint8_t ssr[64] = {0};
uint8_t switch_status[512] = {0};
-
+
/* Initialize our device's struct. */
memset(device, 0, sizeof(sdmmc_device_t));
-
+
/* Try to initialize the driver. */
if (!sdmmc_init(sdmmc, SDMMC_1, SDMMC_VOLTAGE_3V3, SDMMC_BUS_WIDTH_1BIT, SDMMC_SPEED_SD_IDENT))
{
sdmmc_error(sdmmc, "Failed to initialize the SDMMC driver!");
return 0;
}
-
+
/* Bind the underlying driver. */
device->sdmmc = sdmmc;
-
+
sdmmc_info(sdmmc, "SDMMC driver was successfully initialized for SD!");
-
+
/* Apply at least 74 clock cycles. The card should be ready afterwards. */
udelay((74000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
@@ -868,7 +868,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to go idle!");
return 0;
}
-
+
sdmmc_info(sdmmc, "SD card went idle!");
/* Get the SD card's interface operating condition. */
@@ -877,7 +877,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to send if cond!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Sent if cond to SD card!");
/* Get the SD card's operating conditions. */
@@ -886,28 +886,28 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to send op cond!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Sent op cond to SD card!");
-
+
/* Get the SD card's CID. */
if (!sdmmc_device_send_cid(device, cid))
{
sdmmc_error(sdmmc, "Failed to get CID!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got CID from SD card!");
-
+
/* Decode and save the CID. */
sdmmc_sd_decode_cid(device, cid);
-
+
/* Get the SD card's RCA. */
if (!sdmmc_sd_send_relative_addr(device))
{
sdmmc_error(sdmmc, "Failed to get RCA!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got RCA (0x%08x) from SD card!", device->rca);
/* Get the SD card's CSD. */
@@ -916,13 +916,13 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to get CSD!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got CSD from SD card!");
-
+
/* Decode and save the CSD. */
if (!sdmmc_sd_decode_csd(device, csd))
sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure);
-
+
/* If we never switched to 1.8V, change the bus speed mode. */
if (!device->is_180v)
{
@@ -932,7 +932,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Speed mode has been adjusted!");
}
@@ -942,7 +942,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to select SD card!");
return 0;
}
-
+
sdmmc_info(sdmmc, "SD card is now selected!");
/* Change the SD card's block length. */
@@ -951,7 +951,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to set SD card's block length!");
return 0;
}
-
+
sdmmc_info(sdmmc, "SD card's block length is now 512!");
/* It's a good practice to disconnect the pull-up resistor with ACMD42. */
@@ -960,16 +960,16 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to disconnect the pull-up resistor!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Pull-up resistor is now disconnected!");
-
+
/* Get the SD card's SCR. */
if (!sdmmc_sd_send_scr(device, scr))
{
sdmmc_error(sdmmc, "Failed to get SCR!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got SCR from SD card!");
/* Decode and save the SCR. */
@@ -978,7 +978,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Got unknown SCR structure!");
return 0;
}
-
+
/* Switch to wider bus (if supported). */
if ((bus_width == SDMMC_BUS_WIDTH_4BIT)
&& (device->scr.bus_widths & SD_SCR_BUS_WIDTH_4)
@@ -989,7 +989,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to switch to wider bus!");
return 0;
}
-
+
sdmmc_select_bus_width(device->sdmmc, SDMMC_BUS_WIDTH_4BIT);
sdmmc_info(sdmmc, "Switched to wider bus!");
}
@@ -1002,7 +1002,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to switch to high-speed from low voltage!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Switched to high-speed from low voltage!");
}
else if ((device->scr.sda_vsn & (SD_SCR_SPEC_VER_1 | SD_SCR_SPEC_VER_2)) && ((bus_speed != SDMMC_SPEED_SD_DS)))
@@ -1013,7 +1013,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to switch to high-speed from high voltage!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Switched to high-speed from high voltage!");
}
@@ -1026,12 +1026,12 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b
sdmmc_error(sdmmc, "Failed to get SSR!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got SSR from SD card!");
/* Decode and save the SSR. */
sdmmc_sd_decode_ssr(device, scr);
-
+
return 1;
}
@@ -1072,7 +1072,7 @@ static void sdmmc_mmc_decode_cid(sdmmc_device_t *device, uint32_t *cid)
device->cid.month = UNSTUFF_BITS(cid, 12, 4);
device->cid.year = (UNSTUFF_BITS(cid, 8, 4) + 1997);
-
+
if ((device->ext_csd.rev >= 5) && (device->cid.year < 2010))
device->cid.year += 16;
}
@@ -1082,13 +1082,13 @@ static int sdmmc_mmc_decode_csd(sdmmc_device_t *device, uint32_t *csd)
unsigned int e, m, a, b;
device->csd.structure = UNSTUFF_BITS(csd, 126, 2);
-
+
if (!device->csd.structure) {
return 0;
}
-
+
device->csd.mmca_vsn = UNSTUFF_BITS(csd, 122, 4);
-
+
m = UNSTUFF_BITS(csd, 115, 4);
e = UNSTUFF_BITS(csd, 112, 3);
device->csd.taac_ns = ((taac_exp[e] * taac_mant[m] + 9) / 10);
@@ -1119,7 +1119,7 @@ static int sdmmc_mmc_decode_csd(sdmmc_device_t *device, uint32_t *csd)
device->csd.erase_size = ((a + 1) * (b + 1));
device->csd.erase_size <<= (device->csd.write_blkbits - 9);
}
-
+
return 1;
}
@@ -1141,7 +1141,7 @@ static void sdmmc_mmc_decode_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd)
static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_voltage)
{
sdmmc_command_t cmd = {};
-
+
/* Program a large timeout. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -1150,7 +1150,7 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo
{
/* Set high capacity bit. */
uint32_t arg = SD_OCR_CCS;
-
+
/* Set voltage bits. */
if (bus_voltage == SDMMC_VOLTAGE_1V8)
arg |= MMC_VDD_165_195;
@@ -1158,21 +1158,21 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo
arg |= (MMC_VDD_33_34 | MMC_VDD_32_33 | MMC_VDD_31_32 | MMC_VDD_30_31 | MMC_VDD_29_30 | MMC_VDD_28_29 | MMC_VDD_27_28);
else
return 0;
-
+
cmd.opcode = MMC_SEND_OP_COND;
cmd.arg = arg;
cmd.flags = SDMMC_RSP_R3;
-
+
/* Try to send the command. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0))
return 0;
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R3, &resp))
return 0;
-
+
/* Card Power up bit is set. */
if (resp & MMC_CARD_BUSY)
{
@@ -1182,10 +1182,10 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo
return 1;
}
-
+
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 2000000);
-
+
/* Delay for a minimum of 10 milliseconds. */
mdelay(10);
}
@@ -1197,28 +1197,28 @@ static int sdmmc_mmc_send_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd)
{
sdmmc_command_t cmd = {};
sdmmc_request_t req = {};
-
+
cmd.opcode = MMC_SEND_EXT_CSD;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_R1;
-
+
req.data = ext_csd;
req.blksz = 512;
req.num_blocks = 1;
req.is_read = true;
req.is_multi_block = false;
req.is_auto_cmd12 = false;
-
+
/* Try to send the command. */
if (!sdmmc_send_cmd(device->sdmmc, &cmd, &req, 0))
return 0;
-
+
uint32_t resp = 0;
-
+
/* Try to load back the response. */
if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp))
- return 0;
-
+ return 0;
+
/* Evaluate the response. */
if (is_sdmmc_device_r1_error(resp))
return 0;
@@ -1241,7 +1241,7 @@ static int sdmmc_mmc_switch(sdmmc_device_t *device, uint32_t arg)
static int sdmmc_mmc_select_bus_width(sdmmc_device_t *device, SdmmcBusWidth bus_width)
{
uint32_t arg = 0;
-
+
/* Choose the argument for the switch command. */
switch (bus_width)
{
@@ -1256,56 +1256,56 @@ static int sdmmc_mmc_select_bus_width(sdmmc_device_t *device, SdmmcBusWidth bus_
default:
return 0;
}
-
+
/* Try to switch the bus width. */
if (sdmmc_mmc_switch(device, arg) && sdmmc_device_send_status(device))
{
sdmmc_select_bus_width(device->sdmmc, bus_width);
return 1;
}
-
+
return 0;
}
static int sdmmc_mmc_select_hs(sdmmc_device_t *device, bool ignore_status)
{
uint32_t arg = (((MMC_SWITCH_MODE_WRITE_BYTE) << 24) | ((EXT_CSD_HS_TIMING) << 16) | ((EXT_CSD_TIMING_HS) << 8));
-
+
/* Try to switch to HS. */
if (!sdmmc_mmc_switch(device, arg))
return 0;
-
+
/* Check the status if necessary. */
if (!ignore_status && !sdmmc_device_send_status(device))
return 0;
-
+
/* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_HS))
return 0;
-
+
/* Check the status if necessary. */
if (!ignore_status && !sdmmc_device_send_status(device))
return 0;
-
+
return 1;
}
static int sdmmc_mmc_select_hs200(sdmmc_device_t *device)
{
uint32_t arg = (((MMC_SWITCH_MODE_WRITE_BYTE) << 24) | ((EXT_CSD_HS_TIMING) << 16) | ((EXT_CSD_TIMING_HS200) << 8));
-
+
/* Try to switch to HS200. */
if (!sdmmc_mmc_switch(device, arg))
return 0;
-
+
/* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_HS200))
return 0;
-
+
/* Execute tuning procedure. */
if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_MMC_HS200, MMC_SEND_TUNING_BLOCK_HS200))
return 0;
-
+
/* Peek the current status. */
return sdmmc_device_send_status(device);
}
@@ -1313,34 +1313,34 @@ static int sdmmc_mmc_select_hs200(sdmmc_device_t *device)
static int sdmmc_mmc_select_hs400(sdmmc_device_t *device)
{
uint32_t arg = 0;
-
+
/* Switch to HS200 first. */
if (!sdmmc_mmc_select_hs200(device))
return 0;
-
+
/* Fetch and set the tuning tap value. */
sdmmc_set_tuning_tap_val(device->sdmmc);
-
+
/* Switch to HS. */
if (!sdmmc_mmc_select_hs(device, true))
return 0;
-
+
arg = (((MMC_SWITCH_MODE_WRITE_BYTE) << 24) | ((EXT_CSD_BUS_WIDTH) << 16) | ((EXT_CSD_DDR_BUS_WIDTH_8) << 8));
-
+
/* Try to switch to 8bit bus. */
if (!sdmmc_mmc_switch(device, arg))
return 0;
-
+
arg = (((MMC_SWITCH_MODE_WRITE_BYTE) << 24) | ((EXT_CSD_HS_TIMING) << 16) | ((EXT_CSD_TIMING_HS400) << 8));
-
+
/* Try to switch to HS400. */
if (!sdmmc_mmc_switch(device, arg))
return 0;
-
+
/* Reconfigure the internal clock. */
if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_HS400))
return 0;
-
+
/* Peek the current status. */
return sdmmc_device_send_status(device);
}
@@ -1366,18 +1366,18 @@ static int sdmmc_mmc_select_timing(sdmmc_device_t *device, SdmmcBusSpeed bus_spe
/* Switch to HS. */
return sdmmc_mmc_select_hs(device, false);
}
-
+
return 0;
}
static int sdmmc_mmc_select_bkops(sdmmc_device_t *device)
{
uint32_t arg = (((MMC_SWITCH_MODE_SET_BITS) << 24) | ((EXT_CSD_BKOPS_EN) << 16) | ((EXT_CSD_BKOPS_LEVEL_2) << 8));
-
+
/* Try to enable bkops. */
if (!sdmmc_mmc_switch(device, arg))
return 0;
-
+
/* Peek the current status. */
return sdmmc_device_send_status(device);
}
@@ -1385,11 +1385,11 @@ static int sdmmc_mmc_select_bkops(sdmmc_device_t *device)
int sdmmc_mmc_select_partition(sdmmc_device_t *device, SdmmcPartitionNum partition)
{
uint32_t arg = (((MMC_SWITCH_MODE_WRITE_BYTE) << 24) | ((EXT_CSD_PART_CONFIG) << 16) | ((partition) << 8));
-
+
/* Try to change the active partition. */
if (!sdmmc_mmc_switch(device, arg))
return 0;
-
+
/* Peek the current status. */
return sdmmc_device_send_status(device);
}
@@ -1399,25 +1399,25 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
uint32_t cid[4] = {0};
uint32_t csd[4] = {0};
uint8_t ext_csd[512] = {0};
-
+
/* Initialize our device's struct. */
memset(device, 0, sizeof(sdmmc_device_t));
-
+
/* Try to initialize the driver. */
if (!sdmmc_init(sdmmc, SDMMC_4, SDMMC_VOLTAGE_1V8, SDMMC_BUS_WIDTH_1BIT, SDMMC_SPEED_MMC_IDENT))
{
sdmmc_error(sdmmc, "Failed to initialize the SDMMC driver!");
return 0;
}
-
+
/* Bind the underlying driver. */
device->sdmmc = sdmmc;
-
+
/* Set RCA. */
device->rca = 0x01;
-
+
sdmmc_info(sdmmc, "SDMMC driver was successfully initialized for eMMC!");
-
+
/* Apply at least 74 clock cycles. eMMC should be ready afterwards. */
udelay((74000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
@@ -1427,7 +1427,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_error(sdmmc, "Failed to go idle!");
return 0;
}
-
+
sdmmc_info(sdmmc, "eMMC went idle!");
/* Get the eMMC's operating conditions. */
@@ -1436,25 +1436,25 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_error(sdmmc, "Failed to send op cond!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Sent op cond to eMMC!");
-
+
/* Get the eMMC's CID. */
if (!sdmmc_device_send_cid(device, cid))
{
sdmmc_error(sdmmc, "Failed to get CID!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got CID from eMMC!");
-
+
/* Set the eMMC's RCA. */
if (!sdmmc_mmc_set_relative_addr(device))
{
sdmmc_error(sdmmc, "Failed to set RCA!");
return 0;
}
-
+
sdmmc_info(sdmmc, "RCA is now set in eMMC!");
/* Get the eMMC card's CSD. */
@@ -1463,7 +1463,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_error(sdmmc, "Failed to get CSD!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got CSD from eMMC!");
/* Decode and save the CSD. */
@@ -1476,7 +1476,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Speed mode has been adjusted!");
/* Select the eMMC card. */
@@ -1485,7 +1485,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_error(sdmmc, "Failed to select eMMC card!");
return 0;
}
-
+
sdmmc_info(sdmmc, "eMMC card is now selected!");
/* Change the eMMC's block length. */
@@ -1494,37 +1494,37 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
sdmmc_error(sdmmc, "Failed to set eMMC's block length!");
return 0;
}
-
+
sdmmc_info(sdmmc, "eMMC's block length is now 512!");
/* Only specification version 4 and later support the next features. */
if (device->csd.mmca_vsn < CSD_SPEC_VER_4)
return 1;
-
+
/* Change the eMMC's bus width. */
if (!sdmmc_mmc_select_bus_width(device, bus_width))
{
sdmmc_error(sdmmc, "Failed to set eMMC's bus width!");
return 0;
}
-
+
sdmmc_info(sdmmc, "eMMC's bus width has been adjusted!");
-
+
/* Get the eMMC's extended CSD. */
if (!sdmmc_mmc_send_ext_csd(device, ext_csd))
{
sdmmc_error(sdmmc, "Failed to get EXT_CSD!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Got EXT_CSD from eMMC!");
-
+
/* Decode and save the extended CSD. */
sdmmc_mmc_decode_ext_csd(device, ext_csd);
-
+
/* Decode and save the CID. */
sdmmc_mmc_decode_cid(device, cid);
-
+
/* TODO: Handle automatic BKOPS properly. Leave it disabled for now. */
if (false && device->ext_csd.bkops && !(device->ext_csd.auto_bkops_en & EXT_CSD_AUTO_BKOPS_MASK))
{
@@ -1533,18 +1533,18 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth
}
else
sdmmc_info(sdmmc, "BKOPS is disabled!");
-
+
/* Switch to high speed mode. */
if (!sdmmc_mmc_select_timing(device, bus_speed))
{
sdmmc_error(sdmmc, "Failed to switch to high speed mode!");
return 0;
}
-
+
sdmmc_info(sdmmc, "Switched to high speed mode!");
-
+
/* Correct any inconsistent states. */
sdmmc_adjust_sd_clock(sdmmc);
-
+
return 1;
}
\ No newline at end of file
diff --git a/fusee/common/sdmmc/sdmmc_core.c b/fusee/common/sdmmc/sdmmc_core.c
index 500530e84..1fffb1bf4 100644
--- a/fusee/common/sdmmc/sdmmc_core.c
+++ b/fusee/common/sdmmc/sdmmc_core.c
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
#include
#include
#include
@@ -24,14 +24,14 @@
#include "sdmmc_core.h"
#if defined(FUSEE_STAGE1_SRC)
-#include "../../../fusee/fusee-primary/src/car.h"
-#include "../../../fusee/fusee-primary/src/fuse.h"
-#include "../../../fusee/fusee-primary/src/pinmux.h"
-#include "../../../fusee/fusee-primary/src/timers.h"
-#include "../../../fusee/fusee-primary/src/apb_misc.h"
-#include "../../../fusee/fusee-primary/src/gpio.h"
-#include "../../../fusee/fusee-primary/src/pmc.h"
-#include "../../../fusee/fusee-primary/src/max7762x.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/car.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/fuse.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/pinmux.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/timers.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/apb_misc.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/gpio.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/pmc.h"
+#include "../../../fusee/fusee-primary/fusee-primary-main/src/max7762x.h"
#elif defined(FUSEE_STAGE2_SRC)
#include "../../../fusee/fusee-secondary/src/car.h"
#include "../../../fusee/fusee-secondary/src/fuse.h"
@@ -57,7 +57,7 @@ static void sdmmc_print(sdmmc_t *sdmmc, ScreenLogLevel screen_log_level, char *f
{
if (screen_log_level > log_get_log_level())
return;
-
+
print(screen_log_level, "%s: ", sdmmc->name);
vprint(screen_log_level, fmt, list);
print(screen_log_level | SCREEN_LOG_LEVEL_NO_PREFIX, "\n");
@@ -66,7 +66,7 @@ static void sdmmc_print(sdmmc_t *sdmmc, ScreenLogLevel screen_log_level, char *f
void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...)
{
va_list list;
-
+
va_start(list, fmt);
sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_ERROR, fmt, list);
va_end(list);
@@ -75,7 +75,7 @@ void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...)
void sdmmc_warn(sdmmc_t *sdmmc, char *fmt, ...)
{
va_list list;
-
+
va_start(list, fmt);
sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_WARNING, fmt, list);
va_end(list);
@@ -84,7 +84,7 @@ void sdmmc_warn(sdmmc_t *sdmmc, char *fmt, ...)
void sdmmc_info(sdmmc_t *sdmmc, char *fmt, ...)
{
va_list list;
-
+
va_start(list, fmt);
sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_INFO, fmt, list);
va_end(list);
@@ -93,7 +93,7 @@ void sdmmc_info(sdmmc_t *sdmmc, char *fmt, ...)
void sdmmc_debug(sdmmc_t *sdmmc, char *fmt, ...)
{
va_list list;
-
+
va_start(list, fmt);
sdmmc_print(sdmmc, SCREEN_LOG_LEVEL_DEBUG, fmt, list);
va_end(list);
@@ -192,7 +192,7 @@ static bool is_soc_mariko() {
static bool is_sdmmc_clk_rst(SdmmcControllerNum controller)
{
volatile tegra_car_t *car = car_get_regs();
-
+
switch (controller) {
case SDMMC_1:
return (car->rst_dev_l & CLK_L_SDMMC1);
@@ -203,7 +203,7 @@ static bool is_sdmmc_clk_rst(SdmmcControllerNum controller)
case SDMMC_4:
return (car->rst_dev_l & CLK_L_SDMMC4);
}
-
+
return false;
}
@@ -211,7 +211,7 @@ static bool is_sdmmc_clk_rst(SdmmcControllerNum controller)
static void sdmmc_clk_set_rst(SdmmcControllerNum controller)
{
volatile tegra_car_t *car = car_get_regs();
-
+
switch (controller) {
case SDMMC_1:
car->rst_dev_l_set = CLK_L_SDMMC1;
@@ -232,7 +232,7 @@ static void sdmmc_clk_set_rst(SdmmcControllerNum controller)
static void sdmmc_clk_clear_rst(SdmmcControllerNum controller)
{
volatile tegra_car_t *car = car_get_regs();
-
+
switch (controller) {
case SDMMC_1:
car->rst_dev_l_clr = CLK_L_SDMMC1;
@@ -253,7 +253,7 @@ static void sdmmc_clk_clear_rst(SdmmcControllerNum controller)
static bool is_sdmmc_clk_enb(SdmmcControllerNum controller)
{
volatile tegra_car_t *car = car_get_regs();
-
+
switch (controller) {
case SDMMC_1:
return (car->clk_out_enb_l & CLK_L_SDMMC1);
@@ -264,7 +264,7 @@ static bool is_sdmmc_clk_enb(SdmmcControllerNum controller)
case SDMMC_4:
return (car->clk_out_enb_l & CLK_L_SDMMC4);
}
-
+
return false;
}
@@ -272,7 +272,7 @@ static bool is_sdmmc_clk_enb(SdmmcControllerNum controller)
static void sdmmc_clk_set_enb(SdmmcControllerNum controller)
{
volatile tegra_car_t *car = car_get_regs();
-
+
switch (controller) {
case SDMMC_1:
car->clk_enb_l_set = CLK_L_SDMMC1;
@@ -293,7 +293,7 @@ static void sdmmc_clk_set_enb(SdmmcControllerNum controller)
static void sdmmc_clk_clear_enb(SdmmcControllerNum controller)
{
volatile tegra_car_t *car = car_get_regs();
-
+
switch (controller) {
case SDMMC_1:
car->clk_enb_l_clr = CLK_L_SDMMC1;
@@ -376,7 +376,7 @@ static int sdmmc_get_sdclk_div(SdmmcBusSpeed bus_speed)
static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq)
{
volatile tegra_car_t *car = car_get_regs();
-
+
uint32_t car_div = 0;
uint32_t out_freq = 0;
@@ -417,7 +417,7 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq
default:
return 0;
}
-
+
sdmmc_clk_sources[controller].clk_source_val = clk_freq;
sdmmc_clk_sources[controller].clk_div_val = out_freq;
@@ -444,27 +444,27 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq
static int sdmmc_clk_adjust_source(SdmmcControllerNum controller, uint32_t clk_source_val)
{
uint32_t out_val = 0;
-
+
if (sdmmc_clk_sources[controller].clk_source_val == clk_source_val)
out_val = sdmmc_clk_sources[controller].clk_div_val;
else
{
bool was_sdmmc_clk_enb = is_sdmmc_clk_enb(controller);
-
+
/* Clock was already enabled. Disable it. */
if (was_sdmmc_clk_enb)
sdmmc_clk_clear_enb(controller);
-
+
out_val = sdmmc_clk_set_source(controller, clk_source_val);
-
+
/* Clock was already enabled. Enable it back. */
if (was_sdmmc_clk_enb)
sdmmc_clk_set_enb(controller);
-
+
/* Dummy read for value refreshing. */
is_sdmmc_clk_rst(controller);
}
-
+
return out_val;
}
@@ -504,25 +504,25 @@ static void sdmmc_clk_start(SdmmcControllerNum controller, uint32_t clk_source_v
/* Clock was already enabled. Disable it. */
if (is_sdmmc_clk_enb(controller))
sdmmc_clk_clear_enb(controller);
-
+
/* Put the device clock in reset. */
sdmmc_clk_set_rst(controller);
-
+
/* Configure the device clock source. */
uint32_t clk_div = sdmmc_clk_set_source(controller, clk_source_val);
-
+
/* Enable the device clock. */
sdmmc_clk_set_enb(controller);
-
+
/* Dummy read for value refreshing. */
is_sdmmc_clk_rst(controller);
-
+
/* Synchronize. */
udelay((100000 + clk_div - 1) / clk_div);
-
+
/* Take the device clock out of reset. */
sdmmc_clk_clear_rst(controller);
-
+
/* Dummy read for value refreshing. */
is_sdmmc_clk_rst(controller);
}
@@ -532,10 +532,10 @@ static void sdmmc_clk_stop(SdmmcControllerNum controller)
{
/* Put the device clock in reset. */
sdmmc_clk_set_rst(controller);
-
+
/* Disable the device clock. */
sdmmc_clk_clear_enb(controller);
-
+
/* Dummy read for value refreshing. */
is_sdmmc_clk_rst(controller);
}
@@ -548,7 +548,7 @@ static void sdmmc_vendor_clock_cntrl_config(sdmmc_t *sdmmc)
/* Set the PADPIPE clock enable */
sdmmc->regs->vendor_clock_cntrl |= SDMMC_CLOCK_PADPIPE_CLKEN_OVERRIDE;
-
+
/* Set the appropriate trim value. */
switch (sdmmc->controller) {
case SDMMC_1:
@@ -564,7 +564,7 @@ static void sdmmc_vendor_clock_cntrl_config(sdmmc_t *sdmmc)
sdmmc->regs->vendor_clock_cntrl |= (is_soc_mariko() ? SDMMC_CLOCK_TRIM_SDMMC4_MARIKO : SDMMC_CLOCK_TRIM_SDMMC4_ERISTA);
break;
}
-
+
/* Clear the SPI_MODE clock enable. */
sdmmc->regs->vendor_clock_cntrl &= ~(SDMMC_CLOCK_SPI_MODE_CLKEN_OVERRIDE);
}
@@ -588,7 +588,7 @@ static int sdmmc_autocal_config(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
sdmmc_error(sdmmc, "uSD does not support requested voltage!");
return 0;
}
-
+
break;
case SDMMC_2:
case SDMMC_4:
@@ -609,32 +609,32 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
{
volatile tegra_padctl_t *padctl = padctl_get_regs();
bool restart_sd_clock = false;
-
+
/* SD clock is enabled. Disable it and restart later. */
if (sdmmc->is_sd_clk_enabled)
{
restart_sd_clock = true;
sdmmc_disable_sd_clock(sdmmc);
}
-
+
/* Set PAD_E_INPUT_OR_E_PWRD */
if (!(sdmmc->regs->sdmemcomppadctrl & 0x80000000))
{
sdmmc->regs->sdmemcomppadctrl |= 0x80000000;
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Delay. */
udelay(1);
}
-
+
/* Start automatic calibration. */
sdmmc->regs->auto_cal_config |= (SDMMC_AUTOCAL_START | SDMMC_AUTOCAL_ENABLE);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Delay. */
udelay(2);
@@ -646,10 +646,10 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
/* Ensure we haven't timed out. */
if (get_time_since(timebase) > SDMMC_AUTOCAL_TIMEOUT) {
sdmmc_warn(sdmmc, "Auto-calibration timed out!");
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Upon timeout, fall back to standard values. */
if (sdmmc->controller == SDMMC_1) {
uint32_t drvup, drvdn = 0;
@@ -699,16 +699,16 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage)
value |= (drvdn << EMMC4_PAD_DRVDN_COMP_SHIFT);
padctl->emmc4_pad_cfgpadctrl = value;
}
-
+
/* Manually clear the autocal enable bit. */
sdmmc->regs->auto_cal_config &= ~(SDMMC_AUTOCAL_ENABLE);
break;
}
}
-
+
/* Clear PAD_E_INPUT_OR_E_PWRD (relevant for eMMC only) */
sdmmc->regs->sdmemcomppadctrl &= ~(0x80000000);
-
+
/* If requested, enable the SD clock. */
if (restart_sd_clock)
sdmmc_enable_sd_clock(sdmmc);
@@ -721,7 +721,7 @@ static int sdmmc_int_clk_enable(sdmmc_t *sdmmc)
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Program a timeout of 2000ms. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -742,23 +742,23 @@ static int sdmmc_int_clk_enable(sdmmc_t *sdmmc)
sdmmc->regs->host_control2 &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
sdmmc->regs->clock_control &= ~TEGRA_MMC_CLKCON_PROG_CLOCK_MODE;
sdmmc->regs->host_control2 |= SDHCI_HOST_VERSION_4_EN;
-
+
/* Ensure 64bit addressing is supported. */
if (!(sdmmc->regs->capabilities & SDHCI_CAN_64BIT)) {
sdmmc_error(sdmmc, "64bit addressing is unsupported!");
return 0;
}
-
+
/* Enable 64bit addressing. */
sdmmc->regs->host_control2 |= SDHCI_ADDRESSING_64BIT_EN;
-
+
/* Use SDMA by default. */
sdmmc->regs->host_control &= ~SDHCI_CTRL_DMA_MASK;
/* Change to ADMA if possible. */
if (sdmmc->regs->capabilities & SDHCI_CAN_DO_ADMA2)
sdmmc->use_adma = true;
-
+
/* Set the timeout to be the maximum value. */
sdmmc->regs->timeout_control &= 0xF0;
sdmmc->regs->timeout_control |= 0x0E;
@@ -819,10 +819,10 @@ static void sdmmc_tap_config(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
sdmmc->regs->vendor_cap_overrides &= ~(0x3F00);
sdmmc->regs->vendor_cap_overrides |= 0x2800;
}
-
+
/* Clear TAP_VAL_UPDATED_BY_HW */
sdmmc->regs->vendor_tuning_cntrl0 &= ~(0x20000);
-
+
if (bus_speed == SDMMC_SPEED_MMC_HS400)
{
/* We must have obtained the tap value from the tuning procedure here. */
@@ -849,7 +849,7 @@ static void sdmmc_tap_config(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
sdmmc->tap_val = 3;
break;
}
-
+
/* Clear and set the tap value. */
sdmmc->regs->vendor_clock_cntrl &= ~(0xFF0000);
sdmmc->regs->vendor_clock_cntrl |= (sdmmc->tap_val << 16);
@@ -859,20 +859,20 @@ static void sdmmc_tap_config(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
static int sdmmc_dllcal_run(sdmmc_t *sdmmc)
{
bool shutdown_sd_clock = false;
-
+
/* SD clock is disabled. Enable it. */
if (!sdmmc->is_sd_clk_enabled)
{
shutdown_sd_clock = true;
sdmmc_enable_sd_clock(sdmmc);
}
-
+
/* Set the CALIBRATE bit. */
sdmmc->regs->vendor_dllcal_cfg |= 0x80000000;
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Program a timeout of 5ms. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -888,7 +888,7 @@ static int sdmmc_dllcal_run(sdmmc_t *sdmmc)
sdmmc_error(sdmmc, "DLLCAL failed!");
return 0;
}
-
+
/* Program a timeout of 10ms. */
timebase = get_time();
is_timeout = false;
@@ -908,24 +908,24 @@ static int sdmmc_dllcal_run(sdmmc_t *sdmmc)
/* If requested, disable the SD clock. */
if (shutdown_sd_clock)
sdmmc_disable_sd_clock(sdmmc);
-
+
return 1;
}
int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
{
bool restart_sd_clock = false;
-
+
/* SD clock is enabled. Disable it and restart later. */
if (sdmmc->is_sd_clk_enabled)
{
restart_sd_clock = true;
sdmmc_disable_sd_clock(sdmmc);
}
-
+
/* Configure tap values as necessary. */
sdmmc_tap_config(sdmmc, bus_speed);
-
+
/* Set the appropriate host speed. */
switch (bus_speed) {
/* 400kHz initialization mode and a few others. */
@@ -944,7 +944,7 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
sdmmc->regs->host_control |= SDHCI_CTRL_HISPD;
sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_VDD_180);
break;
-
+
/* 200MHz UHS-I (SD) and other modes due to errata. */
case SDMMC_SPEED_MMC_HS200:
case SDMMC_SPEED_SD_SDR104:
@@ -956,14 +956,14 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
sdmmc->regs->host_control2 |= SDHCI_CTRL_UHS_SDR104;
sdmmc->regs->host_control2 |= SDHCI_CTRL_VDD_180;
break;
-
+
/* 200MHz single-data rate (MMC). */
case SDMMC_SPEED_MMC_HS400:
sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK);
sdmmc->regs->host_control2 |= SDHCI_CTRL_HS400;
sdmmc->regs->host_control2 |= SDHCI_CTRL_VDD_180;
break;
-
+
/* 25MHz default speed (SD). */
case SDMMC_SPEED_SD_SDR12:
sdmmc->regs->host_control2 &= ~(SDHCI_CTRL_UHS_MASK);
@@ -975,38 +975,38 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed)
sdmmc_error(sdmmc, "Switching to unsupported speed!");
return 0;
}
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Get the clock's frequency and divider. */
uint32_t freq_val = sdmmc_get_sdclk_freq(bus_speed);
uint32_t div_val = sdmmc_get_sdclk_div(bus_speed);
-
+
/* Adjust the CAR side of the clock. */
uint32_t out_freq_val = sdmmc_clk_adjust_source(sdmmc->controller, freq_val);
-
+
/* Save the internal divider value. */
sdmmc->internal_divider = ((out_freq_val + div_val - 1) / div_val);
-
+
uint16_t div_val_lo = div_val >> 1;
uint16_t div_val_hi = 0;
-
+
if (div_val_lo > 0xFF)
div_val_hi = (div_val_lo >> 8);
-
+
/* Set the clock control divider values. */
sdmmc->regs->clock_control &= ~((SDHCI_DIV_HI_MASK | SDHCI_DIV_MASK) << 6);
sdmmc->regs->clock_control |= ((div_val_hi << SDHCI_DIVIDER_HI_SHIFT) | (div_val_lo << SDHCI_DIVIDER_SHIFT));
-
+
/* If requested, enable the SD clock. */
if (restart_sd_clock)
sdmmc_enable_sd_clock(sdmmc);
-
+
/* Run DLLCAL for HS400 only */
if (bus_speed == SDMMC_SPEED_MMC_HS400)
return sdmmc_dllcal_run(sdmmc);
-
+
return 1;
}
@@ -1015,21 +1015,21 @@ static int sdmmc1_config()
volatile tegra_pinmux_t *pinmux = pinmux_get_regs();
volatile tegra_padctl_t *padctl = padctl_get_regs();
volatile tegra_pmc_t *pmc = pmc_get_regs();
-
+
/* Set up the card detect pin as a GPIO input */
pinmux->pz1 = PINMUX_SELECT_FUNCTION1 | PINMUX_PULL_UP | PINMUX_INPUT;
padctl->vgpio_gpio_mux_sel = 0;
gpio_configure_mode(GPIO_MICROSD_CARD_DETECT, GPIO_MODE_GPIO);
gpio_configure_direction(GPIO_MICROSD_CARD_DETECT, GPIO_DIRECTION_INPUT);
udelay(100);
-
+
/* Check the GPIO. */
if (gpio_read(GPIO_MICROSD_CARD_DETECT))
return 0;
-
+
/* Enable loopback control. */
padctl->sdmmc1_clk_lpbk_control = 1;
-
+
/* Set up the SDMMC1 pinmux. */
pinmux->sdmmc1_clk = PINMUX_DRIVE_2X | PINMUX_PARKED | PINMUX_SELECT_FUNCTION0 | PINMUX_INPUT;
pinmux->sdmmc1_cmd = PINMUX_DRIVE_2X | PINMUX_PARKED | PINMUX_SELECT_FUNCTION0 | PINMUX_INPUT | PINMUX_PULL_UP;
@@ -1040,21 +1040,21 @@ static int sdmmc1_config()
/* Ensure the PMC is prepared for the SDMMC1 card to receive power. */
pmc->no_iopower &= ~PMC_CONTROL_SDMMC1;
-
+
/* Configure the enable line for the SD card power. */
pinmux->dmic3_clk = PINMUX_SELECT_FUNCTION1 | PINMUX_PULL_DOWN | PINMUX_INPUT;
gpio_configure_mode(GPIO_MICROSD_SUPPLY_ENABLE, GPIO_MODE_GPIO);
gpio_write(GPIO_MICROSD_SUPPLY_ENABLE, GPIO_LEVEL_HIGH);
gpio_configure_direction(GPIO_MICROSD_SUPPLY_ENABLE, GPIO_DIRECTION_OUTPUT);
-
+
/* Delay. */
udelay(10000);
-
+
/* Configure Sdmmc1 IO as 3.3V. */
pmc->pwr_det_val |= PMC_CONTROL_SDMMC1;
max77620_regulator_set_voltage(REGULATOR_LDO2, 3300000);
max77620_regulator_enable(REGULATOR_LDO2, 1);
-
+
/* Delay. */
udelay(130);
@@ -1081,14 +1081,14 @@ static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller)
/* Sanitize input number for the controller. */
if ((controller < SDMMC_1) || (controller > SDMMC_4))
return 0;
-
+
/* Clear up memory for our struct. */
memset(sdmmc, 0, sizeof(sdmmc_t));
-
+
/* Bind the appropriate controller and it's register space to our struct. */
sdmmc->controller = controller;
sdmmc->regs = sdmmc_get_regs(controller);
-
+
/* Set up per-device pointers and properties. */
switch (sdmmc->controller) {
case SDMMC_1:
@@ -1107,7 +1107,7 @@ static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller)
/* Function pointers. */
sdmmc->sdmmc_config = sdmmc1_config;
break;
-
+
case SDMMC_2:
/* Controller properties. */
sdmmc->name = "GC";
@@ -1124,7 +1124,7 @@ static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller)
/* Function pointers. */
sdmmc->sdmmc_config = sdmmc2_config;
break;
-
+
case SDMMC_3:
/* Controller properties. */
sdmmc->name = "UNUSED";
@@ -1141,7 +1141,7 @@ static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller)
/* Function pointers. */
sdmmc->sdmmc_config = sdmmc3_config;
break;
-
+
case SDMMC_4:
/* Controller properties. */
sdmmc->name = "eMMC";
@@ -1170,13 +1170,13 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu
sdmmc_error(sdmmc, "Failed to initialize SDMMC%d", controller + 1);
return 0;
}
-
+
/* Perform initial configuration steps if necessary. */
if (!sdmmc->sdmmc_config()) {
sdmmc_error(sdmmc, "Failed to configure controller!");
return 0;
}
-
+
/* Initialize the clock status. */
sdmmc->is_clk_running = false;
@@ -1184,17 +1184,17 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu
if (!is_sdmmc_clk_rst(controller) && is_sdmmc_clk_enb(controller)) {
/* Disable the SD clock. */
sdmmc_disable_sd_clock(sdmmc);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
}
-
+
/* Sort out the clock's frequency. */
uint32_t clk_freq_val = sdmmc_get_sdclk_freq(bus_speed);
-
+
/* Start the SDMMC clock. */
sdmmc_clk_start(controller, clk_freq_val);
-
+
/* Update the clock status. */
sdmmc->is_clk_running = true;
@@ -1203,10 +1203,10 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu
/* Clear SEL_VREG */
sdmmc->regs->vendor_io_trim_cntrl &= ~(0x04);
-
+
/* Configure vendor clocking. */
sdmmc_vendor_clock_cntrl_config(sdmmc);
-
+
/* Set slew codes for SDMMC1 (Erista only). */
if ((controller == SDMMC_1) && !(is_soc_mariko())) {
volatile tegra_padctl_t *padctl = padctl_get_regs();
@@ -1223,28 +1223,28 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu
sdmmc->regs->sdmemcomppadctrl |= 0x00;
else
sdmmc->regs->sdmemcomppadctrl |= 0x07;
-
+
/* Configure autocal offsets. */
if (!sdmmc_autocal_config(sdmmc, bus_voltage)) {
sdmmc_error(sdmmc, "Failed to configure automatic calibration!");
return 0;
}
-
+
/* Do autocal. */
sdmmc_autocal_run(sdmmc, bus_voltage);
-
+
/* Enable the internal clock. */
if (!sdmmc_int_clk_enable(sdmmc)) {
sdmmc_error(sdmmc, "Failed to enable the internal clock!");
return 0;
}
-
+
/* Select the desired bus width. */
sdmmc_select_bus_width(sdmmc, bus_width);
/* Select the desired voltage. */
sdmmc_select_voltage(sdmmc, bus_voltage);
-
+
/* Enable the internal clock. */
if (!sdmmc_select_speed(sdmmc, bus_speed)) {
sdmmc_error(sdmmc, "Failed to apply the correct bus speed!");
@@ -1253,13 +1253,13 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu
/* Correct any inconsistent states. */
sdmmc_adjust_sd_clock(sdmmc);
-
+
/* Enable the SD clock. */
sdmmc_enable_sd_clock(sdmmc);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
return 1;
}
@@ -1270,29 +1270,29 @@ void sdmmc_finish(sdmmc_t *sdmmc)
{
/* Disable the SD clock. */
sdmmc_disable_sd_clock(sdmmc);
-
+
/* 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);
-
+
/* Disable the regulator. */
max77620_regulator_enable(REGULATOR_LDO2, 0);
}
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Stop the SDMMC clock. */
sdmmc_clk_stop(sdmmc->controller);
-
+
/* Clock is no longer running by now. */
sdmmc->is_clk_running = false;
}
@@ -1302,10 +1302,10 @@ static void sdmmc_do_sw_reset(sdmmc_t *sdmmc)
{
/* Assert a software reset. */
sdmmc->regs->software_reset |= (TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE | TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Program a timeout of 100ms. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -1321,7 +1321,7 @@ static int sdmmc_wait_for_inhibit(sdmmc_t *sdmmc, bool wait_for_dat)
{
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Program a timeout of 10ms. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -1331,14 +1331,14 @@ static int sdmmc_wait_for_inhibit(sdmmc_t *sdmmc, bool wait_for_dat)
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 10000);
}
-
+
/* Bit was never released. Reset. */
if (is_timeout)
{
sdmmc_do_sw_reset(sdmmc);
return 0;
}
-
+
if (wait_for_dat)
{
/* Program a timeout of 10ms. */
@@ -1350,7 +1350,7 @@ static int sdmmc_wait_for_inhibit(sdmmc_t *sdmmc, bool wait_for_dat)
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 10000);
}
-
+
/* Bit was never released, reset. */
if (is_timeout)
{
@@ -1366,7 +1366,7 @@ static int sdmmc_wait_busy(sdmmc_t *sdmmc)
{
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Program a timeout of 10ms. */
uint32_t timebase = get_time();
bool is_timeout = false;
@@ -1376,7 +1376,7 @@ static int sdmmc_wait_busy(sdmmc_t *sdmmc)
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 10000);
}
-
+
/* Bit was never released. Reset. */
if (is_timeout)
{
@@ -1392,7 +1392,7 @@ static void sdmmc_intr_enable(sdmmc_t *sdmmc)
/* Enable the relevant interrupts and set all error bits. */
sdmmc->regs->int_enable |= (TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE | TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE | TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT);
sdmmc->regs->int_enable |= 0x017F0000;
-
+
/* Refresh status. */
sdmmc->regs->int_status = sdmmc->regs->int_status;
}
@@ -1407,13 +1407,13 @@ static void sdmmc_intr_disable(sdmmc_t *sdmmc)
static int sdmmc_intr_check(sdmmc_t *sdmmc, uint16_t *status_out, uint16_t status_mask)
{
uint32_t int_status = sdmmc->regs->int_status;
-
+
sdmmc_debug(sdmmc, "INTSTS: %08X", int_status);
-
+
/* Return the status, if necessary. */
if (status_out)
*status_out = (int_status & 0xFFFF);
-
+
if (int_status & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT)
{
/* Acknowledge error by refreshing status. */
@@ -1426,7 +1426,7 @@ static int sdmmc_intr_check(sdmmc_t *sdmmc, uint16_t *status_out, uint16_t statu
sdmmc->regs->int_status = (int_status & status_mask);
return 1;
}
-
+
return 0;
}
@@ -1438,13 +1438,13 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
sdmmc_error(sdmmc, "Empty DMA request!");
return 0;
}
-
+
uint32_t blkcnt = req->num_blocks;
-
+
/* Truncate block count. Length can't be over 65536 bytes. */
if (blkcnt >= 0xFFFF)
blkcnt = 0xFFFF;
-
+
/* 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;
@@ -1454,7 +1454,7 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
sdmmc_error(sdmmc, "Invalid DMA request data buffer: 0x%08X", dma_base_addr);
return 0;
}
-
+
/* Write our address to the registers. */
if (sdmmc->use_adma)
{
@@ -1473,28 +1473,28 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
/* Set the block size ORed with the DMA boundary mask. */
sdmmc->regs->block_size = req->blksz | 0x7000;
-
+
/* Set the block count. */
sdmmc->regs->block_count = blkcnt;
-
+
/* Select basic DMA transfer mode. */
uint32_t transfer_mode = TEGRA_MMC_TRNMOD_DMA_ENABLE;
-
+
/* Select multi block. */
if (req->is_multi_block)
transfer_mode |= (TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT | TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE);
-
+
/* Select read mode. */
if (req->is_read)
transfer_mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
-
+
/* Select AUTO_CMD12. */
if (req->is_auto_cmd12)
{
transfer_mode &= ~(TEGRA_MMC_TRNMOD_AUTO_CMD12 & TEGRA_MMC_TRNMOD_AUTO_CMD23);
transfer_mode |= TEGRA_MMC_TRNMOD_AUTO_CMD12;
}
-
+
/* Set the transfer mode in the register. */
sdmmc->regs->transfer_mode = transfer_mode;
@@ -1504,35 +1504,35 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req)
static int sdmmc_dma_update(sdmmc_t *sdmmc)
{
uint16_t blkcnt = 0;
-
+
/* Loop until all blocks have been consumed. */
do
{
/* Update block count. */
blkcnt = sdmmc->regs->block_count;
-
+
/* Program a large timeout. */
uint32_t timebase = get_time();
bool is_timeout = false;
-
+
/* Watch over the DMA transfer. */
- while (!is_timeout)
+ while (!is_timeout)
{
/* Check interrupts. */
uint16_t intr_status = 0;
int intr_res = sdmmc_intr_check(sdmmc, &intr_status, TEGRA_MMC_NORINTSTS_XFER_COMPLETE | TEGRA_MMC_NORINTSTS_DMA_INTERRUPT);
-
+
/* An error has been raised. Reset. */
if (intr_res < 0)
{
sdmmc_do_sw_reset(sdmmc);
return 0;
}
-
+
/* Transfer is over. */
if (intr_status & TEGRA_MMC_NORINTSTS_XFER_COMPLETE)
return 1;
-
+
/* We have a DMA interrupt. Restart the transfer where it was interrupted. */
if (intr_status & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT)
{
@@ -1547,15 +1547,15 @@ static int sdmmc_dma_update(sdmmc_t *sdmmc)
/* Update SDMA register. */
sdmmc->regs->dma_address = sdmmc->next_dma_addr;
}
-
+
sdmmc->next_dma_addr += 0x80000;
}
-
+
/* Keep checking if timeout expired. */
- is_timeout = (get_time_since(timebase) > 2000000);
+ is_timeout = (get_time_since(timebase) > 2000000);
}
} while (sdmmc->regs->block_count < blkcnt);
-
+
/* Should never get here. Reset. */
sdmmc_do_sw_reset(sdmmc);
return 0;
@@ -1564,7 +1564,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)
{
uint16_t cmd_reg_flags = 0;
-
+
/* Select length flags based on response type. */
if (!(cmd->flags & SDMMC_RSP_PRESENT))
cmd_reg_flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE;
@@ -1574,19 +1574,19 @@ static void sdmmc_set_cmd_flags(sdmmc_t *sdmmc, sdmmc_command_t *cmd, bool is_dm
cmd_reg_flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY;
else
cmd_reg_flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48;
-
+
/* Select CRC flag based on response type. */
if (cmd->flags & SDMMC_RSP_CRC)
cmd_reg_flags |= TEGRA_MMC_TRNMOD_CMD_CRC_CHECK;
-
+
/* Select opcode flag based on response type. */
if (cmd->flags & SDMMC_RSP_OPCODE)
cmd_reg_flags |= TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK;
-
+
/* Select data present flag. */
if (is_dma)
cmd_reg_flags |= TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER;
-
+
/* Set the CMD's argument, opcode and flags. */
sdmmc->regs->argument = cmd->arg;
sdmmc->regs->command = ((cmd->opcode << 8) | cmd_reg_flags);
@@ -1596,11 +1596,11 @@ static int sdmmc_wait_for_cmd(sdmmc_t *sdmmc)
{
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Program a large timeout. */
uint32_t timebase = get_time();
bool is_timeout = false;
-
+
/* Set this for error checking. */
bool is_err = false;
@@ -1608,18 +1608,18 @@ static int sdmmc_wait_for_cmd(sdmmc_t *sdmmc)
while (!is_err && !is_timeout) {
/* Check interrupts. */
int intr_res = sdmmc_intr_check(sdmmc, 0, TEGRA_MMC_NORINTSTS_CMD_COMPLETE);
-
+
/* Command is done. */
if (intr_res > 0)
return 1;
-
+
/* Check for any raised errors. */
is_err = (intr_res < 0);
-
+
/* Keep checking if timeout expired. */
is_timeout = (get_time_since(timebase) > 2000000);
}
-
+
/* Should never get here. Reset. */
sdmmc_do_sw_reset(sdmmc);
return 0;
@@ -1635,7 +1635,7 @@ static int sdmmc_save_response(sdmmc_t *sdmmc, uint32_t flags)
/* CRC is stripped so we need to do some shifting. */
for (int i = 0; i < 4; i++) {
sdmmc->resp[i] = (sdmmc->regs->response[3 - i] << 0x08);
-
+
if (i != 0)
sdmmc->resp[i - 1] |= ((sdmmc->regs->response[3 - i] >> 24) & 0xFF);
}
@@ -1649,14 +1649,14 @@ static int sdmmc_save_response(sdmmc_t *sdmmc, uint32_t flags)
if (!sdmmc_wait_busy(sdmmc))
return 0;
}
-
+
/* Save our response. */
sdmmc->resp[0] = sdmmc->regs->response[0];
}
-
+
return 1;
}
-
+
/* Invalid response. */
return 0;
}
@@ -1666,7 +1666,7 @@ int sdmmc_load_response(sdmmc_t *sdmmc, uint32_t flags, uint32_t *resp)
/* Make sure our output buffer is valid. */
if (!resp)
return 0;
-
+
/* We have a valid response. */
if (flags & SDMMC_RSP_PRESENT)
{
@@ -1679,10 +1679,10 @@ int sdmmc_load_response(sdmmc_t *sdmmc, uint32_t flags, uint32_t *resp)
}
else
resp[0] = sdmmc->resp[0];
-
+
return 1;
}
-
+
/* Invalid response. */
return 0;
}
@@ -1691,68 +1691,68 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
{
uint32_t cmd_result = 0;
bool shutdown_sd_clock = false;
-
+
/* Run automatic calibration on each command submission for SDMMC1 (Erista only). */
if ((sdmmc->controller == SDMMC_1) && !(sdmmc->has_sd) && !(is_soc_mariko()))
sdmmc_autocal_run(sdmmc, sdmmc->bus_voltage);
-
+
/* SD clock is disabled. Enable it. */
if (!sdmmc->is_sd_clk_enabled)
{
shutdown_sd_clock = true;
sdmmc_enable_sd_clock(sdmmc);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Provide 8 clock cycles after enabling the clock. */
udelay((8000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
}
/* Determine if we should wait for data inhibit. */
bool wait_for_dat = (req || (cmd->flags & SDMMC_RSP_BUSY));
-
+
/* Wait for CMD and DAT inhibit. */
if (!sdmmc_wait_for_inhibit(sdmmc, wait_for_dat))
return 0;
uint32_t dma_blkcnt = 0;
bool is_dma = false;
-
+
/* This is a data transfer. */
if (req)
{
is_dma = true;
dma_blkcnt = sdmmc_dma_init(sdmmc, req);
-
+
/* Abort in case initialization failed. */
if (!dma_blkcnt)
{
sdmmc_error(sdmmc, "Failed to initialize the DMA transfer!");
return 0;
}
-
+
/* 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);
}
-
+
/* Enable interrupts. */
sdmmc_intr_enable(sdmmc);
/* Parse and set the CMD's flags. */
sdmmc_set_cmd_flags(sdmmc, cmd, is_dma);
-
+
/* Wait for the CMD to finish. */
cmd_result = sdmmc_wait_for_cmd(sdmmc);
-
+
sdmmc_debug(sdmmc, "CMD(%d): %08X, %08X, %08X, %08X", cmd_result, sdmmc->regs->response[0], sdmmc->regs->response[1], sdmmc->regs->response[2], sdmmc->regs->response[3]);
-
+
if (cmd_result)
{
/* Save response, if necessary. */
sdmmc_save_response(sdmmc, cmd->flags);
-
+
/* Update the DMA request. */
if (req)
{
@@ -1763,7 +1763,7 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
sdmmc_intr_disable(sdmmc);
return 0;
}
-
+
/* If this is a SDMA read operation, copy the data from our bounce buffer. */
if (!sdmmc->use_adma && req->is_read)
{
@@ -1783,20 +1783,20 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
/* Save back the number of DMA blocks. */
if (num_blocks_out)
*num_blocks_out = dma_blkcnt;
-
+
/* Save the response for AUTO_CMD12. */
if (req->is_auto_cmd12)
sdmmc->resp_auto_cmd12 = sdmmc->regs->response[3];
}
-
+
/* Wait for DAT0 to be 0. */
if (req || (cmd->flags & SDMMC_RSP_BUSY))
cmd_result = sdmmc_wait_busy(sdmmc);
}
-
+
/* Provide 8 clock cycles before disabling the clock. */
udelay((8000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
-
+
if (shutdown_sd_clock)
sdmmc_disable_sd_clock(sdmmc);
@@ -1806,17 +1806,17 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u
int sdmmc_switch_voltage(sdmmc_t *sdmmc)
{
volatile tegra_pmc_t *pmc = pmc_get_regs();
-
+
/* Disable the SD clock. */
sdmmc_disable_sd_clock(sdmmc);
-
+
/* Reconfigure the internal clock. */
if (!sdmmc_select_speed(sdmmc, SDMMC_SPEED_SD_SDR12))
{
sdmmc_error(sdmmc, "Failed to apply the correct bus speed for low voltage support!");
return 0;
}
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
@@ -1832,31 +1832,31 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc)
sdmmc_error(sdmmc, "Failed to configure automatic calibration for low voltage support!");
return 0;
}
-
+
/* Do autocal again. */
sdmmc_autocal_run(sdmmc, SDMMC_VOLTAGE_1V8);
-
+
/* Change the desired voltage. */
sdmmc_select_voltage(sdmmc, SDMMC_VOLTAGE_1V8);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Wait a while. */
mdelay(5);
-
+
/* Host control 2 flag should be set by now. */
if (sdmmc->regs->host_control2 & SDHCI_CTRL_VDD_180)
{
/* Enable the SD clock. */
sdmmc_enable_sd_clock(sdmmc);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Wait a while. */
mdelay(1);
-
+
/* Data level is up. Voltage switching is done.*/
if (sdmmc->regs->present_state & SDHCI_DATA_LVL_MASK)
return 1;
@@ -1870,11 +1870,11 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode)
/* Nothing to do. */
if (!sdmmc->has_sd)
return 0;
-
+
/* Wait for CMD and DAT inhibit. */
if (!sdmmc_wait_for_inhibit(sdmmc, true))
return 0;
-
+
/* Select the right size for sending the tuning block. */
if (sdmmc->bus_width == SDMMC_BUS_WIDTH_4BIT)
sdmmc->regs->block_size = 0x40;
@@ -1882,48 +1882,48 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode)
sdmmc->regs->block_size = 0x80;
else
return 0;
-
+
/* Select the block count and transfer mode. */
sdmmc->regs->block_count = 1;
sdmmc->regs->transfer_mode = TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ;
-
+
/* Manually enable the Buffer Read Ready interrupt. */
sdmmc->regs->int_enable |= TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY;
-
+
/* Refresh status. */
sdmmc->regs->int_status = sdmmc->regs->int_status;
-
+
/* Disable the SD clock. */
sdmmc_disable_sd_clock(sdmmc);
-
+
/* Prepare the tuning command. */
sdmmc_command_t cmd = {};
cmd.opcode = opcode;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_R1;
-
+
/* Parse and set the CMD's flags. */
sdmmc_set_cmd_flags(sdmmc, &cmd, true);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Wait a while. */
udelay(1);
-
+
/* Reset. */
sdmmc_do_sw_reset(sdmmc);
-
+
/* Enable back the SD clock. */
sdmmc_enable_sd_clock(sdmmc);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Program a 50ms timeout. */
uint32_t timebase = get_time();
bool is_timeout = false;
-
+
/* Wait for Buffer Read Ready interrupt. */
while (!is_timeout)
{
@@ -1932,13 +1932,13 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode)
{
/* Manually disable the Buffer Read Ready interrupt. */
sdmmc->regs->int_enable &= ~(TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Provide 8 clock cycles. */
udelay((8000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
-
+
return 1;
}
@@ -1948,16 +1948,16 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode)
/* Reset. */
sdmmc_do_sw_reset(sdmmc);
-
+
/* Manually disable the Buffer Read Ready interrupt. */
sdmmc->regs->int_enable &= ~(TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Provide 8 clock cycles. */
udelay((8000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
-
+
return 0;
}
@@ -1973,7 +1973,7 @@ int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcod
uint32_t tuning_cntrl_flag = 0;
sdmmc->regs->vendor_tuning_cntrl1 = 0;
-
+
switch (bus_speed)
{
case SDMMC_SPEED_MMC_HS200:
@@ -1995,12 +1995,12 @@ int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcod
sdmmc->regs->vendor_tuning_cntrl0 &= ~(0xE000);
sdmmc->regs->vendor_tuning_cntrl0 |= tuning_cntrl_flag;
-
+
sdmmc->regs->vendor_tuning_cntrl0 &= ~(0x1FC0);
sdmmc->regs->vendor_tuning_cntrl0 |= 0x40;
-
+
sdmmc->regs->vendor_tuning_cntrl0 |= 0x20000;
-
+
/* Start tuning. */
sdmmc->regs->host_control2 |= SDHCI_CTRL_EXEC_TUNING;
@@ -2008,7 +2008,7 @@ int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcod
for (uint32_t i = 0; i < max_tuning_loop; i++)
{
sdmmc_send_tuning(sdmmc, opcode);
-
+
/* Tuning is done. */
if (!(sdmmc->regs->host_control2 & SDHCI_CTRL_EXEC_TUNING))
break;
@@ -2017,7 +2017,7 @@ int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcod
/* Success! */
if (sdmmc->regs->host_control2 & SDHCI_CTRL_TUNED_CLK)
return 1;
-
+
return 0;
}
@@ -2026,20 +2026,20 @@ int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode)
uint32_t result = 0;
uint32_t cmd_result = 0;
bool shutdown_sd_clock = false;
-
+
/* SD clock is disabled. Enable it. */
if (!sdmmc->is_sd_clk_enabled)
{
shutdown_sd_clock = true;
sdmmc_enable_sd_clock(sdmmc);
-
+
/* Force a register read to refresh the clock control value. */
sdmmc_get_sd_clock_control(sdmmc);
-
+
/* Provide 8 clock cycles after enabling the clock. */
udelay((8000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
}
-
+
/* Wait for CMD and DAT inhibit. */
if (sdmmc_wait_for_inhibit(sdmmc, false))
{
@@ -2051,29 +2051,29 @@ int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode)
cmd.opcode = opcode;
cmd.arg = 0;
cmd.flags = SDMMC_RSP_R1B;
-
+
/* Parse and set the CMD's flags. */
sdmmc_set_cmd_flags(sdmmc, &cmd, false);
-
+
/* Wait for the CMD to finish. */
cmd_result = sdmmc_wait_for_cmd(sdmmc);
-
+
/* Disable interrupts. */
sdmmc_intr_disable(sdmmc);
-
+
if (cmd_result)
{
/* Save response, if necessary. */
sdmmc_save_response(sdmmc, cmd.flags);
-
+
/* Wait for DAT0 to be 0. */
result = sdmmc_wait_busy(sdmmc);
}
}
-
+
/* Provide 8 clock cycles before disabling the clock. */
udelay((8000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider);
-
+
/* Disable the SD clock if requested. */
if (shutdown_sd_clock)
sdmmc_disable_sd_clock(sdmmc);