drivers: memc: memc_mcux_flexspi: correctly handle multi-device usage
When multiple devices are used, the FLEXSPI will place their address spaces sequentially (based on the chip select port used). Additionally, each device must use different sections of the FLEXSPI LUT table. Fix the following calculation issues with multi-device usage: - correct calculation of LUT sequence indices for AHB commands - correctly add address and sequence offset when submitting FLEXSPI IP transfer Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
parent
481462d4a6
commit
ba98dfd976
1 changed files with 26 additions and 6 deletions
|
@ -188,9 +188,12 @@ int memc_flexspi_set_device_config(const struct device *dev,
|
|||
/* Update lut offset with new value */
|
||||
data->port_luts[port].lut_offset = lut_used;
|
||||
}
|
||||
data->port_luts[port].lut_used = lut_count;
|
||||
tmp_config.ARDSeqIndex += data->port_luts[port].lut_offset;
|
||||
tmp_config.AWRSeqIndex += data->port_luts[port].lut_offset;
|
||||
/* LUTs should only be installed on sequence boundaries, every
|
||||
* 4 entries. Round LUT usage up to nearest sequence
|
||||
*/
|
||||
data->port_luts[port].lut_used = ROUND_UP(lut_count, 4);
|
||||
tmp_config.ARDSeqIndex += data->port_luts[port].lut_offset / MEMC_FLEXSPI_CMD_PER_SEQ;
|
||||
tmp_config.AWRSeqIndex += data->port_luts[port].lut_offset / MEMC_FLEXSPI_CMD_PER_SEQ;
|
||||
|
||||
/* Lock IRQs before reconfiguring FlexSPI, to prevent XIP */
|
||||
key = irq_lock();
|
||||
|
@ -215,12 +218,29 @@ int memc_flexspi_reset(const struct device *dev)
|
|||
int memc_flexspi_transfer(const struct device *dev,
|
||||
flexspi_transfer_t *transfer)
|
||||
{
|
||||
flexspi_transfer_t tmp;
|
||||
struct memc_flexspi_data *data = dev->data;
|
||||
status_t status;
|
||||
uint32_t seq_off, addr_offset = 0U;
|
||||
int i;
|
||||
|
||||
/* Adjust transfer LUT index based on port */
|
||||
transfer->seqIndex += data->port_luts[transfer->port].lut_offset;
|
||||
status = FLEXSPI_TransferBlocking(data->base, transfer);
|
||||
/* Calculate sequence offset and address offset based on port */
|
||||
seq_off = data->port_luts[transfer->port].lut_offset /
|
||||
MEMC_FLEXSPI_CMD_PER_SEQ;
|
||||
for (i = 0; i < transfer->port; i++) {
|
||||
addr_offset += data->size[i];
|
||||
}
|
||||
|
||||
if ((seq_off != 0) || (addr_offset != 0)) {
|
||||
/* Adjust device address and sequence index for transfer */
|
||||
memcpy(&tmp, transfer, sizeof(tmp));
|
||||
tmp.seqIndex += seq_off;
|
||||
tmp.deviceAddress += addr_offset;
|
||||
status = FLEXSPI_TransferBlocking(data->base, &tmp);
|
||||
} else {
|
||||
/* Transfer does not need adjustment */
|
||||
status = FLEXSPI_TransferBlocking(data->base, transfer);
|
||||
}
|
||||
|
||||
if (status != kStatus_Success) {
|
||||
LOG_ERR("Transfer error: %d", status);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue