Skip to content

drivers/flash: it51xxx: Add the M1K flash driver #92495

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

GTLin08
Copy link
Collaborator

@GTLin08 GTLin08 commented Jul 2, 2025

This PR includes two commits:

Enable FSPI tri-state by default:
To prevent FSPI pins from floating, which may cause internal leakage and increase SoC power consumption, tri-state is enabled by default.

Add flash M1K driver support:
The flash M1K driver supports read (up to 1K), write (1K), and erase (4K) operations, which can be accessed via DLM.
Accessible flash regions include internal e-Flash or external SPI flash via FSCE# or FSCE1#.

To prevent FSPI pins from floating, which may cause internal leakage
and increase SoC power consumption, tri-state is enabled by default.

Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
Comment on lines 447 to 448
.m1k_base = DT_INST_REG_ADDR_BY_IDX(0, 0),
.smfi_base = DT_INST_REG_ADDR_BY_IDX(0, 1),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is a single driver instance (and I'd imagine it'll stay that way), I think you'd be better off defining these at the top of the file and the using them to hardcode the offset on the register definitions themselves, the current driver has a lot of

cfg->m1k_base + SMFI_M1K_READ_LBA2

just get the offset once and use it as part of SMFI_M1K_READ_LBA2 itself, that should make the driver a bit easier to read.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

flash_set_m1k_dlm_ba(dev, (uint32_t)dst_data);

/* M1k-READ size (Maximum 1024 bytes) */
len = ((len - 1) & M1K_READ_BCNT_MASK);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the outer parenthesis

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

int ret;
uint8_t m1kflhctrl5_cmd;

LOG_INF("%s: offset=%lx, data addr=%p, len=%u", __func__, offset, (uint8_t *)dst_data, len);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOG_DBG?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

int ret;
uint8_t m1kflhctrl7_cmd;

LOG_INF("%s: offset=%lx, data addr=%p, len=%u", __func__, offset, (const uint8_t *)src_data,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOG_DBG

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 271 to 260
if (!is_valid_range(offset, len) || (len > FLASH_WRITE_MAX_SZ)) {
LOG_ERR("Write range exceeds the flash boundaries. FLASH_SIZE=%#x "
"or the len exceeds maximun write size=%u",
FLASH_SIZE, FLASH_WRITE_MAX_SZ);
return -EINVAL;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep it compact, these messages eat up flash no need to be super verbose "out of boundaries: FLASH_SIZE=%#x, size=%u", also log len as well

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

flash_set_m1k_dlm_ba(dev, (uint32_t)src_data);

/* M1k-PROG size (Maximum 1024 bytes) */
len = ((len - 1) & M1K_PROG_BCNT_MASK);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop the outer parenthesis

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

int ret;
uint8_t m1kflhctrl7_cmd;

LOG_INF("%s: offset=%lx, len=%u", __func__, offset, len);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DBG

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@GTLin08 GTLin08 force-pushed the it51xxx_m1k_flash_driver branch from 55bab94 to 34f5e7c Compare July 3, 2025 03:37
fabiobaltieri
fabiobaltieri previously approved these changes Jul 3, 2025
@fabiobaltieri fabiobaltieri added this to the v4.3.0 milestone Jul 3, 2025
Dino-Li
Dino-Li previously approved these changes Jul 7, 2025
Copy link
Collaborator

@de-nordic de-nordic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is not limit in Flash API how much you can read, write or erase at once, as long as caller is able to align function parameters to hardware required alignment and size.

struct flash_it51xxx_dev_data *data = dev->data;
int ret;
uint8_t m1kflhctrl5_cmd;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing len check to avoid any work, and return success, when len is 0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


LOG_DBG("%s: offset=%lx, data addr=%p, len=%u", __func__, offset, (const uint8_t *)src_data,
len);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing len check to avoid any work, and return success, when len is 0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

uint8_t m1kflhctrl7_cmd;

LOG_DBG("%s: offset=%lx, len=%u", __func__, offset, len);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing len check to avoid any work, and return success, when len is 0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 217 to 218
/* M1k-READ size (Maximum 1024 bytes) */
len = (len - 1) & M1K_READ_BCNT_MASK;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not get this lines. So, I request len bytes to be read, but I will get at most 1023 bytes? I mean 1023 not 1024, because the mask will mask is from bit 0 to 9? And actually I always get one less byte?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the hardware specification, this field is a 10-bit 0-based counter, which means the value written represents (N - 1) bytes to transfer. As a result, the maximum value 0x3FF (1023) corresponds to a full 1024-byte (1 KB) transfer.


LOG_DBG("%s: offset=%lx, data addr=%p, len=%u", __func__, offset, (uint8_t *)dst_data, len);

if (!is_valid_range(offset, len) || (len > FLASH_READ_MAX_SZ)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this thing can read at most 1024 bytes at once, shouldn't here be a loop? There is no limit, from the point of Flash API, on how much bytes you can run at once.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

The flash M1K driver supports read (up to 1K), write (1K), and
erase (4K) operations, which can be accessed via DLM.
Accessible flash regions include internal e-Flash or external SPI
flash via FSCE# or FSCE1#.

Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
@GTLin08 GTLin08 dismissed stale reviews from Dino-Li and fabiobaltieri via 20ebd62 July 9, 2025 09:29
@GTLin08 GTLin08 force-pushed the it51xxx_m1k_flash_driver branch from 34f5e7c to 20ebd62 Compare July 9, 2025 09:29
Copy link

sonarqubecloud bot commented Jul 9, 2025

@GTLin08
Copy link
Collaborator Author

GTLin08 commented Jul 9, 2025

There is not limit in Flash API how much you can read, write or erase at once, as long as caller is able to align function parameters to hardware required alignment and size.

The size restrictions in the read, write, and erase functions have been removed in the latest update.

@Dino-Li
Copy link
Collaborator

Dino-Li commented Jul 10, 2025

@de-nordic please revisit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Flash area: RISCV RISCV Architecture (32-bit & 64-bit) platform: ITE ITE
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants