From 0974846c2d2eb506d1443ee338aad4400f59bc70 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 5 Feb 2015 19:03:14 +0100 Subject: [PATCH] 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. --- board.h | 1 + davinci.c | 10 +++++++++- davinci.h | 2 +- nand.c | 13 +++++++++++++ nand.h | 2 ++ uart.h | 2 +- uartboot.c | 5 ++++- ubl.c | 7 ++++--- 8 files changed, 35 insertions(+), 7 deletions(-) diff --git a/board.h b/board.h index 7f2ad8d..d7f896c 100644 --- a/board.h +++ b/board.h @@ -40,6 +40,7 @@ #if defined(board_sysmobts_v2) # define PINMUX0_DEFAULT 0x0000000F # define PINMUX1_DEFAULT PINMUX1_UART0 | PINMUX1_UART1 +# define NAND_nWP_GPIO 33 #endif #endif /* _BOARD_H_ */ diff --git a/davinci.c b/davinci.c index c5e737f..f19f5f1 100644 --- a/davinci.c +++ b/davinci.c @@ -566,13 +566,15 @@ psc_init(void) } int -davinci_platform_init(char *version) +davinci_platform_init(char *version, int *nwp_nand) { int pllCfg; int ddrCfg; int status = E_PASS; unsigned *gpio01 = (unsigned *)(DAVINCI_GPIO_BASE + 0x20); + *nwp_nand = 0; + psc_init(); /* Disable ARM interrupts */ @@ -609,6 +611,12 @@ davinci_platform_init(char *version) char boardCfg; boardCfg = (*gpio01 >> 10) & 0x001F; boardVer = (*gpio01 >> 15) & 0x0007; + if (boardVer == 5) + { + uart_send_str_lf("Board needs GPIO for nWP"); + *nwp_nand = 1; + } + if ( boardVer > 1 ) { /* Davinci @ 405/810 MHz */ diff --git a/davinci.h b/davinci.h index 07908a3..2529229 100644 --- a/davinci.h +++ b/davinci.h @@ -454,7 +454,7 @@ struct gpio_controller { #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 timer0_start(uint32_t period); diff --git a/nand.c b/nand.c index 3fa5254..dfde5ab 100644 --- a/nand.c +++ b/nand.c @@ -25,6 +25,7 @@ #include "davinci.h" #include "util.h" #include "uart.h" +#include "gpio.h" #include "nand.h" /* BUS width defines */ @@ -1083,3 +1084,15 @@ nand_get_bytes_per_block(void) { 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; +} diff --git a/nand.h b/nand.h index b264f9e..68d45c0 100644 --- a/nand.h +++ b/nand.h @@ -68,4 +68,6 @@ int nand_get_bytes_per_page(void); int nand_get_bytes_per_block(void); +int nand_remove_nwp(int need_nwp_nand); + #endif /* _NAND_H_ */ diff --git a/uart.h b/uart.h index 2085af1..c4684d7 100644 --- a/uart.h +++ b/uart.h @@ -34,7 +34,7 @@ struct uart_ack_header_t { 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_str(char *string); diff --git a/uartboot.c b/uartboot.c index 034dc63..b512e7e 100644 --- a/uartboot.c +++ b/uartboot.c @@ -83,7 +83,7 @@ error: } void -uart_boot(uint32_t *jump_entry_point) +uart_boot(uint32_t *jump_entry_point, int need_nwp_nand) { #if defined(FLASH_TYPE_NAND) int wrote_copies = 0; @@ -131,6 +131,7 @@ uart_boot(uint32_t *jump_entry_point) NOR_WriteBytes(nor_get_flashbase(), uart_ack_header.size, (uint32_t) uart_ack_header.recv_buffer); #elif defined(FLASH_TYPE_NAND) + nand_remove_nwp(need_nwp_nand); wrote_copies = 0; for (block_num = START_UBL_BLOCK_NUM; block_num <= END_UBL_BLOCK_NUM; block_num++) { im_desc.magic = uart_ack_header.magic; @@ -199,6 +200,7 @@ uart_boot(uint32_t *jump_entry_point) goto uartboot_error; #elif defined(FLASH_TYPE_NAND) /* Write multiple copy of U-Boot (depending on the defines in NAND.h) */ + nand_remove_nwp(need_nwp_nand); prog_ok = 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) { @@ -256,6 +258,7 @@ uart_boot(uint32_t *jump_entry_point) goto uartboot_error; } #elif defined(FLASH_TYPE_NAND) + nand_remove_nwp(need_nwp_nand); if (nand_erase_all() != E_PASS) { log_info("Erase failed"); goto uartboot_error; diff --git a/ubl.c b/ubl.c index 3cdf4da..a54e46f 100644 --- a/ubl.c +++ b/ubl.c @@ -34,6 +34,7 @@ #define C1_IC (1 << 12) /* icache off/on */ static uint32_t jump_entry_point; +static int need_nwp_nand; enum bootmode_t bootmode; @@ -101,7 +102,7 @@ interrupt_me(void) return; log_info("Boot interrupted"); - uart_boot(&jump_entry_point); + uart_boot(&jump_entry_point, need_nwp_nand); } #else static void @@ -122,7 +123,7 @@ ubl_main(void) if (bootmode == NON_SECURE_UART) 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) goto error; @@ -169,7 +170,7 @@ ubl_main(void) break; default: UARTBOOT: - uart_boot(&jump_entry_point); + uart_boot(&jump_entry_point, need_nwp_nand); break; }