summaryrefslogtreecommitdiffstats
path: root/shared/opensource/flash/flash_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/opensource/flash/flash_api.c')
-rwxr-xr-xshared/opensource/flash/flash_api.c350
1 files changed, 350 insertions, 0 deletions
diff --git a/shared/opensource/flash/flash_api.c b/shared/opensource/flash/flash_api.c
new file mode 100755
index 0000000..5b0ca76
--- /dev/null
+++ b/shared/opensource/flash/flash_api.c
@@ -0,0 +1,350 @@
+/*
+ Copyright 2000-2010 Broadcom Corporation
+
+ Unless you and Broadcom execute a separate written software license
+ agreement governing use of this software, this software is licensed
+ to you under the terms of the GNU General Public License version 2
+ (the “GPL?, available at http://www.broadcom.com/licenses/GPLv2.php,
+ with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and to
+ copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+ Notwithstanding the above, under no circumstances may you combine this
+ software in any way with any other Broadcom software provided under a
+ license other than the GPL, without Broadcom's express prior written
+ consent.
+*/
+
+/***************************************************************************
+ * File Name : flash_api.c
+ *
+ * Description: This file contains the implementation of the wrapper functions
+ * for the flash device interface.
+ ***************************************************************************/
+
+/** Includes. */
+#ifdef _CFE_
+#include "lib_types.h"
+#include "lib_printf.h"
+#include "lib_string.h"
+#include "bcm_map.h"
+#define printk printf
+#else // Linux
+#include <linux/kernel.h>
+#include "bcm_map_part.h"
+#endif
+
+#include "bcmtypes.h"
+#include "bcm_hwdefs.h"
+#include "flash_api.h"
+
+/** Externs. **/
+#if !defined(INC_CFI_FLASH_DRIVER)
+#define INC_CFI_FLASH_DRIVER 0
+#endif
+
+#if !defined(INC_SPI_FLASH_DRIVER)
+#define INC_SPI_FLASH_DRIVER 0
+#endif
+
+#if !defined(INC_NAND_FLASH_DRIVER)
+#define INC_NAND_FLASH_DRIVER 0
+#endif
+
+#if !defined(INC_SPI_PROG_NAND)
+#define INC_SPI_PROG_NAND 0
+#endif
+
+#if (INC_CFI_FLASH_DRIVER==1)
+extern int cfi_flash_init(flash_device_info_t **flash_info);
+#else
+#define cfi_flash_init(x) FLASH_API_ERROR
+#endif
+
+#if (INC_SPI_FLASH_DRIVER==1)
+extern int spi_flash_init(flash_device_info_t **flash_info);
+#else
+#define spi_flash_init(x) FLASH_API_ERROR
+#endif
+
+#if (INC_NAND_FLASH_DRIVER==1) || (INC_SPI_PROG_NAND==1)
+extern int nand_flash_init(flash_device_info_t **flash_info);
+#else
+#define nand_flash_init(x) FLASH_API_ERROR
+#endif
+
+/** Variables. **/
+static flash_device_info_t *g_flash_info = NULL;
+#if (INC_SPI_PROG_NAND==1)
+static flash_device_info_t *g_nand_flash_info = NULL;
+static flash_device_info_t *g_spi_flash_info = NULL;
+#endif
+
+/***************************************************************************
+ * Function Name: display_flash_info
+ * Description : Displays information about the flash part.
+ * Returns : None.
+ ***************************************************************************/
+static void display_flash_info(int ret, flash_device_info_t *flash_info)
+{
+ switch (flash_info->flash_type) {
+ case FLASH_IFC_PARALLEL:
+ printk( "Parallel flash device");
+ break;
+
+ case FLASH_IFC_SPI:
+ printk( "Serial flash device");
+ break;
+
+ case FLASH_IFC_HS_SPI:
+ printk( "HS Serial flash device");
+ break;
+
+ case FLASH_IFC_NAND:
+ printk( "NAND flash device");
+ break;
+ }
+
+ if( ret == FLASH_API_OK ) {
+ printk(": name %s, id 0x%4.4x",
+ flash_info->flash_device_name, flash_info->flash_device_id);
+#if (INC_SPI_PROG_NAND==1)
+ printk(" block %dKB", flash_info->fn_flash_get_sector_size(0) / 1024);
+ printk(" size %dKB", (*flash_info->fn_flash_get_total_size) () / 1024);
+#else
+ if (flash_info->flash_type == FLASH_IFC_NAND)
+ printk(" block %dKB", flash_get_sector_size(0) / 1024);
+ printk(" size %dKB", flash_get_total_size() / 1024);
+#endif
+ printk("\n");
+ }
+ else {
+ printk( " id %4.4x is not supported.\n", flash_info->flash_device_id );
+ }
+} /* display_flash_info */
+
+/***************************************************************************
+ * Function Name: flash_init
+ * Description : Initialize flash part.
+ * Returns : FLASH_API_OK or FLASH_API_ERROR
+ ***************************************************************************/
+int flash_init(void)
+{
+ int type = FLASH_IFC_UNKNOWN;
+ int ret = FLASH_API_ERROR;
+#if (INC_SPI_PROG_NAND==1)
+ int ret_nand = FLASH_API_ERROR;
+#endif
+
+ /* If available, use bootstrap to decide which flash to use */
+#if defined(_BCM96816_) || defined(CONFIG_BCM96816) || defined(_BCM96368_) || defined(CONFIG_BCM96368)
+ unsigned int bootsel;
+#if defined(_BCM96816_) || defined(CONFIG_BCM96816)
+ bootsel = MISC->miscStrapBus;
+#elif defined(_BCM96368_) || defined(CONFIG_BCM96368)
+ bootsel = GPIO->StrapBus;
+#endif
+ switch ((bootsel & MISC_STRAP_BUS_BOOT_SEL_MASK)>>MISC_STRAP_BUS_BOOT_SEL_SHIFT) {
+ case MISC_STRAP_BUS_BOOT_PARALLEL:
+ type = FLASH_IFC_PARALLEL;
+ break;
+
+ case MISC_STRAP_BUS_BOOT_SERIAL:
+ type = FLASH_IFC_SPI;
+ break;
+
+ case MISC_STRAP_BUS_BOOT_NAND:
+ type = FLASH_IFC_NAND;
+ break;
+
+ }
+#elif defined(_BCM96362_) || defined(CONFIG_BCM96362) || defined(_BCM96328_) || defined(CONFIG_BCM96328)
+ if( ((MISC->miscStrapBus & MISC_STRAP_BUS_BOOT_SEL_MASK) >>
+ MISC_STRAP_BUS_BOOT_SEL_SHIFT) == MISC_STRAP_BUS_BOOT_SERIAL )
+ type = FLASH_IFC_SPI;
+ else
+ type = FLASH_IFC_NAND;
+#endif
+
+ switch (type) {
+ case FLASH_IFC_PARALLEL:
+ ret = cfi_flash_init( &g_flash_info );
+ break;
+
+ case FLASH_IFC_SPI:
+ ret = spi_flash_init( &g_flash_info );
+#if (INC_SPI_PROG_NAND==1)
+ ret_nand = nand_flash_init( &g_nand_flash_info );
+#endif
+
+ break;
+
+ case FLASH_IFC_NAND:
+ ret = nand_flash_init( &g_flash_info );
+ break;
+
+ case FLASH_IFC_UNKNOWN:
+ /* Try to detect flash chips, give priority to parallel flash */
+ /* Our reference design has both, and we usually use parallel. */
+ ret = cfi_flash_init( &g_flash_info );
+ if (ret != FLASH_API_OK) {
+ ret = spi_flash_init( &g_flash_info );
+ }
+ break;
+ }
+
+ if (g_flash_info != NULL) {
+ display_flash_info(ret, g_flash_info);
+#if (INC_SPI_PROG_NAND==1)
+ display_flash_info(ret_nand, g_nand_flash_info );
+#endif
+ }
+ else {
+ printk( "BCM Flash API. Flash device is not found.\n" );
+ }
+
+ return( ret );
+} /* flash_init */
+
+/***************************************************************************
+ * Function Name: flash_sector_erase_int
+ * Description : Erase the specfied flash sector.
+ * Returns : FLASH_API_OK or FLASH_API_ERROR
+ ***************************************************************************/
+int flash_sector_erase_int(unsigned short sector)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_sector_erase_int) (sector)
+ : FLASH_API_ERROR );
+} /* flash_sector_erase_int */
+
+/***************************************************************************
+ * Function Name: flash_read_buf
+ * Description : Reads from flash memory.
+ * Returns : number of bytes read or FLASH_API_ERROR
+ ***************************************************************************/
+int flash_read_buf(unsigned short sector, int offset, unsigned char *buffer,
+ int numbytes)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_read_buf) (sector, offset, buffer, numbytes)
+ : FLASH_API_ERROR );
+} /* flash_read_buf */
+
+/***************************************************************************
+ * Function Name: flash_write_buf
+ * Description : Writes to flash memory.
+ * Returns : number of bytes written or FLASH_API_ERROR
+ ***************************************************************************/
+int flash_write_buf(unsigned short sector, int offset, unsigned char *buffer,
+ int numbytes)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_write_buf) (sector, offset, buffer, numbytes)
+ : FLASH_API_ERROR );
+} /* flash_write_buf */
+
+/***************************************************************************
+ * Function Name: flash_get_numsectors
+ * Description : Returns the number of sectors in the flash device.
+ * Returns : Number of sectors in the flash device.
+ ***************************************************************************/
+int flash_get_numsectors(void)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_get_numsectors) ()
+ : FLASH_API_ERROR );
+} /* flash_get_numsectors */
+
+/***************************************************************************
+ * Function Name: flash_get_sector_size
+ * Description : Returns the number of bytes in the specfied flash sector.
+ * Returns : Number of bytes in the specfied flash sector.
+ ***************************************************************************/
+int flash_get_sector_size(unsigned short sector)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_get_sector_size) (sector)
+ : FLASH_API_ERROR );
+} /* flash_get_sector_size */
+
+/***************************************************************************
+ * Function Name: flash_get_memptr
+ * Description : Returns the base MIPS memory address for the specfied flash
+ * sector.
+ * Returns : Base MIPS memory address for the specfied flash sector.
+ ***************************************************************************/
+unsigned char *flash_get_memptr(unsigned short sector)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_get_memptr) (sector)
+ : NULL );
+} /* flash_get_memptr */
+
+/***************************************************************************
+ * Function Name: flash_get_blk
+ * Description : Returns the flash sector for the specfied MIPS address.
+ * Returns : Flash sector for the specfied MIPS address.
+ ***************************************************************************/
+int flash_get_blk(int addr)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_get_blk) (addr)
+ : FLASH_API_ERROR );
+} /* flash_get_blk */
+
+/***************************************************************************
+ * Function Name: flash_get_total_size
+ * Description : Returns the number of bytes in the flash device.
+ * Returns : Number of bytes in the flash device.
+ ***************************************************************************/
+int flash_get_total_size(void)
+{
+ return( (g_flash_info)
+ ? (*g_flash_info->fn_flash_get_total_size) ()
+ : FLASH_API_ERROR );
+} /* flash_get_total_size */
+
+/***************************************************************************
+ * Function Name: flash_get_flash_type
+ * Description : Returns type of the flash memory.
+ * Returns : Type of the flash memory.
+ ***************************************************************************/
+int flash_get_flash_type(void)
+{
+ return( (g_flash_info)
+ ? (g_flash_info->flash_type)
+ : FLASH_API_ERROR );
+} /* flash_get_flash_type */
+
+#if (INC_SPI_PROG_NAND==1)
+/***************************************************************************
+ * Function Name: flash_change_flash_type
+ * Description : change type of the flash memory.
+ * Returns : none
+ ***************************************************************************/
+void flash_change_flash_type(int type)
+{
+
+ if (type == FLASH_IFC_NAND)
+ {
+ if (g_spi_flash_info == NULL)
+ g_spi_flash_info = g_flash_info;
+ g_flash_info = g_nand_flash_info;
+ }
+ else
+ {
+ if (g_spi_flash_info != NULL)
+ g_flash_info = g_spi_flash_info;
+ }
+} /* flash_change_flash_type */
+
+#endif
+