-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Add MSPI + flash driver for the TI K3 platform #88487
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?
Add MSPI + flash driver for the TI K3 platform #88487
Conversation
drivers/mspi/mspi_ti_k3.c
Outdated
uint32_t exec_status = | ||
MSPI_TI_K3_REG_READ_MASKED(FLASH_CMD_CTRL, CMD_EXEC_STATUS, base_address); | ||
while (exec_status != 0 && | ||
k_cyc_to_us_floor32(k_uptime_get() - start_cycles) < req->timeout) { |
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.
k_uptime_get
is the current uptime in milliseconds, calling k_cyc_to_us_floor32
is probably not what you want.
The timeout parameter is not well documented, but it appears to be in milliseconds (from looking at other drivers)
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 is defined in kconfig
Line 35 in fe6366b
int "Completion timeout tolerance (ms)" |
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.
Ahh my bad, I'm not familiar with mspi driver API and only looked at the struct definition. It would be helpful to mention it there 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.
Ok I will update that to use milliseconds everywhere in the MSPI driver. I will also switch over to k_uptime_get
so I don't need the conversions anymore
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.
Also: How are the Kconfig option and timeout field correlated? For me it seems quite unclear since it's used both in flash and MSPI drivers, additionally to the already existing timeout
field
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.
Also: How are the Kconfig option and timeout field correlated? For me it seems quite unclear since it's used both in flash and MSPI drivers, additionally to the already existing
timeout
field
The Kconfig option is offered as a setting to the controllers for its maximum timeout allowence. The timeout field is variable in the transfer struct but should not exceed this Kconfig option.
drivers/mspi/mspi_ti_k3.c
Outdated
MSPI_TI_K3_REG_WRITE(0, CONFIG, RESET_PIN, base_addr); | ||
|
||
/* general clock cycle delays */ | ||
MSPI_TI_K3_REG_WRITE(TI_K3_OSPI_DEFAULT_DELAY, DEV_DELAY, D_NSS, base_addr); |
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.
Seems like the chip select delay should come from struct mspi_ce_control
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.
No, not really. struct mspi_ce_control
is for software controlled CE. However, I do think that this CE timing maybe peripheral device specific but not transfer specific. NXP have a similar setting as well. We can try add that to struct mspi_dev_cfg
Another option is to slide it in through struct mspi_timing_cfg
along with your custom timing parameters.
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.
For now I'm going to add it to the mspi_dev_cfg
to be read from the devicetree
I'm going to add a custom timing config
drivers/mspi/mspi_ti_k3.c
Outdated
#include <zephyr/sys/util.h> | ||
#include <zephyr/sys/util_macro.h> | ||
|
||
LOG_MODULE_REGISTER(flash_ti_k3_mspi, CONFIG_MSPI_LOG_LEVEL); |
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.
There are a number of mentions of "flash" in this file that should be removed.
This driver may be used for things other than flash 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.
Will update that. They are there because it initially started as a standalone flash driver
int mspi_ti_k3_wait_for_idle(const struct device *controller) | ||
{ | ||
const mem_addr_t base_addr = DEVICE_MMIO_GET(controller); | ||
uint32_t idle = MSPI_TI_K3_REG_READ_MASKED(CONFIG, IDLE, base_addr); |
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.
Consider using GENMASK
/FIELD_PREP
/FIELD_GET
, the macro concatenations (TI_K3_OSPI_##reg##_##field##_FLD_OFFSET
) make it difficult to navigate to the register definitions
#define TI_K3_OSPI_CONFIG_REG_IDLE_MASK GENMASK(31, 31)
uint32_t config_reg = sys_read32(base_addr + TI_K3_OSPI_CONFIG_REG_OFFSET);
uint32_t idle = FIELD_GET(TI_K3_OSPI_CONFIG_REG_IDLE_MASK, config_reg);
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 would prefer to keep the macro since it keeps the code in the mspi_ti_k3.c
quite short. I think I will add comments that explains the macros and register definitions
}; | ||
|
||
struct mspi_ti_k3_data { | ||
struct k_mutex lock; |
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.
Add DEVICE_MMIO_RAM;
as the first field
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.
Are you not going to add any soc DTS for the controller?
To ensure compile across PRs, it is best to add the controller to one of the example or testcase.
ce-gpios: | ||
description: | | ||
The used chip select GPIO pins. This property is not used since the driver | ||
only supports the hardware controlled chip select pins. |
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 is used as part of device_id.
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.
Can you explain what you exactly mean with that?
Currently this driver uses hardware implemented chip select in the OSPI_CONFIG_REG
via the PERIPH_CS_LINES_FLD
field. There are 4 dedicated pins for that and they are only referenced by the numbers 0..3, which I directly use in the mspi_ti_k3_dev_config
function. When I would use ce-gpios
with phandle to the GPIO pins I think it would be necassary to do software CS control.
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.
Can you explain what you exactly mean with that?
Currently this driver uses hardware implemented chip select in the
OSPI_CONFIG_REG
via thePERIPH_CS_LINES_FLD
field. There are 4 dedicated pins for that and they are only referenced by the numbers 0..3, which I directly use in themspi_ti_k3_dev_config
function. When I would usece-gpios
with phandle to the GPIO pins I think it would be necassary to do software CS control.
ce-gpios can be used to for software CE control, but it is also used as part of the device id, see struct mspi_dev_id
which is filled by MSPI_DEVICE_ID_DT
. So you would have to have at least a ce-gpio defined in controller dts. The dev_id should be used to validate the peripheral(child) device within the controller, although some choose not to as no plan to support software-multiperipheral function. i.e. switching between child devices by software under the same controller.
If your controller is capable of switching by hardware CE number, then you can pass that 0~3 number in struct mspi_dev_cfg.ce_num
.
I do recognize there might be a compatiblity problem if your CEs are not within one of your GPIO alternate function but dedicated pin. But we will fix it when we get there.
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.
For now I removed the ce-gpios
part from the bindings. However it's still ignored in the driver and added the requirement that GPIO
has to be selected in the Kconfig
drivers/mspi/mspi_ti_k3.c
Outdated
MSPI_TI_K3_REG_WRITE(0, CONFIG, RESET_PIN, base_addr); | ||
|
||
/* general clock cycle delays */ | ||
MSPI_TI_K3_REG_WRITE(TI_K3_OSPI_DEFAULT_DELAY, DEV_DELAY, D_NSS, base_addr); |
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.
No, not really. struct mspi_ce_control
is for software controlled CE. However, I do think that this CE timing maybe peripheral device specific but not transfer specific. NXP have a similar setting as well. We can try add that to struct mspi_dev_cfg
Another option is to slide it in through struct mspi_timing_cfg
along with your custom timing parameters.
drivers/mspi/mspi_ti_k3.c
Outdated
uint32_t exec_status = | ||
MSPI_TI_K3_REG_READ_MASKED(FLASH_CMD_CTRL, CMD_EXEC_STATUS, base_address); | ||
while (exec_status != 0 && | ||
k_cyc_to_us_floor32(k_uptime_get() - start_cycles) < req->timeout) { |
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 is defined in kconfig
Line 35 in fe6366b
int "Completion timeout tolerance (ms)" |
I will add that to this PR when the AM2434 SoC and AM2434 Launchpad are officially supported. The AM2434 SoC support is currently being done in #87321. After that is merged I will add the AM243x LaunchPad board and after that I can also add the MSPI flash test to this PR. Before that I will only add it to the https://github.com/siemens/zephyr/commits/mika/ti/ti-am2434-native-boot/ branch |
def3678
to
1602101
Compare
@m-braunschweig You should squash the 13 commits into 2, one for the controller driver, one for the flash driver. That is zephyr PR policy. |
Add a MSPI driver, used in the TI K3 platform. The driver was tested in 1S-1S-1S and 4S-4S-4S mode with the onboard infineon s25h flash of the am243x launchpad and a custom driver for the flash using this interface. The command and dummy cycles are always taken from the xfer request and never from the devicetree since different commands might have different latencies. The driver is somewhat basic for now and lacks e.g. callback implementation. This is something that can be added in the future. If a non-supported / invalid request is detected a error code is returned. Signed-off-by: Mika Braunschweig <[email protected]>
Add a infineon s25h mspi nor flash driver. This driver was tested on the am243x-lp board. It assumes the flash is in 1S-1S-1S mode and sends a reset command. After that it disables the uniform hybrid sector architecture, if activated, and applies the setting by resetting the flash again. After that the 4S-4S-4S mode is entered and also 4 byte adressing gets enabled. During these stepts the JEDEC id is sometimes verified to ensure a valid connection. Due to the flash possibily entering continious read mode when undesired some read operations will read the JEDEC id to prevent this. Signed-off-by: Mika Braunschweig <[email protected]>
1602101
to
3b9d09f
Compare
@swift-tk done. |
Also I have some more questions to the MSPI driver API:
For the devicetree things I was unsure about I currently check during build time that they are unset. However I don't really like that solution and would be happy to hear about ideas to improve it |
The The settings given to
The device tree properties represent the target configuration that the device will run on most of the time. In the case of flash memory, it represents settings when conducting memory write and read. The default settings for device initialization should be stored as const and possibly used for all register access to maintain maximum compatibility as they should typically be low speed.
If your target operating mode is single mode, then swap the cmds in device tree with cmds used in single mode and the same way with quad mode. Mode switching should be done by
You have to check it each time when a config is passed from device driver. To reduce unnecessary config from repeated |
This PR adds support for MSPI and the Infineon S25H flash on the TI K3 platform. It is tested with the onboard flash of the AM2434 launchpad.
(PR for the driver flash driver: #88446).It's now part of this PR.For running the code on the AM243x Launchpad this branch is used. Until the AM243x Launchpad is generally supported this shouldn't be merged. However I would still like some early review to speed up merging later. Especially on how to potentially handle the timeout parameter better and whether I interpreted the unit being microseconds right.
The driver itself is pretty basic (e.g. no async and XIP support) but enough for running MCUboot on the board (by loading the image into SRAM).
Edit: Mention that this PR also includes the S25H flash driver now