Merge remote-tracking branch 'gfiber-internal/prism_dev' into mergeprism2
diff --git a/board/mv_feroceon/USP/mv_spi.c b/board/mv_feroceon/USP/mv_spi.c
index 3d7da78..835d752 100644
--- a/board/mv_feroceon/USP/mv_spi.c
+++ b/board/mv_feroceon/USP/mv_spi.c
@@ -114,8 +114,8 @@
MV_STATUS ret;
MV_U8* pdout = (MV_U8*)dout;
MV_U8* pdin = (MV_U8*)din;
- int tmp_bitlen = bitlen;
#if 0
+ int tmp_bitlen = bitlen;
unsigned int tmpdout, tmpdin;
int tm, isread = 0;
@@ -161,6 +161,7 @@
/* Verify that the SPI mode is in 8bit mode */
MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG(0), MV_SPI_BYTE_LENGTH_MASK);
+#if 0
/* TX/RX in 8bit chanks */
while (tmp_bitlen > 0)
@@ -179,6 +180,19 @@
tmp_bitlen-=8;
}
+#else
+ if (dout && din)
+ ret = mvSpiReadWrite(0, din, dout, (bitlen + 7) / 8);
+ else if (dout)
+ ret = mvSpiWrite(0, dout, (bitlen + 7) / 8);
+ else if (din)
+ ret = mvSpiRead(0, din, (bitlen + 7) / 8);
+ else
+ ret = MV_OK;
+
+ if (ret)
+ return ret;
+#endif
#if 0
}
diff --git a/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvLib.h b/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvLib.h
index d8b74cd..a7e75d7 100644
--- a/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvLib.h
+++ b/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvLib.h
@@ -403,6 +403,7 @@
char boardName[MV_BOARD_NAME_LEN];
MV_VOID (*pBoardEnvInit)(struct _boardInfo *);
MV_VOID (*pBoardEgigaPhyInit)(struct _boardInfo *);
+ MV_VOID (*pBoardPreBootOs)(struct _boardInfo *);
MV_U8 numBoardMppTypeValue;
MV_BOARD_MPP_TYPE_INFO *pBoardMppTypeValue;
MV_U8 numBoardMppConfigValue;
diff --git a/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.c b/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.c
index b86567f..ef83280 100644
--- a/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.c
+++ b/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.c
@@ -64,8 +64,12 @@
#include "mvCommon.h"
#include "mvBoardEnvLib.h"
#include "mvBoardEnvSpec.h"
+#include "cntmr/mvCntmr.h"
#include "eth-phy/mvEthPhy.h"
#include "gpp/mvGpp.h"
+#include "spi_flash.h"
+#include "sys/mvCpuIf.h"
+#include "sysvar.h"
#include "twsi/mvTwsi.h"
/***************************************************************************
@@ -1317,10 +1321,25 @@
}
}
+extern struct spi_flash *flash;
+
+static MV_VOID gflt200BoardPreBootOs(MV_BOARD_INFO *pBoardInfo)
+{
+ spi_flash_lock(flash, SYSVAR_RO_OFFSET0, SYSVAR_BLOCK_SIZE,
+ SPI_FLASH_LOCK_WRITE|SPI_FLASH_LOCK_DOWN);
+ spi_flash_lock(flash, SYSVAR_RO_OFFSET1, SYSVAR_BLOCK_SIZE,
+ SPI_FLASH_LOCK_WRITE|SPI_FLASH_LOCK_DOWN);
+
+ mvCpuIfEnableWatchdogReset();
+ mvCntmrWrite(WATCHDOG, 0xffffffff);
+ mvCntmrEnable(WATCHDOG);
+}
+
MV_BOARD_INFO gflt200Info = {
.boardName = "GFLT200",
.pBoardEnvInit = gflt200BoardEnvInit,
.pBoardEgigaPhyInit = gflt200BoardEgigaPhyInit,
+ .pBoardPreBootOs = gflt200BoardPreBootOs,
.numBoardMppTypeValue = MV_ARRAY_SIZE(gflt200InfoBoardMppTypeInfo),
.pBoardMppTypeValue = gflt200InfoBoardMppTypeInfo,
.intsGppMaskLow = 0,
diff --git a/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.h b/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.h
index 2e1ce59..a237696 100644
--- a/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.h
+++ b/board/mv_feroceon/mv_kw2/kw2_family/boardEnv/mvBoardEnvSpec.h
@@ -523,10 +523,10 @@
#define GFLT200_EVT1_GPP_POL_LOW 0x0
#define GFLT200_EVT1_GPP_POL_MID 0x0
-#define GFLT200_EVT2_GPP_OUT_ENA_LOW (BIT9 | BIT13 | BIT15 | BIT18 | BIT27 | BIT29)
+#define GFLT200_EVT2_GPP_OUT_ENA_LOW (BIT13 | BIT15 | BIT18 | BIT27 | BIT29)
#define GFLT200_EVT2_GPP_OUT_ENA_MID (BIT4)
-#define GFLT200_EVT2_GPP_OUT_VAL_LOW (BIT21 | BIT28)
+#define GFLT200_EVT2_GPP_OUT_VAL_LOW (BIT9 | BIT21 | BIT28)
#define GFLT200_EVT2_GPP_OUT_VAL_MID (BIT5)
#define GFLT200_EVT2_GPP_POL_LOW 0x0
diff --git a/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/mvCtrlEnvSpec.h b/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/mvCtrlEnvSpec.h
index eed78d3..84a6f7c 100644
--- a/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/mvCtrlEnvSpec.h
+++ b/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/mvCtrlEnvSpec.h
@@ -135,7 +135,7 @@
#define MV_GPP_MAX_PINS 96
#define MV_GPP_MAX_GROUP 3
-#define MV_CNTMR_MAX_COUNTER 2
+#define MV_CNTMR_MAX_COUNTER 3
#define MV_UART_MAX_CHAN 2
#define MV_XOR_6510_6530_MAX_UNIT 0
diff --git a/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.c b/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.c
index d9be3f2..7a8fb8d 100644
--- a/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.c
+++ b/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.c
@@ -890,3 +890,18 @@
}
#endif
+
+MV_VOID mvCpuIfEnableWatchdogReset(MV_VOID)
+{
+ MV_U32 val;
+
+ /* clear watchdog timer interrupt */
+ val = MV_REG_READ(CPU_AHB_MBUS_CAUSE_INT_REG);
+ val &= ~CAMCIR_ARM_WD_TIMER_INT_REQ;
+ MV_REG_WRITE(CPU_AHB_MBUS_CAUSE_INT_REG, val);
+
+ /* enable reset upon watchdog timer expiration */
+ val = MV_REG_READ(CPU_RSTOUTN_MASK_REG);
+ val |= CRMR_WD_RST_OUT_MASK;
+ MV_REG_WRITE(CPU_RSTOUTN_MASK_REG, val);
+}
diff --git a/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.h b/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.h
index 0df8f7d..2f2a2fe 100644
--- a/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.h
+++ b/board/mv_feroceon/mv_kw2/kw2_family/ctrlEnv/sys/mvCpuIf.h
@@ -111,6 +111,7 @@
MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
MV_VOID mvCpuIfAddDecShow(MV_VOID);
+MV_VOID mvCpuIfEnableWatchdogReset(MV_VOID);
#ifdef __cplusplus
}
diff --git a/board/mv_feroceon/mv_kw2/mv_main.c b/board/mv_feroceon/mv_kw2/mv_main.c
index 75fb62c..f2dd23b 100644
--- a/board/mv_feroceon/mv_kw2/mv_main.c
+++ b/board/mv_feroceon/mv_kw2/mv_main.c
@@ -1476,3 +1476,11 @@
return pd->boot_mode;
}
#endif /* CONFIG_POST || CONFIG_LOGBUFFER*/
+
+void board_pre_boot_os(void)
+{
+ MV_BOARD_INFO *pBoardInfo = mvBoardInfoGet();
+
+ if (pBoardInfo->pBoardPreBootOs)
+ pBoardInfo->pBoardPreBootOs(pBoardInfo);
+}
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index ea01393..ae835c0 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -166,6 +166,12 @@
}
void arch_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__arch_lmb_reserve")));
+void __board_pre_boot_os(void)
+{
+ /* please define platform specific board_pre_boot_os() */
+}
+void board_pre_boot_os(void) __attribute__((weak, alias("__board_pre_boot_os")));
+
#if defined(__ARM__)
#define IH_INITRD_ARCH IH_ARCH_ARM
#elif defined(__avr32__)
@@ -673,6 +679,8 @@
return 1;
}
+ board_pre_boot_os();
+
boot_fn(0, argc, argv, &images);
show_boot_progress (-9);
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 5d7990b..4c8f542 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -177,6 +177,123 @@
puts("Usage: sf protect on/off\n");
return 1;
}
+
+static int do_spi_flash_lock(int argc, char *argv[])
+{
+ int ret;
+ int lock;
+ char *endp;
+ unsigned long offset;
+
+ if (argc < 2)
+ goto usage;
+
+ offset = simple_strtoul(argv[1], &endp, 0);
+ if (*endp)
+ goto usage;
+
+ if (argc < 3)
+ ret = spi_flash_read_lock(flash, offset, &lock);
+ else {
+ if (!strcmp(argv[2], "off"))
+ lock = SPI_FLASH_LOCK_NONE;
+ else if (!strcmp(argv[2], "on"))
+ lock = SPI_FLASH_LOCK_WRITE;
+ else if (!strcmp(argv[2], "never"))
+ lock = SPI_FLASH_LOCK_DOWN;
+ else if (!strcmp(argv[2], "forever"))
+ lock = SPI_FLASH_LOCK_WRITE|SPI_FLASH_LOCK_DOWN;
+ else
+ goto usage;
+
+ ret = spi_flash_write_lock(flash, offset, lock);
+ }
+
+ if (ret) {
+ printf("SPI flash %s failed, error %d\n", argv[0], ret);
+ return 1;
+ }
+ else if (argc < 3) {
+ switch (lock) {
+ case SPI_FLASH_LOCK_NONE:
+ puts("off\n");
+ break;
+ case SPI_FLASH_LOCK_WRITE:
+ puts("on\n");
+ break;
+ case SPI_FLASH_LOCK_DOWN:
+ puts("never\n");
+ break;
+ case SPI_FLASH_LOCK_WRITE|SPI_FLASH_LOCK_DOWN:
+ puts("forever\n");
+ break;
+ default:
+ printf("? (%x)\n", lock);
+ break;
+ }
+ }
+
+ return 0;
+
+usage:
+ puts("Usage: sf lock offset [mode]\n"
+ " modes:\n"
+ " 'off' - unlocked\n"
+ " 'on' - locked\n"
+ " 'never' - unlock until power cycle\n"
+ " 'forever' - lock until power cycle\n");
+
+ return 1;
+}
+
+static int do_spi_flash_lock_range(int argc, char *argv[])
+{
+ int ret;
+ int lock;
+ char *endp;
+ unsigned long offset;
+ unsigned long len;
+
+ if (argc < 4)
+ goto usage;
+
+ offset = simple_strtoul(argv[1], &endp, 0);
+ if (*endp)
+ goto usage;
+
+ len = simple_strtoul(argv[2], &endp, 0);
+ if (*endp)
+ goto usage;
+
+ if (!strcmp(argv[3], "off"))
+ lock = SPI_FLASH_LOCK_NONE;
+ else if (!strcmp(argv[3], "on"))
+ lock = SPI_FLASH_LOCK_WRITE;
+ else if (!strcmp(argv[3], "never"))
+ lock = SPI_FLASH_LOCK_DOWN;
+ else if (!strcmp(argv[3], "forever"))
+ lock = SPI_FLASH_LOCK_WRITE|SPI_FLASH_LOCK_DOWN;
+ else
+ goto usage;
+
+ ret = spi_flash_lock(flash, offset, len, lock);
+ if (ret) {
+ printf("SPI flash %s failed, error %d\n", argv[0], ret);
+ return 1;
+ }
+
+ return 0;
+
+usage:
+ puts("Usage: sf lock-range offset len mode\n"
+ " modes:\n"
+ " 'off' - unlocked\n"
+ " 'on' - locked\n"
+ " 'never' - unlock until power cycle\n"
+ " 'forever' - lock until power cycle\n");
+
+ return 1;
+}
#endif
static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@@ -205,6 +322,10 @@
#ifdef CONFIG_SPI_FLASH_PROTECTION
if (strcmp(cmd, "protect") == 0)
return do_spi_flash_protect(argc - 1, argv + 1);
+ if (strcmp(cmd, "lock") == 0)
+ return do_spi_flash_lock(argc - 1, argv + 1);
+ if (strcmp(cmd, "lock-range") == 0)
+ return do_spi_flash_lock_range(argc - 1, argv + 1);
#endif
usage:
@@ -225,5 +346,7 @@
#ifdef CONFIG_SPI_FLASH_PROTECTION
"sf protect on - protect spi flash\n"
"sf protect off - unprotect spi flash\n"
+ "sf lock offset [mode] - get sector lock or set to `mode'\n"
+ "sf lock-range offset len mode - set address range lock to `mode'\n"
#endif
);
diff --git a/common/cmd_sysvar.c b/common/cmd_sysvar.c
index 742da73..06e402e 100644
--- a/common/cmd_sysvar.c
+++ b/common/cmd_sysvar.c
@@ -57,6 +57,15 @@
/* check crc32 and wc32 (write count) */
if (check_var(buf, SYSVAR_LOAD_MODE) == SYSVAR_SUCCESS) {
+#ifdef CONFIG_SPI_FLASH_PROTECTION
+ printf("SV: Unprotecting flash\n");
+ ret = spi_flash_protect(sf_dev, 0);
+ if (ret) {
+ printf("## Error: failed to unprotect flash\n");
+ goto recovery_err;
+ }
+#endif
+
/* erase SPI flash */
ret = spi_flash_erase(sf_dev, sysvar_offset[j], buf->data_len);
if (ret) {
@@ -77,6 +86,13 @@
goto recovery_err;
}
+#ifdef CONFIG_SPI_FLASH_PROTECTION
+ printf("SV: Protecting flash\n");
+ ret = spi_flash_protect(sf_dev, 1);
+ if (ret)
+ printf("## Error: failed to protect flash\n");
+#endif
+
buf->loaded = true;
print_msg("Data recovery was completed", SYSVAR_MESSAGE);
return 0;
diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c
index 3f814de..985880a 100644
--- a/drivers/mtd/spi/stmicro.c
+++ b/drivers/mtd/spi/stmicro.c
@@ -46,6 +46,8 @@
#define CMD_M25PXX_DP 0xb9 /* Deep Power-down */
#define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */
#define CMD_M25PXX_EN4BYTEADDR 0xb7 /* Enter 4-byte address mode */
+#define CMD_M25PXX_RDLR 0xe8 /* Read Lock Register */
+#define CMD_M25PXX_WRLR 0xe5 /* Write Lock Register */
#define STM_ID_M25P16 0x15
#define STM_ID_M25P20 0x12
@@ -198,6 +200,29 @@
return -1;
}
+static u8 *stmicro_set_cmd_addr(struct stmicro_spi_flash *stm, u8 *cmd,
+ u32 addr)
+{
+ unsigned long page_addr = addr / stm->params->page_size;
+
+ switch (stm->params->addr_cycles) {
+ case 4:
+ *cmd++ = page_addr >> 16;
+ *cmd++ = page_addr >> 8;
+ *cmd++ = page_addr;
+ *cmd++ = addr % stm->params->page_size;
+ break;
+ case 3:
+ default:
+ *cmd++ = page_addr >> 8;
+ *cmd++ = page_addr;
+ *cmd++ = addr % stm->params->page_size;
+ break;
+ }
+
+ return cmd;
+}
+
static int stmicro_read_fast(struct spi_flash *flash,
u32 offset, size_t len, void *buf)
{
@@ -431,6 +456,88 @@
spi_release_bus(flash->spi);
return ret;
}
+
+static int stmicro_read_lock(struct spi_flash *flash, u32 offset, int *lock)
+{
+ u8 cmd[5];
+ u8 data;
+ int ret;
+ struct stmicro_spi_flash *stm = to_stmicro_spi_flash(flash);
+
+ ret = spi_claim_bus(flash->spi);
+ if (ret)
+ return ret;
+
+ cmd[0] = CMD_M25PXX_RDLR;
+ stmicro_set_cmd_addr(stm, &cmd[1], offset);
+ ret = spi_flash_cmd_read(flash->spi, cmd, 1 + stm->params->addr_cycles,
+ &data, 1);
+ if (ret < 0) {
+ debug("SF: STMicro Read Lock register failed\n");
+ return ret;
+ }
+
+ spi_release_bus(flash->spi);
+ *lock = data;
+
+ return 0;
+}
+
+static int stmicro_write_lock(struct spi_flash *flash, u32 offset, int lock)
+{
+ u8 cmd[5];
+ u8 data = lock;
+ int ret;
+ struct stmicro_spi_flash *stm = to_stmicro_spi_flash(flash);
+
+ ret = spi_claim_bus(flash->spi);
+ if (ret)
+ return ret;
+
+ ret = spi_flash_cmd(flash->spi, CMD_M25PXX_WREN, NULL, 0);
+ if (ret < 0) {
+ debug("SF: Write Enable failed\n");
+ return ret;
+ }
+
+ cmd[0] = CMD_M25PXX_WRLR;
+ stmicro_set_cmd_addr(stm, &cmd[1], offset);
+ ret = spi_flash_cmd_write(flash->spi, cmd, 1 + stm->params->addr_cycles,
+ &data, 1);
+ if (ret < 0) {
+ debug("SF: STMicro Write Lock register failed\n");
+ return ret;
+ }
+
+ spi_release_bus(flash->spi);
+
+ return 0;
+}
+
+static int stmicro_lock(struct spi_flash *flash, u32 offset, size_t len,
+ int lock)
+{
+ int ret;
+ u32 cur;
+ u32 end;
+ u32 sector_size;
+ struct stmicro_spi_flash *stm = to_stmicro_spi_flash(flash);
+
+ sector_size
+ = (u32)stm->params->page_size * stm->params->pages_per_sector;
+ cur = (offset / sector_size) * sector_size;
+ end = offset + len;
+
+ while (cur < end) {
+ ret = stmicro_write_lock(flash, cur, lock);
+ if (ret)
+ return ret;
+
+ cur += sector_size;
+ }
+
+ return 0;
+}
#endif
struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
@@ -466,6 +573,9 @@
stm->flash.read = stmicro_read_fast;
#ifdef CONFIG_SPI_FLASH_PROTECTION
stm->flash.protect = stmicro_protect;
+ stm->flash.read_lock = stmicro_read_lock;
+ stm->flash.write_lock = stmicro_write_lock;
+ stm->flash.lock = stmicro_lock;
#endif
stm->flash.size = params->page_size * params->pages_per_sector
* params->nr_sectors;
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 935ad5d..76ba799 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -23,8 +23,13 @@
#ifndef _SPI_FLASH_H_
#define _SPI_FLASH_H_
+#include <asm/errno.h>
#include <spi.h>
+#define SPI_FLASH_LOCK_NONE 0x00
+#define SPI_FLASH_LOCK_WRITE 0x01 /* disable sector erase/program */
+#define SPI_FLASH_LOCK_DOWN 0x02 /* disable lock modification */
+
struct spi_flash_region {
unsigned int count;
unsigned int size;
@@ -45,6 +50,12 @@
size_t len);
#ifdef CONFIG_SPI_FLASH_PROTECTION
int (*protect)(struct spi_flash *flash, int enable);
+ int (*read_lock)(struct spi_flash *flash, u32 offset,
+ int *lock);
+ int (*write_lock)(struct spi_flash *flash, u32 offset,
+ int lock);
+ int (*lock)(struct spi_flash *flash, u32 offset, size_t len,
+ int lock);
#endif
};
@@ -74,5 +85,32 @@
{
return flash->protect(flash, enable);
}
+
+static inline int spi_flash_read_lock(struct spi_flash *flash, u32 offset,
+ int *lock)
+{
+ if (flash->read_lock)
+ return flash->read_lock(flash, offset, lock);
+
+ return -ENOSYS;
+}
+
+static inline int spi_flash_write_lock(struct spi_flash *flash, u32 offset,
+ int lock)
+{
+ if (flash->write_lock)
+ return flash->write_lock(flash, offset, lock);
+
+ return -ENOSYS;
+}
+
+static inline int spi_flash_lock(struct spi_flash *flash, u32 offset,
+ size_t len, int lock)
+{
+ if (flash->lock)
+ return flash->lock(flash, offset, len, lock);
+
+ return -ENOSYS;
+}
#endif
#endif /* _SPI_FLASH_H_ */