📄 flash_msm.c
字号:
/********************************************************************** * flash_msm.c * * MSM specific flash support * * This file implements MSM specific functions and data used by both * NAND and NOR device drivers * * Copyright (C) 2005-2006 Qualcomm, Inc. * **********************************************************************//*=========================================================================== EDIT HISTORY FOR MODULE This section contains comments describing changes made to the module. Notice that changes are listed in reverse chronological order. $Header: //depot/asic/msm6260/drivers/flash/MSM_FLASH.01.04/flash_msm.c#2 $ $DateTime: 2006/05/29 09:29:30 $ $Author: dhamimp $when who what, where, why-------- --- ----------------------------------------------------------2006-05-26 dp Update base addr offsets to depend on hwio reg files for physical/virtual mapping in L42006-05-17 dp Made OneNAND CS CFG init for tools alone2006-05-04 dp Adding controller abstraction layer2006-02-18 rt Fix the spare_byte_offset determination function2006-02-17 rt Add support for 2K page NAND devices2005-09-26 yug Added some known good default values for cfg registers.2005-08-24 drh Featurize letting PBL set config registers2005-08-03 drh Changes to compile in L4 environment2005-07-30 drh Created from MSM6275===========================================================================*/#include "flash.h"#ifndef FS_UNIT_TEST #include "msm.h"#endif#include "flashi.h"#include "flash_nand.h"#include "flash_nand_msm.h"#include "flash_nor_msm.h"#include "flash_nor_device.h"#include "flash_msg.h"/**************************************************************** * Global Data ***************************************************************//* Only when compiled into DMSS or for NOR boot */#if !defined(BUILD_JNAND) && !defined(BOOT_LOADER) && \ !defined(BUILD_NANDPRG) && !defined(BUILD_BOOT_CHAIN_OEMSBL)/* GLOBAL FOR AMSS & TOOLS */ /* List only flash parts tested by this target */ const fsi_nor_device *(spansion_parts[]) = { &S29WS256N0SB, #ifdef FEATURE_NSRW_FLASH &S71GL064A, #endif NULL }; /* Flash geometric data buffer. The blk_region array field of this structure can be used * for all flash device data structures in the intel_devices_array */ flash_geometry_info flash_geometry_data; word cfi_data[CFI_WORD_SIZE]; /* Probe table for flash that has the AMSS code */ ProbeTbl probe_info_code_flash[] = { { (volatile word *)0x00000000, &spansion_probe }, { (volatile word *) FLASH_PROBE_END, 0 } }; /* Probe table for flash that would have the NOR EFS2 if any */ ProbeTbl probe_info_data_flash[] = { { (volatile word *)0x00000000, &spansion_probe }, { (volatile word *) FLASH_PROBE_END, 0 }}; int probe_info_size = (sizeof(probe_info_data_flash)/sizeof(ProbeTbl))-1;#endif/* Array of probe functions to call for supported NAND controllers * Last entry needs to have NULL function pointers */struct flash_ctlr_probers nand_ctlr_probers_array[] = { {flash_nand_ctlr_a_device_probe, flash_nand_ctlr_a_is_busy}, {flash_onenand_ctlr_a_device_probe, flash_onenand_ctlr_a_is_busy}, {NULL, NULL},};/* Array of probe functions to call for devices via NAND controller * Last entry needs to have NULL function pointers */struct flash_probers nand_probers_array[] = { {toshiba_probe}, {samsung_probe}, NULL,};/* Array of probe functions to call for devices via OneNAND controller * Last entry needs to have NULL function pointers */struct flash_probers onenand_probers_array[] = { {samsung_onenand_probe}, NULL,};/***********************************************************************FUNCTION flash_nand_msm_initDESCRIPTION This function does any MSM specific initializaiton necessary for NAND flash to operate. This function reads the EBI2 CFG register to see if the NAND Controller has control over the supported CS. DEPENDENCIES We assume all CS and CFG register settings for the bus are initialized before we are called here.RETURN VALUE TRUE if the NAND_BUS_EN or NAND2_BUS_EN bits are set**********************************************************************/uint32flash_nand_msm_init(void){ uint32 ebi2_cfg_val = 0; uint32 mask; mask = HWIO_FMSK(EBI2_CFG,NAND_BUS_EN) | HWIO_FMSK(EBI2_CFG,NAND2_BUS_EN); ebi2_cfg_val = HWIO_INM(EBI2_CFG, mask); if (ebi2_cfg_val == 0) { return FALSE; } /* Proceed with trying to detect a NAND device via the NAND controller */ return TRUE;}/***********************************************************************FUNCTION flash_onenand_msm_initDESCRIPTION This function does any MSM specific initializaiton necessary for OneNAND flash to operate.DEPENDENCIES NoneRETURN VALUE TRUE if successful with *baseaddr_ptr set correctly. FALSE if not supported or otherwise**********************************************************************/uint32flash_onenand_msm_init(uint32 *baseaddr_ptr){ uint32 boot_rom_cfg = 0; /* BOOT configuration for OneNAND CS */ uint32 cs = 0; /* Read the e-fuse to decide which chip-select for OneNAND to sit on */ boot_rom_cfg = HWIO_INM(EF_CONFIG_MSB, HWIO_EF_CONFIG_MSB_BOOT_ROM_CFG_BMSK); boot_rom_cfg >>= 0x1C; boot_rom_cfg &= 0x3; /* We only consider the least two bits of boot_rom_cfg */ switch(boot_rom_cfg) { case 0x0: /* CS3 */ *baseaddr_ptr = EBI2_GP3_BASE; cs = 3; break; case 0x1: /* CS2 */ *baseaddr_ptr = EBI2_GP2_BASE; cs = 2; break; case 0x2: /* CS1 */ *baseaddr_ptr = EBI2_GP1_BASE; cs = 1; break; case 0x3: /* CS0 */ *baseaddr_ptr = EBI2_GP0_BASE; cs = 0; break; } TPRINTF(3,("\nfomi: EFUSE base address detected = 0x%x\n", *baseaddr_ptr));#if defined(BUILD_JNAND) || defined(BUILD_NANDPRG) /* * The initialization done below is only for tools and * will be moved to the boot code to intialize them on bootup for AMSS. */ /* Assume always CS3 for test purposes. The following segment of * code will be removed in the final build */ /* Configure EBI2 so the NAND controller does not have control over * the GP0_CS_N pin. */ HWIO_EBI2_CFG_OUT(0x0); HWIO_GPn_CFG0_OUTI(cs, ONENAND_DEFAULT_CFG0_VALUE); /* Set up the GP3_CS_N interface: Write Protect disabled, 16 bit * device. */ HWIO_GPn_CFG1_OUTI(cs, ONENAND_DEFAULT_CFG1_VALUE); /* Enable GPIO36 to access EBI2 CS3 bus */ HWIO_GPIO_PAGE_OUT(0x24); HWIO_GPIO_CFG_OUT(0x4); #endif /* defined(BUILD_JNAND) || defined(BUILD_NANDPRG) */ return TRUE;}/***********************************************************************FUNCTION flash_nand_get_NAND_wait_statesDESCRIPTION This function returns the wait states to use in the config register based on the flash width.DEPENDENCIES Only used when compiled into MJNANDRETURN VALUE None**********************************************************************/uint32flash_nand_get_NAND_wait_states( int width ){ /* Currently both 8 and 16-bit wait states are the same. Do not * remove the if statement because of the future need to possibly * make the wait states different for the two flash widths. */ if (width == FLASHI_NAND_16BIT) { return( 0 << HWIO_SHFT(NAND_FLASH_CFG2, WR_CS_SETUP) | 4 << HWIO_SHFT(NAND_FLASH_CFG2, WR_SETUP) | 2 << HWIO_SHFT(NAND_FLASH_CFG2, WR_HOLD) | 3 << HWIO_SHFT(NAND_FLASH_CFG2, RD_SETUP) | 3 << HWIO_SHFT(NAND_FLASH_CFG2, RD_HOLD) | 3 << HWIO_SHFT(NAND_FLASH_CFG2, ID_RD_HOLD) ); } else { return( 0 << HWIO_SHFT(NAND_FLASH_CFG2, WR_CS_SETUP) | 4 << HWIO_SHFT(NAND_FLASH_CFG2, WR_SETUP) | 2 << HWIO_SHFT(NAND_FLASH_CFG2, WR_HOLD) | 3 << HWIO_SHFT(NAND_FLASH_CFG2, RD_SETUP) | 3 << HWIO_SHFT(NAND_FLASH_CFG2, RD_HOLD) | 3 << HWIO_SHFT(NAND_FLASH_CFG2, ID_RD_HOLD) ); }}#if !defined(BUILD_JNAND) && !defined(BOOT_LOADER) && \ !defined(BUILD_NANDPRG) && !defined(BUILD_BOOT_CHAIN_OEMSBL)/***********************************************************************FUNCTION flash_nor_msm_initDESCRIPTION This function does any MSM specific initializaiton necessary for NAND flash to operateDEPENDENCIES NoneRETURN VALUE None**********************************************************************/voidflash_nor_msm_init(void){}/*===========================================================================FUNCTION FLASH_GEOMETRY_INITDESCRIPTION Execute the CFI query command to read out block layout and fill corresponding flash fsi_nor_device structure.DEPENDENCIES Must be done before any operations are carried out on the flash hardware. RETURN VALUE FLASH_SUCCESS - Success FLASH_FAILURE - An error occurred.SIDE EFFECTS None===========================================================================*/flash_statusflash_geometry_init (fsi_nor_device *nor_device, flash_ptr_type baseaddr){ volatile word *cfi_data_ptr = (volatile word *)(cfi_data + 0x2DL); word saved_int; word count; /* Fill the fsi_device_info structure appropriately */ if (nor_device->flash_geometry == INIT_USING_CFI_AT_RUNTIME) { /* Perform the ARM specific probe without interrupt */ INTLOCK_SAV (saved_int); flash_read_cfi(baseaddr, &flash_geometry_data, cfi_data); INTFREE_SAV (saved_int); /* Verify device is CFI compliant */ if ( ((inp(cfi_data + 0x10L) != 'Q')) || ((inp(cfi_data + 0x11L) != 'R')) || ((inp(cfi_data + 0x12L) != 'Y')) ) { return FLASH_FAILURE; } /* Fill the flash geometric data */ flash_geometry_data.device_size = inp (cfi_data + 0x27L); flash_geometry_data.x_iface = inpw(cfi_data + 0x28L); flash_geometry_data.write_buf_size = inpw(cfi_data + 0x2AL); flash_geometry_data.num_erase_blk_region = inp (cfi_data + 0x2CL); for (count = 0; count < flash_geometry_data.num_erase_blk_region; count ++) { flash_geometry_data.blk_regions[count].numblocks = (inp(cfi_data_ptr + 0x0) | (inp(cfi_data_ptr + 0x1) << 8)) + 1; flash_geometry_data.blk_regions[count].blocksize_bytes = (inp(cfi_data_ptr + 0x2) | (inp(cfi_data_ptr + 0x3) << 8)) * 256; cfi_data_ptr += 0x4; } nor_device->flash_geometry= &flash_geometry_data; } return FLASH_SUCCESS; }#endif#ifndef FEATURE_IG_DPRGS/* Stub for function not used in NON DMSS */#if defined(BUILD_JNAND) || defined(BOOT_LOADER) || defined(BUILD_NANDPRG)dwordrex_int_lock(void){ return 0;}dword rex_int_free(void){ return 0;}#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -