GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
|
||||
ccflags-y += -I$(srctree)/product/update/flash
|
||||
ccflags-y += -I$(srctree)/product/update/store
|
||||
|
||||
obj-y += auto_update_adapter.o
|
||||
obj-y += update.o
|
||||
|
||||
obj-y += flash/
|
||||
obj-y += store/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AUTO_UPDATE_ADAPTER_H__
|
||||
#define __AUTO_UPDATE_ADAPTER_H__
|
||||
|
||||
/*
|
||||
* On success, return 0. otherwise it will return -1.
|
||||
*/
|
||||
int do_auto_update(void);
|
||||
|
||||
#endif
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __CHIP_ADAPTER_H__
|
||||
#define __CHIP_ADAPTER_H__
|
||||
|
||||
#ifndef LOAD_ADDR
|
||||
|
||||
#if defined(CONFIG_TARGET_XM720XXX)
|
||||
#define LOAD_ADDR ((unsigned char *)0x42000000)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TARGET_XM760XXX)
|
||||
#define LOAD_ADDR ((unsigned char *)0x41000000)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TARGET_RATELVXX)
|
||||
#define LOAD_ADDR ((unsigned char *)0x3a000000)
|
||||
#endif
|
||||
|
||||
#endif /* LOAD_ADDR */
|
||||
|
||||
typedef enum {
|
||||
AD_BOOTFROM_EMMC = 0xF1,
|
||||
AD_BOOTFROM_NAND,
|
||||
AD_BOOTFROM_SPINAND,
|
||||
AD_BOOTFROM_SPINOR,
|
||||
AD_BOOTFROM_BUTT
|
||||
} AD_BOOT_TYPE;
|
||||
|
||||
#if defined(CONFIG_TARGET_RATELVXX)
|
||||
static int get_boot_info(void)
|
||||
{
|
||||
unsigned int reg_val, boot_mode;
|
||||
int boot_media = 0xFF;
|
||||
|
||||
reg_val = readl(REG_START_FLAG);
|
||||
boot_mode = BOOT_SOURCE(reg_val);
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_FROM_NAND:
|
||||
boot_media = AD_BOOTFROM_NAND;
|
||||
break;
|
||||
case BOOT_FROM_SPI:
|
||||
boot_media = AD_BOOTFROM_SPINOR;
|
||||
break;
|
||||
case BOOT_FROM_EMMC:
|
||||
boot_media = AD_BOOTFROM_EMMC;
|
||||
break;
|
||||
default:
|
||||
#ifdef CONFIG_LOTUS_FPGA
|
||||
boot_media = AD_BOOTFROM_SPINOR;
|
||||
#else
|
||||
boot_media = 0xFF;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return boot_media;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_TARGET_XMORCA)
|
||||
static int get_boot_info(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl((void *)(SYS_CTRL_REG_BASE + REG_SYSSTAT));
|
||||
if (get_sys_boot_mode(reg) == BOOT_FROM_SPI_NOR) {
|
||||
/* SFC_DEVICE_MODE:0:SPINOR 1:SPINAND */
|
||||
if (get_spi_device_type(reg)) {
|
||||
/* SPINAND */
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else {
|
||||
/* SPINOR */
|
||||
return AD_BOOTFROM_SPINOR;
|
||||
}
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_SPI_NAND) {
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_EMMC_4BITS ||
|
||||
get_sys_boot_mode(reg) == BOOT_FROM_EMMC_8BITS) {
|
||||
return AD_BOOTFROM_EMMC;
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
#else
|
||||
/* CONFIG_TARGET_XM720XXX | CONFIG_TARGET_XM760XXX */
|
||||
static int get_boot_info(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl((void *)(SYS_CTRL_REG_BASE + REG_SYSSTAT));
|
||||
if (get_sys_boot_mode(reg) == BOOT_FROM_SPI) {
|
||||
/* SFC_DEVICE_MODE:0:SPINOR 1:SPINAND */
|
||||
if (get_spi_device_type(reg)) {
|
||||
/* SPINAND */
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else {
|
||||
/* SPINOR */
|
||||
return AD_BOOTFROM_SPINOR;
|
||||
}
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_NAND) {
|
||||
return AD_BOOTFROM_NAND;
|
||||
} else if (get_sys_boot_mode(reg) == BOOT_FROM_EMMC) {
|
||||
return AD_BOOTFROM_EMMC;
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
#endif /* CONFIG_TARGET_RATELVXX */
|
||||
|
||||
#endif /* __CHIP_ADAPTER_H__ */
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
ccflags-y += -I$(srctree)/product/update
|
||||
ccflags-y += -I$(srctree)/lotus/misc
|
||||
|
||||
obj-$(CONFIG_CMD_SF) += au_spinor_flash.o
|
||||
obj-$(CONFIG_CMD_NAND) += au_nand_flash.o
|
||||
obj-$(CONFIG_SUPPORT_EMMC_BOOT) += au_emmc_flash.o
|
||||
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <mmc.h>
|
||||
#include <sparse_format.h>
|
||||
#include <unsparse.h>
|
||||
|
||||
#include "update_comm.h"
|
||||
|
||||
#define EMMC_SUCCESS UP_SUCCESS
|
||||
#define EMMC_FAILURE UP_FAILURE
|
||||
|
||||
#define EMMC_BLOCK_SHIFT 9
|
||||
#define EMMC_BLOCK_SIZE (1 << EMMC_BLOCK_SHIFT)
|
||||
|
||||
int au_emmc_flash_init(void)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
(void)mmc_init(mmc);
|
||||
|
||||
return EMMC_SUCCESS;
|
||||
}
|
||||
|
||||
int au_emmc_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
#if 0
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
if (len % MMC_MAX_BLOCK_LEN) {
|
||||
blk_derase(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT) + 1);
|
||||
} else {
|
||||
blk_derase(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT));
|
||||
}
|
||||
#endif
|
||||
return EMMC_SUCCESS;
|
||||
}
|
||||
|
||||
int au_emmc_flash_write(unsigned long offset, unsigned long len,
|
||||
unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
if (len % MMC_MAX_BLOCK_LEN) {
|
||||
blk_dwrite(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT) + 1, buf);
|
||||
} else {
|
||||
blk_dwrite(mmc_get_blk_desc(mmc), (offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT), buf);
|
||||
}
|
||||
|
||||
return EMMC_SUCCESS;
|
||||
}
|
||||
|
||||
int au_emmc_flash_ext4_write(unsigned long offset, unsigned long len,
|
||||
unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
struct mmc *mmc = find_mmc_device(0);
|
||||
int retlen;
|
||||
|
||||
if (!mmc) {
|
||||
printf("%s:find mmc device failed\n", __func__);
|
||||
return EMMC_FAILURE;
|
||||
}
|
||||
|
||||
if (len % MMC_MAX_BLOCK_LEN)
|
||||
retlen = ext4_unsparse(mmc, 0, buf,
|
||||
(offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT) + 1);
|
||||
else
|
||||
retlen = ext4_unsparse(mmc, 0, buf,
|
||||
(offset >> EMMC_BLOCK_SHIFT),
|
||||
(len >> EMMC_BLOCK_SHIFT));
|
||||
return retlen;
|
||||
}
|
||||
|
||||
int au_emmc_flash_get_block_size(void)
|
||||
{
|
||||
return (int)EMMC_BLOCK_SIZE;
|
||||
}
|
||||
#endif // CONFIG_AUTO_UPDATE
|
||||
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AU_EMMC_FLASH_H__
|
||||
#define __AU_EMMC_FLASH_H__
|
||||
|
||||
#ifdef CONFIG_SUPPORT_EMMC_BOOT
|
||||
int au_emmc_flash_init(void);
|
||||
int au_emmc_flash_erase(unsigned long offset, unsigned long len);
|
||||
int au_emmc_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_emmc_flash_ext4_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_emmc_flash_get_block_size(void);
|
||||
#else
|
||||
int au_emmc_flash_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_emmc_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int au_emmc_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_emmc_flash_ext4_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_emmc_flash_get_block_size(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,217 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <nand.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
#define PERCENT_VALUE 100
|
||||
#define NAND_SUCCESS UP_SUCCESS
|
||||
#define NAND_FAILURE UP_FAILURE
|
||||
|
||||
static struct mtd_info *g_nand_flash = NULL;
|
||||
|
||||
static void schedule_notify(unsigned long offset, unsigned long len, unsigned long off_start)
|
||||
{
|
||||
int percent_complete = -1;
|
||||
unsigned long long n;
|
||||
|
||||
do {
|
||||
n = (unsigned long long)(offset - off_start) * PERCENT_VALUE;
|
||||
int percent;
|
||||
|
||||
do_div(n, len);
|
||||
percent = (int)n;
|
||||
|
||||
/* output progress message only at whole percent
|
||||
* steps to reduce the number of messages
|
||||
* printed on (slow) serial consoles
|
||||
*/
|
||||
if (percent != percent_complete)
|
||||
printf("\rOperation at 0x%lx -- %3d%% complete.", offset, percent);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
int au_nand_flash_init(void)
|
||||
{
|
||||
g_nand_flash = nand_info[0];
|
||||
if (g_nand_flash == NULL) {
|
||||
printf("nand_info() fail.\n");
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
int ret;
|
||||
unsigned long erase_len;
|
||||
unsigned long erase_step;
|
||||
unsigned long length;
|
||||
nand_erase_options_t opts;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
|
||||
length = len;
|
||||
erase_step = nand_flash->erasesize;
|
||||
erase_len = length;
|
||||
opts.length = erase_step;
|
||||
opts.offset = offset;
|
||||
opts.quiet = 1;
|
||||
|
||||
while (length > 0) {
|
||||
if (length < erase_step)
|
||||
erase_step = length;
|
||||
|
||||
ret = nand_erase_opts(nand_flash, &opts);
|
||||
if (ret) {
|
||||
printf("nand_erase_opts() fail.\n");
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
length -= erase_step;
|
||||
opts.offset += erase_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(opts.offset, erase_len, offset);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
unsigned long offset_notify;
|
||||
unsigned long write_start;
|
||||
unsigned long write_len;
|
||||
unsigned long write_step;
|
||||
size_t length;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
offset = offset & (nand_flash->writesize - 1) ? (size_t)(offset +
|
||||
(nand_flash->writesize - offset % nand_flash->writesize)) : offset;
|
||||
|
||||
length = len & (nand_flash->erasesize - 1) ? (size_t)(len +
|
||||
(nand_flash->erasesize - len % nand_flash->erasesize)) : len;
|
||||
|
||||
write_step = length;
|
||||
write_start = offset;
|
||||
offset_notify = offset;
|
||||
write_len = length;
|
||||
|
||||
while (length > 0) {
|
||||
size_t rw_size = write_step;
|
||||
|
||||
ret = nand_write_skip_bad(nand_flash, (size_t)offset, &rw_size, NULL, lim, (u_char *)pbuf, 0);
|
||||
if (ret) {
|
||||
printf("NAND write to offset %lx failed %d\n", offset, ret);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
length -= write_step;
|
||||
offset_notify += write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset_notify, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_yaffs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
size_t rw_size = len;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
ret = nand_write_yaffs_skip_bad(nand_flash, offset, &rw_size, (u_char *)buf);
|
||||
if (ret) {
|
||||
printf("Write yaffs fail !!\n");
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
printf("Write yaffs done\n");
|
||||
|
||||
return NAND_SUCCESS;
|
||||
}
|
||||
|
||||
int au_nand_flash_ubifs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = au_nand_flash_write(offset, len, lim, buf);
|
||||
|
||||
printf("Write ubifs done\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get count of area's bad block for nand flash */
|
||||
int au_nand_flash_get_bad_blkcnt(unsigned long offset, unsigned long len)
|
||||
{
|
||||
int count = 0;
|
||||
unsigned long block_offset = 0;
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (nand_flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return NAND_FAILURE;
|
||||
}
|
||||
|
||||
if (offset & (nand_flash->erasesize - 1))
|
||||
block_offset = offset & (nand_flash->erasesize - 1);
|
||||
|
||||
if (len & (nand_flash->erasesize - 1))
|
||||
len = ALIGN(len, nand_flash->erasesize);
|
||||
|
||||
for (int i = 0; i < len / nand_flash->erasesize; i++) {
|
||||
if (nand_block_isbad(nand_flash, offset))
|
||||
count++;
|
||||
offset += nand_flash->erasesize - block_offset;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_page_size(int with_oob)
|
||||
{
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
if (with_oob) {
|
||||
return (nand_flash->writesize + nand_flash->oobsize);
|
||||
} else {
|
||||
return (nand_flash->writesize);
|
||||
}
|
||||
}
|
||||
|
||||
int au_nand_flash_get_erase_size(void)
|
||||
{
|
||||
struct mtd_info *nand_flash = g_nand_flash;
|
||||
|
||||
return nand_flash->erasesize;
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_UPDATE
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AU_NAND_FLASH_H__
|
||||
#define __AU_NAND_FLASH_H__
|
||||
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
int au_nand_flash_init(void);
|
||||
int au_nand_flash_erase(unsigned long offset, unsigned long len);
|
||||
int au_nand_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_nand_flash_yaffs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_nand_flash_ubifs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf);
|
||||
int au_nand_flash_get_bad_blkcnt(unsigned long offset, unsigned long len);
|
||||
int au_nand_flash_get_page_size(int with_oob);
|
||||
int au_nand_flash_get_erase_size(void);
|
||||
#else
|
||||
int au_nand_flash_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_yaffs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_ubifs_write(unsigned long offset, unsigned long len, unsigned long lim, unsigned char *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_bad_blkcnt(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_pages_size(int with_oob)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int au_nand_flash_get_erase_size(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,205 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <spi_flash.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
#define PERCENT_VALUE 100
|
||||
#define SPINOR_SUCCESS UP_SUCCESS
|
||||
#define SPINOR_FAILURE UP_FAILURE
|
||||
|
||||
static struct spi_flash *g_spinor_flash;
|
||||
|
||||
static void schedule_notify(unsigned long offset, unsigned long len, unsigned long off_start)
|
||||
{
|
||||
int percent_complete = -1;
|
||||
unsigned long long n;
|
||||
|
||||
do {
|
||||
n = (unsigned long long)(offset - off_start) * PERCENT_VALUE;
|
||||
int percent;
|
||||
|
||||
do_div(n, len);
|
||||
percent = (int)n;
|
||||
|
||||
/* output progress message only at whole percent
|
||||
* steps to reduce the number of messages
|
||||
* printed on (slow) serial consoles
|
||||
*/
|
||||
if (percent != percent_complete) {
|
||||
printf("\rOperation at 0x%lx -- %3d%% complete.", offset, percent);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
int au_spinor_flash_init(void)
|
||||
{
|
||||
g_spinor_flash = spi_flash_probe(0, 0, 0, 0);
|
||||
if (g_spinor_flash == NULL) {
|
||||
printf("spi_flash_probe fail.\n");
|
||||
return SPINOR_FAILURE;
|
||||
};
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
int ret = SPINOR_SUCCESS;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
unsigned long erase_start, erase_len, erase_step;
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
erase_start = offset;
|
||||
erase_len = len;
|
||||
erase_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < erase_step)
|
||||
erase_step = len;
|
||||
#if (UBOOTVERSION == 202001)
|
||||
ret = spi_flash_erase(flash, (u32)offset, erase_step);
|
||||
#elif (UBOOTVERSION == 201611)
|
||||
ret = flash->erase(flash, (u32)offset, erase_step);
|
||||
#else
|
||||
printf("%s:invalid uboot version!\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("%s: erase fail.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
len -= erase_step;
|
||||
offset += erase_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, erase_len, erase_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
int ret;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
unsigned long write_start, write_len, write_step;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
write_start = offset;
|
||||
write_len = len;
|
||||
write_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < write_step)
|
||||
write_step = len;
|
||||
|
||||
ret = flash->write(flash, offset, write_step, pbuf);
|
||||
if (ret) {
|
||||
printf("SPINOR write to offset %lx failed %d\n", offset, ret);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
len -= write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_jffs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
int ret;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
unsigned long write_start, write_len, write_step;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
write_start = offset;
|
||||
write_len = len;
|
||||
write_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < write_step)
|
||||
write_step = len;
|
||||
|
||||
ret = flash->write(flash, offset, write_step, pbuf);
|
||||
if (ret) {
|
||||
printf("SPINOR write to offset %lx failed %d\n", offset, ret);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
len -= write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
int au_spinor_flash_ubifs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
int ret;
|
||||
struct spi_flash *flash = g_spinor_flash;
|
||||
unsigned long write_start, write_len, write_step;
|
||||
unsigned char *pbuf = buf;
|
||||
struct mtd_info_ex *spiflash_info = get_spiflash_info();
|
||||
|
||||
if (flash == NULL) {
|
||||
printf("%s: Invalid param.\n", __func__);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
write_start = offset;
|
||||
write_len = len;
|
||||
write_step = spiflash_info->erasesize;
|
||||
|
||||
while (len > 0) {
|
||||
if (len < write_step)
|
||||
write_step = len;
|
||||
|
||||
ret = flash->write(flash, offset, write_step, pbuf);
|
||||
if (ret) {
|
||||
printf("SPINOR write to offset %lx failed %d\n", offset, ret);
|
||||
return SPINOR_FAILURE;
|
||||
}
|
||||
|
||||
offset += write_step;
|
||||
pbuf += write_step;
|
||||
len -= write_step;
|
||||
/* notify real time schedule */
|
||||
schedule_notify(offset, write_len, write_start);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return SPINOR_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __AU_SPINORE_FLASH_H__
|
||||
#define __AU_SPINORE_FLASH_H__
|
||||
|
||||
#ifdef CONFIG_CMD_SF
|
||||
int au_spinor_flash_init(void);
|
||||
int au_spinor_flash_erase(unsigned long offset, unsigned long len);
|
||||
int au_spinor_flash_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf);
|
||||
int au_spinor_flash_jffs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf);
|
||||
int au_spinor_flash_ubifs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf);
|
||||
#else
|
||||
int au_spinor_flash_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_erase(unsigned long offset, unsigned long len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_jffs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int au_spinor_flash_ubifs_write(unsigned long offset, unsigned len, unsigned lim, unsigned char* buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
ccflags-y += -I$(srctree)/product/update
|
||||
|
||||
obj-y += store_mmc.o
|
||||
obj-y += store_usb.o
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_SD_UPDATE == 1)
|
||||
#include <mmc.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
int store_mmc_init(void)
|
||||
{
|
||||
struct mmc *mmc;
|
||||
unsigned int dev_num = 0;
|
||||
|
||||
agin:
|
||||
mmc = find_mmc_device(dev_num);
|
||||
if (mmc == NULL) {
|
||||
printf("No mmc driver found!\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
|
||||
if (!IS_SD(mmc)) {
|
||||
dev_num++;
|
||||
goto agin;
|
||||
}
|
||||
|
||||
if (((unsigned long)mmc->block_dev.vendor[0] == 0) ||
|
||||
((unsigned long)mmc->block_dev.product[0] == 0)) {
|
||||
printf("*No SD card found!\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
return UP_SUCCESS;
|
||||
}
|
||||
|
||||
void store_mmc_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int mmc_get_target_dev(void)
|
||||
{
|
||||
struct mmc *mmc = NULL;
|
||||
int dev_num = 0;
|
||||
|
||||
agin:
|
||||
mmc = find_mmc_device(dev_num);
|
||||
if (mmc == NULL) {
|
||||
printf("Error: No mmc driver found!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!IS_SD(mmc)) {
|
||||
dev_num++;
|
||||
goto agin;
|
||||
}
|
||||
|
||||
return dev_num;
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_SD_UPDATE
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __STORE_MMC_H__
|
||||
#define __STORE_MMC_H__
|
||||
|
||||
int store_mmc_init(void);
|
||||
|
||||
int store_mmc_deinit(void);
|
||||
|
||||
int mmc_get_target_dev(void);
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_USB_UPDATE == 1)
|
||||
#include <usb.h>
|
||||
#include "update_comm.h"
|
||||
|
||||
int store_usb_init(void)
|
||||
{
|
||||
int ret;
|
||||
#ifndef CONFIG_XMEDIA_MC
|
||||
try_again:
|
||||
if (usb_stop() < 0) {
|
||||
debug("usb_stop failed\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
/* delay for 1000 ms */
|
||||
mdelay(1000);
|
||||
ret = usb_init();
|
||||
if (ret == -ESRCH) {
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
debug("usb_init failed!\n");
|
||||
return UP_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* check whether a storage device is attached (assume that it's
|
||||
* a USB memory stick, since nothing else should be attached).
|
||||
*/
|
||||
ret = usb_stor_scan(0);
|
||||
if (ret == -1) {
|
||||
debug("No USB device found. Not initialized!\n");
|
||||
return UP_FAILURE;
|
||||
} else {
|
||||
return UP_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
return UP_FAILURE;
|
||||
}
|
||||
|
||||
void store_usb_deinit(void)
|
||||
{
|
||||
#ifndef CONFIG_XMEDIA_MC
|
||||
usb_stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_USB_UPDATE
|
||||
@@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __STORE_USB_H__
|
||||
#define __STORE_USB_H__
|
||||
|
||||
int store_usb_init(void);
|
||||
|
||||
int store_usb_deinit(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
#include <common.h>
|
||||
|
||||
#if (CONFIG_AUTO_UPDATE == 1)
|
||||
#include <linux/io.h>
|
||||
#include "update_comm.h"
|
||||
#include "auto_update_adapter.h"
|
||||
|
||||
#if defined(CONFIG_TARGET_RATELVXX)
|
||||
static int check_update_button(void)
|
||||
{
|
||||
/* to add some judgement if neccessary */
|
||||
unsigned int sd_update_flag;
|
||||
|
||||
printf("board check_update_button bootflag:0x%x REG_ROM_RUN_TIME:%d\n",
|
||||
readl(REG_START_FLAG), readl(REG_ROM_RUN_TIME));
|
||||
|
||||
/* sd update */
|
||||
sd_update_flag = readl(REG_START_FLAG);
|
||||
if (SD_UPDATE_MODE(sd_update_flag))
|
||||
return UP_TRUE;
|
||||
|
||||
/* usb device update */
|
||||
if (SD_UDISK_UPDATE_CHECK_NEED(sd_update_flag))
|
||||
return UP_TRUE; /* update enable */
|
||||
else
|
||||
return UP_FALSE;
|
||||
}
|
||||
|
||||
static void clear_update_flag(void)
|
||||
{
|
||||
/* REG_UPDATE_MODE_CLEAR: write only */
|
||||
writel(0, REG_START_FLAG);
|
||||
}
|
||||
|
||||
#else /* CONFIG_TARGET_RATELVXX */
|
||||
|
||||
#define REG_SYS_BOOT6 0x0148
|
||||
#define SD_UPDAT_MAGIC 0x444f574e
|
||||
|
||||
#define BIT_UPDATE_FLAG 2
|
||||
#define BIT_UPDATE_FLAG_CLEAR 0
|
||||
#define REG_SYS_STAT 0x008C
|
||||
#define REG_MISC_CTRL51 0x8200
|
||||
|
||||
#ifndef REG_SC_DDRT14
|
||||
#define REG_SC_DDRT14 0x00C8
|
||||
#endif
|
||||
|
||||
#define REG_UPDATE_MODE (SYS_CTRL_REG_BASE + REG_SYS_STAT)
|
||||
#define REG_UPDATE_MODE_CLEAR (SYS_CTRL_REG_BASE + REG_MISC_CTRL51)
|
||||
#define REG_BOOTSTRAP_FLAG (SYS_CTRL_REG_BASE + REG_SC_DDRT14)
|
||||
|
||||
static int check_update_button(void)
|
||||
{
|
||||
unsigned int sd_update_flag;
|
||||
unsigned int update_mode = 0;
|
||||
|
||||
/* sd update */
|
||||
sd_update_flag = readl(SYS_CTRL_REG_BASE + REG_SYS_BOOT6);
|
||||
if (sd_update_flag == SD_UPDAT_MAGIC) {
|
||||
printf("SD card upgrade\n");
|
||||
return UP_TRUE;
|
||||
}
|
||||
|
||||
/* usb device update */
|
||||
update_mode = readl(REG_UPDATE_MODE);
|
||||
update_mode = ((update_mode >> BIT_UPDATE_FLAG) & 0x01);
|
||||
if (update_mode) {
|
||||
printf("U disk upgrade\n");
|
||||
return UP_TRUE;
|
||||
} else {
|
||||
printf("Upgrade flag disabled\n");
|
||||
return UP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_update_flag(void)
|
||||
{
|
||||
unsigned int clear_value = 0x1;
|
||||
|
||||
clear_value = (clear_value << BIT_UPDATE_FLAG_CLEAR);
|
||||
/* update mode clear */
|
||||
writel(clear_value, REG_UPDATE_MODE_CLEAR);
|
||||
/* set bootstrap flag */
|
||||
/* 0:主flash, 主uboot分区启动 */
|
||||
writel(0x00, REG_BOOTSTRAP_FLAG);
|
||||
}
|
||||
#endif /* CONFIG_TARGET_RATELVXX */
|
||||
|
||||
void auto_update(void)
|
||||
{
|
||||
int update_flag = -1;
|
||||
|
||||
printf("%s entry.\n", __func__);
|
||||
|
||||
if (check_update_button()) {
|
||||
update_flag = do_auto_update();
|
||||
clear_update_flag();
|
||||
if (update_flag == 0) {
|
||||
printf("%s ok, reset.\n", __func__);
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s exit.\n", __func__);
|
||||
}
|
||||
|
||||
#endif // CONFIG_AUTO_UPDATE == 1
|
||||
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __UPDATE_H__
|
||||
#define __UPDATE_H__
|
||||
|
||||
void auto_update(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) LOTUS. All rights reserved. */
|
||||
|
||||
#ifndef __UPDATE_COMM_H__
|
||||
#define __UPDATE_COMM_H__
|
||||
|
||||
#define UP_TRUE 1
|
||||
#define UP_FALSE 0
|
||||
|
||||
#define UP_SUCCESS 0
|
||||
#define UP_FAILURE -1
|
||||
|
||||
#define AU_DEBUG 1
|
||||
#undef debug_print
|
||||
#ifdef AU_DEBUG
|
||||
#define debug_print(fmt, args...) printf(fmt, ##args)
|
||||
#else
|
||||
#define debug_print(fmt, args...)
|
||||
#endif /* AU_DEBUG */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user