QSPIF: Add back enable_fast_mode

This function writes a "config" register to ensure that the flash part
is in high performance mode, not low-power mode. This is required at
by at least MX25R6435F in order to operate at frequencies > 33MHz
(for reference, DISCO_L475VG_IOT01A runs the QSPI interface at 80 MHz).
The config register that this writes does not appear to be covered by
the SFDP spec (JESD216D.01) so this remains the status quo of
unconditional execution, as has been done on master since #8352.
pull/11531/head
Kyle Kearney 2019-10-18 14:34:56 -07:00
parent cc4d428f3f
commit d2ef56859c
2 changed files with 71 additions and 0 deletions

View File

@ -716,6 +716,7 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
// Detect and Set fastest Bus mode (default 1-1-1) // Detect and Set fastest Bus mode (default 1-1-1)
_sfdp_detect_best_bus_read_mode(param_table, basic_table_size, shouldSetQuadEnable, is_qpi_mode); _sfdp_detect_best_bus_read_mode(param_table, basic_table_size, shouldSetQuadEnable, is_qpi_mode);
if (true == shouldSetQuadEnable) { if (true == shouldSetQuadEnable) {
_enable_fast_mode();
// Set Quad Enable and QPI Bus modes if Supported // Set Quad Enable and QPI Bus modes if Supported
tr_debug("Init - Setting Quad Enable"); tr_debug("Init - Setting Quad Enable");
if (0 != _sfdp_set_quad_enabled(param_table)) { if (0 != _sfdp_set_quad_enabled(param_table)) {
@ -1279,6 +1280,73 @@ int QSPIFBlockDevice::_set_write_enable()
return status; return status;
} }
int QSPIFBlockDevice::_enable_fast_mode()
{
const int NUM_REGISTERS = QSPI_STATUS_REGISTER_COUNT + 1; // Status registers + one config register
char status_reg[NUM_REGISTERS] = {0};
unsigned int read_conf_register_inst = 0x15;
char status_reg_qer_setup[NUM_REGISTERS] = {0};
status_reg_qer_setup[2] = 0x2; // Bit 1 of config Reg 2
// Configure BUS Mode to 1_1_1 for all commands other than Read
if (QSPI_STATUS_OK != _qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
0, QSPI_CFG_BUS_SINGLE, 0)) {
tr_error("_qspi_configure_format failed");
return -1;
}
// Read Status Register
if (QSPI_STATUS_OK == _qspi_send_general_command(read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL, 0,
&status_reg[1],
NUM_REGISTERS - 1)) { // store received values in status_value
tr_debug("Reading Config Register Success: value = 0x%x", (int)status_reg[2]);
} else {
tr_error("Reading Config Register failed");
return -1;
}
// Set Bits for Quad Enable
for (int i = 0; i < NUM_REGISTERS; i++) {
status_reg[i] |= status_reg_qer_setup[i];
}
// Write new Status Register Setup
if (_set_write_enable() != 0) {
tr_error("Write Enabe failed");
return -1;
}
if (QSPI_STATUS_OK == _qspi_send_general_command(QSPIF_INST_WSR1, QSPI_NO_ADDRESS_COMMAND, status_reg,
NUM_REGISTERS, NULL,
0)) { // Write Fast mode bit to status_register
tr_debug("fast mode enable - Writing Config Register Success: value = 0x%x",
(int)status_reg[2]);
} else {
tr_error("fast mode enable - Writing Config Register failed");
return -1;
}
if (false == _is_mem_ready()) {
tr_error("Device not ready after write, failed");
return -1;
}
// For Debug
memset(status_reg, 0, NUM_REGISTERS);
if (QSPI_STATUS_OK == _qspi_send_general_command(read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL, 0,
&status_reg[1],
NUM_REGISTERS - 1)) { // store received values in status_value
tr_debug("Verifying Config Register Success: value = 0x%x", (int)status_reg[2]);
} else {
tr_error("Verifying Config Register failed");
return -1;
}
return 0;
}
bool QSPIFBlockDevice::_is_mem_ready() bool QSPIFBlockDevice::_is_mem_ready()
{ {
// Check Status Register Busy Bit to Verify the Device isn't Busy // Check Status Register Busy Bit to Verify the Device isn't Busy

View File

@ -275,6 +275,9 @@ private:
// Wait on status register until write not-in-progress // Wait on status register until write not-in-progress
bool _is_mem_ready(); bool _is_mem_ready();
// Enable Fast Mode - for flash chips with low power default
int _enable_fast_mode();
/****************************************/ /****************************************/
/* SFDP Detection and Parsing Functions */ /* SFDP Detection and Parsing Functions */
/****************************************/ /****************************************/