Skip to content
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

storage: implement generic extensible flash driver #521

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _targets/Makefile.riscv64-noelv
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
# Copyright 2024 Phoenix Systems
#

DEFAULT_COMPONENTS := grlib-uart
DEFAULT_COMPONENTS := grlib-uart flashdrv
2 changes: 1 addition & 1 deletion _targets/Makefile.sparcv8leon-gr712rc
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
# Copyright 2023 Phoenix Systems
#

DEFAULT_COMPONENTS := grlib-multi gr712rc-flash
DEFAULT_COMPONENTS := grlib-multi flashdrv
12 changes: 12 additions & 0 deletions storage/flashdrv/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# Makefile for Phoenix-RTOS ftmctrl-flash driver
#
# Copyright 2023, 2024 Phoenix Systems
#

NAME := flashdrv
LOCAL_SRCS := common.c flashsrv.c
DEP_LIBS := libftmctrl libspimctrl
LIBS := libjffs2 libstorage libmtd libptable libcache

include $(binary.mk)
28 changes: 28 additions & 0 deletions storage/flashdrv/common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Phoenix-RTOS
*
* GRLIB FTMCTRL Flash driver
*
* Common auxiliary functions
*
* Copyright 2024 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <flashdrv/common.h>


off_t common_getSectorOffset(size_t sectorsz, off_t offs)
{
return offs & ~(sectorsz - 1);
}


bool common_isValidAddress(size_t memsz, off_t offs, size_t len)
{
return ((offs < memsz) && ((offs + len) <= memsz));
}
10 changes: 10 additions & 0 deletions storage/flashdrv/drv/grlib-ftmctrl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# Makefile for Phoenix-RTOS libftmctrl driver
#
# Copyright 2023, 2024 Phoenix Systems
#

NAME := libftmctrl
LOCAL_SRCS := amd-flash.c flashdrv.c flash.c intel-flash.c

include $(static-lib.mk)
148 changes: 148 additions & 0 deletions storage/flashdrv/drv/grlib-ftmctrl/amd-flash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Phoenix-RTOS
*
* GRLIB FTMCTRL Flash driver
*
* AMD command set flash interface
*
* Copyright 2024 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include "cmds.h"
#include "flash.h"

#include <errno.h>


/* Valid offset on flash - for executing commands */
#define FLASH_VALID_OFFS 0x0
#define STS_FULL_CHECK ((1 << 5) | (1 << 4) | (1 << 3) | (1 << 1))

/* TODO: adapt also to x16 interface */

static void amd_unlockSequence(volatile uint8_t *base)
{
*(base + 0x0aaa) = 0xaa;
*(base + 0x0555) = 0x55;
}


static void amd_issueReset(volatile uint8_t *base)
{
*(base + FLASH_VALID_OFFS) = AMD_CMD_RESET;
}


static uint8_t amd_statusRead(volatile uint8_t *base)
{
*(base + 0x0aaa) = CMD_RD_STATUS;

return *(base + FLASH_VALID_OFFS);
}


static void amd_statusClear(volatile uint8_t *base)
{
*(base + 0x0aaa) = AMD_CMD_CLR_STATUS;
}


static int amd_statusCheck(volatile uint8_t *base, const char *msg)
{
int ret = 0;
uint8_t status = amd_statusRead(base);

if ((status & STS_FULL_CHECK) != 0) {
LOG_ERROR("%s error: status 0x%x", msg, status);
ret = -EIO;
}

return ret;
}


static void amd_issueWriteBuffer(volatile uint8_t *base, off_t sectorOffs, off_t programOffs, size_t len)
{
(void)programOffs;

amd_unlockSequence(base);

*(base + sectorOffs) = AMD_CMD_WR_BUF;
*(base + sectorOffs) = (len - 1) & 0xff;
}


static void amd_issueWriteConfirm(volatile uint8_t *base, off_t sectorOffs)
{
*(base + sectorOffs) = AMD_CMD_WR_CONFIRM;
}


static void amd_issueSectorErase(volatile uint8_t *base, off_t sectorOffs)
{
amd_unlockSequence(base);
*(base + 0x0aaa) = AMD_CMD_BE_CYC1;

amd_unlockSequence(base);
*(base + sectorOffs) = AMD_CMD_BE_CYC2;
}


static void amd_issueChipErase(volatile uint8_t *base)
{
amd_unlockSequence(base);
*(base + 0x0aaa) = AMD_CMD_CE_CYC1;

amd_unlockSequence(base);
*(base + 0x0aaa) = AMD_CMD_CE_CYC2;
}


static void amd_enterQuery(volatile uint8_t *base, off_t sectorOffs)
{
*(base + sectorOffs + 0xaa) = CMD_RD_QUERY;
}


static void amd_exitQuery(volatile uint8_t *base)
{
*base = AMD_CMD_EXIT_QUERY;
}


void ftmctrl_amd_register(void)
{
static const flash_ops_t ops = {
.statusRead = amd_statusRead,
.statusCheck = amd_statusCheck,
.statusClear = amd_statusClear,
.issueReset = amd_issueReset,
.issueWriteBuffer = amd_issueWriteBuffer,
.issueWriteConfirm = amd_issueWriteConfirm,
.issueSectorErase = amd_issueSectorErase,
.issueChipErase = amd_issueChipErase,
.enterQuery = amd_enterQuery,
.exitQuery = amd_exitQuery
};

static const flash_dev_t amd_devices[] = {
{
.name = "Infineon S29GL01/512T",
.vendor = 0x01,
.device = 0x227e,
.chipWidth = 16,
.statusRdyMask = (1 << 7),
.usePolling = 1,
.ops = &ops,
},
};

for (size_t i = 0; i < (sizeof(amd_devices) / sizeof(amd_devices[0])); ++i) {
ftmctrl_flash_register(&amd_devices[i]);
}
}
43 changes: 43 additions & 0 deletions storage/flashdrv/drv/grlib-ftmctrl/cmds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Phoenix-RTOS
*
* GRLIB FTMCTRL Flash driver
*
* Flash commands
*
* Copyright 2024 Phoenix Systems
* Author: Lukasz Leczkowski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#ifndef _FTMCTRL_CMDS_H_
#define _FTMCTRL_CMDS_H_


/* Common flash commands */
#define CMD_RD_QUERY 0x98u /* Read/Enter Query */
#define CMD_RD_STATUS 0x70u /* Read Status Register */

/* Intel command set */
#define INTEL_CMD_RESET 0xffu /* Reset/Read Array */
#define INTEL_CMD_WR_BUF 0xe8u /* Write to Buffer */
#define INTEL_CMD_WR_CONFIRM 0xd0u /* Write Confirm */
#define INTEL_CMD_CLR_STATUS 0x50u /* Clear Status Register */
#define INTEL_CMD_BE_CYC1 0x20u /* Block Erase (1st bus cycle) */

/* AMD command set */
#define AMD_CMD_RESET 0xf0u /* Reset/ASO Exit */
#define AMD_CMD_WR_BUF 0x25u /* Write to Buffer */
#define AMD_CMD_WR_CONFIRM 0x29u /* Write Confirm */
#define AMD_CMD_CLR_STATUS 0x71u /* Clear Status Register */
#define AMD_CMD_CE_CYC1 0x80u /* Chip Erase (1st bus cycle) */
#define AMD_CMD_CE_CYC2 0x10u /* Chip Erase (2nd bus cycle) */
#define AMD_CMD_BE_CYC1 0x80u /* Block Erase (1st bus cycle) */
#define AMD_CMD_BE_CYC2 0x30u /* Block Erase (2nd bus cycle) */
#define AMD_CMD_EXIT_QUERY 0xf0u /* Exit Query */


#endif
Loading
Loading