-
Notifications
You must be signed in to change notification settings - Fork 8.1k
driver: flash_mspi_nor: Allow specific read/write IO modes and frequencies #97504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Request review from @anangl too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are adding write/read frequencies but not write/read io_modes to struct mspi_dev_cfg, why?
Anyway, I don't think this is the correct approach.
Please also include the specific devices in the description you are targeting so we can check the datasheets.
I do understand there might be a need for some flash devices that have different maximum frequency for write and read operation and even different io mode. But changing the mspi scope seems wrong, so maybe just add bindings to the flash scope(jedec,mspi-nor).
@swift-tk The read-command and write-command themselves convey the IO mode. The problem with the driver right now is that it would follow Dual IO from I can add Any other changes that you would recommend to add this support? |
You can separate io-mode for write and read but only on the flash device level, do not change the controller API unless this separation is generally appliable among controller IPs. I would also suggest the same for frequencies. To reiterate, the MSPI controllers should not be liable on their peripheral device states which should be managed by device drivers themselves. When device state changes such as frequency or io mode, the device driver should call mspi_dev_config API to reconfigure the controller.
The |
Remove unnecessary function argument, makes later commits also simpler. Signed-off-by: Utsav Munendra <[email protected]>
Instead of just tracking in a bool whether the MSPI device is in Standard MSPI vs. QPI/OPI config, track the entire MSPI config which was last applied. This makes it easier later to track more than two configs to apply based on the next command to transceive. Signed-off-by: Utsav Munendra <[email protected]>
Re-did the PR after previous comments, might have oversimplied the IO mode selection logic while missing some flash mode transition, so requesting careful review. Works for all configs I can apply with my hardware setup. Commits are self-contained to help with review. |
Track MSPI XIP config too in order to be able to detect and switch out of this config when needed. Signed-off-by: Utsav Munendra <[email protected]>
Also in preparation for allowing control command frequency to be different from the read/write frequency and initialization frequency. Signed-off-by: Utsav Munendra <[email protected]>
Remove the Boolean tracking of MSPI IO mode as we can now rely on tracking the entire dev config applied to the MSPI device, multiple of which will exist in later commits. Signed-off-by: Utsav Munendra <[email protected]>
The driver currently provides no way to use Dual IO Read and Single IO for the rest of the commands currently, and would erroneously use Single IO PP command in Dual IO mode. This PR fixes and adds support for that. Signed-off-by: Utsav Munendra <[email protected]>
|
|
||
dev_data->in_target_io_mode = false; | ||
dev_data->last_applied_cfg = &dev_data->mspi_control_cfg; | ||
dev_data->mspi_control_cfg.freq = target_freq; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand the logic here. renaming mspi_nor_init_cfg to mspi_control_cfg, putting it in data, and then changing the freq back and forth..
The original intention is to maintain a lower freq for commands so we don't have to worry about timing issues and to maintain maximum capability for those flash chips that may have lower freq when accessing registers than accessing memory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Even in the original intention, we switch out of 50MHz by the time
switch_to_target_io_mode()
was run for control commands too. Renamedmspi_nor_init_cfg
tomspi_control_cfg
because I want to have a MSPI dev config for all control (not read & write) commands like read status, erase etc. and not for use just during init. Perhapsmspi_base_cfg
is a better name? - Moved to data from config because the frequency is changed during runtime and cannot be const anymore. Frequency needs to be <= 50MHz only during initial commands like Read ID because I believe JEDEC compliance mandates supporting upto 50MHz. After init, we should use device tree specified frequency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The switching to target IO mode means the device is ready to conduct memory access, thus target frequency should be used. The mspi_nor_init_cfg
is not only used during init phase but also in cmd phase if register access cmd aren't available in target IO mode.
Maintaining freq <= 50MHz in "cmd mode" should have very limited effect towards bandwidth as the transfers are short. Most of the time is instead spent waiting for and polling the flash status, which dominates the overall latency by orders of magnitude.
Please keep this section the same as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are suggesting to leave the mspi_nor_init_cfg
untouched, that is going to change the behavior of the driver, by the way. Also, in this PR, the target frequency is saved in the config early on, but only applied after switch_to_target_io_mode()
for control commands.
Assume Quad IO and not QPI, then all status reg read after initialization happens in mspi_max_frequency
currently on mainline and this PR. Using the init config with <= 50MHz freq instead will barely affect bandwidth indeed, but I would lean towards not changing the behavior if there is no reason to.
I will leave mspi_nor_init_cfg
untouched if you believe that change in behavior is OK though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, mspi_nor_init_cfg
and all related change should be reverted. So no need to get the target freq early on.
No, I think below code already guaranteed that reg read would go back to using mspi_nor_init_cfg
if (dev_data->in_target_io_mode) {
if (dev_data->packet.num_bytes != 0 ||
(dev_data->xfer.addr_length != 0 &&
!dev_config->single_io_addr)) {
/* Only the IO mode is to be changed, so the
* initial configuration structure can be used
* for this operation.
*/
cfg = &dev_config->mspi_nor_init_cfg;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll revert it. Latest comments seem to approve of this now. Though, the code you highlighted on mainline would only pick Single IO out of mspi_nor_init_cfg
to be applied with mspi_dev_config
but this PR picks both IO mode and frequency out of the chosen configs, so that will result in init freq being applied which was not the case before.
cfg = dev_data->write_cfg; | ||
} else { | ||
/* For all other commands, use control command config */ | ||
cfg = &dev_data->mspi_control_cfg; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've lost track, does this change the driver behavior? I think it does...
@anangl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not!
- All this is wrapped within a
!dev_config->multi_io_cmd
so drivers set with QPI or OPI as the IO mode skip this config selection logic anyways like mainline. They stay in QPI/OPI forever after initialization. - Mainline drivers currently do not override read and write IO mode, so both read and write configs point to
mspi_nor_cfg
and that is applied just like on mainline for read and writes. - For all control commands, just select Single IO mode always because codepath is not taken for QPI/OPI anyways. I believe the earlier logic accomplished the same, but instead of always selecting Single IO mode, it was trying to detect when Octal/Quad/Dual IO 1-1-x or 1-x-x specifically would not work.
A change in behavior could be that mspi_dev_config
is called more times than before, but the communication with flash should stay the same for a device-tree config as far as I have tried.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion it's okay as it is now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, now as in how it is on mainline or this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this PR.
if (cfg && cfg != dev_data->last_applied_cfg) { | ||
rc = mspi_dev_config(dev_config->bus, &dev_config->mspi_id, | ||
MSPI_DEVICE_CONFIG_IO_MODE, cfg); | ||
MSPI_DEVICE_CONFIG_IO_MODE | MSPI_DEVICE_CONFIG_FREQUENCY, cfg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, I clearly miss it from before. Configuring the freqeuncy here is reasonable and aligned with the original intent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, read, write and control commands after this PR could all have different frequencies (needed because of different IO modes) so that's why worked backwards from here for this commit 9d54c63
return rc; | ||
} | ||
dev_data->last_applied_cfg = NULL; | ||
dev_data->last_applied_cfg = mspi_cfg; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed. Neither IO mode nor frequency is reconfigured for XIP (see XIP_DEV_CFG_MASK
), so all changes related to XIP can be dropped IMO.
/* Do initial checks at max 50MHz required to be supported by JEDEC */ | ||
dev_data->mspi_control_cfg.freq = MIN(target_freq, MHZ(50)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest to not move mspi_control_cfg
to dev_data
just to be able to do the above modification, but use here a local variable instead:
/* Do initial checks at max 50MHz required to be supported by JEDEC */ | |
dev_data->mspi_control_cfg.freq = MIN(target_freq, MHZ(50)); | |
/* Do initial checks at max 50MHz required to be supported by JEDEC */ | |
init_mspi_control_cfg = dev_config->mspi_control_cfg; | |
init_mspi_control_cfg.freq = MIN(init_mspi_control_cfg.freq, MHZ(50)); |
This way we'll avoid forcing the flash_mspi_nor_data
structure to be initialized with non-zero content what unnecessarily consumes some flash.
Consider these MSPI flash parts: Gigadevice GD25LE64E, Macronix MX25U6432F, Winbond W25Q64JW. If only D0 and D1 lines are connected to these flash parts, then Dual IO 1-1-2
DREAD 0x3B
and Single IOPP 0x02
are the best read and write commands available to use. Notice that neither Dual IOPP_1_1_2 0xA2
command is supported in any of these flash parts, and neither these flash parts support Dual Peripheral Interface (like QPI, OPI), so all general commands need to be in Single IO.The driver currently provides no way to use Dual IO Read and Single IO for the rest of the commands currently, and would erroneously use Single IO PP command in Dual IO mode. This PR fixes and adds support for that.
Target Board
nRF54H20 MSPI and flash driver to support Gigadevice GD25LE64E, Macronix MX25U6432F and Winbond W25Q64JW.
Modifications
mspi-max-frequency
is not the highest possible frequency to use for all modes. Allow read/write frequency to be granularly specified.Testing
The following modes for flash driver worked in local testing: