sysmobts: Be able to toggle the nWP on the flash through a GPIO

Starting from revision F we can toggle a GPIO to control nWP of
the NAND chip. This means that during power-on or other mode of
operation no changes can be done to the flash.

Remove the nWP before we try to write to the flash in the UART
mode. Leave it enabled for further operations.
This commit is contained in:
Holger Hans Peter Freyther 2015-02-05 19:03:14 +01:00
parent 92b4a3a288
commit 0974846c2d
8 changed files with 35 additions and 7 deletions

View File

@ -40,6 +40,7 @@
#if defined(board_sysmobts_v2) #if defined(board_sysmobts_v2)
# define PINMUX0_DEFAULT 0x0000000F # define PINMUX0_DEFAULT 0x0000000F
# define PINMUX1_DEFAULT PINMUX1_UART0 | PINMUX1_UART1 # define PINMUX1_DEFAULT PINMUX1_UART0 | PINMUX1_UART1
# define NAND_nWP_GPIO 33
#endif #endif
#endif /* _BOARD_H_ */ #endif /* _BOARD_H_ */

View File

@ -566,13 +566,15 @@ psc_init(void)
} }
int int
davinci_platform_init(char *version) davinci_platform_init(char *version, int *nwp_nand)
{ {
int pllCfg; int pllCfg;
int ddrCfg; int ddrCfg;
int status = E_PASS; int status = E_PASS;
unsigned *gpio01 = (unsigned *)(DAVINCI_GPIO_BASE + 0x20); unsigned *gpio01 = (unsigned *)(DAVINCI_GPIO_BASE + 0x20);
*nwp_nand = 0;
psc_init(); psc_init();
/* Disable ARM interrupts */ /* Disable ARM interrupts */
@ -609,6 +611,12 @@ davinci_platform_init(char *version)
char boardCfg; char boardCfg;
boardCfg = (*gpio01 >> 10) & 0x001F; boardCfg = (*gpio01 >> 10) & 0x001F;
boardVer = (*gpio01 >> 15) & 0x0007; boardVer = (*gpio01 >> 15) & 0x0007;
if (boardVer == 5)
{
uart_send_str_lf("Board needs GPIO for nWP");
*nwp_nand = 1;
}
if ( boardVer > 1 ) if ( boardVer > 1 )
{ {
/* Davinci @ 405/810 MHz */ /* Davinci @ 405/810 MHz */

View File

@ -454,7 +454,7 @@ struct gpio_controller {
#define GPIOC ((volatile struct gpio_controller *) DAVINCI_GPIO_BASE) #define GPIOC ((volatile struct gpio_controller *) DAVINCI_GPIO_BASE)
int davinci_platform_init(char *version); int davinci_platform_init(char *version, int *nwp_nand);
void ddr_vtp_calibration(void); void ddr_vtp_calibration(void);
void timer0_start(uint32_t period); void timer0_start(uint32_t period);

13
nand.c
View File

@ -25,6 +25,7 @@
#include "davinci.h" #include "davinci.h"
#include "util.h" #include "util.h"
#include "uart.h" #include "uart.h"
#include "gpio.h"
#include "nand.h" #include "nand.h"
/* BUS width defines */ /* BUS width defines */
@ -1083,3 +1084,15 @@ nand_get_bytes_per_block(void)
{ {
return nand_info.pages_per_block * nand_info.bytes_per_page; return nand_info.pages_per_block * nand_info.bytes_per_page;
} }
int
nand_remove_nwp(int need_gpio)
{
#ifdef NAND_nWP_GPIO
if (need_gpio) {
gpio_direction_out(NAND_nWP_GPIO, 1);
waitloop(50);
}
#endif
return 0;
}

2
nand.h
View File

@ -68,4 +68,6 @@ int nand_get_bytes_per_page(void);
int nand_get_bytes_per_block(void); int nand_get_bytes_per_block(void);
int nand_remove_nwp(int need_nwp_nand);
#endif /* _NAND_H_ */ #endif /* _NAND_H_ */

2
uart.h
View File

@ -34,7 +34,7 @@ struct uart_ack_header_t {
uint8_t *inflate_dstbuf; uint8_t *inflate_dstbuf;
}; };
void uart_boot(uint32_t *jump_entry_point); void uart_boot(uint32_t *jump_entry_point, int need_npw_gpio);
void uart_send_lf(void); void uart_send_lf(void);
void uart_send_str(char *string); void uart_send_str(char *string);

View File

@ -83,7 +83,7 @@ error:
} }
void void
uart_boot(uint32_t *jump_entry_point) uart_boot(uint32_t *jump_entry_point, int need_nwp_nand)
{ {
#if defined(FLASH_TYPE_NAND) #if defined(FLASH_TYPE_NAND)
int wrote_copies = 0; int wrote_copies = 0;
@ -131,6 +131,7 @@ uart_boot(uint32_t *jump_entry_point)
NOR_WriteBytes(nor_get_flashbase(), uart_ack_header.size, NOR_WriteBytes(nor_get_flashbase(), uart_ack_header.size,
(uint32_t) uart_ack_header.recv_buffer); (uint32_t) uart_ack_header.recv_buffer);
#elif defined(FLASH_TYPE_NAND) #elif defined(FLASH_TYPE_NAND)
nand_remove_nwp(need_nwp_nand);
wrote_copies = 0; wrote_copies = 0;
for (block_num = START_UBL_BLOCK_NUM; block_num <= END_UBL_BLOCK_NUM; block_num++) { for (block_num = START_UBL_BLOCK_NUM; block_num <= END_UBL_BLOCK_NUM; block_num++) {
im_desc.magic = uart_ack_header.magic; im_desc.magic = uart_ack_header.magic;
@ -199,6 +200,7 @@ uart_boot(uint32_t *jump_entry_point)
goto uartboot_error; goto uartboot_error;
#elif defined(FLASH_TYPE_NAND) #elif defined(FLASH_TYPE_NAND)
/* Write multiple copy of U-Boot (depending on the defines in NAND.h) */ /* Write multiple copy of U-Boot (depending on the defines in NAND.h) */
nand_remove_nwp(need_nwp_nand);
prog_ok = 0; prog_ok = 0;
wrote_copies = 0; wrote_copies = 0;
for (block_num = START_UBOOT_BLOCK_NUM; (block_num+MAX_BLOCK_PER_UBOOT-1) <= END_UBOOT_BLOCK_NUM; block_num += MAX_BLOCK_PER_UBOOT) { for (block_num = START_UBOOT_BLOCK_NUM; (block_num+MAX_BLOCK_PER_UBOOT-1) <= END_UBOOT_BLOCK_NUM; block_num += MAX_BLOCK_PER_UBOOT) {
@ -256,6 +258,7 @@ uart_boot(uint32_t *jump_entry_point)
goto uartboot_error; goto uartboot_error;
} }
#elif defined(FLASH_TYPE_NAND) #elif defined(FLASH_TYPE_NAND)
nand_remove_nwp(need_nwp_nand);
if (nand_erase_all() != E_PASS) { if (nand_erase_all() != E_PASS) {
log_info("Erase failed"); log_info("Erase failed");
goto uartboot_error; goto uartboot_error;

7
ubl.c
View File

@ -34,6 +34,7 @@
#define C1_IC (1 << 12) /* icache off/on */ #define C1_IC (1 << 12) /* icache off/on */
static uint32_t jump_entry_point; static uint32_t jump_entry_point;
static int need_nwp_nand;
enum bootmode_t bootmode; enum bootmode_t bootmode;
@ -101,7 +102,7 @@ interrupt_me(void)
return; return;
log_info("Boot interrupted"); log_info("Boot interrupted");
uart_boot(&jump_entry_point); uart_boot(&jump_entry_point, need_nwp_nand);
} }
#else #else
static void static void
@ -122,7 +123,7 @@ ubl_main(void)
if (bootmode == NON_SECURE_UART) if (bootmode == NON_SECURE_UART)
while ((UART0->LSR & 0x40) == 0); while ((UART0->LSR & 0x40) == 0);
status = davinci_platform_init(UBL_VERSION_STR); status = davinci_platform_init(UBL_VERSION_STR, &need_nwp_nand);
if (status != E_PASS) if (status != E_PASS)
goto error; goto error;
@ -169,7 +170,7 @@ ubl_main(void)
break; break;
default: default:
UARTBOOT: UARTBOOT:
uart_boot(&jump_entry_point); uart_boot(&jump_entry_point, need_nwp_nand);
break; break;
} }