arm/tlsr82: support flash protection and voltage calibration.
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
parent
bfde3c007d
commit
acf21d2a8e
4 changed files with 417 additions and 1 deletions
|
|
@ -422,6 +422,31 @@ config TLSR82_FLASH_WRITE_BUFFER_SIZE
|
|||
Flash byte write buffer size, the larger this size, the higher byte write
|
||||
efficiency.
|
||||
|
||||
config TLSR82_FLASH_PROTECT
|
||||
bool "Flash erase/write protect enable"
|
||||
default n
|
||||
---help---
|
||||
When enable this config, application can use ioctl(fd, MTDIOC_PROTECT/
|
||||
MTDIOC_UNPROTECT, arg) to protect or unprotect the flash. The protect
|
||||
and unprotect operations cost several millisecond, be careful to use it
|
||||
if the application has performance requirements.
|
||||
|
||||
config TLSR82_FLASH_CALI
|
||||
bool "Flash volatge calibration enable"
|
||||
default n
|
||||
---help---
|
||||
When enable the flash calibration, flash driver will read the calibration
|
||||
parameters stored in the falsh during initialization and use these
|
||||
parameters to calibrate the flash voltage.
|
||||
|
||||
config TLSR82_FLASH_CALI_PARA_ADDR
|
||||
hex "Flash voltage calibration address"
|
||||
default 0x3ffd0
|
||||
depends on TLSR82_FLASH_CALI
|
||||
---help---
|
||||
This is the flash calibration parameters address, this address must be
|
||||
equal to the address defined in production tools.
|
||||
|
||||
config TLSR82_FLASH_TEST
|
||||
bool "Enable the falsh test when initializing"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -61,6 +61,35 @@
|
|||
# define FLASH_MID_TH25D40UA 0x1360eb
|
||||
#endif
|
||||
|
||||
/* Flash status register bit definitions
|
||||
* FLASH_STATUS_WIP: The Write In Progress (WIP) bit indicates whether
|
||||
* the memory is busy in program/erase/write status
|
||||
* register progress.
|
||||
* FLASH_STATUS_WEL: The Write Enable Latch (WEL) bit indicates the
|
||||
* status of the internal Write Enable Latch.
|
||||
* FLASH_STATUS_BP: The Block Protect (BP2, BP1, BP0) bits are
|
||||
* non-volatile. They define the size of the area to be
|
||||
* software protected against Program and Erase commands.
|
||||
* FLASH_STATUS_SRP: The Status Register Protect (SRP) bit operates in
|
||||
* conjunction with the Write Protect (WP#) signal.
|
||||
*/
|
||||
|
||||
#define FLASH_STATUS_WIP_SHIFT 0
|
||||
#define FLASH_STATUS_WIP_MASK (0x1 << FLASH_STATUS_WIP_SHIFT)
|
||||
#define FLASH_STATUS_WEL_SHIFT 1
|
||||
#define FLASH_STATUS_WEL_MASK (0x1 << FLASH_STATUS_WEL_SHIFT)
|
||||
#define FLASH_STATUS_BP_SHIFT 2
|
||||
#define FLASH_STATUS_BP_MASK (0x7 << FLASH_STATUS_BP_SHIFT)
|
||||
#define FLASH_STATUS_RSVD_SHIFT 5
|
||||
#define FLASH_STATUS_RSVD_MASK (0x3 << FLASH_STATUS_RSVD_SHIFT)
|
||||
#define FLASH_STATUS_SRP_SHIFT 7
|
||||
#define FLASH_STATUS_SRP_MASK (0x1 << FLASH_STATUS_SRP_SHIFT)
|
||||
|
||||
/* NONE: do not protect, ALL: protect all the flash */
|
||||
|
||||
#define FLASH_STATUS_BP_NONE (0x0 << FLASH_STATUS_BP_SHIFT)
|
||||
#define FLASH_STATUS_BP_ALL (0x7 << FLASH_STATUS_BP_SHIFT)
|
||||
|
||||
/* Flash command definitions */
|
||||
|
||||
#define FLASH_INVALID_ADDR 0xffffffff
|
||||
|
|
@ -89,6 +118,11 @@
|
|||
#define FLASH_CMD_READ_UID1 0x4b
|
||||
#define FLASH_CMD_READ_UID2 0x5a
|
||||
|
||||
/* Flash status type definitions */
|
||||
|
||||
#define FLASH_STATUS_TYPE_8BIT 0x0
|
||||
#define FLASH_STATUS_TYPE_16BIT 0x1
|
||||
|
||||
/* Flash lock/unlock macros definitions */
|
||||
|
||||
#ifndef CONFIG_TLSR8278_BLE_SDK
|
||||
|
|
@ -452,6 +486,137 @@ void tlsr82_flash_write_data(uint32_t addr, const uint8_t *buf, uint32_t len)
|
|||
tlsr82_flash_write(FLASH_CMD_WRITE, addr, buf, len);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tlsr82_flash_read_status
|
||||
*
|
||||
* Description:
|
||||
* This function reads the status of flash.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cmd - the cmd of read status.
|
||||
*
|
||||
* Returned Value:
|
||||
* status.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t tlsr82_flash_read_status(uint8_t cmd)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
|
||||
tlsr82_flash_read(cmd, FLASH_INVALID_ADDR, 0, &status, 1);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tlsr82_flash_write_status
|
||||
*
|
||||
* Description:
|
||||
* Write the status to flash status register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* type - the type of status.8 bit or 16 bit.
|
||||
* status - the value of status.
|
||||
*
|
||||
* Returned Value:
|
||||
* void
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tlsr82_flash_write_status(uint8_t type, uint16_t status)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
|
||||
/* Follow the sdk to write flash status register */
|
||||
|
||||
buf[0] = (uint8_t)(status & 0x00ff);
|
||||
buf[1] = (uint8_t)(status >> 8);
|
||||
|
||||
if (type == FLASH_STATUS_TYPE_8BIT)
|
||||
{
|
||||
tlsr82_flash_write(FLASH_CMD_WRITE_STATUS_LBYTE,
|
||||
FLASH_INVALID_ADDR, buf, 1);
|
||||
}
|
||||
else if (type == FLASH_STATUS_TYPE_16BIT)
|
||||
{
|
||||
tlsr82_flash_write(FLASH_CMD_WRITE_STATUS_LBYTE,
|
||||
FLASH_INVALID_ADDR, buf, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tlsr82_flash_protect
|
||||
*
|
||||
* Description:
|
||||
* This function serves to set the protection area of the flash.
|
||||
* Note: after check the sdk code, this function can be applied to all
|
||||
* flash chips:
|
||||
* FLASH_MID_GD25LD10C 0x1160c8 128K
|
||||
* FLASH_MID_GD25LD40C 0x1360c8 512K
|
||||
* FLASH_MID_GD25LD80C 0x1460c8 1M
|
||||
* FLASH_MID_ZB25WD10A 0x11325e 128K
|
||||
* FLASH_MID_ZB25WD40B 0x13325e 512K
|
||||
* FLASH_MID_ZB25WD80B 0x14325e 1M
|
||||
* FLASH_MID_ZB25WD20A 0x12325e 256K
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TLSR82_FLASH_PROTECT
|
||||
void tlsr82_flash_protect(void)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t data;
|
||||
|
||||
status = tlsr82_flash_read_status(FLASH_CMD_READ_STATUS_LBYTE);
|
||||
data = FLASH_STATUS_BP_ALL | (status & (~FLASH_STATUS_BP_MASK));
|
||||
|
||||
tlsr82_flash_write_status(FLASH_STATUS_TYPE_8BIT, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tlsr82_flash_unprotect
|
||||
*
|
||||
* Description:
|
||||
* This function serves to release flash protection.
|
||||
* Note: after check the sdk code, this function can be applied to all
|
||||
* flash chips:
|
||||
* FLASH_MID_GD25LD10C 0x1160c8 128K
|
||||
* FLASH_MID_GD25LD40C 0x1360c8 512K
|
||||
* FLASH_MID_GD25LD80C 0x1460c8 1M
|
||||
* FLASH_MID_ZB25WD10A 0x11325e 128K
|
||||
* FLASH_MID_ZB25WD40B 0x13325e 512K
|
||||
* FLASH_MID_ZB25WD80B 0x14325e 1M
|
||||
* FLASH_MID_ZB25WD20A 0x12325e 256K
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* void
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TLSR82_FLASH_PROTECT
|
||||
void tlsr82_flash_unprotect(void)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t data;
|
||||
|
||||
status = tlsr82_flash_read_status(FLASH_CMD_READ_STATUS_LBYTE);
|
||||
data = FLASH_STATUS_BP_NONE | (status & (~FLASH_STATUS_BP_MASK));
|
||||
|
||||
tlsr82_flash_write_status(FLASH_STATUS_TYPE_8BIT, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tlsr82_flash_read_uid
|
||||
*
|
||||
|
|
@ -502,7 +667,7 @@ int tlsr82_flash_miduid_check(uint32_t *pmid, uint8_t *puid)
|
|||
/* Read the flash manufacaturer ID */
|
||||
|
||||
tlsr82_flash_read(FLASH_CMD_READ_JEDEC_ID, FLASH_INVALID_ADDR,
|
||||
0, (uint8_t *)pmid, 3);
|
||||
0, (uint8_t *)pmid, 3);
|
||||
#ifdef CONFIG_ARCH_CHIP_TLSR8258
|
||||
if (mid == FLASH_MID_GD25LE80C)
|
||||
{
|
||||
|
|
@ -542,3 +707,98 @@ int tlsr82_flash_miduid_check(uint32_t *pmid, uint8_t *puid)
|
|||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tlsr82_flash_calibrate
|
||||
*
|
||||
* Description:
|
||||
* Follow telink sdk to do flash voltage calibration, the flash supply
|
||||
* voltage accuracy is very important, the low flash supply voltage will
|
||||
* cause the flash data destoied.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mid - manufacaturer
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_TLSR82_FLASH_CALI
|
||||
void tlsr82_flash_calibrate(uint32_t mid)
|
||||
{
|
||||
#if defined(CONFIG_ARCH_CHIP_TLSR8278)
|
||||
|
||||
uint16_t cali_data = *(uint16_t *)CONFIG_TLSR82_FLASH_CALI_PARA_ADDR;
|
||||
|
||||
finfo("cali_data=0x%x\n");
|
||||
|
||||
if ((0xffff == cali_data) || (0 != (cali_data & 0xf8f8)))
|
||||
{
|
||||
/* No flash calibration paramters */
|
||||
|
||||
finfo("No flash calibration parameters\n");
|
||||
|
||||
if (mid == FLASH_MID_ZB25WD10A || mid == FLASH_MID_ZB25WD40B ||
|
||||
mid == FLASH_MID_ZB25WD80B || mid == FLASH_MID_ZB25WD20A)
|
||||
{
|
||||
/* LDO mode flash ldo trim 1.95V */
|
||||
|
||||
tlsr82_analog_write(0x09, ((tlsr82_analog_read(0x09) & 0x8f) |
|
||||
(FLASH_VOLTAGE_1V95 << 4)));
|
||||
|
||||
/* DCDC mode flash ldo trim 1.90V */
|
||||
|
||||
tlsr82_analog_write(0x0c, ((tlsr82_analog_read(0x0c) & 0xf8) |
|
||||
FLASH_VOLTAGE_1V9));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flash calibration parameters exist, write the flash calibration
|
||||
* parameters to the register
|
||||
*/
|
||||
|
||||
finfo("Calibrate the flash voltage\n");
|
||||
|
||||
tlsr82_analog_write(0x09, ((tlsr82_analog_read(0x09) & 0x8f) |
|
||||
((cali_data & 0xff00) >> 4)));
|
||||
tlsr82_analog_write(0x0c, ((tlsr82_analog_read(0x0c) & 0xf8) |
|
||||
(cali_data & 0xff)));
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_CHIP_TLSR8258)
|
||||
|
||||
uint8_t cali_data = *(uint8_t *)CONFIG_TLSR82_FLASH_CALI_PARA_ADDR;
|
||||
|
||||
finfo("cali_data=0x%x\n");
|
||||
|
||||
if (0xff == cali_data)
|
||||
{
|
||||
/* No flash calibration paramters */
|
||||
|
||||
finfo("No flash calibration parameters\n");
|
||||
|
||||
if (mid == FLASH_MID_ZB25WD10A || mid == FLASH_MID_ZB25WD40B ||
|
||||
mid == FLASH_MID_ZB25WD80B || mid == FLASH_MID_ZB25WD20A)
|
||||
{
|
||||
/* DCDC mode flash ldo trim 1.95V */
|
||||
|
||||
tlsr82_analog_write(0x0c, ((tlsr82_analog_read(0x0c) & 0xf8) |
|
||||
FLASH_VOLTAGE_1V95));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flash calibration parameters exist, write the flash calibration
|
||||
* parameters to the register
|
||||
*/
|
||||
|
||||
finfo("Calibrate the flash voltage\n");
|
||||
|
||||
tlsr82_analog_write(0x0c, ((tlsr82_analog_read(0x0c) & 0xf8) |
|
||||
(cali_data & 0x7)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -37,6 +37,15 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define FLASH_VOLTAGE_1V6 0x00
|
||||
#define FLASH_VOLTAGE_1V65 0x01
|
||||
#define FLASH_VOLTAGE_1V7 0x02
|
||||
#define FLASH_VOLTAGE_1V75 0x03
|
||||
#define FLASH_VOLTAGE_1V8 0x04
|
||||
#define FLASH_VOLTAGE_1V85 0x05
|
||||
#define FLASH_VOLTAGE_1V9 0x06
|
||||
#define FLASH_VOLTAGE_1V95 0x07
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
|
@ -64,8 +73,25 @@ void tlsr82_flash_erase_sector(uint32_t addr);
|
|||
void tlsr82_flash_read_data(uint32_t addr, uint8_t *buf, uint32_t len);
|
||||
void tlsr82_flash_write_data(uint32_t addr, const uint8_t *buf,
|
||||
uint32_t len);
|
||||
uint8_t tlsr82_flash_read_status(uint8_t cmd);
|
||||
void tlsr82_flash_write_status(uint8_t type, uint16_t status);
|
||||
|
||||
#ifdef CONFIG_TLSR82_FLASH_PROTECT
|
||||
void tlsr82_flash_protect(void);
|
||||
void tlsr82_flash_unprotect(void);
|
||||
#else
|
||||
# define tlsr82_flash_protect()
|
||||
# define tlsr82_flash_unprotect()
|
||||
#endif
|
||||
|
||||
int tlsr82_flash_miduid_check(uint32_t *pmid, uint8_t *puid);
|
||||
|
||||
#ifdef CONFIG_TLSR82_FLASH_CALIBRATE
|
||||
void tlsr82_flash_calibrate(uint32_t mid);
|
||||
#else
|
||||
# define tlsr82_flash_calibrate(mid)
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,14 @@
|
|||
#define FLASH_WRITE_TRACE_START()
|
||||
#define FLASH_WRITE_TRACE_END()
|
||||
|
||||
/* Flash protect/unprotect trace marco definition */
|
||||
|
||||
#define FLASH_PROT_TRACE_START()
|
||||
#define FLASH_PROT_TRACE_END()
|
||||
|
||||
#define FLASH_UNPROT_TRACE_START()
|
||||
#define FLASH_UNPROT_TRACE_END()
|
||||
|
||||
#define FLASH_BUF_LIST16(n) \
|
||||
n , n + 1, n + 2, n + 3, n + 4, n + 5, n + 6, n + 7, \
|
||||
n + 8, n + 9, n + 10, n + 11, n + 12, n + 13, n + 14, n + 15,
|
||||
|
|
@ -481,6 +489,83 @@ static int tlsr82_flash_test(struct tlsr82_flash_dev_s *priv)
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TLSR82_FLASH_PROTECT
|
||||
/* 5. Flash protect/unprotect test:
|
||||
* 1) erase the chip;
|
||||
* 2) write data into chip;
|
||||
* 3) protect flash;
|
||||
* 4) erase the chip with flash protected;
|
||||
* 5) read the chip, the data should be same as the data written in 2);
|
||||
*/
|
||||
|
||||
uint8_t status;
|
||||
uint32_t addr;
|
||||
|
||||
/* 1) erase the chip */
|
||||
|
||||
ferr("Erase chip for protect/unprotect test\n");
|
||||
tlsr82_flash_chip_erase(priv);
|
||||
ferr("Erase chip finished\n");
|
||||
|
||||
/* 2) write data into chip */
|
||||
|
||||
tlsr82_flash_print("Write buffer data:", flash_buffer, TLSR82_PAGE_SIZE);
|
||||
for (i = 0; i < npages; i++)
|
||||
{
|
||||
ret = tlsr82_flash_bwrite(&priv->mtd, i, 1, flash_buffer);
|
||||
if (ret != 1)
|
||||
{
|
||||
ferr(" Flash block write failed, ret=%d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3) protect the flash, read the flash status register */
|
||||
|
||||
FLASH_PROT_TRACE_START();
|
||||
tlsr82_flash_protect();
|
||||
FLASH_PROT_TRACE_END();
|
||||
|
||||
status = tlsr82_flash_read_status(5);
|
||||
ferr("Current flash status: 0x%x\n", status);
|
||||
|
||||
/* 4) erase the chip with flash protected */
|
||||
|
||||
addr = priv->baseaddr;
|
||||
for (i = 0; i < priv->nsectors; i++)
|
||||
{
|
||||
tlsr82_flash_erase_sector(addr);
|
||||
addr += priv->sectorsize;
|
||||
}
|
||||
|
||||
FLASH_UNPROT_TRACE_START();
|
||||
tlsr82_flash_unprotect();
|
||||
FLASH_UNPROT_TRACE_END();
|
||||
|
||||
/* 5) read the chip, the data should be same as the data written in 2) */
|
||||
|
||||
for (i = 0; i < npages; i++)
|
||||
{
|
||||
memset(flash_read_buffer, 0, TLSR82_PAGE_SIZE);
|
||||
ret = tlsr82_flash_bread(&priv->mtd, i, 1, flash_read_buffer);
|
||||
if (ret != 1)
|
||||
{
|
||||
ferr(" Flash block read failed, ret=%d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (memcmp(flash_read_buffer, flash_buffer, TLSR82_PAGE_SIZE) != 0)
|
||||
{
|
||||
ferr(" Flash write compre is not equal, page_i=%d\n", i);
|
||||
tlsr82_flash_print("Write buffer data:", flash_buffer,
|
||||
TLSR82_PAGE_SIZE);
|
||||
tlsr82_flash_print("Read buffer data:", flash_read_buffer,
|
||||
TLSR82_PAGE_SIZE);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ferr("======== Flash test Success ========\n");
|
||||
|
||||
return OK;
|
||||
|
|
@ -685,6 +770,22 @@ static int tlsr82_flash_ioctl(struct mtd_dev_s *dev, int cmd,
|
|||
}
|
||||
break;
|
||||
|
||||
case MTDIOC_PROTECT:
|
||||
{
|
||||
/* Ignore arg, direct protect full chip */
|
||||
|
||||
tlsr82_flash_protect();
|
||||
}
|
||||
break;
|
||||
|
||||
case MTDIOC_UNPROTECT:
|
||||
{
|
||||
/* Ignore arg, direct unprotect full chip */
|
||||
|
||||
tlsr82_flash_unprotect();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOTTY; /* Bad/unsupported command */
|
||||
break;
|
||||
|
|
@ -776,6 +877,10 @@ struct mtd_dev_s *tlsr82_flash_initialize(uint32_t offset, uint32_t size)
|
|||
goto errout;
|
||||
}
|
||||
|
||||
/* Calibrate the flash */
|
||||
|
||||
tlsr82_flash_calibrate(g_flash_mid);
|
||||
|
||||
#ifdef CONFIG_TLSR82_FLASH_TEST
|
||||
ret = tlsr82_flash_test(priv);
|
||||
if (ret < 0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue