diff --git a/fusee/common/sdmmc/sdmmc.c b/fusee/common/sdmmc/sdmmc.c index 2385c58e1..2fb6bd320 100644 --- a/fusee/common/sdmmc/sdmmc.c +++ b/fusee/common/sdmmc/sdmmc.c @@ -71,8 +71,7 @@ static const unsigned int taac_mant[] = { Common SDMMC device functions. */ -static bool is_sdmmc_device_r1_error(uint32_t status) -{ +static bool is_sdmmc_device_r1_error(uint32_t status) { return (status & (R1_OUT_OF_RANGE | R1_ADDRESS_ERROR | R1_BLOCK_LEN_ERROR | R1_ERASE_SEQ_ERROR | R1_ERASE_PARAM | R1_WP_VIOLATION | R1_LOCK_UNLOCK_FAILED | R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND @@ -80,8 +79,7 @@ static bool is_sdmmc_device_r1_error(uint32_t status) | R1_WP_ERASE_SKIP | R1_ERASE_RESET | R1_SWITCH_ERROR)); } -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) -{ +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; @@ -89,36 +87,39 @@ static int sdmmc_device_send_r1_cmd(sdmmc_device_t *device, uint32_t opcode, uin cmd.flags = (is_busy ? SDMMC_RSP_R1B : SDMMC_RSP_R1); /* Try to send the command. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp)) { return 0; + } /* Mask the response, if necessary. */ - if (resp_mask) + 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) - { + if (resp_state != 0xFFFFFFFF) { /* We didn't get the expected state. */ - if (R1_CURRENT_STATE(resp) != resp_state) + if (R1_CURRENT_STATE(resp) != resp_state) { return 0; + } } return 1; } -static int sdmmc_device_go_idle(sdmmc_device_t *device) -{ +static int sdmmc_device_go_idle(sdmmc_device_t *device) { sdmmc_command_t cmd = {}; cmd.opcode = MMC_GO_IDLE_STATE; @@ -128,8 +129,7 @@ static int sdmmc_device_go_idle(sdmmc_device_t *device) return sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0); } -static int sdmmc_device_send_cid(sdmmc_device_t *device, uint32_t *cid) -{ +static int sdmmc_device_send_cid(sdmmc_device_t *device, uint32_t *cid) { sdmmc_command_t cmd = {}; cmd.opcode = MMC_ALL_SEND_CID; @@ -137,15 +137,15 @@ static int sdmmc_device_send_cid(sdmmc_device_t *device, uint32_t *cid) cmd.flags = SDMMC_RSP_R2; /* Try to send the command. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0)) + 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); } -static int sdmmc_device_send_csd(sdmmc_device_t *device, uint32_t *csd) -{ +static int sdmmc_device_send_csd(sdmmc_device_t *device, uint32_t *csd) { sdmmc_command_t cmd = {}; cmd.opcode = MMC_SEND_CSD; @@ -153,45 +153,40 @@ static int sdmmc_device_send_csd(sdmmc_device_t *device, uint32_t *csd) cmd.flags = SDMMC_RSP_R2; /* Try to send the command. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0)) + 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) -{ +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) -{ +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) -{ +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); } -static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data, bool is_read) -{ +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) - { + while (num_sectors) { uint32_t num_blocks_out = 0; uint32_t num_retries = 10; - for (; num_retries > 0; num_retries--) - { + 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; @@ -204,8 +199,7 @@ static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num req.is_auto_cmd12 = true; /* Try to send the command. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, &req, &num_blocks_out)) - { + if (!sdmmc_send_cmd(device->sdmmc, &cmd, &req, &num_blocks_out)) { /* Abort the transmission. */ sdmmc_abort(device->sdmmc, MMC_STOP_TRANSMISSION); @@ -214,14 +208,15 @@ static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num /* Wait for a while. */ mdelay(100); - } - else + } else { break; + } } /* Failed to read/write on all attempts. */ - if (!num_retries) + if (!num_retries) { return 0; + } /* Advance to next sector. */ sector += num_blocks_out; @@ -232,21 +227,19 @@ static int sdmmc_device_rw(sdmmc_device_t *device, uint32_t sector, uint32_t num return 1; } -int sdmmc_device_read(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data) -{ +int sdmmc_device_read(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data) { return sdmmc_device_rw(device, sector, num_sectors, data, true); } -int sdmmc_device_write(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data) -{ +int sdmmc_device_write(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data) { return sdmmc_device_rw(device, sector, num_sectors, data, false); } -int sdmmc_device_finish(sdmmc_device_t *device) -{ +int sdmmc_device_finish(sdmmc_device_t *device) { /* Place the device in idle state. */ - if (!sdmmc_device_go_idle(device)) + if (!sdmmc_device_go_idle(device)) { return 0; + } /* Terminate the device. */ sdmmc_finish(device->sdmmc); @@ -257,8 +250,7 @@ int sdmmc_device_finish(sdmmc_device_t *device) SD device functions. */ -static void sdmmc_sd_decode_cid(sdmmc_device_t *device, uint32_t *cid) -{ +static void sdmmc_sd_decode_cid(sdmmc_device_t *device, uint32_t *cid) { device->cid.manfid = UNSTUFF_BITS(cid, 120, 8); device->cid.oemid = UNSTUFF_BITS(cid, 104, 16); device->cid.prod_name[0] = UNSTUFF_BITS(cid, 96, 8); @@ -273,8 +265,7 @@ static void sdmmc_sd_decode_cid(sdmmc_device_t *device, uint32_t *cid) device->cid.month = UNSTUFF_BITS(cid, 8, 4); } -static int sdmmc_sd_decode_csd(sdmmc_device_t *device, uint32_t *csd) -{ +static int sdmmc_sd_decode_csd(sdmmc_device_t *device, uint32_t *csd) { unsigned int e, m; device->csd.structure = UNSTUFF_BITS(csd, 126, 2); @@ -339,14 +330,12 @@ static int sdmmc_sd_decode_csd(sdmmc_device_t *device, uint32_t *csd) return 1; } -static int sdmmc_sd_decode_scr(sdmmc_device_t *device, uint8_t *scr) -{ +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) - { + for (int i = 0; i < 8; i += 4) { tmp[i + 3] = scr[i]; tmp[i + 2] = scr[i + 1]; tmp[i + 1] = scr[i + 2]; @@ -360,28 +349,28 @@ static int sdmmc_sd_decode_scr(sdmmc_device_t *device, uint8_t *scr) 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) + if (device->scr.sda_vsn == SD_SCR_SPEC_VER_2) { device->scr.sda_spec3 = UNSTUFF_BITS(resp, 47, 1); - - if (device->scr.sda_spec3) + } + if (device->scr.sda_spec3) { device->scr.cmds = UNSTUFF_BITS(resp, 32, 2); - + } + /* Unknown SCR structure version. */ - if (UNSTUFF_BITS(resp, 60, 4)) + if (UNSTUFF_BITS(resp, 60, 4)) { return 0; - else + } else { return 1; + } } -static void sdmmc_sd_decode_ssr(sdmmc_device_t *device, uint8_t *ssr) -{ +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) - { + for (int i = 0; i < 64; i += 4) { tmp[i + 3] = ssr[i]; tmp[i + 2] = ssr[i + 1]; tmp[i + 1] = ssr[i + 2]; @@ -400,31 +389,32 @@ static void sdmmc_sd_decode_ssr(sdmmc_device_t *device, uint8_t *ssr) 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) + if (device->ssr.speed_class < 4) { device->ssr.speed_class <<= 1; - else if (device->ssr.speed_class == 4) + } 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); } -static int sdmmc_sd_send_app_cmd(sdmmc_device_t *device, sdmmc_command_t *cmd, sdmmc_request_t *req, uint32_t resp_mask, uint32_t resp_state) -{ +static int sdmmc_sd_send_app_cmd(sdmmc_device_t *device, sdmmc_command_t *cmd, sdmmc_request_t *req, uint32_t resp_mask, uint32_t resp_state) { /* Try to send the APP command. */ - if (!sdmmc_device_send_r1_cmd(device, MMC_APP_CMD, (device->rca << 16), false, resp_mask, resp_state)) + 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)) + 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) -{ +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; @@ -433,8 +423,7 @@ static int sdmmc_sd_send_if_cond(sdmmc_device_t *device, bool *is_sd_ver2) cmd.flags = SDMMC_RSP_R7; /* Command failed, this means SD Card is not version 2. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0)) - { + if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0)) { *is_sd_ver2 = false; return 1; } @@ -442,12 +431,12 @@ static int sdmmc_sd_send_if_cond(sdmmc_device_t *device, bool *is_sd_ver2) uint32_t resp = 0; /* Try to load back the response. */ - if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R7, &resp)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R7, &resp)) { return 0; + } /* Check if we got a valid response. */ - if ((resp & 0xFF) == 0xAA) - { + if ((resp & 0xFF) == 0xAA) { *is_sd_ver2 = true; return 1; } @@ -455,67 +444,66 @@ static int sdmmc_sd_send_if_cond(sdmmc_device_t *device, bool *is_sd_ver2) return 0; } -static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool is_uhs_en) -{ +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; - while (!is_timeout) - { + while (!is_timeout) { /* 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) - { + if (is_sd_ver2) { arg |= SD_OCR_XPC; arg |= SD_OCR_CCS; } /* Request support 1.8V switching. */ - if (is_uhs_en) + 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)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R3, &resp)) { return 0; + } /* Card Power up bit is set. */ - if (resp & MMC_CARD_BUSY) - { + if (resp & MMC_CARD_BUSY) { /* We have a SDHC block mode card. */ - if (resp & SD_OCR_CCS) + if (resp & SD_OCR_CCS) { device->is_block_sdhc = true; - + } /* We asked for low voltage support and the card accepted. */ - if (is_uhs_en && (resp & SD_ROCR_S18A)) - { + if (is_uhs_en && (resp & SD_ROCR_S18A)) { /* Voltage switching is only valid for SDMMC1. */ - if (device->sdmmc->controller == SDMMC_1) - { + if (device->sdmmc->controller == SDMMC_1) { /* Failed to issue voltage switching command. */ - if (!sdmmc_device_send_r1_cmd(device, SD_SWITCH_VOLTAGE, 0, false, 0, R1_STATE_READY)) + 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)) + if (!sdmmc_switch_voltage(device->sdmmc)) { return 0; + } /* We are now running at 1.8V. */ device->is_180v = true; @@ -535,8 +523,7 @@ static int sdmmc_sd_send_op_cond(sdmmc_device_t *device, bool is_sd_ver2, bool i return 0; } -static int sdmmc_sd_send_relative_addr(sdmmc_device_t *device) -{ +static int sdmmc_sd_send_relative_addr(sdmmc_device_t *device) { sdmmc_command_t cmd = {}; cmd.opcode = SD_SEND_RELATIVE_ADDR; @@ -547,21 +534,21 @@ static int sdmmc_sd_send_relative_addr(sdmmc_device_t *device) uint32_t timebase = get_time(); bool is_timeout = false; - while (!is_timeout) - { + while (!is_timeout) { /* Try to send the command. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, 0, 0)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R6, &resp)) { return 0; + } /* Save the RCA. */ - if (resp >> 16) - { + if (resp >> 16) { device->rca = (resp >> 16); return 1; } @@ -576,8 +563,7 @@ static int sdmmc_sd_send_relative_addr(sdmmc_device_t *device) return 0; } -static int sdmmc_sd_send_scr(sdmmc_device_t *device, uint8_t *scr) -{ +static int sdmmc_sd_send_scr(sdmmc_device_t *device, uint8_t *scr) { sdmmc_command_t cmd = {}; sdmmc_request_t req = {}; @@ -593,44 +579,46 @@ static int sdmmc_sd_send_scr(sdmmc_device_t *device, uint8_t *scr) req.is_auto_cmd12 = false; /* Try to send the APP command. */ - if (!sdmmc_sd_send_app_cmd(device, &cmd, &req, 0, R1_STATE_TRAN)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp)) { return 0; + } /* Evaluate the response. */ - if (is_sdmmc_device_r1_error(resp)) + if (is_sdmmc_device_r1_error(resp)) { return 0; - else + } else { return 1; + } } -static int sdmmc_sd_set_clr_card_detect(sdmmc_device_t *device) -{ +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)) + 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) -{ +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)) + 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); } -static int sdmmc_sd_switch(sdmmc_device_t *device, uint32_t mode, uint32_t group, uint8_t value, uint8_t *data) -{ +static int sdmmc_sd_switch(sdmmc_device_t *device, uint32_t mode, uint32_t group, uint8_t value, uint8_t *data) { sdmmc_command_t cmd = {}; sdmmc_request_t req = {}; @@ -648,37 +636,40 @@ static int sdmmc_sd_switch(sdmmc_device_t *device, uint32_t mode, uint32_t group req.is_auto_cmd12 = false; /* Try to send the command. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, &req, 0)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp)) { return 0; + } /* Evaluate the response. */ - if (is_sdmmc_device_r1_error(resp)) + if (is_sdmmc_device_r1_error(resp)) { return 0; - else + } else { return 1; + } } -static int sdmmc_sd_set_current_limit(sdmmc_device_t *device, uint8_t *status) -{ +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) - { + while (current_limit > SD_SET_CURRENT_NO_CHANGE) { /* Switch the current limit. */ - if (!sdmmc_sd_switch(device, SD_SWITCH_SET, 3, current_limit, status)) + 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) + if (((status[15] >> 4) & 0x0F) == current_limit) { break; + } current_limit--; } @@ -686,113 +677,121 @@ static int sdmmc_sd_set_current_limit(sdmmc_device_t *device, uint8_t *status) return 1; } -static int sdmmc_sd_switch_hs(sdmmc_device_t *device, uint32_t type, uint8_t *status) -{ +static int sdmmc_sd_switch_hs(sdmmc_device_t *device, uint32_t type, uint8_t *status) { /* Test if the card supports high-speed mode. */ - if (!sdmmc_sd_switch(device, 0, 0, type, status)) + if (!sdmmc_sd_switch(device, 0, 0, type, status)) { return 0; + } uint32_t res_type = (status[16] & 0xF); /* This high-speed mode type is not supported. */ - if (res_type != type) + if (res_type != type) { return 0; + } - if ((((uint16_t)status[0] << 8) | status[1]) < 0x320) - { + if ((((uint16_t)status[0] << 8) | status[1]) < 0x320) { /* Try to switch to high-speed mode. */ - if (!sdmmc_sd_switch(device, 1, 0, type, status)) + if (!sdmmc_sd_switch(device, 1, 0, type, status)) { return 0; + } /* Something failed when switching to high-speed mode. */ - if ((status[16] & 0xF) != res_type) + if ((status[16] & 0xF) != res_type) { return 0; + } } return 1; } -static int sdmmc_sd_switch_hs_low(sdmmc_device_t *device, uint8_t *status) -{ +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)) + if (!sdmmc_sd_set_current_limit(device, status)) { return 0; + } /* Invalid bus width. */ - if (device->sdmmc->bus_width != SDMMC_BUS_WIDTH_4BIT) + if (device->sdmmc->bus_width != SDMMC_BUS_WIDTH_4BIT) { return 0; + } /* Get the supported high-speed type. */ - if (!sdmmc_sd_switch(device, 0, 0, 0xF, status)) + if (!sdmmc_sd_switch(device, 0, 0, 0xF, status)) { return 0; + } /* High-speed SDR104 is supported. */ - if (status[13] & SD_MODE_UHS_SDR104) - { + if (status[13] & SD_MODE_UHS_SDR104) { /* Switch to high-speed. */ - if (!sdmmc_sd_switch_hs(device, UHS_SDR104_BUS_SPEED, status)) + if (!sdmmc_sd_switch_hs(device, UHS_SDR104_BUS_SPEED, status)) { return 0; + } /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR104)) + if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR104)) { return 0; + } /* Run tuning. */ - if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR104, MMC_SEND_TUNING_BLOCK)) + if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR104, MMC_SEND_TUNING_BLOCK)) { return 0; - } - else if (status[13] & SD_MODE_UHS_SDR50) /* High-speed SDR50 is supported. */ - { + } + } else if (status[13] & SD_MODE_UHS_SDR50) { /* High-speed SDR50 is supported. */ /* Switch to high-speed. */ - if (!sdmmc_sd_switch_hs(device, UHS_SDR50_BUS_SPEED, status)) + if (!sdmmc_sd_switch_hs(device, UHS_SDR50_BUS_SPEED, status)) { return 0; + } /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR50)) + if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR50)) { return 0; + } /* Run tuning. */ - if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR50, MMC_SEND_TUNING_BLOCK)) + if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR50, MMC_SEND_TUNING_BLOCK)) { return 0; - } - else if (status[13] & SD_MODE_UHS_SDR12) /* High-speed SDR12 is supported. */ - { + } + } else if (status[13] & SD_MODE_UHS_SDR12) { /* High-speed SDR12 is supported. */ /* Switch to high-speed. */ - if (!sdmmc_sd_switch_hs(device, UHS_SDR12_BUS_SPEED, status)) + if (!sdmmc_sd_switch_hs(device, UHS_SDR12_BUS_SPEED, status)) { return 0; + } /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR12)) + if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR12)) { return 0; + } /* Run tuning. */ - if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR12, MMC_SEND_TUNING_BLOCK)) + if (!sdmmc_execute_tuning(device->sdmmc, SDMMC_SPEED_SD_SDR12, MMC_SEND_TUNING_BLOCK)) { return 0; - } - else + } + } else { return 0; - + } /* Peek the SD card's status. */ return sdmmc_device_send_status(device); } -static int sdmmc_sd_switch_hs_high(sdmmc_device_t *device, uint8_t *status) -{ +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)) + if (!sdmmc_sd_switch(device, 0, 0, 0xF, status)) { return 0; + } /* High-speed is supported. */ - if (status[13] & 2) - { + if (status[13] & 2) { /* Switch to high-speed. */ - if (!sdmmc_sd_switch_hs(device, SDHCI_CTRL_UHS_SDR25, status)) + 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)) + if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_SDR25)) { return 0; + } /* Peek the SD card's status. */ return sdmmc_device_send_status(device); @@ -802,8 +801,7 @@ static int sdmmc_sd_switch_hs_high(sdmmc_device_t *device, uint8_t *status) return 1; } -static int sdmmc_sd_status(sdmmc_device_t *device, uint8_t *ssr) -{ +static int sdmmc_sd_status(sdmmc_device_t *device, uint8_t *ssr) { sdmmc_command_t cmd = {}; sdmmc_request_t req = {}; @@ -819,24 +817,26 @@ static int sdmmc_sd_status(sdmmc_device_t *device, uint8_t *ssr) req.is_auto_cmd12 = false; /* Try to send the APP command. */ - if (!sdmmc_sd_send_app_cmd(device, &cmd, &req, 0, R1_STATE_TRAN)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp)) { return 0; + } /* Evaluate the response. */ - if (is_sdmmc_device_r1_error(resp)) + if (is_sdmmc_device_r1_error(resp)) { return 0; - else + } else { return 1; + } } -int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed) -{ +int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed) { bool is_sd_ver2 = false; uint32_t cid[4] = {0}; uint32_t csd[4] = {0}; @@ -848,8 +848,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b 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)) - { + 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; } @@ -863,8 +862,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b udelay((74000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider); /* Instruct the SD card to go idle. */ - if (!sdmmc_device_go_idle(device)) - { + if (!sdmmc_device_go_idle(device)) { sdmmc_error(sdmmc, "Failed to go idle!"); return 0; } @@ -872,8 +870,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "SD card went idle!"); /* Get the SD card's interface operating condition. */ - if (!sdmmc_sd_send_if_cond(device, &is_sd_ver2)) - { + if (!sdmmc_sd_send_if_cond(device, &is_sd_ver2)) { sdmmc_error(sdmmc, "Failed to send if cond!"); return 0; } @@ -881,8 +878,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "Sent if cond to SD card!"); /* Get the SD card's operating conditions. */ - if (!sdmmc_sd_send_op_cond(device, is_sd_ver2, (bus_width == SDMMC_BUS_WIDTH_4BIT) && (bus_speed == SDMMC_SPEED_SD_SDR104))) - { + if (!sdmmc_sd_send_op_cond(device, is_sd_ver2, (bus_width == SDMMC_BUS_WIDTH_4BIT) && (bus_speed == SDMMC_SPEED_SD_SDR104))) { sdmmc_error(sdmmc, "Failed to send op cond!"); return 0; } @@ -890,8 +886,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "Sent op cond to SD card!"); /* Get the SD card's CID. */ - if (!sdmmc_device_send_cid(device, cid)) - { + if (!sdmmc_device_send_cid(device, cid)) { sdmmc_error(sdmmc, "Failed to get CID!"); return 0; } @@ -902,8 +897,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_sd_decode_cid(device, cid); /* Get the SD card's RCA. */ - if (!sdmmc_sd_send_relative_addr(device)) - { + if (!sdmmc_sd_send_relative_addr(device)) { sdmmc_error(sdmmc, "Failed to get RCA!"); return 0; } @@ -911,8 +905,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "Got RCA (0x%08x) from SD card!", device->rca); /* Get the SD card's CSD. */ - if (!sdmmc_device_send_csd(device, csd)) - { + if (!sdmmc_device_send_csd(device, csd)) { sdmmc_error(sdmmc, "Failed to get CSD!"); return 0; } @@ -920,15 +913,14 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "Got CSD from SD card!"); /* Decode and save the CSD. */ - if (!sdmmc_sd_decode_csd(device, 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) - { + if (!device->is_180v) { /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_DS)) - { + if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_SD_DS)) { sdmmc_error(sdmmc, "Failed to apply the correct bus speed!"); return 0; } @@ -937,8 +929,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b } /* Select the SD card. */ - if (!sdmmc_device_select_card(device)) - { + if (!sdmmc_device_select_card(device)) { sdmmc_error(sdmmc, "Failed to select SD card!"); return 0; } @@ -946,8 +937,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "SD card is now selected!"); /* Change the SD card's block length. */ - if (!sdmmc_device_set_blocklen(device, 512)) - { + if (!sdmmc_device_set_blocklen(device, 512)) { sdmmc_error(sdmmc, "Failed to set SD card's block length!"); return 0; } @@ -955,8 +945,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "SD card's block length is now 512!"); /* It's a good practice to disconnect the pull-up resistor with ACMD42. */ - if (!sdmmc_sd_set_clr_card_detect(device)) - { + if (!sdmmc_sd_set_clr_card_detect(device)) { sdmmc_error(sdmmc, "Failed to disconnect the pull-up resistor!"); return 0; } @@ -964,8 +953,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "Pull-up resistor is now disconnected!"); /* Get the SD card's SCR. */ - if (!sdmmc_sd_send_scr(device, scr)) - { + if (!sdmmc_sd_send_scr(device, scr)) { sdmmc_error(sdmmc, "Failed to get SCR!"); return 0; } @@ -973,8 +961,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "Got SCR from SD card!"); /* Decode and save the SCR. */ - if (!sdmmc_sd_decode_scr(device, scr)) - { + if (!sdmmc_sd_decode_scr(device, scr)) { sdmmc_error(sdmmc, "Got unknown SCR structure!"); return 0; } @@ -982,10 +969,8 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b /* Switch to wider bus (if supported). */ if ((bus_width == SDMMC_BUS_WIDTH_4BIT) && (device->scr.bus_widths & SD_SCR_BUS_WIDTH_4) - && (device->scr.sda_vsn & (SD_SCR_SPEC_VER_1 | SD_SCR_SPEC_VER_2))) - { - if (!sdmmc_sd_set_bus_width(device)) - { + && (device->scr.sda_vsn & (SD_SCR_SPEC_VER_1 | SD_SCR_SPEC_VER_2))) { + if (!sdmmc_sd_set_bus_width(device)) { sdmmc_error(sdmmc, "Failed to switch to wider bus!"); return 0; } @@ -994,22 +979,17 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_info(sdmmc, "Switched to wider bus!"); } - if (device->is_180v) - { + if (device->is_180v) { /* Switch to high-speed from low voltage (if possible). */ - if (!sdmmc_sd_switch_hs_low(device, switch_status)) - { + if (!sdmmc_sd_switch_hs_low(device, switch_status)) { 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))) - { + } else if ((device->scr.sda_vsn & (SD_SCR_SPEC_VER_1 | SD_SCR_SPEC_VER_2)) && ((bus_speed != SDMMC_SPEED_SD_DS))) { /* Switch to high-speed from high voltage (if possible). */ - if (!sdmmc_sd_switch_hs_high(device, switch_status)) - { + if (!sdmmc_sd_switch_hs_high(device, switch_status)) { sdmmc_error(sdmmc, "Failed to switch to high-speed from high voltage!"); return 0; } @@ -1021,8 +1001,7 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b sdmmc_adjust_sd_clock(sdmmc); /* Get the SD card's SSR. */ - if (!sdmmc_sd_status(device, ssr)) - { + if (!sdmmc_sd_status(device, ssr)) { sdmmc_error(sdmmc, "Failed to get SSR!"); return 0; } @@ -1039,10 +1018,8 @@ int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth b MMC device functions. */ -static void sdmmc_mmc_decode_cid(sdmmc_device_t *device, uint32_t *cid) -{ - switch (device->csd.mmca_vsn) - { +static void sdmmc_mmc_decode_cid(sdmmc_device_t *device, uint32_t *cid) { + switch (device->csd.mmca_vsn) { case 0: /* MMC v1.0 - v1.2 */ case 1: /* MMC v1.4 */ device->cid.prod_name[6] = UNSTUFF_BITS(cid, 48, 8); @@ -1073,12 +1050,12 @@ 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)) + if ((device->ext_csd.rev >= 5) && (device->cid.year < 2010)) { device->cid.year += 16; + } } -static int sdmmc_mmc_decode_csd(sdmmc_device_t *device, uint32_t *csd) -{ +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); @@ -1112,8 +1089,7 @@ static int sdmmc_mmc_decode_csd(sdmmc_device_t *device, uint32_t *csd) device->csd.write_blkbits = UNSTUFF_BITS(csd, 22, 4); device->csd.write_partial = UNSTUFF_BITS(csd, 21, 1); - if (device->csd.write_blkbits >= 9) - { + if (device->csd.write_blkbits >= 9) { a = UNSTUFF_BITS(csd, 42, 5); b = UNSTUFF_BITS(csd, 37, 5); device->csd.erase_size = ((a + 1) * (b + 1)); @@ -1123,8 +1099,7 @@ static int sdmmc_mmc_decode_csd(sdmmc_device_t *device, uint32_t *csd) return 1; } -static void sdmmc_mmc_decode_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd) -{ +static void sdmmc_mmc_decode_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd) { device->ext_csd.rev = ext_csd[EXT_CSD_REV]; device->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; device->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; @@ -1138,48 +1113,49 @@ static void sdmmc_mmc_decode_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd) device->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS]; } -static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_voltage) -{ +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; - while (!is_timeout) - { + while (!is_timeout) { /* Set high capacity bit. */ uint32_t arg = SD_OCR_CCS; /* Set voltage bits. */ - if (bus_voltage == SDMMC_VOLTAGE_1V8) + if (bus_voltage == SDMMC_VOLTAGE_1V8) { arg |= MMC_VDD_165_195; - else if (bus_voltage == SDMMC_VOLTAGE_3V3) + } else if (bus_voltage == SDMMC_VOLTAGE_3V3) { 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 + } 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)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R3, &resp)) { return 0; + } /* Card Power up bit is set. */ - if (resp & MMC_CARD_BUSY) - { + if (resp & MMC_CARD_BUSY) { /* We have a SDHC block mode card. */ - if (resp & SD_OCR_CCS) + if (resp & SD_OCR_CCS) { device->is_block_sdhc = true; - + } + return 1; } @@ -1193,8 +1169,7 @@ static int sdmmc_mmc_send_op_cond(sdmmc_device_t *device, SdmmcBusVoltage bus_vo return 0; } -static int sdmmc_mmc_send_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd) -{ +static int sdmmc_mmc_send_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd) { sdmmc_command_t cmd = {}; sdmmc_request_t req = {}; @@ -1210,41 +1185,40 @@ static int sdmmc_mmc_send_ext_csd(sdmmc_device_t *device, uint8_t *ext_csd) req.is_auto_cmd12 = false; /* Try to send the command. */ - if (!sdmmc_send_cmd(device->sdmmc, &cmd, &req, 0)) + 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)) + if (!sdmmc_load_response(device->sdmmc, SDMMC_RSP_R1, &resp)) { return 0; + } /* Evaluate the response. */ - if (is_sdmmc_device_r1_error(resp)) + if (is_sdmmc_device_r1_error(resp)) { return 0; - else + } else { return 1; + } } -static int sdmmc_mmc_set_relative_addr(sdmmc_device_t *device) -{ +static int sdmmc_mmc_set_relative_addr(sdmmc_device_t *device) { /* Try to send the command. */ return sdmmc_device_send_r1_cmd(device, MMC_SET_RELATIVE_ADDR, (device->rca << 16), false, 0, 0xFFFFFFFF); } -static int sdmmc_mmc_switch(sdmmc_device_t *device, uint32_t arg) -{ +static int sdmmc_mmc_switch(sdmmc_device_t *device, uint32_t arg) { /* Try to send the command. */ return sdmmc_device_send_r1_cmd(device, MMC_SWITCH, arg, true, 0, 0xFFFFFFFF); } -static int sdmmc_mmc_select_bus_width(sdmmc_device_t *device, SdmmcBusWidth bus_width) -{ +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) - { + switch (bus_width) { case SDMMC_BUS_WIDTH_1BIT: return 1; case SDMMC_BUS_WIDTH_4BIT: @@ -1258,8 +1232,7 @@ static int sdmmc_mmc_select_bus_width(sdmmc_device_t *device, SdmmcBusWidth bus_ } /* Try to switch the bus width. */ - if (sdmmc_mmc_switch(device, arg) && sdmmc_device_send_status(device)) - { + if (sdmmc_mmc_switch(device, arg) && sdmmc_device_send_status(device)) { sdmmc_select_bus_width(device->sdmmc, bus_width); return 1; } @@ -1267,102 +1240,105 @@ static int sdmmc_mmc_select_bus_width(sdmmc_device_t *device, SdmmcBusWidth bus_ return 0; } -static int sdmmc_mmc_select_hs(sdmmc_device_t *device, bool ignore_status) -{ +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)) + if (!sdmmc_mmc_switch(device, arg)) { return 0; + } /* Check the status if necessary. */ - if (!ignore_status && !sdmmc_device_send_status(device)) + if (!ignore_status && !sdmmc_device_send_status(device)) { return 0; + } /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_HS)) + 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)) + if (!ignore_status && !sdmmc_device_send_status(device)) { return 0; + } return 1; } -static int sdmmc_mmc_select_hs200(sdmmc_device_t *device) -{ +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)) + if (!sdmmc_mmc_switch(device, arg)) { return 0; + } /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_HS200)) + 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)) + 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); } -static int sdmmc_mmc_select_hs400(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)) + 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)) + 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)) + 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)) + if (!sdmmc_mmc_switch(device, arg)) { return 0; + } /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_HS400)) + if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_HS400)) { return 0; + } /* Peek the current status. */ return sdmmc_device_send_status(device); } -static int sdmmc_mmc_select_timing(sdmmc_device_t *device, SdmmcBusSpeed bus_speed) -{ +static int sdmmc_mmc_select_timing(sdmmc_device_t *device, SdmmcBusSpeed bus_speed) { if ((bus_speed == SDMMC_SPEED_MMC_HS400) && (device->sdmmc->bus_width == SDMMC_BUS_WIDTH_8BIT) && - (device->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_HS400_1_8V)) - { + (device->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_HS400_1_8V)) { /* Switch to HS400. */ return sdmmc_mmc_select_hs400(device); - } - else if (((bus_speed == SDMMC_SPEED_MMC_HS400) || (bus_speed == SDMMC_SPEED_MMC_HS200)) && + } else if (((bus_speed == SDMMC_SPEED_MMC_HS400) || (bus_speed == SDMMC_SPEED_MMC_HS200)) && ((device->sdmmc->bus_width == SDMMC_BUS_WIDTH_8BIT) || (device->sdmmc->bus_width == SDMMC_BUS_WIDTH_4BIT)) && - (device->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_HS200_1_8V)) - { + (device->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_HS200_1_8V)) { /* Switch to HS200. */ return sdmmc_mmc_select_hs200(device); - } - else if (device->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_HS_52) - { + } else if (device->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_HS_52) { /* Switch to HS. */ return sdmmc_mmc_select_hs(device, false); } @@ -1370,32 +1346,31 @@ static int sdmmc_mmc_select_timing(sdmmc_device_t *device, SdmmcBusSpeed bus_spe return 0; } -static int sdmmc_mmc_select_bkops(sdmmc_device_t *device) -{ +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)) + if (!sdmmc_mmc_switch(device, arg)) { return 0; + } /* Peek the current status. */ return sdmmc_device_send_status(device); } -int sdmmc_mmc_select_partition(sdmmc_device_t *device, SdmmcPartitionNum partition) -{ +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)) + if (!sdmmc_mmc_switch(device, arg)) { return 0; + } /* Peek the current status. */ return sdmmc_device_send_status(device); } -int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed) -{ +int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed) { uint32_t cid[4] = {0}; uint32_t csd[4] = {0}; uint8_t ext_csd[512] = {0}; @@ -1404,8 +1379,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth 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)) - { + 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; } @@ -1422,8 +1396,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth udelay((74000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider); /* Instruct the eMMC to go idle. */ - if (!sdmmc_device_go_idle(device)) - { + if (!sdmmc_device_go_idle(device)) { sdmmc_error(sdmmc, "Failed to go idle!"); return 0; } @@ -1431,8 +1404,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth sdmmc_info(sdmmc, "eMMC went idle!"); /* Get the eMMC's operating conditions. */ - if (!sdmmc_mmc_send_op_cond(device, SDMMC_VOLTAGE_1V8)) - { + if (!sdmmc_mmc_send_op_cond(device, SDMMC_VOLTAGE_1V8)) { sdmmc_error(sdmmc, "Failed to send op cond!"); return 0; } @@ -1440,8 +1412,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth sdmmc_info(sdmmc, "Sent op cond to eMMC!"); /* Get the eMMC's CID. */ - if (!sdmmc_device_send_cid(device, cid)) - { + if (!sdmmc_device_send_cid(device, cid)) { sdmmc_error(sdmmc, "Failed to get CID!"); return 0; } @@ -1449,8 +1420,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth sdmmc_info(sdmmc, "Got CID from eMMC!"); /* Set the eMMC's RCA. */ - if (!sdmmc_mmc_set_relative_addr(device)) - { + if (!sdmmc_mmc_set_relative_addr(device)) { sdmmc_error(sdmmc, "Failed to set RCA!"); return 0; } @@ -1458,8 +1428,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth sdmmc_info(sdmmc, "RCA is now set in eMMC!"); /* Get the eMMC card's CSD. */ - if (!sdmmc_device_send_csd(device, csd)) - { + if (!sdmmc_device_send_csd(device, csd)) { sdmmc_error(sdmmc, "Failed to get CSD!"); return 0; } @@ -1467,12 +1436,12 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth sdmmc_info(sdmmc, "Got CSD from eMMC!"); /* Decode and save the CSD. */ - if (!sdmmc_mmc_decode_csd(device, csd)) + if (!sdmmc_mmc_decode_csd(device, csd)) { sdmmc_warn(sdmmc, "Got unknown CSD structure (0x%08x)!", device->csd.structure); - + } + /* Reconfigure the internal clock. */ - if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_LEGACY)) - { + if (!sdmmc_select_speed(device->sdmmc, SDMMC_SPEED_MMC_LEGACY)) { sdmmc_error(sdmmc, "Failed to apply the correct bus speed!"); return 0; } @@ -1480,8 +1449,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth sdmmc_info(sdmmc, "Speed mode has been adjusted!"); /* Select the eMMC card. */ - if (!sdmmc_device_select_card(device)) - { + if (!sdmmc_device_select_card(device)) { sdmmc_error(sdmmc, "Failed to select eMMC card!"); return 0; } @@ -1489,8 +1457,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth sdmmc_info(sdmmc, "eMMC card is now selected!"); /* Change the eMMC's block length. */ - if (!sdmmc_device_set_blocklen(device, 512)) - { + if (!sdmmc_device_set_blocklen(device, 512)) { sdmmc_error(sdmmc, "Failed to set eMMC's block length!"); return 0; } @@ -1498,12 +1465,12 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth 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) + 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)) - { + if (!sdmmc_mmc_select_bus_width(device, bus_width)) { sdmmc_error(sdmmc, "Failed to set eMMC's bus width!"); return 0; } @@ -1511,8 +1478,7 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth 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)) - { + if (!sdmmc_mmc_send_ext_csd(device, ext_csd)) { sdmmc_error(sdmmc, "Failed to get EXT_CSD!"); return 0; } @@ -1526,17 +1492,15 @@ int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth 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)) - { + if (false && device->ext_csd.bkops && !(device->ext_csd.auto_bkops_en & EXT_CSD_AUTO_BKOPS_MASK)) { sdmmc_mmc_select_bkops(device); sdmmc_info(sdmmc, "BKOPS is enabled!"); - } - else + } else { sdmmc_info(sdmmc, "BKOPS is disabled!"); - + } + /* Switch to high speed mode. */ - if (!sdmmc_mmc_select_timing(device, bus_speed)) - { + if (!sdmmc_mmc_select_timing(device, bus_speed)) { sdmmc_error(sdmmc, "Failed to switch to high speed mode!"); return 0; } diff --git a/fusee/common/sdmmc/sdmmc_core.c b/fusee/common/sdmmc/sdmmc_core.c index 1fffb1bf4..3bc8f5c88 100644 --- a/fusee/common/sdmmc/sdmmc_core.c +++ b/fusee/common/sdmmc/sdmmc_core.c @@ -53,54 +53,44 @@ #endif #include "../log.h" -static void sdmmc_print(sdmmc_t *sdmmc, ScreenLogLevel screen_log_level, char *fmt, va_list list) -{ - if (screen_log_level > log_get_log_level()) +static void sdmmc_print(sdmmc_t *sdmmc, ScreenLogLevel screen_log_level, char *fmt, va_list list) { + 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"); } -void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...) -{ +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); } -void sdmmc_warn(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); } -void sdmmc_info(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); } -void sdmmc_debug(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); } -void sdmmc_dump_regs(sdmmc_t *sdmmc) -{ +void sdmmc_dump_regs(sdmmc_t *sdmmc) { sdmmc_debug(sdmmc, "dma_address: 0x%08" PRIX32, sdmmc->regs->dma_address); sdmmc_debug(sdmmc, "block_size: 0x%04" PRIX16, sdmmc->regs->block_size); sdmmc_debug(sdmmc, "block_count: 0x%04" PRIX16, sdmmc->regs->block_count); @@ -189,8 +179,7 @@ static bool is_soc_mariko() { } /* Check if the SDMMC device clock is held in reset. */ -static bool is_sdmmc_clk_rst(SdmmcControllerNum controller) -{ +static bool is_sdmmc_clk_rst(SdmmcControllerNum controller) { volatile tegra_car_t *car = car_get_regs(); switch (controller) { @@ -208,8 +197,7 @@ static bool is_sdmmc_clk_rst(SdmmcControllerNum controller) } /* Put the SDMMC device clock in reset. */ -static void sdmmc_clk_set_rst(SdmmcControllerNum controller) -{ +static void sdmmc_clk_set_rst(SdmmcControllerNum controller) { volatile tegra_car_t *car = car_get_regs(); switch (controller) { @@ -229,8 +217,7 @@ static void sdmmc_clk_set_rst(SdmmcControllerNum controller) } /* Take the SDMMC device clock out of reset. */ -static void sdmmc_clk_clear_rst(SdmmcControllerNum controller) -{ +static void sdmmc_clk_clear_rst(SdmmcControllerNum controller) { volatile tegra_car_t *car = car_get_regs(); switch (controller) { @@ -250,8 +237,7 @@ static void sdmmc_clk_clear_rst(SdmmcControllerNum controller) } /* Check if the SDMMC device clock is enabled. */ -static bool is_sdmmc_clk_enb(SdmmcControllerNum controller) -{ +static bool is_sdmmc_clk_enb(SdmmcControllerNum controller) { volatile tegra_car_t *car = car_get_regs(); switch (controller) { @@ -269,8 +255,7 @@ static bool is_sdmmc_clk_enb(SdmmcControllerNum controller) } /* Enable the SDMMC device clock. */ -static void sdmmc_clk_set_enb(SdmmcControllerNum controller) -{ +static void sdmmc_clk_set_enb(SdmmcControllerNum controller) { volatile tegra_car_t *car = car_get_regs(); switch (controller) { @@ -290,8 +275,7 @@ static void sdmmc_clk_set_enb(SdmmcControllerNum controller) } /* Disable the SDMMC device clock. */ -static void sdmmc_clk_clear_enb(SdmmcControllerNum controller) -{ +static void sdmmc_clk_clear_enb(SdmmcControllerNum controller) { volatile tegra_car_t *car = car_get_regs(); switch (controller) { @@ -311,10 +295,8 @@ static void sdmmc_clk_clear_enb(SdmmcControllerNum controller) } /* Get the appropriate SDMMC maximum frequency. */ -static int sdmmc_get_sdclk_freq(SdmmcBusSpeed bus_speed) -{ - switch (bus_speed) - { +static int sdmmc_get_sdclk_freq(SdmmcBusSpeed bus_speed) { + switch (bus_speed) { case SDMMC_SPEED_MMC_IDENT: case SDMMC_SPEED_MMC_LEGACY: return 26000; @@ -344,10 +326,8 @@ static int sdmmc_get_sdclk_freq(SdmmcBusSpeed bus_speed) } /* Get the appropriate SDMMC divider for the SDCLK. */ -static int sdmmc_get_sdclk_div(SdmmcBusSpeed bus_speed) -{ - switch (bus_speed) - { +static int sdmmc_get_sdclk_div(SdmmcBusSpeed bus_speed) { + switch (bus_speed) { case SDMMC_SPEED_MMC_IDENT: return 66; case SDMMC_SPEED_SD_IDENT: @@ -373,15 +353,13 @@ static int sdmmc_get_sdclk_div(SdmmcBusSpeed bus_speed) } /* Set the device clock source and CAR divider. */ -static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq) -{ +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; - switch (clk_freq) - { + switch (clk_freq) { case 25000: out_freq = 24728; car_div = SDMMC_CAR_DIVIDER_SD_SDR12; @@ -421,8 +399,7 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq sdmmc_clk_sources[controller].clk_source_val = clk_freq; sdmmc_clk_sources[controller].clk_div_val = out_freq; - switch (controller) - { + switch (controller) { case SDMMC_1: car->clk_source_sdmmc1 = (CLK_SOURCE_FIRST | car_div); break; @@ -441,26 +418,26 @@ static int sdmmc_clk_set_source(SdmmcControllerNum controller, uint32_t clk_freq } /* Adjust the device clock source value. */ -static int sdmmc_clk_adjust_source(SdmmcControllerNum controller, uint32_t clk_source_val) -{ +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) + if (sdmmc_clk_sources[controller].clk_source_val == clk_source_val) { out_val = sdmmc_clk_sources[controller].clk_div_val; - else - { + } else { bool was_sdmmc_clk_enb = is_sdmmc_clk_enb(controller); /* Clock was already enabled. Disable it. */ - if (was_sdmmc_clk_enb) + 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) + if (was_sdmmc_clk_enb) { sdmmc_clk_set_enb(controller); - + } + /* Dummy read for value refreshing. */ is_sdmmc_clk_rst(controller); } @@ -469,42 +446,40 @@ static int sdmmc_clk_adjust_source(SdmmcControllerNum controller, uint32_t clk_s } /* Enable the SD clock if possible. */ -static void sdmmc_enable_sd_clock(sdmmc_t *sdmmc) -{ - if ((sdmmc->has_sd) && !(sdmmc->regs->clock_control & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)) - sdmmc->regs->clock_control |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; +static void sdmmc_enable_sd_clock(sdmmc_t *sdmmc) { + if ((sdmmc->has_sd) && !(sdmmc->regs->clock_control & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)) { + sdmmc->regs->clock_control |= TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; + } sdmmc->is_sd_clk_enabled = true; } /* Disable the SD clock. */ -static void sdmmc_disable_sd_clock(sdmmc_t *sdmmc) -{ +static void sdmmc_disable_sd_clock(sdmmc_t *sdmmc) { sdmmc->is_sd_clk_enabled = false; sdmmc->regs->clock_control &= ~TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE; } /* Automatically enable or disable the SD clock. */ -void sdmmc_adjust_sd_clock(sdmmc_t *sdmmc) -{ - if (!(sdmmc->has_sd) && (sdmmc->regs->clock_control & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)) +void sdmmc_adjust_sd_clock(sdmmc_t *sdmmc) { + if (!(sdmmc->has_sd) && (sdmmc->regs->clock_control & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)) { sdmmc_disable_sd_clock(sdmmc); - else if (sdmmc->is_sd_clk_enabled && !(sdmmc->regs->clock_control & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)) + } else if (sdmmc->is_sd_clk_enabled && !(sdmmc->regs->clock_control & TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE)) { sdmmc_enable_sd_clock(sdmmc); + } } /* Return the clock control value. Used for dummy reads. */ -static int sdmmc_get_sd_clock_control(sdmmc_t *sdmmc) -{ +static int sdmmc_get_sd_clock_control(sdmmc_t *sdmmc) { return sdmmc->regs->clock_control; } /* Start the SDMMC clock. */ -static void sdmmc_clk_start(SdmmcControllerNum controller, uint32_t clk_source_val) -{ +static void sdmmc_clk_start(SdmmcControllerNum controller, uint32_t clk_source_val) { /* Clock was already enabled. Disable it. */ - if (is_sdmmc_clk_enb(controller)) + if (is_sdmmc_clk_enb(controller)) { sdmmc_clk_clear_enb(controller); - + } + /* Put the device clock in reset. */ sdmmc_clk_set_rst(controller); @@ -528,8 +503,7 @@ static void sdmmc_clk_start(SdmmcControllerNum controller, uint32_t clk_source_v } /* Stop the SDMMC clock. */ -static void sdmmc_clk_stop(SdmmcControllerNum controller) -{ +static void sdmmc_clk_stop(SdmmcControllerNum controller) { /* Put the device clock in reset. */ sdmmc_clk_set_rst(controller); @@ -541,8 +515,9 @@ static void sdmmc_clk_stop(SdmmcControllerNum controller) } /* Configure clock trimming. */ -static void sdmmc_vendor_clock_cntrl_config(sdmmc_t *sdmmc) -{ +static void sdmmc_vendor_clock_cntrl_config(sdmmc_t *sdmmc) { + bool is_mariko = is_soc_mariko(); + /* Clear the I/O conditioning constants. */ sdmmc->regs->vendor_clock_cntrl &= ~(SDMMC_CLOCK_TRIM_MASK | SDMMC_CLOCK_TAP_MASK); @@ -552,16 +527,16 @@ static void sdmmc_vendor_clock_cntrl_config(sdmmc_t *sdmmc) /* Set the appropriate trim value. */ switch (sdmmc->controller) { case SDMMC_1: - sdmmc->regs->vendor_clock_cntrl |= (is_soc_mariko() ? SDMMC_CLOCK_TRIM_SDMMC1_MARIKO : SDMMC_CLOCK_TRIM_SDMMC1_ERISTA); + sdmmc->regs->vendor_clock_cntrl |= (is_mariko ? SDMMC_CLOCK_TRIM_SDMMC1_MARIKO : SDMMC_CLOCK_TRIM_SDMMC1_ERISTA); break; case SDMMC_2: - sdmmc->regs->vendor_clock_cntrl |= (is_soc_mariko() ? SDMMC_CLOCK_TRIM_SDMMC2_MARIKO : SDMMC_CLOCK_TRIM_SDMMC2_ERISTA); + sdmmc->regs->vendor_clock_cntrl |= (is_mariko ? SDMMC_CLOCK_TRIM_SDMMC2_MARIKO : SDMMC_CLOCK_TRIM_SDMMC2_ERISTA); break; case SDMMC_3: sdmmc->regs->vendor_clock_cntrl |= SDMMC_CLOCK_TRIM_SDMMC3; break; case SDMMC_4: - sdmmc->regs->vendor_clock_cntrl |= (is_soc_mariko() ? SDMMC_CLOCK_TRIM_SDMMC4_MARIKO : SDMMC_CLOCK_TRIM_SDMMC4_ERISTA); + sdmmc->regs->vendor_clock_cntrl |= (is_mariko ? SDMMC_CLOCK_TRIM_SDMMC4_MARIKO : SDMMC_CLOCK_TRIM_SDMMC4_ERISTA); break; } @@ -570,19 +545,20 @@ static void sdmmc_vendor_clock_cntrl_config(sdmmc_t *sdmmc) } /* Configure automatic calibration. */ -static int sdmmc_autocal_config(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) -{ +static int sdmmc_autocal_config(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) { + bool is_mariko = is_soc_mariko(); + switch (sdmmc->controller) { case SDMMC_1: case SDMMC_3: switch (voltage) { case SDMMC_VOLTAGE_1V8: sdmmc->regs->auto_cal_config &= ~(SDMMC_AUTOCAL_PDPU_CONFIG_MASK); - sdmmc->regs->auto_cal_config |= (is_soc_mariko() ? SDMMC_AUTOCAL_PDPU_SDMMC1_1V8_MARIKO : SDMMC_AUTOCAL_PDPU_SDMMC1_1V8_ERISTA); + sdmmc->regs->auto_cal_config |= (is_mariko ? SDMMC_AUTOCAL_PDPU_SDMMC1_1V8_MARIKO : SDMMC_AUTOCAL_PDPU_SDMMC1_1V8_ERISTA); break; case SDMMC_VOLTAGE_3V3: sdmmc->regs->auto_cal_config &= ~(SDMMC_AUTOCAL_PDPU_CONFIG_MASK); - sdmmc->regs->auto_cal_config |= (is_soc_mariko() ? SDMMC_AUTOCAL_PDPU_SDMMC1_3V3_MARIKO : SDMMC_AUTOCAL_PDPU_SDMMC1_3V3_ERISTA); + sdmmc->regs->auto_cal_config |= (is_mariko ? SDMMC_AUTOCAL_PDPU_SDMMC1_3V3_MARIKO : SDMMC_AUTOCAL_PDPU_SDMMC1_3V3_ERISTA); break; default: sdmmc_error(sdmmc, "uSD does not support requested voltage!"); @@ -605,21 +581,19 @@ static int sdmmc_autocal_config(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) } /* Run automatic calibration. */ -static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) -{ +static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) { volatile tegra_padctl_t *padctl = padctl_get_regs(); bool restart_sd_clock = false; + bool is_mariko = is_soc_mariko(); /* SD clock is enabled. Disable it and restart later. */ - if (sdmmc->is_sd_clk_enabled) - { + 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)) - { + if (!(sdmmc->regs->sdmemcomppadctrl & 0x80000000)) { sdmmc->regs->sdmemcomppadctrl |= 0x80000000; /* Force a register read to refresh the clock control value. */ @@ -653,7 +627,7 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) /* Upon timeout, fall back to standard values. */ if (sdmmc->controller == SDMMC_1) { uint32_t drvup, drvdn = 0; - if (is_soc_mariko()) { + if (is_mariko) { drvup = 0x8; drvdn = 0x8; } else { @@ -667,7 +641,7 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) padctl->sdmmc1_pad_cfgpadctrl = value; } else if (sdmmc->controller == SDMMC_2) { uint32_t drvup, drvdn = 0; - if (is_soc_mariko()) { + if (is_mariko) { drvup = 0xA; drvdn = 0xA; uint32_t value = padctl->emmc2_pad_cfgpadctrl; @@ -686,7 +660,7 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) } } else if (sdmmc->controller == SDMMC_4) { uint32_t drvup, drvdn = 0; - if (is_soc_mariko()) { + if (is_mariko) { drvup = 0xA; drvdn = 0xA; } else { @@ -710,12 +684,12 @@ static void sdmmc_autocal_run(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) sdmmc->regs->sdmemcomppadctrl &= ~(0x80000000); /* If requested, enable the SD clock. */ - if (restart_sd_clock) + if (restart_sd_clock) { sdmmc_enable_sd_clock(sdmmc); + } } -static int sdmmc_int_clk_enable(sdmmc_t *sdmmc) -{ +static int sdmmc_int_clk_enable(sdmmc_t *sdmmc) { /* Enable the internal clock. */ sdmmc->regs->clock_control |= TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE; @@ -756,8 +730,9 @@ static int sdmmc_int_clk_enable(sdmmc_t *sdmmc) sdmmc->regs->host_control &= ~SDHCI_CTRL_DMA_MASK; /* Change to ADMA if possible. */ - if (sdmmc->regs->capabilities & SDHCI_CAN_DO_ADMA2) + 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; @@ -766,55 +741,43 @@ static int sdmmc_int_clk_enable(sdmmc_t *sdmmc) return 1; } -void sdmmc_select_bus_width(sdmmc_t *sdmmc, SdmmcBusWidth width) -{ - if (width == SDMMC_BUS_WIDTH_1BIT) - { +void sdmmc_select_bus_width(sdmmc_t *sdmmc, SdmmcBusWidth width) { + if (width == SDMMC_BUS_WIDTH_1BIT) { sdmmc->regs->host_control &= ~(SDHCI_CTRL_4BITBUS | SDHCI_CTRL_8BITBUS); sdmmc->bus_width = SDMMC_BUS_WIDTH_1BIT; - } - else if (width == SDMMC_BUS_WIDTH_4BIT) - { + } else if (width == SDMMC_BUS_WIDTH_4BIT) { sdmmc->regs->host_control |= SDHCI_CTRL_4BITBUS; sdmmc->regs->host_control &= ~SDHCI_CTRL_8BITBUS; sdmmc->bus_width = SDMMC_BUS_WIDTH_4BIT; - } - else if (width == SDMMC_BUS_WIDTH_8BIT) - { + } else if (width == SDMMC_BUS_WIDTH_8BIT) { sdmmc->regs->host_control |= SDHCI_CTRL_8BITBUS; sdmmc->bus_width = SDMMC_BUS_WIDTH_8BIT; - } - else + } else { sdmmc_error(sdmmc, "Invalid bus width specified!"); + } } -void sdmmc_select_voltage(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) -{ - if (voltage == SDMMC_VOLTAGE_NONE) - { +void sdmmc_select_voltage(sdmmc_t *sdmmc, SdmmcBusVoltage voltage) { + if (voltage == SDMMC_VOLTAGE_NONE) { sdmmc->regs->power_control &= ~TEGRA_MMC_PWRCTL_SD_BUS_POWER; sdmmc->bus_voltage = SDMMC_VOLTAGE_NONE; - } - else if (voltage == SDMMC_VOLTAGE_1V8) - { + } else if (voltage == SDMMC_VOLTAGE_1V8) { sdmmc->regs->power_control |= TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8; sdmmc->regs->power_control |= TEGRA_MMC_PWRCTL_SD_BUS_POWER; sdmmc->bus_voltage = SDMMC_VOLTAGE_1V8; - } - else if (voltage == SDMMC_VOLTAGE_3V3) - { + } else if (voltage == SDMMC_VOLTAGE_3V3) { sdmmc->regs->power_control |= TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3; sdmmc->regs->power_control |= TEGRA_MMC_PWRCTL_SD_BUS_POWER; sdmmc->bus_voltage = SDMMC_VOLTAGE_3V3; - } - else + } else { sdmmc_error(sdmmc, "Invalid power state specified!"); + } } -static void sdmmc_tap_config(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed) -{ - if (bus_speed == SDMMC_SPEED_MMC_HS400) - { +static void sdmmc_tap_config(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed) { + bool is_mariko = is_soc_mariko(); + + if (bus_speed == SDMMC_SPEED_MMC_HS400) { /* Clear and set DQS_TRIM_VAL (used in HS400) */ sdmmc->regs->vendor_cap_overrides &= ~(0x3F00); sdmmc->regs->vendor_cap_overrides |= 0x2800; @@ -823,27 +786,22 @@ static void sdmmc_tap_config(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed) /* Clear TAP_VAL_UPDATED_BY_HW */ sdmmc->regs->vendor_tuning_cntrl0 &= ~(0x20000); - if (bus_speed == SDMMC_SPEED_MMC_HS400) - { + if (bus_speed == SDMMC_SPEED_MMC_HS400) { /* We must have obtained the tap value from the tuning procedure here. */ - if (sdmmc->is_tuning_tap_val_set) - { + if (sdmmc->is_tuning_tap_val_set) { /* Clear and set the tap value. */ sdmmc->regs->vendor_clock_cntrl &= ~(0xFF0000); sdmmc->regs->vendor_clock_cntrl |= (sdmmc->tap_val << 16); } - } - else - { + } else { /* Use the recommended values. */ - switch (sdmmc->controller) - { + switch (sdmmc->controller) { case SDMMC_1: - sdmmc->tap_val = (is_soc_mariko() ? 0xB : 4); + sdmmc->tap_val = (is_mariko ? 0xB : 4); break; case SDMMC_2: case SDMMC_4: - sdmmc->tap_val = (is_soc_mariko() ? 0xB : 0); + sdmmc->tap_val = (is_mariko ? 0xB : 0); break; case SDMMC_3: sdmmc->tap_val = 3; @@ -856,13 +814,11 @@ static void sdmmc_tap_config(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed) } } -static int sdmmc_dllcal_run(sdmmc_t *sdmmc) -{ +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) - { + if (!sdmmc->is_sd_clk_enabled) { shutdown_sd_clock = true; sdmmc_enable_sd_clock(sdmmc); } @@ -906,19 +862,18 @@ static int sdmmc_dllcal_run(sdmmc_t *sdmmc) } /* If requested, disable the SD clock. */ - if (shutdown_sd_clock) + if (shutdown_sd_clock) { sdmmc_disable_sd_clock(sdmmc); - + } + return 1; } -int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed) -{ +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) - { + if (sdmmc->is_sd_clk_enabled) { restart_sd_clock = true; sdmmc_disable_sd_clock(sdmmc); } @@ -992,26 +947,28 @@ int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed) uint16_t div_val_lo = div_val >> 1; uint16_t div_val_hi = 0; - if (div_val_lo > 0xFF) + 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) + if (restart_sd_clock) { sdmmc_enable_sd_clock(sdmmc); - + } + /* Run DLLCAL for HS400 only */ - if (bus_speed == SDMMC_SPEED_MMC_HS400) + if (bus_speed == SDMMC_SPEED_MMC_HS400) { return sdmmc_dllcal_run(sdmmc); + } return 1; } -static int sdmmc1_config() -{ +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(); @@ -1024,8 +981,9 @@ static int sdmmc1_config() udelay(100); /* Check the GPIO. */ - if (gpio_read(GPIO_MICROSD_CARD_DETECT)) + if (gpio_read(GPIO_MICROSD_CARD_DETECT)) { return 0; + } /* Enable loopback control. */ padctl->sdmmc1_clk_lpbk_control = 1; @@ -1061,26 +1019,23 @@ static int sdmmc1_config() return 1; } -static int sdmmc2_config() -{ +static int sdmmc2_config() { return 1; } -static int sdmmc3_config() -{ +static int sdmmc3_config() { return 1; } -static int sdmmc4_config() -{ +static int sdmmc4_config() { return 1; } -static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller) -{ +static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller) { /* Sanitize input number for the controller. */ - if ((controller < SDMMC_1) || (controller > SDMMC_4)) + if ((controller < SDMMC_1) || (controller > SDMMC_4)) { return 0; + } /* Clear up memory for our struct. */ memset(sdmmc, 0, sizeof(sdmmc_t)); @@ -1163,8 +1118,9 @@ static int sdmmc_init_controller(sdmmc_t *sdmmc, SdmmcControllerNum controller) return 1; } -int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bus_voltage, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed) -{ +int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bus_voltage, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed) { + bool is_mariko = is_soc_mariko(); + /* Initialize our controller structure. */ if (!sdmmc_init_controller(sdmmc, controller)) { sdmmc_error(sdmmc, "Failed to initialize SDMMC%d", controller + 1); @@ -1208,7 +1164,7 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu sdmmc_vendor_clock_cntrl_config(sdmmc); /* Set slew codes for SDMMC1 (Erista only). */ - if ((controller == SDMMC_1) && !(is_soc_mariko())) { + if ((controller == SDMMC_1) && !is_mariko) { volatile tegra_padctl_t *padctl = padctl_get_regs(); uint32_t value = padctl->sdmmc1_pad_cfgpadctrl; value &= ~(SDMMC1_CLK_CFG_CAL_DRVDN_SLWR_MASK | SDMMC1_CLK_CFG_CAL_DRVDN_SLWF_MASK); @@ -1219,11 +1175,12 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu /* Set vref sel. */ sdmmc->regs->sdmemcomppadctrl &= 0x0F; - if ((controller == SDMMC_1) && is_soc_mariko()) + if ((controller == SDMMC_1) && is_mariko) { sdmmc->regs->sdmemcomppadctrl |= 0x00; - else + } else { sdmmc->regs->sdmemcomppadctrl |= 0x07; - + } + /* Configure autocal offsets. */ if (!sdmmc_autocal_config(sdmmc, bus_voltage)) { sdmmc_error(sdmmc, "Failed to configure automatic calibration!"); @@ -1263,11 +1220,9 @@ int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bu return 1; } -void sdmmc_finish(sdmmc_t *sdmmc) -{ +void sdmmc_finish(sdmmc_t *sdmmc) { /* Stop everything. */ - if (sdmmc->is_clk_running) - { + if (sdmmc->is_clk_running) { /* Disable the SD clock. */ sdmmc_disable_sd_clock(sdmmc); @@ -1275,8 +1230,7 @@ void sdmmc_finish(sdmmc_t *sdmmc) sdmmc_select_voltage(sdmmc, SDMMC_VOLTAGE_NONE); /* Disable the SD card power. */ - if (sdmmc->controller == SDMMC_1) - { + if (sdmmc->controller == SDMMC_1) { /* Disable GPIO output. */ gpio_configure_direction(GPIO_MICROSD_SUPPLY_ENABLE, GPIO_DIRECTION_INPUT); @@ -1298,8 +1252,7 @@ void sdmmc_finish(sdmmc_t *sdmmc) } } -static void sdmmc_do_sw_reset(sdmmc_t *sdmmc) -{ +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); @@ -1317,8 +1270,7 @@ static void sdmmc_do_sw_reset(sdmmc_t *sdmmc) } } -static int sdmmc_wait_for_inhibit(sdmmc_t *sdmmc, bool wait_for_dat) -{ +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); @@ -1333,14 +1285,12 @@ static int sdmmc_wait_for_inhibit(sdmmc_t *sdmmc, bool wait_for_dat) } /* Bit was never released. Reset. */ - if (is_timeout) - { + if (is_timeout) { sdmmc_do_sw_reset(sdmmc); return 0; } - if (wait_for_dat) - { + if (wait_for_dat) { /* Program a timeout of 10ms. */ timebase = get_time(); is_timeout = false; @@ -1352,8 +1302,7 @@ static int sdmmc_wait_for_inhibit(sdmmc_t *sdmmc, bool wait_for_dat) } /* Bit was never released, reset. */ - if (is_timeout) - { + if (is_timeout) { sdmmc_do_sw_reset(sdmmc); return 0; } @@ -1362,8 +1311,7 @@ static int sdmmc_wait_for_inhibit(sdmmc_t *sdmmc, bool wait_for_dat) return 1; } -static int sdmmc_wait_busy(sdmmc_t *sdmmc) -{ +static int sdmmc_wait_busy(sdmmc_t *sdmmc) { /* Force a register read to refresh the clock control value. */ sdmmc_get_sd_clock_control(sdmmc); @@ -1378,8 +1326,7 @@ static int sdmmc_wait_busy(sdmmc_t *sdmmc) } /* Bit was never released. Reset. */ - if (is_timeout) - { + if (is_timeout) { sdmmc_do_sw_reset(sdmmc); return 0; } @@ -1387,8 +1334,7 @@ static int sdmmc_wait_busy(sdmmc_t *sdmmc) return 1; } -static void sdmmc_intr_enable(sdmmc_t *sdmmc) -{ +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; @@ -1397,31 +1343,27 @@ static void sdmmc_intr_enable(sdmmc_t *sdmmc) sdmmc->regs->int_status = sdmmc->regs->int_status; } -static void sdmmc_intr_disable(sdmmc_t *sdmmc) -{ +static void sdmmc_intr_disable(sdmmc_t *sdmmc) { /* Clear all error bits and disable the relevant 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); } -static int sdmmc_intr_check(sdmmc_t *sdmmc, uint16_t *status_out, uint16_t status_mask) -{ +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) + if (status_out) { *status_out = (int_status & 0xFFFF); - - if (int_status & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) - { + } + + if (int_status & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { /* Acknowledge error by refreshing status. */ sdmmc->regs->int_status = int_status; return -1; - } - else if (int_status & status_mask) - { + } else if (int_status & status_mask) { /* Mask the status. */ sdmmc->regs->int_status = (int_status & status_mask); return 1; @@ -1430,11 +1372,9 @@ static int sdmmc_intr_check(sdmmc_t *sdmmc, uint16_t *status_out, uint16_t statu return 0; } -static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req) -{ +static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req) { /* Invalid block count or size. */ - if (!req->blksz || !req->num_blocks) - { + if (!req->blksz || !req->num_blocks) { sdmmc_error(sdmmc, "Empty DMA request!"); return 0; } @@ -1442,28 +1382,25 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req) uint32_t blkcnt = req->num_blocks; /* Truncate block count. Length can't be over 65536 bytes. */ - if (blkcnt >= 0xFFFF) + 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; /* DMA buffer address must be aligned to 4 bytes. */ - if ((4 - (dma_base_addr & 0x03)) & 0x03) - { + if ((4 - (dma_base_addr & 0x03)) & 0x03) { 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) - { + if (sdmmc->use_adma) { /* Set ADMA registers. */ sdmmc->regs->adma_address = dma_base_addr; sdmmc->regs->upper_adma_address = 0; - } - else - { + } else { /* Set SDMA register. */ sdmmc->regs->dma_address = dma_base_addr; } @@ -1481,16 +1418,17 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req) uint32_t transfer_mode = TEGRA_MMC_TRNMOD_DMA_ENABLE; /* Select multi block. */ - if (req->is_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) + if (req->is_read) { transfer_mode |= TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ; - + } + /* Select AUTO_CMD12. */ - if (req->is_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; } @@ -1501,13 +1439,11 @@ static int sdmmc_dma_init(sdmmc_t *sdmmc, sdmmc_request_t *req) return blkcnt; } -static int sdmmc_dma_update(sdmmc_t *sdmmc) -{ +static int sdmmc_dma_update(sdmmc_t *sdmmc) { uint16_t blkcnt = 0; /* Loop until all blocks have been consumed. */ - do - { + do { /* Update block count. */ blkcnt = sdmmc->regs->block_count; @@ -1516,34 +1452,29 @@ static int sdmmc_dma_update(sdmmc_t *sdmmc) 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) - { + if (intr_res < 0) { sdmmc_do_sw_reset(sdmmc); return 0; } /* Transfer is over. */ - if (intr_status & TEGRA_MMC_NORINTSTS_XFER_COMPLETE) + 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) - { - if (sdmmc->use_adma) - { + if (intr_status & TEGRA_MMC_NORINTSTS_DMA_INTERRUPT) { + if (sdmmc->use_adma) { /* Update ADMA registers. */ sdmmc->regs->adma_address = sdmmc->next_dma_addr; sdmmc->regs->upper_adma_address = 0; - } - else - { + } else { /* Update SDMA register. */ sdmmc->regs->dma_address = sdmmc->next_dma_addr; } @@ -1561,39 +1492,41 @@ static int sdmmc_dma_update(sdmmc_t *sdmmc) return 0; } -static void sdmmc_set_cmd_flags(sdmmc_t *sdmmc, sdmmc_command_t *cmd, bool is_dma) -{ +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)) + if (!(cmd->flags & SDMMC_RSP_PRESENT)) { cmd_reg_flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE; - else if (cmd->flags & SDMMC_RSP_136) + } else if (cmd->flags & SDMMC_RSP_136) { cmd_reg_flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136; - else if (cmd->flags & SDMMC_RSP_BUSY) + } else if (cmd->flags & SDMMC_RSP_BUSY) { cmd_reg_flags = TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY; - else + } 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) + 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) + if (cmd->flags & SDMMC_RSP_OPCODE) { cmd_reg_flags |= TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK; - + } + /* Select data present flag. */ - if (is_dma) + 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); } -static int sdmmc_wait_for_cmd(sdmmc_t *sdmmc) -{ +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); @@ -1610,8 +1543,9 @@ static int sdmmc_wait_for_cmd(sdmmc_t *sdmmc) int intr_res = sdmmc_intr_check(sdmmc, 0, TEGRA_MMC_NORINTSTS_CMD_COMPLETE); /* Command is done. */ - if (intr_res > 0) + if (intr_res > 0) { return 1; + } /* Check for any raised errors. */ is_err = (intr_res < 0); @@ -1625,29 +1559,25 @@ static int sdmmc_wait_for_cmd(sdmmc_t *sdmmc) return 0; } -static int sdmmc_save_response(sdmmc_t *sdmmc, uint32_t flags) -{ +static int sdmmc_save_response(sdmmc_t *sdmmc, uint32_t flags) { /* We have a valid response. */ - if (flags & SDMMC_RSP_PRESENT) - { - if (flags & SDMMC_RSP_136) - { + if (flags & SDMMC_RSP_PRESENT) { + if (flags & SDMMC_RSP_136) { /* 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) + if (i != 0) { sdmmc->resp[i - 1] |= ((sdmmc->regs->response[3 - i] >> 24) & 0xFF); + } } - } - else - { + } else { /* Card is still busy. */ - if (flags & SDMMC_RSP_BUSY) - { + if (flags & SDMMC_RSP_BUSY) { /* Wait for DAT0 level mask. */ - if (!sdmmc_wait_busy(sdmmc)) + if (!sdmmc_wait_busy(sdmmc)) { return 0; + } } /* Save our response. */ @@ -1661,24 +1591,22 @@ static int sdmmc_save_response(sdmmc_t *sdmmc, uint32_t flags) return 0; } -int sdmmc_load_response(sdmmc_t *sdmmc, uint32_t flags, uint32_t *resp) -{ +int sdmmc_load_response(sdmmc_t *sdmmc, uint32_t flags, uint32_t *resp) { /* Make sure our output buffer is valid. */ - if (!resp) + if (!resp) { return 0; + } /* We have a valid response. */ - if (flags & SDMMC_RSP_PRESENT) - { - if (flags & SDMMC_RSP_136) - { + if (flags & SDMMC_RSP_PRESENT) { + if (flags & SDMMC_RSP_136) { resp[0] = sdmmc->resp[0]; resp[1] = sdmmc->resp[1]; resp[2] = sdmmc->resp[2]; resp[3] = sdmmc->resp[3]; - } - else + } else { resp[0] = sdmmc->resp[0]; + } return 1; } @@ -1687,18 +1615,18 @@ int sdmmc_load_response(sdmmc_t *sdmmc, uint32_t flags, uint32_t *resp) return 0; } -int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, uint32_t *num_blocks_out) -{ +int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, uint32_t *num_blocks_out) { uint32_t cmd_result = 0; bool shutdown_sd_clock = false; + bool is_mariko = is_soc_mariko(); /* Run automatic calibration on each command submission for SDMMC1 (Erista only). */ - if ((sdmmc->controller == SDMMC_1) && !(sdmmc->has_sd) && !(is_soc_mariko())) + if ((sdmmc->controller == SDMMC_1) && !(sdmmc->has_sd) && !is_mariko) { sdmmc_autocal_run(sdmmc, sdmmc->bus_voltage); + } /* SD clock is disabled. Enable it. */ - if (!sdmmc->is_sd_clk_enabled) - { + if (!sdmmc->is_sd_clk_enabled) { shutdown_sd_clock = true; sdmmc_enable_sd_clock(sdmmc); @@ -1713,28 +1641,28 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u 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)) + 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) - { + if (req) { is_dma = true; dma_blkcnt = sdmmc_dma_init(sdmmc, req); /* Abort in case initialization failed. */ - if (!dma_blkcnt) - { + 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) + if (!sdmmc->use_adma && !req->is_read) { memcpy((void *)sdmmc->dma_bounce_buf, (void *)req->data, req->blksz * req->num_blocks); + } } /* Enable interrupts. */ @@ -1748,25 +1676,21 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u 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) - { + if (cmd_result) { /* Save response, if necessary. */ sdmmc_save_response(sdmmc, cmd->flags); /* Update the DMA request. */ - if (req) - { + if (req) { /* Disable interrupts and abort in case updating failed. */ - if (!sdmmc_dma_update(sdmmc)) - { + if (!sdmmc_dma_update(sdmmc)) { sdmmc_warn(sdmmc, "Failed to update the DMA transfer!"); 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) - { + 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); } @@ -1776,43 +1700,42 @@ int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, u /* Disable interrupts. */ sdmmc_intr_disable(sdmmc); - if (cmd_result) - { - if (req) - { + if (cmd_result) { + if (req) { /* Save back the number of DMA blocks. */ - if (num_blocks_out) + if (num_blocks_out) { *num_blocks_out = dma_blkcnt; - - /* Save the response for AUTO_CMD12. */ - if (req->is_auto_cmd12) + } + /* 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)) + 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) + if (shutdown_sd_clock) { sdmmc_disable_sd_clock(sdmmc); - + } + return cmd_result; } -int sdmmc_switch_voltage(sdmmc_t *sdmmc) -{ +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)) - { + 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; } @@ -1827,8 +1750,7 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc) pmc->pwr_det_val &= ~(PMC_CONTROL_SDMMC1); /* Reconfigure autocal offsets. */ - if (!sdmmc_autocal_config(sdmmc, SDMMC_VOLTAGE_1V8)) - { + if (!sdmmc_autocal_config(sdmmc, SDMMC_VOLTAGE_1V8)) { sdmmc_error(sdmmc, "Failed to configure automatic calibration for low voltage support!"); return 0; } @@ -1846,8 +1768,7 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc) mdelay(5); /* Host control 2 flag should be set by now. */ - if (sdmmc->regs->host_control2 & SDHCI_CTRL_VDD_180) - { + if (sdmmc->regs->host_control2 & SDHCI_CTRL_VDD_180) { /* Enable the SD clock. */ sdmmc_enable_sd_clock(sdmmc); @@ -1858,30 +1779,33 @@ int sdmmc_switch_voltage(sdmmc_t *sdmmc) mdelay(1); /* Data level is up. Voltage switching is done.*/ - if (sdmmc->regs->present_state & SDHCI_DATA_LVL_MASK) + if (sdmmc->regs->present_state & SDHCI_DATA_LVL_MASK) { return 1; + } } return 0; } -static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode) -{ +static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode) { /* Nothing to do. */ - if (!sdmmc->has_sd) + if (!sdmmc->has_sd) { return 0; + } /* Wait for CMD and DAT inhibit. */ - if (!sdmmc_wait_for_inhibit(sdmmc, true)) + 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) + if (sdmmc->bus_width == SDMMC_BUS_WIDTH_4BIT) { sdmmc->regs->block_size = 0x40; - else if (sdmmc->bus_width == SDMMC_BUS_WIDTH_8BIT) + } else if (sdmmc->bus_width == SDMMC_BUS_WIDTH_8BIT) { sdmmc->regs->block_size = 0x80; - else + } else { return 0; + } /* Select the block count and transfer mode. */ sdmmc->regs->block_count = 1; @@ -1925,11 +1849,9 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode) bool is_timeout = false; /* Wait for Buffer Read Ready interrupt. */ - while (!is_timeout) - { + while (!is_timeout) { /* Buffer Read Ready was asserted. */ - if (sdmmc_intr_check(sdmmc, 0, TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY) > 0) - { + if (sdmmc_intr_check(sdmmc, 0, TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY) > 0) { /* Manually disable the Buffer Read Ready interrupt. */ sdmmc->regs->int_enable &= ~(TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY); @@ -1961,21 +1883,18 @@ static int sdmmc_send_tuning(sdmmc_t *sdmmc, uint32_t opcode) return 0; } -void sdmmc_set_tuning_tap_val(sdmmc_t *sdmmc) -{ +void sdmmc_set_tuning_tap_val(sdmmc_t *sdmmc) { sdmmc->tap_val = (sdmmc->regs->vendor_clock_cntrl >> 16); sdmmc->is_tuning_tap_val_set = true; } -int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcode) -{ +int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcode) { uint32_t max_tuning_loop = 0; uint32_t tuning_cntrl_flag = 0; sdmmc->regs->vendor_tuning_cntrl1 = 0; - switch (bus_speed) - { + switch (bus_speed) { case SDMMC_SPEED_MMC_HS200: case SDMMC_SPEED_MMC_HS400: case SDMMC_SPEED_SD_SDR104: @@ -2005,31 +1924,30 @@ int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcod sdmmc->regs->host_control2 |= SDHCI_CTRL_EXEC_TUNING; /* Repeat until Execute Tuning is set to 0 or the number of loops reaches the maximum value. */ - for (uint32_t i = 0; i < max_tuning_loop; i++) - { + 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)) + if (!(sdmmc->regs->host_control2 & SDHCI_CTRL_EXEC_TUNING)) { break; + } } /* Success! */ - if (sdmmc->regs->host_control2 & SDHCI_CTRL_TUNED_CLK) + if (sdmmc->regs->host_control2 & SDHCI_CTRL_TUNED_CLK) { return 1; + } return 0; } -int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode) -{ +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) - { + if (!sdmmc->is_sd_clk_enabled) { shutdown_sd_clock = true; sdmmc_enable_sd_clock(sdmmc); @@ -2041,8 +1959,7 @@ int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode) } /* Wait for CMD and DAT inhibit. */ - if (sdmmc_wait_for_inhibit(sdmmc, false)) - { + if (sdmmc_wait_for_inhibit(sdmmc, false)) { /* Enable interrupts. */ sdmmc_intr_enable(sdmmc); @@ -2061,8 +1978,7 @@ int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode) /* Disable interrupts. */ sdmmc_intr_disable(sdmmc); - if (cmd_result) - { + if (cmd_result) { /* Save response, if necessary. */ sdmmc_save_response(sdmmc, cmd.flags); @@ -2075,8 +1991,9 @@ int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode) udelay((8000 + sdmmc->internal_divider - 1) / sdmmc->internal_divider); /* Disable the SD clock if requested. */ - if (shutdown_sd_clock) + if (shutdown_sd_clock) { sdmmc_disable_sd_clock(sdmmc); - + } + return result; -} +} \ No newline at end of file diff --git a/fusee/fusee-primary/fusee-primary-main/src/di.c b/fusee/fusee-primary/fusee-primary-main/src/di.c index 60468d600..59cc1e44f 100644 --- a/fusee/fusee-primary/fusee-primary-main/src/di.c +++ b/fusee/fusee-primary/fusee-primary-main/src/di.c @@ -62,169 +62,25 @@ static void dsi_wait(uint32_t timeout, uint32_t offset, uint32_t mask, uint32_t udelay(delay); } -static void display_init_erista(void) { - volatile tegra_car_t *car = car_get_regs(); - volatile tegra_pmc_t *pmc = pmc_get_regs(); - volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); - - /* Power on. */ - uint8_t val = 0xD0; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); - - /* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */ - car->rst_dev_h_clr = 0x1010000; - car->clk_enb_h_set = 0x1010000; - car->rst_dev_l_clr = 0x18000000; - car->clk_enb_l_set = 0x18000000; - car->clk_enb_x_set = 0x20000; - car->clk_source_uart_fst_mipi_cal = 0xA; - car->clk_enb_w_set = 0x80000; - car->clk_source_dsia_lp = 0xA; - - /* DPD idle. */ - pmc->io_dpd_req = 0x40000000; - pmc->io_dpd2_req = 0x40000000; - - /* Configure pins. */ - pinmux->nfc_en &= ~PINMUX_TRISTATE; - pinmux->nfc_int &= ~PINMUX_TRISTATE; - pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE; - pinmux->lcd_bl_en &= ~PINMUX_TRISTATE; - pinmux->lcd_rst &= ~PINMUX_TRISTATE; - - /* Configure Backlight +-5V GPIOs. */ - gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT); - - /* Enable Backlight +5V. */ - gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH); - - udelay(10000); - - /* Enable Backlight -5V. */ - gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH); - - udelay(10000); - - /* Configure Backlight PWM, EN and RST GPIOs. */ - gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT); - - /* Enable Backlight EN. */ - gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH); - - /* Configure display interface and display. */ - MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; - - do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); - do_register_writes(DI_BASE, display_config_dc_01, 94); - do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8); - do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14); - do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0); - do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14); - - udelay(10000); - - /* Enable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH); - - udelay(60000); - - MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204; - MAKE_DSI_REG(DSI_WR_DATA) = 0x337; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5); - - MAKE_DSI_REG(DSI_WR_DATA) = 0x406; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5); - - MAKE_DSI_REG(DSI_HOST_CONTROL) = (DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC); - dsi_wait(150000, DSI_HOST_CONTROL, DSI_HOST_CONTROL_IMM_BTA, 5000); - - /* Parse LCD vendor. */ - uint32_t host_response[3]; - for (uint32_t i = 0; i < 3; i++) { - host_response[i] = MAKE_DSI_REG(DSI_RD_DATA); - } - - /* The last word from host response is: - Bits 0-7: FAB - Bits 8-15: REV - Bits 16-23: Minor REV - */ - if ((host_response[2] & 0xFF) == 0x10) { - g_lcd_vendor = 0; - } else { - g_lcd_vendor = (host_response[2] >> 8) & 0xFF00; - } - g_lcd_vendor = (g_lcd_vendor & 0xFFFFFF00) | (host_response[2] & 0xFF); - - /* LCD vendor specific configuration. */ - switch (g_lcd_vendor) { - case 0x10: /* Japan Display Inc screens. */ - do_dsi_sleep_or_register_writes(display_config_jdi_specific_init_01, 48); - break; - case 0xF20: /* Innolux nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_innolux_nx_abca2_specific_init_01, 14); - break; - case 0xF30: /* AUO nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_init_01, 14); - break; - default: - /* Innolux and AUO nx-abcc screens. */ - if ((g_lcd_vendor | 0x10) == 0x1030) { - do_dsi_sleep_or_register_writes(display_config_innolux_auo_40_nx_abcc_specific_init_01, 5); - } - break; - } - - udelay(20000); - - do_register_writes(CAR_BASE, display_config_plld_02_erista, 3); - do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19); - MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4; - do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10); - - udelay(10000); - - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - - udelay(10000); - - do_register_writes(DI_BASE, display_config_dc_02, 113); -} - -static void display_init_mariko(void) { +void display_init(void) { volatile tegra_car_t *car = car_get_regs(); volatile tegra_pmc_t *pmc = pmc_get_regs(); volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); uint32_t hardware_type = fuse_get_hardware_type(); /* Power on. */ - uint8_t val = 0x3A; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1); - val = 0x71; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1); - val = 0xD0; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + if (is_mariko) { + uint8_t val = 0x3A; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1); + val = 0x71; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1); + val = 0xD0; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + } else { + uint8_t val = 0xD0; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + } /* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */ car->rst_dev_h_clr = 0x1010000; @@ -247,7 +103,7 @@ static void display_init_mariko(void) { pinmux->lcd_bl_en &= ~PINMUX_TRISTATE; pinmux->lcd_rst &= ~PINMUX_TRISTATE; - if (hardware_type == 5) { + if (is_mariko && (hardware_type == 5)) { /* HardwareType_Five only configures GPIO_LCD_BL_RST. */ gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO); gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT); @@ -282,19 +138,41 @@ static void display_init_mariko(void) { /* Configure display interface and display. */ MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; - MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0; - APB_MISC_GP_DSI_PAD_CONTROL_0 = 0; - - do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + if (is_mariko) { + MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0; + APB_MISC_GP_DSI_PAD_CONTROL_0 = 0; + } + + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + } else { + do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); + } do_register_writes(DI_BASE, display_config_dc_01, 94); do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8); - do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14); - do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7); + } else { + do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14); udelay(10000); @@ -303,8 +181,8 @@ static void display_init_mariko(void) { gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH); udelay(60000); - - if (hardware_type == 5) { + + if (is_mariko && (hardware_type == 5)) { MAKE_DSI_REG(DSI_BTA_TIMING) = 0x40103; } else { MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204; @@ -362,33 +240,50 @@ static void display_init_mariko(void) { udelay(20000); - do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3); + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3); + } else { + do_register_writes(CAR_BASE, display_config_plld_02_erista, 3); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19); MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4; do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10); udelay(10000); - - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - + + if (is_mariko) { + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + } else { + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + } + udelay(10000); do_register_writes(DI_BASE, display_config_dc_02, 113); } -static void display_end_erista(void) { +void display_end(void) { volatile tegra_car_t *car = car_get_regs(); volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); /* Disable Backlight. */ display_backlight(false); @@ -408,93 +303,17 @@ static void display_end_erista(void) { do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13); udelay(40000); - do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); - do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13); - - udelay(10000); - - /* LCD vendor specific shutdown. */ - switch (g_lcd_vendor) { - case 0x10: /* Japan Display Inc screens. */ - do_dsi_sleep_or_register_writes(display_config_jdi_specific_fini_01, 22); - break; - case 0xF30: /* AUO nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_fini_01, 38); - break; - case 0x1020: /* Innolux nx-abcc screens. */ - do_dsi_sleep_or_register_writes(display_config_innolux_nx_abcc_specific_fini_01, 10); - break; - case 0x1030: /* AUO nx-abcc screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abcc_specific_fini_01, 10); - break; - default: - break; + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + } else { + do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); } - - udelay(5000); - - MAKE_DSI_REG(DSI_WR_DATA) = 0x1005; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - - udelay(50000); - - /* Disable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable Backlight -5V. */ - gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable Backlight +5V. */ - gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable clocks. */ - car->rst_dev_h_set = 0x1010000; - car->clk_enb_h_clr = 0x1010000; - car->rst_dev_l_set = 0x18000000; - car->clk_enb_l_clr = 0x18000000; - - MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF)); - MAKE_DSI_REG(DSI_POWER_CONTROL) = 0; - - /* Backlight PWM. */ - gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO); - - pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE); - pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1); -} - -static void display_end_mariko(void) { - volatile tegra_car_t *car = car_get_regs(); - - /* Disable Backlight. */ - display_backlight(false); - - MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1; - MAKE_DSI_REG(DSI_WR_DATA) = 0x2805; - - /* Wait 5 frames. */ - uint32_t start_val = MAKE_HOST1X_REG(0x30A4); - while (MAKE_HOST1X_REG(0x30A4) < start_val + 5) { - /* Wait. */ - } - - MAKE_DI_REG(DC_CMD_STATE_ACCESS) = (READ_MUX | WRITE_MUX); - MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0; - - do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13); - udelay(40000); - - do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13); if (g_lcd_vendor != 0x2050) { @@ -527,8 +346,8 @@ static void display_end_mariko(void) { udelay((g_lcd_vendor == 0x2050) ? 120000 : 50000); /* Disable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); - + gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); + if (g_lcd_vendor == 0x2050) { udelay(30000); } else { @@ -553,21 +372,13 @@ static void display_end_mariko(void) { MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF)); MAKE_DSI_REG(DSI_POWER_CONTROL) = 0; -} - -void display_init(void) { - if (is_soc_mariko()) { - display_init_mariko(); - } else { - display_init_erista(); - } -} - -void display_end(void) { - if (is_soc_mariko()) { - display_end_mariko(); - } else { - display_end_erista(); + + if (!is_mariko) { + /* Backlight PWM. */ + gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO); + + pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE); + pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1); } } diff --git a/fusee/fusee-primary/fusee-primary-main/src/hwinit.c b/fusee/fusee-primary/fusee-primary-main/src/hwinit.c index c6de69f3e..a6169ca1b 100644 --- a/fusee/fusee-primary/fusee-primary-main/src/hwinit.c +++ b/fusee/fusee-primary/fusee-primary-main/src/hwinit.c @@ -61,52 +61,39 @@ static void config_oscillators(void) { car->clk_sys_rate = 2; } -static void config_gpios_erista(void) { +static void config_gpios(void) { volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); - pinmux->uart2_tx = 0; - pinmux->uart3_tx = 0; - pinmux->pe6 = PINMUX_INPUT; - pinmux->ph6 = PINMUX_INPUT; - - gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO); - gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT); - - i2c_config(I2C_1); - i2c_config(I2C_5); - uart_config(UART_A); - - /* Configure volume up/down buttons as inputs. */ - gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_BUTTON_VOL_DOWN, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT); - gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT); -} - -static void config_gpios_mariko(void) { - volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); - uint32_t hardware_type = fuse_get_hardware_type(); - - /* Only for HardwareType_Iowa and HardwareType_Five. */ - if ((hardware_type == 3) || (hardware_type == 5)) { + if (is_mariko) { + uint32_t hardware_type = fuse_get_hardware_type(); + + /* Only for HardwareType_Iowa and HardwareType_Five. */ + if ((hardware_type == 3) || (hardware_type == 5)) { + pinmux->uart2_tx = 0; + pinmux->uart3_tx = 0; + gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); + gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); + gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); + gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); + } + } else { pinmux->uart2_tx = 0; pinmux->uart3_tx = 0; - gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); - gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); } pinmux->pe6 = PINMUX_INPUT; pinmux->ph6 = PINMUX_INPUT; + if (!is_mariko) { + gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); + gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); + } gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO); gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO); + if (!is_mariko) { + gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); + gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); + } gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT); gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT); @@ -120,17 +107,11 @@ static void config_gpios_mariko(void) { gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT); gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT); - /* Configure home button as input. */ - gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO); - gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT); -} - -static void config_pmc_scratch(void) { - volatile tegra_pmc_t *pmc = pmc_get_regs(); - - pmc->scratch20 &= 0xFFF3FFFF; - pmc->scratch190 &= 0xFFFFFFFE; - pmc->secure_scratch21 |= 0x10; + if (is_mariko) { + /* Configure home button as input. */ + gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO); + gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT); + } } static void mbist_workaround(void) { @@ -214,27 +195,36 @@ static void config_se_brom(void) { pmc->rst_status = 0; } -static void nx_hwinit_erista(bool enable_log) { +void nx_hwinit(bool enable_log) { volatile tegra_pmc_t *pmc = pmc_get_regs(); volatile tegra_car_t *car = car_get_regs(); + bool is_mariko = is_soc_mariko(); - /* Bootrom stuff we skipped by going through RCM. */ - config_se_brom(); + if (!is_mariko) { + /* Bootrom stuff we skipped by going through RCM. */ + config_se_brom(); - AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F; - pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD); + AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F; + pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD); - /* Apply the memory built-in self test workaround. */ - mbist_workaround(); + /* Apply the memory built-in self test workaround. */ + mbist_workaround(); + } - /* Reboot SE. */ + /* Enable SE clock. */ clkrst_reboot(CARDEVICE_SE); + if (is_mariko) { + /* Lock the SE clock. */ + car->clk_source_se |= 0x100; + } /* Initialize the fuse driver. */ fuse_init(); - /* Initialize the memory controller. */ - mc_enable(); + if (!is_mariko) { + /* Initialize the memory controller. */ + mc_enable(); + } /* Configure oscillators. */ config_oscillators(); @@ -243,9 +233,7 @@ static void nx_hwinit_erista(bool enable_log) { APB_MISC_PP_PINMUX_GLOBAL_0 = 0; /* Configure GPIOs. */ - /* NOTE: [3.0.0+] Part of the GPIO configuration is skipped if the unit is SDEV. */ - /* NOTE: [6.0.0+] The GPIO configuration's order was changed a bit. */ - config_gpios_erista(); + config_gpios(); /* UART debugging. */ if (enable_log) { @@ -253,111 +241,7 @@ static void nx_hwinit_erista(bool enable_log) { uart_init(UART_A, 115200); } - /* Reboot CL-DVFS. */ - clkrst_reboot(CARDEVICE_CL_DVFS); - - /* Reboot I2C1. */ - clkrst_reboot(CARDEVICE_I2C1); - - /* Reboot I2C5. */ - clkrst_reboot(CARDEVICE_I2C5); - - /* Reboot SE. */ - /* NOTE: [4.0.0+] This was removed. */ - /* clkrst_reboot(CARDEVICE_SE); */ - - /* Reboot TZRAM. */ - clkrst_reboot(CARDEVICE_TZRAM); - - /* Initialize I2C1. */ - /* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */ - i2c_init(I2C_1); - - /* Initialize I2C5. */ - i2c_init(I2C_5); - - /* Configure the PMIC. */ - uint8_t val = 0x40; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); - val = 0x60; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); - val = 0x38; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1); - val = 0x3A; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1); - val = 0x38; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1); - val = 0xF; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1); - val = 0xC7; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1); - val = 0x4F; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1); - val = 0x29; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1); - val = 0x1B; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1); - - /* NOTE: [3.0.0+] This was added. */ - val = 0x22; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1); - - /* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */ - /* - i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); - val |= 0x40; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); - */ - - /* Configure SD0 voltage. */ - val = 42; /* 42 = (1125000 - 600000) / 12500 -> 1.125V */ - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1); - - /* Configure and lock PMC scratch registers. */ - /* NOTE: [4.0.0+] This was removed. */ - config_pmc_scratch(); - - /* Set super clock burst policy. */ - car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333); - - /* Configure memory controller carveouts. */ - /* NOTE: [4.0.0+] This is now done in the Secure Monitor. */ - /* mc_config_carveout(); */ - - /* Save SDRAM parameters to scratch. */ - sdram_save_params(sdram_get_params(fuse_get_dram_id())); - - /* Initialize SDRAM. */ - sdram_init(); -} - -static void nx_hwinit_mariko(bool enable_log) { - volatile tegra_pmc_t *pmc = pmc_get_regs(); - volatile tegra_car_t *car = car_get_regs(); - - /* Enable SE clock and lock it. */ - clkrst_reboot(CARDEVICE_SE); - car->clk_source_se |= 0x100; - - /* Make all fuse registers visible. */ - clkrst_enable_fuse_regs(true); - - /* Configure oscillators. */ - config_oscillators(); - - /* Disable pinmux tristate input clamping. */ - APB_MISC_PP_PINMUX_GLOBAL_0 = 0; - - /* Configure GPIOs. */ - config_gpios_mariko(); - - /* UART debugging. */ - if (enable_log) { - clkrst_reboot(CARDEVICE_UARTA); - uart_init(UART_A, 115200); - } - - /* Enable CL-DVFS clock. */ + /* Enable CL-DVFS clock. */ clkrst_reboot(CARDEVICE_CL_DVFS); /* Enable I2C1 clock. */ @@ -373,43 +257,71 @@ static void nx_hwinit_mariko(bool enable_log) { i2c_init(I2C_5); /* Configure the PMIC. */ - uint8_t val = 0x40; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); - val = 0x78; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); - + if (is_mariko) { + uint8_t val = 0x40; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); + val = 0x78; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); + } else { + uint8_t val = 0x40; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); + val = 0x60; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); + val = 0x38; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1); + val = 0x3A; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1); + val = 0x38; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1); + val = 0xF; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1); + val = 0xC7; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1); + val = 0x4F; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1); + val = 0x29; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1); + val = 0x1B; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1); + + /* NOTE: [3.0.0+] This was added. */ + val = 0x22; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1); + + /* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */ + /* + i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); + val |= 0x40; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); + */ + } + /* Configure SD0 voltage. */ - val = 0x24; + uint8_t val = 0x24; i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1); /* Enable LDO8 in HardwareType_Hoag only. */ - if (fuse_get_hardware_type() == 2) { + if (is_mariko && (fuse_get_hardware_type() == 2)) { val = 0xE8; i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO8_CFG, &val, 1); } /* Initialize I2C1. */ i2c_init(I2C_1); - + /* Set super clock burst policy. */ car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333); - /* Mariko only PMC configuration for TZRAM. */ - pmc->tzram_pwr_cntrl &= 0xFFFFFFFE; - pmc->tzram_non_sec_disable = 0x3; - pmc->tzram_sec_disable = 0x3; + if (is_mariko) { + /* Mariko only PMC configuration for TZRAM. */ + pmc->tzram_pwr_cntrl &= 0xFFFFFFFE; + pmc->tzram_non_sec_disable = 0x3; + pmc->tzram_sec_disable = 0x3; + } /* Save SDRAM parameters to scratch. */ sdram_save_params(sdram_get_params(fuse_get_dram_id())); /* Initialize SDRAM. */ sdram_init(); -} - -void nx_hwinit(bool enable_log) { - if (is_soc_mariko()) { - nx_hwinit_mariko(enable_log); - } else { - nx_hwinit_erista(enable_log); - } } \ No newline at end of file diff --git a/fusee/fusee-primary/fusee-primary-main/src/se.h b/fusee/fusee-primary/fusee-primary-main/src/se.h index 4f01d26f9..2cc97f8ec 100644 --- a/fusee/fusee-primary/fusee-primary-main/src/se.h +++ b/fusee/fusee-primary/fusee-primary-main/src/se.h @@ -37,6 +37,9 @@ /* This keyslot was added in 5.0.0. */ #define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA +/* Mariko keyslots. */ +#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7 + #define KEYSLOT_AES_MAX 0x10 #define KEYSLOT_RSA_MAX 0x2 diff --git a/fusee/fusee-secondary/src/cluster.c b/fusee/fusee-secondary/src/cluster.c index bd7b339b5..daf4359b6 100644 --- a/fusee/fusee-secondary/src/cluster.c +++ b/fusee/fusee-secondary/src/cluster.c @@ -107,95 +107,23 @@ static void cluster_pmc_enable_partition(uint32_t part, uint32_t toggle) { } } -static void cluster_boot_cpu0_erista(uint32_t entry) { +void cluster_boot_cpu0(uint32_t entry) { volatile tegra_car_t *car = car_get_regs(); + bool is_mariko = is_soc_mariko(); /* Set ACTIVE_CLUSER to FAST. */ FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 &= 0xFFFFFFFE; /* Enable VddCpu. */ - cluster_enable_power(0); - - if (!(car->pllx_base & 0x40000000)) { - car->pllx_misc3 &= 0xFFFFFFF7; - udelay(2); - car->pllx_base = 0x80404E02; - car->pllx_base = 0x404E02; - car->pllx_misc = ((car->pllx_misc & 0xFFFBFFFF) | 0x40000); - car->pllx_base = 0x40404E02; - } - - while (!(car->pllx_base & 0x8000000)) { - /* Wait. */ - } - - /* Configure MSELECT source and enable clock. */ - car->clk_source_mselect = ((car->clk_source_mselect & 0x1FFFFF00) | 6); - car->clk_out_enb_v = ((car->clk_out_enb_v & 0xFFFFFFF7) | 8); - - /* Configure initial CPU clock frequency and enable clock. */ - car->cclk_brst_pol = 0x20008888; - car->super_cclk_div = 0x80000000; - car->clk_enb_v_set = 1; - - clkrst_reboot(CARDEVICE_CORESIGHT); - - /* CAR2PMC_CPU_ACK_WIDTH should be set to 0. */ - car->cpu_softrst_ctrl2 &= 0xFFFFF000; - - /* Enable CPU rail. */ - cluster_pmc_enable_partition(1, 0); - - /* Enable cluster 0 non-CPU. */ - cluster_pmc_enable_partition(0x8000, 15); - - /* Enable CE0. */ - cluster_pmc_enable_partition(0x4000, 14); - - /* Request and wait for RAM repair. */ - FLOW_CTLR_RAM_REPAIR_0 = 1; - while (!(FLOW_CTLR_RAM_REPAIR_0 & 2)) { - /* Wait. */ - } - - MAKE_EXCP_VEC_REG(0x100) = 0; - - /* Set reset vector. */ - SB_AA64_RESET_LOW_0 = (entry | 1); - SB_AA64_RESET_HIGH_0 = 0; - - /* Non-secure reset vector write disable. */ - SB_CSR_0 = 2; - (void)SB_CSR_0; - - /* Set CPU_STRICT_TZ_APERTURE_CHECK. */ - /* NOTE: [4.0.0+] This was added, but it breaks Exosphère. */ - /* MAKE_MC_REG(MC_TZ_SECURITY_CTRL) = 1; */ - - /* Clear MSELECT reset. */ - car->rst_dev_v &= 0xFFFFFFF7; - - /* Clear NONCPU reset. */ - car->rst_cpug_cmplx_clr = 0x20000000; - - /* Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.*/ - /* NOTE: [5.0.0+] This was changed so only CPU0 reset is cleared. */ - /* car->rst_cpug_cmplx_clr = 0x411F000F; */ - car->rst_cpug_cmplx_clr = 0x41010001; -} - -static void cluster_boot_cpu0_mariko(uint32_t entry) { - volatile tegra_car_t *car = car_get_regs(); - - /* Set ACTIVE_CLUSER to FAST. */ - FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 &= 0xFFFFFFFE; - - /* Enable VddCpu. */ - cluster_enable_power(fuse_get_regulator()); + cluster_enable_power(is_mariko ? fuse_get_regulator() : 0); if (!(car->pllx_base & 0x40000000)) { car->pllx_misc3 &= 0xFFFFFFF7; udelay(2); + if (!is_mariko) { + car->pllx_base = 0x80404E02; + car->pllx_base = 0x404E02; + } car->pllx_misc = ((car->pllx_misc & 0xFFFBFFFF) | 0x40000); car->pllx_base = 0x40404E02; } @@ -250,14 +178,11 @@ static void cluster_boot_cpu0_mariko(uint32_t entry) { /* Clear MSELECT reset. */ rst_disable(CARDEVICE_MSELECT); - /* Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.*/ + if (!is_mariko) { + /* Clear NONCPU reset. */ + car->rst_cpug_cmplx_clr = 0x20000000; + } + + /* Clear CPU{0} POR and CORE, CX0, L2, and DBG reset.*/ car->rst_cpug_cmplx_clr = 0x41010001; } - -void cluster_boot_cpu0(uint32_t entry) { - if (is_soc_mariko()) { - cluster_boot_cpu0_mariko(uint32_t entry); - } else { - cluster_boot_cpu0_erista(uint32_t entry); - } -} diff --git a/fusee/fusee-secondary/src/di.c b/fusee/fusee-secondary/src/di.c index 60468d600..59cc1e44f 100644 --- a/fusee/fusee-secondary/src/di.c +++ b/fusee/fusee-secondary/src/di.c @@ -62,169 +62,25 @@ static void dsi_wait(uint32_t timeout, uint32_t offset, uint32_t mask, uint32_t udelay(delay); } -static void display_init_erista(void) { - volatile tegra_car_t *car = car_get_regs(); - volatile tegra_pmc_t *pmc = pmc_get_regs(); - volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); - - /* Power on. */ - uint8_t val = 0xD0; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); - - /* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */ - car->rst_dev_h_clr = 0x1010000; - car->clk_enb_h_set = 0x1010000; - car->rst_dev_l_clr = 0x18000000; - car->clk_enb_l_set = 0x18000000; - car->clk_enb_x_set = 0x20000; - car->clk_source_uart_fst_mipi_cal = 0xA; - car->clk_enb_w_set = 0x80000; - car->clk_source_dsia_lp = 0xA; - - /* DPD idle. */ - pmc->io_dpd_req = 0x40000000; - pmc->io_dpd2_req = 0x40000000; - - /* Configure pins. */ - pinmux->nfc_en &= ~PINMUX_TRISTATE; - pinmux->nfc_int &= ~PINMUX_TRISTATE; - pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE; - pinmux->lcd_bl_en &= ~PINMUX_TRISTATE; - pinmux->lcd_rst &= ~PINMUX_TRISTATE; - - /* Configure Backlight +-5V GPIOs. */ - gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT); - - /* Enable Backlight +5V. */ - gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH); - - udelay(10000); - - /* Enable Backlight -5V. */ - gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH); - - udelay(10000); - - /* Configure Backlight PWM, EN and RST GPIOs. */ - gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT); - - /* Enable Backlight EN. */ - gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH); - - /* Configure display interface and display. */ - MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; - - do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); - do_register_writes(DI_BASE, display_config_dc_01, 94); - do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8); - do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14); - do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0); - do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14); - - udelay(10000); - - /* Enable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH); - - udelay(60000); - - MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204; - MAKE_DSI_REG(DSI_WR_DATA) = 0x337; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5); - - MAKE_DSI_REG(DSI_WR_DATA) = 0x406; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5); - - MAKE_DSI_REG(DSI_HOST_CONTROL) = (DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC); - dsi_wait(150000, DSI_HOST_CONTROL, DSI_HOST_CONTROL_IMM_BTA, 5000); - - /* Parse LCD vendor. */ - uint32_t host_response[3]; - for (uint32_t i = 0; i < 3; i++) { - host_response[i] = MAKE_DSI_REG(DSI_RD_DATA); - } - - /* The last word from host response is: - Bits 0-7: FAB - Bits 8-15: REV - Bits 16-23: Minor REV - */ - if ((host_response[2] & 0xFF) == 0x10) { - g_lcd_vendor = 0; - } else { - g_lcd_vendor = (host_response[2] >> 8) & 0xFF00; - } - g_lcd_vendor = (g_lcd_vendor & 0xFFFFFF00) | (host_response[2] & 0xFF); - - /* LCD vendor specific configuration. */ - switch (g_lcd_vendor) { - case 0x10: /* Japan Display Inc screens. */ - do_dsi_sleep_or_register_writes(display_config_jdi_specific_init_01, 48); - break; - case 0xF20: /* Innolux nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_innolux_nx_abca2_specific_init_01, 14); - break; - case 0xF30: /* AUO nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_init_01, 14); - break; - default: - /* Innolux and AUO nx-abcc screens. */ - if ((g_lcd_vendor | 0x10) == 0x1030) { - do_dsi_sleep_or_register_writes(display_config_innolux_auo_40_nx_abcc_specific_init_01, 5); - } - break; - } - - udelay(20000); - - do_register_writes(CAR_BASE, display_config_plld_02_erista, 3); - do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19); - MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4; - do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10); - - udelay(10000); - - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - - udelay(10000); - - do_register_writes(DI_BASE, display_config_dc_02, 113); -} - -static void display_init_mariko(void) { +void display_init(void) { volatile tegra_car_t *car = car_get_regs(); volatile tegra_pmc_t *pmc = pmc_get_regs(); volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); uint32_t hardware_type = fuse_get_hardware_type(); /* Power on. */ - uint8_t val = 0x3A; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1); - val = 0x71; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1); - val = 0xD0; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + if (is_mariko) { + uint8_t val = 0x3A; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1); + val = 0x71; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1); + val = 0xD0; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + } else { + uint8_t val = 0xD0; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + } /* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */ car->rst_dev_h_clr = 0x1010000; @@ -247,7 +103,7 @@ static void display_init_mariko(void) { pinmux->lcd_bl_en &= ~PINMUX_TRISTATE; pinmux->lcd_rst &= ~PINMUX_TRISTATE; - if (hardware_type == 5) { + if (is_mariko && (hardware_type == 5)) { /* HardwareType_Five only configures GPIO_LCD_BL_RST. */ gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO); gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT); @@ -282,19 +138,41 @@ static void display_init_mariko(void) { /* Configure display interface and display. */ MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; - MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0; - APB_MISC_GP_DSI_PAD_CONTROL_0 = 0; - - do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + if (is_mariko) { + MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0; + APB_MISC_GP_DSI_PAD_CONTROL_0 = 0; + } + + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + } else { + do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); + } do_register_writes(DI_BASE, display_config_dc_01, 94); do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8); - do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14); - do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7); + } else { + do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14); udelay(10000); @@ -303,8 +181,8 @@ static void display_init_mariko(void) { gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH); udelay(60000); - - if (hardware_type == 5) { + + if (is_mariko && (hardware_type == 5)) { MAKE_DSI_REG(DSI_BTA_TIMING) = 0x40103; } else { MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204; @@ -362,33 +240,50 @@ static void display_init_mariko(void) { udelay(20000); - do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3); + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3); + } else { + do_register_writes(CAR_BASE, display_config_plld_02_erista, 3); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19); MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4; do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10); udelay(10000); - - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - + + if (is_mariko) { + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + } else { + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + } + udelay(10000); do_register_writes(DI_BASE, display_config_dc_02, 113); } -static void display_end_erista(void) { +void display_end(void) { volatile tegra_car_t *car = car_get_regs(); volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); /* Disable Backlight. */ display_backlight(false); @@ -408,93 +303,17 @@ static void display_end_erista(void) { do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13); udelay(40000); - do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); - do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13); - - udelay(10000); - - /* LCD vendor specific shutdown. */ - switch (g_lcd_vendor) { - case 0x10: /* Japan Display Inc screens. */ - do_dsi_sleep_or_register_writes(display_config_jdi_specific_fini_01, 22); - break; - case 0xF30: /* AUO nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_fini_01, 38); - break; - case 0x1020: /* Innolux nx-abcc screens. */ - do_dsi_sleep_or_register_writes(display_config_innolux_nx_abcc_specific_fini_01, 10); - break; - case 0x1030: /* AUO nx-abcc screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abcc_specific_fini_01, 10); - break; - default: - break; + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + } else { + do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); } - - udelay(5000); - - MAKE_DSI_REG(DSI_WR_DATA) = 0x1005; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - - udelay(50000); - - /* Disable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable Backlight -5V. */ - gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable Backlight +5V. */ - gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable clocks. */ - car->rst_dev_h_set = 0x1010000; - car->clk_enb_h_clr = 0x1010000; - car->rst_dev_l_set = 0x18000000; - car->clk_enb_l_clr = 0x18000000; - - MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF)); - MAKE_DSI_REG(DSI_POWER_CONTROL) = 0; - - /* Backlight PWM. */ - gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO); - - pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE); - pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1); -} - -static void display_end_mariko(void) { - volatile tegra_car_t *car = car_get_regs(); - - /* Disable Backlight. */ - display_backlight(false); - - MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1; - MAKE_DSI_REG(DSI_WR_DATA) = 0x2805; - - /* Wait 5 frames. */ - uint32_t start_val = MAKE_HOST1X_REG(0x30A4); - while (MAKE_HOST1X_REG(0x30A4) < start_val + 5) { - /* Wait. */ - } - - MAKE_DI_REG(DC_CMD_STATE_ACCESS) = (READ_MUX | WRITE_MUX); - MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0; - - do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13); - udelay(40000); - - do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13); if (g_lcd_vendor != 0x2050) { @@ -527,8 +346,8 @@ static void display_end_mariko(void) { udelay((g_lcd_vendor == 0x2050) ? 120000 : 50000); /* Disable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); - + gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); + if (g_lcd_vendor == 0x2050) { udelay(30000); } else { @@ -553,21 +372,13 @@ static void display_end_mariko(void) { MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF)); MAKE_DSI_REG(DSI_POWER_CONTROL) = 0; -} - -void display_init(void) { - if (is_soc_mariko()) { - display_init_mariko(); - } else { - display_init_erista(); - } -} - -void display_end(void) { - if (is_soc_mariko()) { - display_end_mariko(); - } else { - display_end_erista(); + + if (!is_mariko) { + /* Backlight PWM. */ + gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO); + + pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE); + pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1); } } diff --git a/fusee/fusee-secondary/src/key_derivation.c b/fusee/fusee-secondary/src/key_derivation.c index 91c566545..60a65141a 100644 --- a/fusee/fusee-secondary/src/key_derivation.c +++ b/fusee/fusee-secondary/src/key_derivation.c @@ -61,6 +61,15 @@ static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MAST {0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* MasterKek seed 07. */ }; +static const uint8_t AL16 master_kek_seeds_mariko[MASTERKEY_REVISION_910_CURRENT - MASTERKEY_REVISION_500_510][0x10] = { + { 0x77, 0x60, 0x5A, 0xD2, 0xEE, 0x6E, 0xF8, 0x3C, 0x3F, 0x72, 0xE2, 0x59, 0x9D, 0xAC, 0x5E, 0x56 }, /* Mariko MasterKek seed 05. */ + { 0x1E, 0x80, 0xB8, 0x17, 0x3E, 0xC0, 0x60, 0xAA, 0x11, 0xBE, 0x1A, 0x4A, 0xA6, 0x6F, 0xE4, 0xAE }, /* Mariko MasterKek seed 06. */ + { 0x94, 0x08, 0x67, 0xBD, 0x0A, 0x00, 0x38, 0x84, 0x11, 0xD3, 0x1A, 0xDB, 0xDD, 0x8D, 0xF1, 0x8A }, /* Mariko MasterKek seed 07. */ + { 0x5C, 0x24, 0xE3, 0xB8, 0xB4, 0xF7, 0x00, 0xC2, 0x3C, 0xFD, 0x0A, 0xCE, 0x13, 0xC3, 0xDC, 0x23 }, /* Mariko MasterKek seed 08. */ + { 0x86, 0x69, 0xF0, 0x09, 0x87, 0xC8, 0x05, 0xAE, 0xB5, 0x7B, 0x48, 0x74, 0xDE, 0x62, 0xA6, 0x13 }, /* Mariko MasterKek seed 09. */ + { 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82 }, /* Mariko MasterKek seed 0A. */ +}; + static nx_dec_keyblob_t AL16 g_dec_keyblobs[32]; static int get_keyblob(nx_keyblob_t *dst, uint32_t revision, const nx_keyblob_t *keyblobs, uint32_t available_revision) { @@ -121,7 +130,7 @@ int load_package1_key(uint32_t revision) { } /* Derive all Switch keys. */ -int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_keys, unsigned int *out_keygen_type) { +int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_keys, unsigned int *out_keygen_type) { uint8_t AL16 work_buffer[0x10]; uint8_t AL16 zeroes[0x10] = {0}; @@ -215,6 +224,16 @@ int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, ui return mkey_detect_revision(fuse_get_hardware_state() != 0); } +int derive_nx_keydata_mariko(uint32_t target_firmware) { + /* Derive keys for Exosphere, lock critical keyslots. */ + decrypt_data_into_keyslot(0xA, 0xE, devicekey_4x_seed, 0x10); + decrypt_data_into_keyslot(0x7, 0xC, &master_kek_seeds_mariko[target_firmware - MASTERKEY_REVISION_600_610], 0x10); + decrypt_data_into_keyslot(0x7, 0x7, masterkey_seed, 0x10); + + /* Setup master key revision, derive older master keys for use. */ + return mkey_detect_revision(fuse_get_hardware_state() != 0); +} + static void generate_specific_aes_key(void *dst, const void *wrapped_key, bool should_mask, uint32_t target_firmware, uint32_t generation) { unsigned int keyslot = devkey_get_keyslot(generation); diff --git a/fusee/fusee-secondary/src/key_derivation.h b/fusee/fusee-secondary/src/key_derivation.h index 48ec076a2..e2b0c0f8e 100644 --- a/fusee/fusee-secondary/src/key_derivation.h +++ b/fusee/fusee-secondary/src/key_derivation.h @@ -47,7 +47,8 @@ typedef struct nx_keyblob_t { }; } nx_keyblob_t; -int derive_nx_keydata(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_key, unsigned int *out_keygen_type); +int derive_nx_keydata_erista(uint32_t target_firmware, const nx_keyblob_t *keyblobs, uint32_t available_revision, const void *tsec_key, void *tsec_root_key, unsigned int *out_keygen_type); +int derive_nx_keydata_mariko(uint32_t target_firmware); int load_package1_key(uint32_t revision); void derive_bis_key(void *dst, BisPartition partition_id, uint32_t target_firmware); diff --git a/fusee/fusee-secondary/src/masterkey.c b/fusee/fusee-secondary/src/masterkey.c index 430709fad..5d8397550 100644 --- a/fusee/fusee-secondary/src/masterkey.c +++ b/fusee/fusee-secondary/src/masterkey.c @@ -22,6 +22,7 @@ #include "utils.h" #include "masterkey.h" #include "se.h" +#include "fuse.h" static unsigned int g_mkey_revision = 0; static bool g_determined_mkey_revision = false; @@ -94,6 +95,11 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 9.1.0 New Device Keygen Source to be added on next change-of-keys. */ }; +/* Determine the current SoC for Mariko specific code. */ +static bool is_soc_mariko() { + return (fuse_get_soc_type() == 1); +} + static bool check_mkey_revision(unsigned int revision, bool is_retail) { uint8_t final_vector[0x10]; @@ -153,8 +159,10 @@ unsigned int mkey_get_keyslot(unsigned int revision) { if (revision > g_mkey_revision) { generic_panic(); } - - if (revision == g_mkey_revision) { + + if (is_soc_mariko()) { + return KEYSLOT_SWITCH_MASTERKEY_MARIKO; + } else if (revision == g_mkey_revision) { return KEYSLOT_SWITCH_MASTERKEY; } else { /* Load into a temp keyslot. */ diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index a8c0de223..0a15f09f7 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -671,6 +671,7 @@ uint32_t nxboot_main(void) { volatile tegra_pmc_t *pmc = pmc_get_regs(); loader_ctx_t *loader_ctx = get_loader_ctx(); const bool is_experimental = fusee_is_experimental(); + bool is_mariko = is_soc_mariko(); package2_header_t *package2; size_t package2_size; void *tsec_fw; @@ -692,7 +693,7 @@ uint32_t nxboot_main(void) { exo_emummc_config_t exo_emummc_cfg; /* Set the start time (Mariko only). */ - if (is_soc_mariko()) { + if (is_mariko) { MAILBOX_NX_BOOTLOADER_START_TIME = get_time(); } @@ -785,7 +786,7 @@ uint32_t nxboot_main(void) { print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Detected target firmware %ld!\n", target_firmware); /* Handle TSEC and Sept (Erista only). */ - if (!is_soc_mariko()) { + if (!is_mariko) { /* Read the TSEC firmware from a file, otherwise from PK1L. */ if (loader_ctx->tsecfw_path[0] != '\0') { tsec_fw_size = get_file_size(loader_ctx->tsecfw_path); @@ -888,10 +889,14 @@ uint32_t nxboot_main(void) { /* Display splash screen. */ display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000); - /* Derive keydata. If on 7.0.0+, sept has already derived keys for us. */ + /* Derive keydata. */ unsigned int keygen_type = 0; - if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { - if (derive_nx_keydata(target_firmware, g_keyblobs, available_revision, tsec_key, tsec_root_keys, &keygen_type) != 0) { + if (is_mariko) { + if (derive_nx_keydata_mariko(target_firmware) != 0) { + fatal_error("[NXBOOT] Key derivation failed!\n"); + } + } else if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { /* If on 7.0.0+, sept has already derived keys for us (Erista only). */ + if (derive_nx_keydata_erista(target_firmware, g_keyblobs, available_revision, tsec_key, tsec_root_keys, &keygen_type) != 0) { fatal_error("[NXBOOT] Key derivation failed!\n"); } } @@ -923,7 +928,7 @@ uint32_t nxboot_main(void) { nxboot_configure_exosphere(target_firmware, keygen_type, &exo_emummc_cfg); /* Initialize BootReason on older firmware versions (Erista only). */ - if (!is_soc_mariko()) { + if (!is_mariko) { if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0) { print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Initializing BootReason...\n"); nxboot_set_bootreason((void *)MAILBOX_NX_BOOTLOADER_BOOT_REASON_BASE); @@ -948,7 +953,7 @@ uint32_t nxboot_main(void) { if (read_from_file(warmboot_fw, warmboot_fw_size, loader_ctx->warmboot_path) != warmboot_fw_size) { fatal_error("[NXBOOT] Could not read the warmboot firmware from %s!\n", loader_ctx->warmboot_path); } - } else if (!is_soc_mariko()) { + } else if (!is_mariko) { /* Use Atmosphere's warmboot firmware implementation (Erista only). */ warmboot_fw_size = warmboot_bin_size; warmboot_fw = malloc(warmboot_fw_size); @@ -965,7 +970,7 @@ uint32_t nxboot_main(void) { } /* Patch warmboot firmware for atmosphere (Erista only). */ - if (!is_soc_mariko() && (warmboot_fw != NULL) && (warmboot_fw_size >= sizeof(warmboot_ams_header_t))) { + if (!is_mariko && (warmboot_fw != NULL) && (warmboot_fw_size >= sizeof(warmboot_ams_header_t))) { warmboot_ams_header_t *ams_header = (warmboot_ams_header_t *)warmboot_fw; if (ams_header->ams_metadata.magic == WARMBOOT_MAGIC) { /* Set target firmware */ @@ -985,13 +990,13 @@ uint32_t nxboot_main(void) { /* Copy the warmboot firmware and set the address in PMC if necessary. */ if (warmboot_fw && (warmboot_fw_size > 0)) { memcpy(warmboot_memaddr, warmboot_fw, warmboot_fw_size); - if (!is_soc_mariko() && (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0)) { + if (!is_mariko && (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0)) { pmc->scratch1 = (uint32_t)warmboot_memaddr; } } /* Handle warmboot security check. */ - if (is_soc_mariko()) { + if (is_mariko) { /* TODO */ } else { /* Set 3.0.0/3.0.1/3.0.2 warmboot security check. */ @@ -1071,7 +1076,7 @@ uint32_t nxboot_main(void) { } /* Copy the Mariko's Exosphère fatal program to a good location. */ - if (is_soc_mariko()) { + if (is_mariko) { void * const mariko_fatal_dst = (void *)0x80020000; memset(mariko_fatal_dst, 0, 0x20000); @@ -1107,8 +1112,8 @@ uint32_t nxboot_main(void) { /* Wait for the splash screen to have been displayed for as long as it should be. */ splash_screen_wait_delay(); - /* Set reset for USBD, USB2, AHBDMA, and APBDMA on Erista. */ - if (!is_soc_mariko()) { + /* Set reset for USBD, USB2, AHBDMA, and APBDMA (Erista only). */ + if (!is_mariko) { rst_enable(CARDEVICE_USBD); rst_enable(CARDEVICE_USB2); rst_enable(CARDEVICE_AHBDMA); diff --git a/fusee/fusee-secondary/src/nxboot_iram.c b/fusee/fusee-secondary/src/nxboot_iram.c index fe28eb0e2..6c1da0f1e 100644 --- a/fusee/fusee-secondary/src/nxboot_iram.c +++ b/fusee/fusee-secondary/src/nxboot_iram.c @@ -34,6 +34,8 @@ static bool is_soc_mariko() { } void nxboot_finish(uint32_t boot_memaddr) { + bool is_mariko = is_soc_mariko(); + /* Boot up Exosphère. */ MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 0; MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_DRAM_INITIALIZED_4X; @@ -41,7 +43,7 @@ void nxboot_finish(uint32_t boot_memaddr) { /* Terminate the display. */ display_end(); - if (is_soc_mariko()) { + if (is_mariko) { /* Boot CPU0. */ cluster_boot_cpu0(boot_memaddr); } else { @@ -71,7 +73,7 @@ void nxboot_finish(uint32_t boot_memaddr) { MAILBOX_NX_BOOTLOADER_SETUP_STATE = NX_BOOTLOADER_STATE_FINISHED_4X; /* Set the end time (Mariko only).*/ - if (is_soc_mariko()) { + if (is_mariko) { MAILBOX_NX_BOOTLOADER_END_TIME = get_time(); } diff --git a/fusee/fusee-secondary/src/se.h b/fusee/fusee-secondary/src/se.h index cb7c3ca28..d62174384 100644 --- a/fusee/fusee-secondary/src/se.h +++ b/fusee/fusee-secondary/src/se.h @@ -37,6 +37,9 @@ /* This keyslot was added in 5.0.0. */ #define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA +/* Mariko keyslots. */ +#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7 + #define KEYSLOT_AES_MAX 0x10 #define KEYSLOT_RSA_MAX 0x2 diff --git a/sept/sept-primary/src/se.h b/sept/sept-primary/src/se.h index 4f01d26f9..2cc97f8ec 100644 --- a/sept/sept-primary/src/se.h +++ b/sept/sept-primary/src/se.h @@ -37,6 +37,9 @@ /* This keyslot was added in 5.0.0. */ #define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA +/* Mariko keyslots. */ +#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7 + #define KEYSLOT_AES_MAX 0x10 #define KEYSLOT_RSA_MAX 0x2 diff --git a/sept/sept-secondary/key_derivation/src/se.h b/sept/sept-secondary/key_derivation/src/se.h index 5d5b72c98..508da9fa4 100644 --- a/sept/sept-secondary/key_derivation/src/se.h +++ b/sept/sept-secondary/key_derivation/src/se.h @@ -38,6 +38,9 @@ /* This keyslot was added in 5.0.0. */ #define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA +/* Mariko keyslots. */ +#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7 + #define KEYSLOT_AES_MAX 0x10 #define KEYSLOT_RSA_MAX 0x2 diff --git a/sept/sept-secondary/src/cluster.c b/sept/sept-secondary/src/cluster.c index bd7b339b5..daf4359b6 100644 --- a/sept/sept-secondary/src/cluster.c +++ b/sept/sept-secondary/src/cluster.c @@ -107,95 +107,23 @@ static void cluster_pmc_enable_partition(uint32_t part, uint32_t toggle) { } } -static void cluster_boot_cpu0_erista(uint32_t entry) { +void cluster_boot_cpu0(uint32_t entry) { volatile tegra_car_t *car = car_get_regs(); + bool is_mariko = is_soc_mariko(); /* Set ACTIVE_CLUSER to FAST. */ FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 &= 0xFFFFFFFE; /* Enable VddCpu. */ - cluster_enable_power(0); - - if (!(car->pllx_base & 0x40000000)) { - car->pllx_misc3 &= 0xFFFFFFF7; - udelay(2); - car->pllx_base = 0x80404E02; - car->pllx_base = 0x404E02; - car->pllx_misc = ((car->pllx_misc & 0xFFFBFFFF) | 0x40000); - car->pllx_base = 0x40404E02; - } - - while (!(car->pllx_base & 0x8000000)) { - /* Wait. */ - } - - /* Configure MSELECT source and enable clock. */ - car->clk_source_mselect = ((car->clk_source_mselect & 0x1FFFFF00) | 6); - car->clk_out_enb_v = ((car->clk_out_enb_v & 0xFFFFFFF7) | 8); - - /* Configure initial CPU clock frequency and enable clock. */ - car->cclk_brst_pol = 0x20008888; - car->super_cclk_div = 0x80000000; - car->clk_enb_v_set = 1; - - clkrst_reboot(CARDEVICE_CORESIGHT); - - /* CAR2PMC_CPU_ACK_WIDTH should be set to 0. */ - car->cpu_softrst_ctrl2 &= 0xFFFFF000; - - /* Enable CPU rail. */ - cluster_pmc_enable_partition(1, 0); - - /* Enable cluster 0 non-CPU. */ - cluster_pmc_enable_partition(0x8000, 15); - - /* Enable CE0. */ - cluster_pmc_enable_partition(0x4000, 14); - - /* Request and wait for RAM repair. */ - FLOW_CTLR_RAM_REPAIR_0 = 1; - while (!(FLOW_CTLR_RAM_REPAIR_0 & 2)) { - /* Wait. */ - } - - MAKE_EXCP_VEC_REG(0x100) = 0; - - /* Set reset vector. */ - SB_AA64_RESET_LOW_0 = (entry | 1); - SB_AA64_RESET_HIGH_0 = 0; - - /* Non-secure reset vector write disable. */ - SB_CSR_0 = 2; - (void)SB_CSR_0; - - /* Set CPU_STRICT_TZ_APERTURE_CHECK. */ - /* NOTE: [4.0.0+] This was added, but it breaks Exosphère. */ - /* MAKE_MC_REG(MC_TZ_SECURITY_CTRL) = 1; */ - - /* Clear MSELECT reset. */ - car->rst_dev_v &= 0xFFFFFFF7; - - /* Clear NONCPU reset. */ - car->rst_cpug_cmplx_clr = 0x20000000; - - /* Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.*/ - /* NOTE: [5.0.0+] This was changed so only CPU0 reset is cleared. */ - /* car->rst_cpug_cmplx_clr = 0x411F000F; */ - car->rst_cpug_cmplx_clr = 0x41010001; -} - -static void cluster_boot_cpu0_mariko(uint32_t entry) { - volatile tegra_car_t *car = car_get_regs(); - - /* Set ACTIVE_CLUSER to FAST. */ - FLOW_CTLR_BPMP_CLUSTER_CONTROL_0 &= 0xFFFFFFFE; - - /* Enable VddCpu. */ - cluster_enable_power(fuse_get_regulator()); + cluster_enable_power(is_mariko ? fuse_get_regulator() : 0); if (!(car->pllx_base & 0x40000000)) { car->pllx_misc3 &= 0xFFFFFFF7; udelay(2); + if (!is_mariko) { + car->pllx_base = 0x80404E02; + car->pllx_base = 0x404E02; + } car->pllx_misc = ((car->pllx_misc & 0xFFFBFFFF) | 0x40000); car->pllx_base = 0x40404E02; } @@ -250,14 +178,11 @@ static void cluster_boot_cpu0_mariko(uint32_t entry) { /* Clear MSELECT reset. */ rst_disable(CARDEVICE_MSELECT); - /* Clear CPU{0,1,2,3} POR and CORE, CX0, L2, and DBG reset.*/ + if (!is_mariko) { + /* Clear NONCPU reset. */ + car->rst_cpug_cmplx_clr = 0x20000000; + } + + /* Clear CPU{0} POR and CORE, CX0, L2, and DBG reset.*/ car->rst_cpug_cmplx_clr = 0x41010001; } - -void cluster_boot_cpu0(uint32_t entry) { - if (is_soc_mariko()) { - cluster_boot_cpu0_mariko(uint32_t entry); - } else { - cluster_boot_cpu0_erista(uint32_t entry); - } -} diff --git a/sept/sept-secondary/src/di.c b/sept/sept-secondary/src/di.c index 60468d600..59cc1e44f 100644 --- a/sept/sept-secondary/src/di.c +++ b/sept/sept-secondary/src/di.c @@ -62,169 +62,25 @@ static void dsi_wait(uint32_t timeout, uint32_t offset, uint32_t mask, uint32_t udelay(delay); } -static void display_init_erista(void) { - volatile tegra_car_t *car = car_get_regs(); - volatile tegra_pmc_t *pmc = pmc_get_regs(); - volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); - - /* Power on. */ - uint8_t val = 0xD0; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); - - /* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */ - car->rst_dev_h_clr = 0x1010000; - car->clk_enb_h_set = 0x1010000; - car->rst_dev_l_clr = 0x18000000; - car->clk_enb_l_set = 0x18000000; - car->clk_enb_x_set = 0x20000; - car->clk_source_uart_fst_mipi_cal = 0xA; - car->clk_enb_w_set = 0x80000; - car->clk_source_dsia_lp = 0xA; - - /* DPD idle. */ - pmc->io_dpd_req = 0x40000000; - pmc->io_dpd2_req = 0x40000000; - - /* Configure pins. */ - pinmux->nfc_en &= ~PINMUX_TRISTATE; - pinmux->nfc_int &= ~PINMUX_TRISTATE; - pinmux->lcd_bl_pwm &= ~PINMUX_TRISTATE; - pinmux->lcd_bl_en &= ~PINMUX_TRISTATE; - pinmux->lcd_rst &= ~PINMUX_TRISTATE; - - /* Configure Backlight +-5V GPIOs. */ - gpio_configure_mode(GPIO_LCD_BL_P5V, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_N5V, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_LCD_BL_P5V, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_N5V, GPIO_DIRECTION_OUTPUT); - - /* Enable Backlight +5V. */ - gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_HIGH); - - udelay(10000); - - /* Enable Backlight -5V. */ - gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_HIGH); - - udelay(10000); - - /* Configure Backlight PWM, EN and RST GPIOs. */ - gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_EN, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_LCD_BL_PWM, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_EN, GPIO_DIRECTION_OUTPUT); - gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT); - - /* Enable Backlight EN. */ - gpio_write(GPIO_LCD_BL_EN, GPIO_LEVEL_HIGH); - - /* Configure display interface and display. */ - MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; - - do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); - do_register_writes(DI_BASE, display_config_dc_01, 94); - do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8); - do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14); - do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0); - do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14); - - udelay(10000); - - /* Enable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH); - - udelay(60000); - - MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204; - MAKE_DSI_REG(DSI_WR_DATA) = 0x337; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5); - - MAKE_DSI_REG(DSI_WR_DATA) = 0x406; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - dsi_wait(250000, DSI_TRIGGER, (DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO), 5); - - MAKE_DSI_REG(DSI_HOST_CONTROL) = (DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC); - dsi_wait(150000, DSI_HOST_CONTROL, DSI_HOST_CONTROL_IMM_BTA, 5000); - - /* Parse LCD vendor. */ - uint32_t host_response[3]; - for (uint32_t i = 0; i < 3; i++) { - host_response[i] = MAKE_DSI_REG(DSI_RD_DATA); - } - - /* The last word from host response is: - Bits 0-7: FAB - Bits 8-15: REV - Bits 16-23: Minor REV - */ - if ((host_response[2] & 0xFF) == 0x10) { - g_lcd_vendor = 0; - } else { - g_lcd_vendor = (host_response[2] >> 8) & 0xFF00; - } - g_lcd_vendor = (g_lcd_vendor & 0xFFFFFF00) | (host_response[2] & 0xFF); - - /* LCD vendor specific configuration. */ - switch (g_lcd_vendor) { - case 0x10: /* Japan Display Inc screens. */ - do_dsi_sleep_or_register_writes(display_config_jdi_specific_init_01, 48); - break; - case 0xF20: /* Innolux nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_innolux_nx_abca2_specific_init_01, 14); - break; - case 0xF30: /* AUO nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_init_01, 14); - break; - default: - /* Innolux and AUO nx-abcc screens. */ - if ((g_lcd_vendor | 0x10) == 0x1030) { - do_dsi_sleep_or_register_writes(display_config_innolux_auo_40_nx_abcc_specific_init_01, 5); - } - break; - } - - udelay(20000); - - do_register_writes(CAR_BASE, display_config_plld_02_erista, 3); - do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19); - MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4; - do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10); - - udelay(10000); - - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - - udelay(10000); - - do_register_writes(DI_BASE, display_config_dc_02, 113); -} - -static void display_init_mariko(void) { +void display_init(void) { volatile tegra_car_t *car = car_get_regs(); volatile tegra_pmc_t *pmc = pmc_get_regs(); volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); uint32_t hardware_type = fuse_get_hardware_type(); /* Power on. */ - uint8_t val = 0x3A; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1); - val = 0x71; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1); - val = 0xD0; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + if (is_mariko) { + uint8_t val = 0x3A; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2, &val, 1); + val = 0x71; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD2_CFG, &val, 1); + val = 0xD0; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + } else { + uint8_t val = 0xD0; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO0_CFG, &val, 1); + } /* Enable MIPI CAL, DSI, DISP1, HOST1X, UART_FST_MIPI_CAL, DSIA LP clocks. */ car->rst_dev_h_clr = 0x1010000; @@ -247,7 +103,7 @@ static void display_init_mariko(void) { pinmux->lcd_bl_en &= ~PINMUX_TRISTATE; pinmux->lcd_rst &= ~PINMUX_TRISTATE; - if (hardware_type == 5) { + if (is_mariko && (hardware_type == 5)) { /* HardwareType_Five only configures GPIO_LCD_BL_RST. */ gpio_configure_mode(GPIO_LCD_BL_RST, GPIO_MODE_GPIO); gpio_configure_direction(GPIO_LCD_BL_RST, GPIO_DIRECTION_OUTPUT); @@ -282,19 +138,41 @@ static void display_init_mariko(void) { /* Configure display interface and display. */ MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG2) = 0; - MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0; - APB_MISC_GP_DSI_PAD_CONTROL_0 = 0; - - do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + if (is_mariko) { + MAKE_MIPI_CAL_REG(MIPI_CAL_MIPI_BIAS_PAD_CFG0) = 0; + APB_MISC_GP_DSI_PAD_CONTROL_0 = 0; + } + + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + } else { + do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); + } do_register_writes(DI_BASE, display_config_dc_01, 94); do_register_writes(DSI_BASE, display_config_dsi_01_init_01, 8); - do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_01_init_02_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_01_init_02_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_03, 14); - do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_01_init_04_mariko, 7); + } else { + do_register_writes(DSI_BASE, display_config_dsi_01_init_04_erista, 0); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_05, 10); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_06, 12); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_07, 14); udelay(10000); @@ -303,8 +181,8 @@ static void display_init_mariko(void) { gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_HIGH); udelay(60000); - - if (hardware_type == 5) { + + if (is_mariko && (hardware_type == 5)) { MAKE_DSI_REG(DSI_BTA_TIMING) = 0x40103; } else { MAKE_DSI_REG(DSI_BTA_TIMING) = 0x50204; @@ -362,33 +240,50 @@ static void display_init_mariko(void) { udelay(20000); - do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3); + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_02_mariko, 3); + } else { + do_register_writes(CAR_BASE, display_config_plld_02_erista, 3); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_08, 1); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_init_09, 19); MAKE_DI_REG(DC_DISP_DISP_CLOCK_CONTROL) = 4; do_register_writes(DSI_BASE, display_config_dsi_01_init_10, 10); udelay(10000); - - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); - do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); - do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); - + + if (is_mariko) { + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_mariko, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_mariko, 7); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_mariko, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + } else { + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_01, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_02_erista, 2); + do_register_writes(DSI_BASE, display_config_dsi_01_init_11_erista, 4); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_03_erista, 6); + do_register_writes(MIPI_CAL_BASE, display_config_mipi_cal_04, 10); + } + udelay(10000); do_register_writes(DI_BASE, display_config_dc_02, 113); } -static void display_end_erista(void) { +void display_end(void) { volatile tegra_car_t *car = car_get_regs(); volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); /* Disable Backlight. */ display_backlight(false); @@ -408,93 +303,17 @@ static void display_end_erista(void) { do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13); udelay(40000); - do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); - do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); - do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13); - - udelay(10000); - - /* LCD vendor specific shutdown. */ - switch (g_lcd_vendor) { - case 0x10: /* Japan Display Inc screens. */ - do_dsi_sleep_or_register_writes(display_config_jdi_specific_fini_01, 22); - break; - case 0xF30: /* AUO nx-abca2 screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abca2_specific_fini_01, 38); - break; - case 0x1020: /* Innolux nx-abcc screens. */ - do_dsi_sleep_or_register_writes(display_config_innolux_nx_abcc_specific_fini_01, 10); - break; - case 0x1030: /* AUO nx-abcc screens. */ - do_dsi_sleep_or_register_writes(display_config_auo_nx_abcc_specific_fini_01, 10); - break; - default: - break; + if (is_mariko) { + do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); + } else { + do_register_writes(CAR_BASE, display_config_plld_01_erista, 4); } - - udelay(5000); - - MAKE_DSI_REG(DSI_WR_DATA) = 0x1005; - MAKE_DSI_REG(DSI_TRIGGER) = DSI_TRIGGER_HOST; - - udelay(50000); - - /* Disable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable Backlight -5V. */ - gpio_write(GPIO_LCD_BL_N5V, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable Backlight +5V. */ - gpio_write(GPIO_LCD_BL_P5V, GPIO_LEVEL_LOW); - - udelay(10000); - - /* Disable clocks. */ - car->rst_dev_h_set = 0x1010000; - car->clk_enb_h_clr = 0x1010000; - car->rst_dev_l_set = 0x18000000; - car->clk_enb_l_clr = 0x18000000; - - MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF)); - MAKE_DSI_REG(DSI_POWER_CONTROL) = 0; - - /* Backlight PWM. */ - gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO); - - pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE); - pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1); -} - -static void display_end_mariko(void) { - volatile tegra_car_t *car = car_get_regs(); - - /* Disable Backlight. */ - display_backlight(false); - - MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 1; - MAKE_DSI_REG(DSI_WR_DATA) = 0x2805; - - /* Wait 5 frames. */ - uint32_t start_val = MAKE_HOST1X_REG(0x30A4); - while (MAKE_HOST1X_REG(0x30A4) < start_val + 5) { - /* Wait. */ - } - - MAKE_DI_REG(DC_CMD_STATE_ACCESS) = (READ_MUX | WRITE_MUX); - MAKE_DSI_REG(DSI_VIDEO_MODE_CONTROL) = 0; - - do_register_writes(DI_BASE, display_config_dc_01_fini_01, 13); - udelay(40000); - - do_register_writes(CAR_BASE, display_config_plld_01_mariko, 4); do_register_writes(DSI_BASE, display_config_dsi_01_fini_01, 2); - do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + if (is_mariko) { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_mariko, 1); + } else { + do_register_writes(DSI_BASE, display_config_dsi_phy_timing_erista, 1); + } do_register_writes(DSI_BASE, display_config_dsi_01_fini_02, 13); if (g_lcd_vendor != 0x2050) { @@ -527,8 +346,8 @@ static void display_end_mariko(void) { udelay((g_lcd_vendor == 0x2050) ? 120000 : 50000); /* Disable Backlight RST. */ - gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); - + gpio_write(GPIO_LCD_BL_RST, GPIO_LEVEL_LOW); + if (g_lcd_vendor == 0x2050) { udelay(30000); } else { @@ -553,21 +372,13 @@ static void display_end_mariko(void) { MAKE_DSI_REG(DSI_PAD_CONTROL_0) = (DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF)); MAKE_DSI_REG(DSI_POWER_CONTROL) = 0; -} - -void display_init(void) { - if (is_soc_mariko()) { - display_init_mariko(); - } else { - display_init_erista(); - } -} - -void display_end(void) { - if (is_soc_mariko()) { - display_end_mariko(); - } else { - display_end_erista(); + + if (!is_mariko) { + /* Backlight PWM. */ + gpio_configure_mode(GPIO_LCD_BL_PWM, GPIO_MODE_SFIO); + + pinmux->lcd_bl_pwm = ((pinmux->lcd_bl_pwm & ~PINMUX_TRISTATE) | PINMUX_TRISTATE); + pinmux->lcd_bl_pwm = (((pinmux->lcd_bl_pwm >> 2) << 2) | 1); } } diff --git a/sept/sept-secondary/src/hwinit.c b/sept/sept-secondary/src/hwinit.c index c6de69f3e..a6169ca1b 100644 --- a/sept/sept-secondary/src/hwinit.c +++ b/sept/sept-secondary/src/hwinit.c @@ -61,52 +61,39 @@ static void config_oscillators(void) { car->clk_sys_rate = 2; } -static void config_gpios_erista(void) { +static void config_gpios(void) { volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); + bool is_mariko = is_soc_mariko(); - pinmux->uart2_tx = 0; - pinmux->uart3_tx = 0; - pinmux->pe6 = PINMUX_INPUT; - pinmux->ph6 = PINMUX_INPUT; - - gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO); - gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT); - - i2c_config(I2C_1); - i2c_config(I2C_5); - uart_config(UART_A); - - /* Configure volume up/down buttons as inputs. */ - gpio_configure_mode(GPIO_BUTTON_VOL_UP, GPIO_MODE_GPIO); - gpio_configure_mode(GPIO_BUTTON_VOL_DOWN, GPIO_MODE_GPIO); - gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT); - gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT); -} - -static void config_gpios_mariko(void) { - volatile tegra_pinmux_t *pinmux = pinmux_get_regs(); - uint32_t hardware_type = fuse_get_hardware_type(); - - /* Only for HardwareType_Iowa and HardwareType_Five. */ - if ((hardware_type == 3) || (hardware_type == 5)) { + if (is_mariko) { + uint32_t hardware_type = fuse_get_hardware_type(); + + /* Only for HardwareType_Iowa and HardwareType_Five. */ + if ((hardware_type == 3) || (hardware_type == 5)) { + pinmux->uart2_tx = 0; + pinmux->uart3_tx = 0; + gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); + gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); + gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); + gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); + } + } else { pinmux->uart2_tx = 0; pinmux->uart3_tx = 0; - gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); - gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); - gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); - gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); } pinmux->pe6 = PINMUX_INPUT; pinmux->ph6 = PINMUX_INPUT; + if (!is_mariko) { + gpio_configure_mode(TEGRA_GPIO(G, 0), GPIO_MODE_GPIO); + gpio_configure_mode(TEGRA_GPIO(D, 1), GPIO_MODE_GPIO); + } gpio_configure_mode(TEGRA_GPIO(E, 6), GPIO_MODE_GPIO); gpio_configure_mode(TEGRA_GPIO(H, 6), GPIO_MODE_GPIO); + if (!is_mariko) { + gpio_configure_direction(TEGRA_GPIO(G, 0), GPIO_DIRECTION_INPUT); + gpio_configure_direction(TEGRA_GPIO(D, 1), GPIO_DIRECTION_INPUT); + } gpio_configure_direction(TEGRA_GPIO(E, 6), GPIO_DIRECTION_INPUT); gpio_configure_direction(TEGRA_GPIO(H, 6), GPIO_DIRECTION_INPUT); @@ -120,17 +107,11 @@ static void config_gpios_mariko(void) { gpio_configure_direction(GPIO_BUTTON_VOL_UP, GPIO_DIRECTION_INPUT); gpio_configure_direction(GPIO_BUTTON_VOL_DOWN, GPIO_DIRECTION_INPUT); - /* Configure home button as input. */ - gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO); - gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT); -} - -static void config_pmc_scratch(void) { - volatile tegra_pmc_t *pmc = pmc_get_regs(); - - pmc->scratch20 &= 0xFFF3FFFF; - pmc->scratch190 &= 0xFFFFFFFE; - pmc->secure_scratch21 |= 0x10; + if (is_mariko) { + /* Configure home button as input. */ + gpio_configure_mode(TEGRA_GPIO(Y, 1), GPIO_MODE_GPIO); + gpio_configure_direction(TEGRA_GPIO(Y, 1), GPIO_DIRECTION_INPUT); + } } static void mbist_workaround(void) { @@ -214,27 +195,36 @@ static void config_se_brom(void) { pmc->rst_status = 0; } -static void nx_hwinit_erista(bool enable_log) { +void nx_hwinit(bool enable_log) { volatile tegra_pmc_t *pmc = pmc_get_regs(); volatile tegra_car_t *car = car_get_regs(); + bool is_mariko = is_soc_mariko(); - /* Bootrom stuff we skipped by going through RCM. */ - config_se_brom(); + if (!is_mariko) { + /* Bootrom stuff we skipped by going through RCM. */ + config_se_brom(); - AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F; - pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD); + AHB_AHB_SPARE_REG_0 &= 0xFFFFFF9F; + pmc->scratch49 = (((pmc->scratch49 >> 1) << 1) & 0xFFFFFFFD); - /* Apply the memory built-in self test workaround. */ - mbist_workaround(); + /* Apply the memory built-in self test workaround. */ + mbist_workaround(); + } - /* Reboot SE. */ + /* Enable SE clock. */ clkrst_reboot(CARDEVICE_SE); + if (is_mariko) { + /* Lock the SE clock. */ + car->clk_source_se |= 0x100; + } /* Initialize the fuse driver. */ fuse_init(); - /* Initialize the memory controller. */ - mc_enable(); + if (!is_mariko) { + /* Initialize the memory controller. */ + mc_enable(); + } /* Configure oscillators. */ config_oscillators(); @@ -243,9 +233,7 @@ static void nx_hwinit_erista(bool enable_log) { APB_MISC_PP_PINMUX_GLOBAL_0 = 0; /* Configure GPIOs. */ - /* NOTE: [3.0.0+] Part of the GPIO configuration is skipped if the unit is SDEV. */ - /* NOTE: [6.0.0+] The GPIO configuration's order was changed a bit. */ - config_gpios_erista(); + config_gpios(); /* UART debugging. */ if (enable_log) { @@ -253,111 +241,7 @@ static void nx_hwinit_erista(bool enable_log) { uart_init(UART_A, 115200); } - /* Reboot CL-DVFS. */ - clkrst_reboot(CARDEVICE_CL_DVFS); - - /* Reboot I2C1. */ - clkrst_reboot(CARDEVICE_I2C1); - - /* Reboot I2C5. */ - clkrst_reboot(CARDEVICE_I2C5); - - /* Reboot SE. */ - /* NOTE: [4.0.0+] This was removed. */ - /* clkrst_reboot(CARDEVICE_SE); */ - - /* Reboot TZRAM. */ - clkrst_reboot(CARDEVICE_TZRAM); - - /* Initialize I2C1. */ - /* NOTE: [6.0.0+] This was moved to after the PMIC is configured. */ - i2c_init(I2C_1); - - /* Initialize I2C5. */ - i2c_init(I2C_5); - - /* Configure the PMIC. */ - uint8_t val = 0x40; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); - val = 0x60; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); - val = 0x38; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1); - val = 0x3A; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1); - val = 0x38; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1); - val = 0xF; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1); - val = 0xC7; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1); - val = 0x4F; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1); - val = 0x29; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1); - val = 0x1B; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1); - - /* NOTE: [3.0.0+] This was added. */ - val = 0x22; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1); - - /* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */ - /* - i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); - val |= 0x40; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); - */ - - /* Configure SD0 voltage. */ - val = 42; /* 42 = (1125000 - 600000) / 12500 -> 1.125V */ - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1); - - /* Configure and lock PMC scratch registers. */ - /* NOTE: [4.0.0+] This was removed. */ - config_pmc_scratch(); - - /* Set super clock burst policy. */ - car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333); - - /* Configure memory controller carveouts. */ - /* NOTE: [4.0.0+] This is now done in the Secure Monitor. */ - /* mc_config_carveout(); */ - - /* Save SDRAM parameters to scratch. */ - sdram_save_params(sdram_get_params(fuse_get_dram_id())); - - /* Initialize SDRAM. */ - sdram_init(); -} - -static void nx_hwinit_mariko(bool enable_log) { - volatile tegra_pmc_t *pmc = pmc_get_regs(); - volatile tegra_car_t *car = car_get_regs(); - - /* Enable SE clock and lock it. */ - clkrst_reboot(CARDEVICE_SE); - car->clk_source_se |= 0x100; - - /* Make all fuse registers visible. */ - clkrst_enable_fuse_regs(true); - - /* Configure oscillators. */ - config_oscillators(); - - /* Disable pinmux tristate input clamping. */ - APB_MISC_PP_PINMUX_GLOBAL_0 = 0; - - /* Configure GPIOs. */ - config_gpios_mariko(); - - /* UART debugging. */ - if (enable_log) { - clkrst_reboot(CARDEVICE_UARTA); - uart_init(UART_A, 115200); - } - - /* Enable CL-DVFS clock. */ + /* Enable CL-DVFS clock. */ clkrst_reboot(CARDEVICE_CL_DVFS); /* Enable I2C1 clock. */ @@ -373,43 +257,71 @@ static void nx_hwinit_mariko(bool enable_log) { i2c_init(I2C_5); /* Configure the PMIC. */ - uint8_t val = 0x40; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); - val = 0x78; - i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); - + if (is_mariko) { + uint8_t val = 0x40; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); + val = 0x78; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); + } else { + uint8_t val = 0x40; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGBBC, &val, 1); + val = 0x60; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, &val, 1); + val = 0x38; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG0, &val, 1); + val = 0x3A; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG1, &val, 1); + val = 0x38; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_CFG2, &val, 1); + val = 0xF; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO4, &val, 1); + val = 0xC7; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_LDO8, &val, 1); + val = 0x4F; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD0, &val, 1); + val = 0x29; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD1, &val, 1); + val = 0x1B; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_SD3, &val, 1); + + /* NOTE: [3.0.0+] This was added. */ + val = 0x22; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_FPS_GPIO3, &val, 1); + + /* TODO: In 3.x+, if the unit is SDEV, the MBLPD bit is set. */ + /* + i2c_query(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); + val |= 0x40; + i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_CNFGGLBL1, &val, 1); + */ + } + /* Configure SD0 voltage. */ - val = 0x24; + uint8_t val = 0x24; i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_SD0, &val, 1); /* Enable LDO8 in HardwareType_Hoag only. */ - if (fuse_get_hardware_type() == 2) { + if (is_mariko && (fuse_get_hardware_type() == 2)) { val = 0xE8; i2c_send(I2C_5, MAX77620_PWR_I2C_ADDR, MAX77620_REG_LDO8_CFG, &val, 1); } /* Initialize I2C1. */ i2c_init(I2C_1); - + /* Set super clock burst policy. */ car->sclk_brst_pol = ((car->sclk_brst_pol & 0xFFFF8888) | 0x3333); - /* Mariko only PMC configuration for TZRAM. */ - pmc->tzram_pwr_cntrl &= 0xFFFFFFFE; - pmc->tzram_non_sec_disable = 0x3; - pmc->tzram_sec_disable = 0x3; + if (is_mariko) { + /* Mariko only PMC configuration for TZRAM. */ + pmc->tzram_pwr_cntrl &= 0xFFFFFFFE; + pmc->tzram_non_sec_disable = 0x3; + pmc->tzram_sec_disable = 0x3; + } /* Save SDRAM parameters to scratch. */ sdram_save_params(sdram_get_params(fuse_get_dram_id())); /* Initialize SDRAM. */ sdram_init(); -} - -void nx_hwinit(bool enable_log) { - if (is_soc_mariko()) { - nx_hwinit_mariko(enable_log); - } else { - nx_hwinit_erista(enable_log); - } } \ No newline at end of file diff --git a/sept/sept-secondary/src/se.h b/sept/sept-secondary/src/se.h index 94290ecb8..a29877177 100644 --- a/sept/sept-secondary/src/se.h +++ b/sept/sept-secondary/src/se.h @@ -37,6 +37,9 @@ /* This keyslot was added in 5.0.0. */ #define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA +/* Mariko keyslots. */ +#define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7 + #define KEYSLOT_AES_MAX 0x10 #define KEYSLOT_RSA_MAX 0x2