first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,723 @@
|
||||
// Copyright (C) 2008-2009 Apple, Inc. All rights reserved.
|
||||
//
|
||||
// This document is the property of Apple, Inc.
|
||||
// It is considered confidential and proprietary.
|
||||
//
|
||||
// This document may not be reproduced or transmitted in any form,
|
||||
// in whole or in part, without the express written permission of
|
||||
// Apple, Inc.
|
||||
//
|
||||
|
||||
#include "WMRFeatures.h"
|
||||
#if WMR_BUILDING_IBOOT
|
||||
#include "nandid.h"
|
||||
#include <drivers/nand_device_tree.h>
|
||||
#include <target/nand_spec_tables.h>
|
||||
#include <sys.h>
|
||||
#include <debug.h>
|
||||
#else
|
||||
#include "NandSpec.h"
|
||||
#include "NandSpecTables.h"
|
||||
#endif
|
||||
|
||||
#include "WMROAM.h"
|
||||
#include "FIL.h"
|
||||
|
||||
// =============================================================================
|
||||
// Preprocessor Definitions
|
||||
|
||||
#define WITH_NAND_DT_CONFIG (WITH_NAND_FILESYSTEM && WITH_DEVICETREE)
|
||||
|
||||
// =============================================================================
|
||||
// Extern global variables
|
||||
|
||||
// =============================================================================
|
||||
// Private Function Declarations
|
||||
|
||||
static BOOL32 isSameChipId(const NandChipId chipId1, const NandChipId chipId2);
|
||||
static BOOL32 isSameConfigId(const NandConfigId* configId1, const NandConfigId* configId2);
|
||||
|
||||
static const NandGeometry* lookupNandGeometry(const NandChipId chipId);
|
||||
static const NandTiming* lookupNandTiming(const NandConfigId* configId);
|
||||
static const NandBoardSupport* lookupBoardSupport(const NandConfigId* configId);
|
||||
static BOOL32 isValidChipId(const NandChipId chipId);
|
||||
static BOOL32 getChipIdAndTotalCECountAndCEMap(const NandChipId* chipIds, NandChipId* foundChipId, UInt32* totalCECount, UInt32* ceMap);
|
||||
static BOOL32 areChipIdsIdentical(const NandChipId* chipIds, NandChipId* chipId);
|
||||
static UInt32 setBitCount(UInt32 x);
|
||||
static BOOL32 checkCESymmetryAndGetPackageCnt(NandLandingMap *landingMap, UInt32 ceMap, UInt8* pkgCnt);
|
||||
|
||||
// =============================================================================
|
||||
// Private Global Variables
|
||||
#if WITH_NAND_DT_CONFIG
|
||||
static NandInfo currentNandInfo;
|
||||
static UInt32 currentCECount = 0;
|
||||
static UInt32 currentCEBitmap = 0;
|
||||
static UInt32 currentActiveDataBus = 0;
|
||||
#endif //WITH_NAND_DT_CONFIG
|
||||
static UInt32 currentCorrectableBits = 0;
|
||||
static UInt32 currentRefreshThreshold = 0;
|
||||
static BOOL32 ppnDevice = FALSE32;
|
||||
static BOOL32 toggleDevice = FALSE32;
|
||||
static BOOL32 _retire_on_invalid_refresh;
|
||||
static void *_ppn_feature_list = NULL;
|
||||
static UInt32 _ppn_feature_size = 0;
|
||||
static void *_dbg_chipids_list = NULL;
|
||||
static UInt32 _dbg_chipids_size = 0;
|
||||
|
||||
static UInt32 _dqsHalfCycleClocks;
|
||||
static UInt32 _ceSetupClocks;
|
||||
static UInt32 _ceHoldClocks;
|
||||
static UInt32 _ADLClocks;
|
||||
static UInt32 _WHRClocks;
|
||||
|
||||
static UInt32 _readPreClocks;
|
||||
static UInt32 _readPostClocks;
|
||||
static UInt32 _writePreClocks;
|
||||
static UInt32 _writePostClocks;
|
||||
|
||||
static UInt32 _readSetupClocks;
|
||||
static UInt32 _readHoldClocks;
|
||||
static UInt32 _readDccycleClocks;
|
||||
static UInt32 _writeSetupClocks;
|
||||
static UInt32 _writeHoldClocks;
|
||||
|
||||
static UInt32 _regDQSTimingCtrl;
|
||||
|
||||
// =============================================================================
|
||||
// Local constants
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Private Function Definitions
|
||||
|
||||
// compare the contents of a buffer to the given value, repeated
|
||||
static BOOL32 comparePattern(const UInt8 *buffer, UInt8 value, UInt32 length)
|
||||
{
|
||||
UInt32 idx;
|
||||
|
||||
for (idx = 0; idx < length; ++idx)
|
||||
{
|
||||
if (buffer[idx] != value)
|
||||
{
|
||||
return FALSE32;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return TRUE32;
|
||||
}
|
||||
|
||||
static BOOL32 isSameChipId(const NandChipId chipId1,
|
||||
const NandChipId chipId2)
|
||||
{
|
||||
UInt32 idx;
|
||||
// Treat 0x00 as dont-care
|
||||
for (idx = 0; idx < COMPARE_NAND_CHIP_ID_SIZE; ++idx)
|
||||
{
|
||||
if (chipId1[idx] && chipId2[idx] && (chipId1[idx] != chipId2[idx]))
|
||||
{
|
||||
return FALSE32;
|
||||
}
|
||||
}
|
||||
return TRUE32;
|
||||
}
|
||||
|
||||
static BOOL32 isSameConfigId(const NandConfigId* configId1,
|
||||
const NandConfigId* configId2)
|
||||
{
|
||||
if (0 == WMR_MEMCMP(configId1, configId2, sizeof(NandConfigId)))
|
||||
{
|
||||
return TRUE32;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE32;
|
||||
}
|
||||
}
|
||||
|
||||
static const NandGeometry* lookupNandGeometry(const NandChipId chipId)
|
||||
{
|
||||
UInt32 count = sizeof(_nandGeometryTable) / sizeof(_nandGeometryTable[0]);
|
||||
UInt32 idx;
|
||||
|
||||
for (idx = 0; idx < count; idx++)
|
||||
{
|
||||
const NandGeometry* geometry = &_nandGeometryTable[idx];
|
||||
if (isSameChipId(chipId, geometry->chipId))
|
||||
{
|
||||
return geometry;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if AND_ENABLE_NAND_DESCRIPTION_TEXT
|
||||
static const NandDescription* lookupNandDescription(const NandPackageId* packageId)
|
||||
{
|
||||
UInt32 idx;
|
||||
|
||||
for (idx = 0; idx < _nandDescriptionTableSize; idx++)
|
||||
{
|
||||
const NandDescription* description = &_nandDescriptionTable[idx];
|
||||
if (isSamePackageId(packageId, &(description->packageId)))
|
||||
{
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const NandTiming* lookupNandTiming(const NandConfigId* configId)
|
||||
{
|
||||
UInt32 count = sizeof(_nandTimingTable) / sizeof(_nandTimingTable[0]);
|
||||
UInt32 idx;
|
||||
|
||||
for (idx = 0; idx < count; idx++)
|
||||
{
|
||||
const NandTiming* timing = &_nandTimingTable[idx];
|
||||
if (isSameConfigId(configId, &(timing->configId)))
|
||||
{
|
||||
return timing;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const NandBoardSupport* lookupBoardSupport(const NandConfigId* configId)
|
||||
{
|
||||
UInt32 count = sizeof(_nandBoardSupportTable) / sizeof(_nandBoardSupportTable[0]);
|
||||
UInt32 idx;
|
||||
|
||||
for (idx = 0; idx < count; idx++)
|
||||
{
|
||||
const NandBoardSupport* support = &_nandBoardSupportTable[idx];
|
||||
if (isSameConfigId(configId, &(support->configId)))
|
||||
{
|
||||
return support;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL32 isValidChipId(NandChipId const chipId)
|
||||
{
|
||||
if (comparePattern(&chipId[0], 0x00, NAND_CHIP_ID_SIZE) ||
|
||||
comparePattern(&chipId[0], 0xFF, NAND_CHIP_ID_SIZE))
|
||||
{
|
||||
return FALSE32;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE32;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL32 getChipIdAndTotalCECountAndCEMap(const NandChipId* chipIds, NandChipId* foundChipId, UInt32* totalCECount, UInt32* ceMap)
|
||||
{
|
||||
BOOL32 found = FALSE32;
|
||||
UInt32 i;
|
||||
|
||||
*ceMap = 0;
|
||||
*totalCECount = 0;
|
||||
|
||||
for (i = 0; i < NAND_MAX_CE_COUNT_TOTAL; i++)
|
||||
{
|
||||
if (isValidChipId(chipIds[i]))
|
||||
{
|
||||
if (!found)
|
||||
{
|
||||
WMR_MEMSET(foundChipId, 0, sizeof(NandChipId));
|
||||
WMR_MEMCPY(foundChipId, chipIds[i], VALID_NAND_CHIP_ID_SIZE);
|
||||
found = TRUE32;
|
||||
}
|
||||
(*totalCECount)++;
|
||||
(*ceMap) |= (1 << i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static BOOL32 areChipIdsIdentical(const NandChipId* chipIds, NandChipId* chipId)
|
||||
{
|
||||
UInt32 i;
|
||||
|
||||
for (i = 0; i < NAND_MAX_CE_COUNT_TOTAL; i++)
|
||||
{
|
||||
if (isValidChipId(chipIds[i]) && (!isSameChipId(*chipId, chipIds[i])))
|
||||
{
|
||||
return FALSE32;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE32;
|
||||
}
|
||||
|
||||
static UInt32 setBitCount(UInt32 x)
|
||||
{
|
||||
// Count the ones
|
||||
UInt32 cnt = 0;
|
||||
|
||||
while (x)
|
||||
{
|
||||
if (x & 1)
|
||||
{
|
||||
cnt++;
|
||||
}
|
||||
x = x >> 1;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static BOOL32 checkCESymmetryAndGetPackageCnt(NandLandingMap *landingMap, UInt32 ceMap, UInt8* pkgCnt)
|
||||
{
|
||||
UInt32 mask;
|
||||
UInt32 i = 0;
|
||||
UInt32 cePerPkg = setBitCount((*landingMap)[0] & ceMap);
|
||||
|
||||
*pkgCnt = 0;
|
||||
|
||||
do
|
||||
{
|
||||
mask = (*landingMap)[i];
|
||||
|
||||
if (mask & ceMap)
|
||||
{
|
||||
if (cePerPkg != setBitCount(mask & ceMap))
|
||||
{
|
||||
return FALSE32;
|
||||
}
|
||||
(*pkgCnt)++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (mask != 0);
|
||||
|
||||
return TRUE32;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Public Function Definitions
|
||||
BOOL32 findNandInfo(const NandChipId* chipIds,
|
||||
NandInfo* nandInfo,
|
||||
const UInt32 numActiveDataBus)
|
||||
{
|
||||
NandConfigId detectedConfigId;
|
||||
NandChipId chipId;
|
||||
UInt32 totalCECount;
|
||||
UInt32 ceMap;
|
||||
UInt32 i;
|
||||
|
||||
nandInfo->boardInfo = &_nandBoardInfo;
|
||||
nandInfo->boardSupport = NULL;
|
||||
nandInfo->configTiming = NULL;
|
||||
nandInfo->format = &_nandFormatRaw;
|
||||
|
||||
WMR_MEMSET(&detectedConfigId, 0, sizeof(NandConfigId));
|
||||
|
||||
if (!getChipIdAndTotalCECountAndCEMap(chipIds, &chipId, &totalCECount, &ceMap))
|
||||
{
|
||||
WMR_PRINT(INIT, "No NAND Detected\n");
|
||||
return FALSE32;
|
||||
}
|
||||
|
||||
if (!areChipIdsIdentical(chipIds, &chipId))
|
||||
{
|
||||
WMR_PRINT(INIT, "Chip IDs not identical!\n");
|
||||
return FALSE32;
|
||||
}
|
||||
|
||||
if (!checkCESymmetryAndGetPackageCnt(&_nandBoardInfo.landingMap, ceMap, &(detectedConfigId.packageCnt)))
|
||||
{
|
||||
WMR_PRINT(INIT, "Chip IDs not symmetrical!\n");
|
||||
return FALSE32;
|
||||
}
|
||||
|
||||
detectedConfigId.connectedBusCnt = numActiveDataBus;
|
||||
|
||||
nandInfo->geometry = lookupNandGeometry(chipId);
|
||||
|
||||
if (!nandInfo->geometry)
|
||||
{
|
||||
WMR_PRINT(INIT, "Unknown Chip ID!\n");
|
||||
return FALSE32;
|
||||
}
|
||||
|
||||
for (i = 0; i < detectedConfigId.packageCnt; i++)
|
||||
{
|
||||
WMR_MEMCPY(&(detectedConfigId.packageIds[i].chipId), nandInfo->geometry->chipId, sizeof(NandChipId));
|
||||
detectedConfigId.packageIds[i].ceCnt = totalCECount / detectedConfigId.packageCnt;
|
||||
}
|
||||
|
||||
nandInfo->boardSupport = lookupBoardSupport(&detectedConfigId);
|
||||
nandInfo->configTiming = lookupNandTiming(&detectedConfigId);
|
||||
|
||||
if (!nandInfo->boardSupport)
|
||||
{
|
||||
WMR_PRINT(INIT, "Board support not found!\n");
|
||||
return FALSE32;
|
||||
}
|
||||
|
||||
if (!nandInfo->configTiming)
|
||||
{
|
||||
WMR_PRINT(INIT, "Nand timing not found!\n");
|
||||
return FALSE32;
|
||||
}
|
||||
|
||||
#if WITH_NAND_DT_CONFIG
|
||||
currentNandInfo = *nandInfo;
|
||||
currentCECount = totalCECount;
|
||||
currentCEBitmap = ceMap;
|
||||
currentActiveDataBus = numActiveDataBus;
|
||||
#endif //WITH_NAND_DT_CONFIG
|
||||
|
||||
return TRUE32;
|
||||
}
|
||||
|
||||
void setECCLevels(UInt32 numCorrectableBits, UInt32 refreshThresholdBits)
|
||||
{
|
||||
currentCorrectableBits = numCorrectableBits;
|
||||
currentRefreshThreshold = refreshThresholdBits;
|
||||
}
|
||||
|
||||
#if WITH_NAND_DT_CONFIG
|
||||
void addNandProperty(DTNode *node, char *name, uint32_t value)
|
||||
{
|
||||
uint32_t propSize = 0;
|
||||
void *propData = NULL;
|
||||
|
||||
if (FindProperty(node, &name, &propData, &propSize) &&
|
||||
(propSize == sizeof(value)))
|
||||
{
|
||||
*(uint32_t*)propData = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
WMR_PRINT(ERROR, "Failed to find NAND property: %s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
static void fillPpnFeatures(DTNode *node)
|
||||
{
|
||||
char *propName = "ppn-features";
|
||||
void *propData = NULL;
|
||||
UInt32 propSize = 0;
|
||||
UInt32 totalSize = sizeof(_ppn_feature_size) + _ppn_feature_size;
|
||||
UInt8 *cursor;
|
||||
|
||||
if (!FindProperty(node, &propName, &propData, &propSize) ||
|
||||
(totalSize > propSize))
|
||||
{
|
||||
WMR_PANIC("expected device tree property %s of at least %u bytes", propName, (unsigned)totalSize);
|
||||
}
|
||||
|
||||
cursor = propData;
|
||||
|
||||
WMR_MEMCPY(cursor, &_ppn_feature_size, sizeof(_ppn_feature_size));
|
||||
cursor += sizeof(_ppn_feature_size);
|
||||
|
||||
WMR_MEMCPY(cursor, _ppn_feature_list, _ppn_feature_size);
|
||||
cursor += _ppn_feature_size;
|
||||
}
|
||||
|
||||
static void fillNandPpnProperties(DTNode *node)
|
||||
{
|
||||
const NandPpn *ppn = currentNandInfo.ppn;
|
||||
|
||||
addNandProperty(node, "ppn-spec-version", ppn->specVersion);
|
||||
addNandProperty(node, "blocks-cau", ppn->blocksPerCau);
|
||||
addNandProperty(node, "caus-ce", ppn->causPerCe);
|
||||
addNandProperty(node, "slc-pages", ppn->slcPagesPerBlock);
|
||||
addNandProperty(node, "mlc-pages", ppn->mlcPagesPerBlock);
|
||||
addNandProperty(node, "match-oddeven-caus", ppn->matchOddEvenCaus);
|
||||
addNandProperty(node, "cau-bits", ppn->bitsPerCau);
|
||||
addNandProperty(node, "page-bits", ppn->bitsPerPage);
|
||||
addNandProperty(node, "block-bits", ppn->bitsPerBlock);
|
||||
addNandProperty(node, "max-transaction-size", ppn->maxTransactionSize);
|
||||
|
||||
fillPpnFeatures(node);
|
||||
}
|
||||
|
||||
static void fillDbgChipIds(DTNode *node)
|
||||
{
|
||||
char *propName = "dbg-chipids";
|
||||
void *propData = NULL;
|
||||
UInt32 propSize = 0;
|
||||
UInt32 totalSize = _dbg_chipids_size;
|
||||
UInt8 *cursor;
|
||||
|
||||
if (NULL == _dbg_chipids_list)
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!FindProperty(node, &propName, &propData, &propSize) ||
|
||||
(totalSize > propSize))
|
||||
{
|
||||
WMR_PRINT(ERROR, "expected device tree property %s of at least %lu bytes", propName, totalSize);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cursor = propData;
|
||||
|
||||
WMR_MEMCPY(cursor, _dbg_chipids_list, _dbg_chipids_size);
|
||||
cursor += _dbg_chipids_size;
|
||||
|
||||
exit:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void fillNandConfigProperties(DTNode *node)
|
||||
{
|
||||
uint32_t propSize = 0;
|
||||
void *propData = NULL;
|
||||
char *propName = NULL;
|
||||
|
||||
if (0 == currentCECount) {
|
||||
fillDbgChipIds(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// Configuration
|
||||
addNandProperty(node, "#ce", currentCECount);
|
||||
addNandProperty(node, "ce-bitmap", currentCEBitmap);
|
||||
|
||||
propName = "device-readid";
|
||||
if (FindProperty(node, &propName, &propData, &propSize) &&
|
||||
(propSize == NAND_CHIP_ID_SIZE))
|
||||
{
|
||||
WMR_MEMCPY(propData, currentNandInfo.geometry->chipId, NAND_CHIP_ID_SIZE);
|
||||
}
|
||||
|
||||
// Geometry
|
||||
addNandProperty(node, "#databus", currentActiveDataBus);
|
||||
addNandProperty(node, "#ce-blocks", currentNandInfo.geometry->blocksPerCS);
|
||||
addNandProperty(node, "#block-pages", currentNandInfo.geometry->pagesPerBlock);
|
||||
addNandProperty(node, "#page-bytes", currentNandInfo.geometry->dataBytesPerPage);
|
||||
addNandProperty(node, "#spare-bytes", currentNandInfo.geometry->spareBytesPerPage);
|
||||
addNandProperty(node, "#die-ce", currentNandInfo.geometry->diesPerCS);
|
||||
|
||||
// Formatting
|
||||
addNandProperty(node, "bbt-format", currentNandInfo.geometry->initialBBType);
|
||||
addNandProperty(node, "vendor-type", currentNandInfo.boardSupport->vsType);
|
||||
addNandProperty(node, "ecc-threshold", currentRefreshThreshold);
|
||||
addNandProperty(node, "ecc-correctable", currentCorrectableBits);
|
||||
|
||||
// Bus Timing
|
||||
addNandProperty(node, "read-setup-clks", _readSetupClocks);
|
||||
addNandProperty(node, "read-hold-clks", _readHoldClocks);
|
||||
addNandProperty(node, "read-dccycle-clks", _readDccycleClocks);
|
||||
addNandProperty(node, "write-setup-clks", _writeSetupClocks);
|
||||
addNandProperty(node, "write-hold-clks", _writeHoldClocks);
|
||||
|
||||
// NAND Format parameters
|
||||
addNandProperty(node, "meta-per-logical-page", currentNandInfo.format->metaPerLogicalPage);
|
||||
addNandProperty(node, "valid-meta-per-logical-page", currentNandInfo.format->validMetaPerLogicalPage);
|
||||
if (currentNandInfo.format->logicalPageSize == 0)
|
||||
{
|
||||
// Use native page size
|
||||
UInt32 pageSize = currentNandInfo.geometry->dataBytesPerPage;
|
||||
addNandProperty(node, "logical-page-size", pageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
addNandProperty(node, "logical-page-size", currentNandInfo.format->logicalPageSize);
|
||||
}
|
||||
|
||||
if (toggleDevice)
|
||||
{
|
||||
addNandProperty(node, "toggle-device", 1);
|
||||
addNandProperty(node, "enable-diff-dqs", _nandBoardInfo.useDiffDQSMode);
|
||||
addNandProperty(node, "enable-diff-re", _nandBoardInfo.useDiffREMode);
|
||||
addNandProperty(node, "enable-vref", _nandBoardInfo.useVref);
|
||||
|
||||
addNandProperty(node, "dqs-half-cycle-clks", _dqsHalfCycleClocks);
|
||||
|
||||
addNandProperty(node, "ce-setup-clks", _ceSetupClocks);
|
||||
addNandProperty(node, "ce-hold-clks", _ceHoldClocks);
|
||||
addNandProperty(node, "adl-clks", _ADLClocks);
|
||||
addNandProperty(node, "whr-clks", _WHRClocks);
|
||||
|
||||
addNandProperty(node, "read-pre-clks", _readPreClocks);
|
||||
addNandProperty(node, "read-post-clks", _readPostClocks);
|
||||
addNandProperty(node, "write-pre-clks", _writePreClocks);
|
||||
addNandProperty(node, "write-post-clks", _writePostClocks);
|
||||
|
||||
addNandProperty(node, "reg-dqs-delay", _regDQSTimingCtrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
addNandProperty(node, "toggle-device", 0);
|
||||
}
|
||||
|
||||
if (ppnDevice == TRUE32)
|
||||
{
|
||||
addNandProperty(node, "ppn-device", 1);
|
||||
fillNandPpnProperties(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
addNandProperty(node, "ppn-device", 0);
|
||||
}
|
||||
|
||||
addNandProperty(node, "retire-on-invalid-refresh", _retire_on_invalid_refresh);
|
||||
|
||||
}
|
||||
|
||||
#endif //WITH_NAND_CONFIG
|
||||
|
||||
void reportToggleModeFMCTimingValues(UInt32 dqsHalfCycleClocks,
|
||||
UInt32 ceSetupClocks,
|
||||
UInt32 ceHoldClocks,
|
||||
UInt32 adlClocks,
|
||||
UInt32 whrClocks,
|
||||
UInt32 readPreClocks,
|
||||
UInt32 readPostClocks,
|
||||
UInt32 writePreClocks,
|
||||
UInt32 writePostClocks,
|
||||
UInt32 regDQSTimingCtrl)
|
||||
{
|
||||
_dqsHalfCycleClocks = dqsHalfCycleClocks;
|
||||
_ceSetupClocks = ceSetupClocks;
|
||||
_ceHoldClocks = ceHoldClocks;
|
||||
_ADLClocks = adlClocks;
|
||||
_WHRClocks = whrClocks;
|
||||
_readPreClocks = readPreClocks;
|
||||
_readPostClocks = readPostClocks;
|
||||
_writePreClocks = writePreClocks;
|
||||
_writePostClocks = writePostClocks;
|
||||
_regDQSTimingCtrl = regDQSTimingCtrl;
|
||||
}
|
||||
|
||||
void setToggleMode()
|
||||
{
|
||||
toggleDevice = TRUE32;
|
||||
}
|
||||
|
||||
|
||||
void reportFMCTimingValues(UInt32 readSetupClocks,
|
||||
UInt32 readHoldClocks,
|
||||
UInt32 readDccycleClocks,
|
||||
UInt32 writeSetupClocks,
|
||||
UInt32 writeHoldClocks)
|
||||
{
|
||||
_readSetupClocks = readSetupClocks;
|
||||
_readHoldClocks = readHoldClocks;
|
||||
_readDccycleClocks = readDccycleClocks;
|
||||
_writeSetupClocks = writeSetupClocks;
|
||||
_writeHoldClocks = writeHoldClocks;
|
||||
}
|
||||
|
||||
void setNandIdPpnConfig(const NandChipId* chipIds,
|
||||
NandInfo* nandInfo,
|
||||
UInt32 busses,
|
||||
UInt32 ces)
|
||||
{
|
||||
#if WITH_NAND_DT_CONFIG
|
||||
currentActiveDataBus = busses;
|
||||
currentNandInfo = *nandInfo;
|
||||
|
||||
getChipIdAndTotalCECountAndCEMap(chipIds, (NandChipId*)¤tNandInfo.geometry->chipId, ¤tCECount, ¤tCEBitmap);
|
||||
WMR_ASSERT(ces == currentCECount);
|
||||
#endif //WITH_NAND_DT_CONFIG
|
||||
nandInfo->format = &_nandFormatPpn;
|
||||
ppnDevice = TRUE32;
|
||||
}
|
||||
|
||||
void setPPNOptions(BOOL32 retire_on_invalid_refresh)
|
||||
{
|
||||
_retire_on_invalid_refresh = retire_on_invalid_refresh;
|
||||
}
|
||||
|
||||
void reportPpnFeatures(void *list, UInt32 size)
|
||||
{
|
||||
_ppn_feature_list = list;
|
||||
_ppn_feature_size = size;
|
||||
}
|
||||
|
||||
void reportDbgChipIds(void *list, UInt32 size)
|
||||
{
|
||||
_dbg_chipids_list = list;
|
||||
_dbg_chipids_size = size;
|
||||
}
|
||||
|
||||
// Bitmap of valid CEs (all CEs are identical to CE0) gets cross-checked
|
||||
// against landing map from nand table
|
||||
// If a valid CE bit is set on an invalid landing bit, returns error
|
||||
BOOL32 checkPpnLandingMap(UInt32 validCEMap)
|
||||
{
|
||||
NandLandingMap *landingMap;
|
||||
UInt32 i = 0;
|
||||
UInt32 current;
|
||||
UInt32 intersect, remainder;
|
||||
|
||||
landingMap = &_nandBoardInfo.landingMap;
|
||||
remainder = validCEMap;
|
||||
|
||||
do {
|
||||
current = (*landingMap)[i];
|
||||
intersect = remainder & current;
|
||||
remainder &= ~intersect;
|
||||
i++;
|
||||
} while ((current != 0) && (remainder != 0));
|
||||
|
||||
if (remainder != 0)
|
||||
{
|
||||
WMR_PRINT(ERROR, "Valid CE bit detected on an invalid landing bit!\n");
|
||||
return FALSE32;
|
||||
}
|
||||
return TRUE32;
|
||||
}
|
||||
|
||||
const NandFormat * getPPNFormat(void)
|
||||
{
|
||||
return &_nandFormatPpn;
|
||||
}
|
||||
|
||||
BOOL32 targetSupportsToggle(void)
|
||||
{
|
||||
return _nandBoardInfo.useToggleMode ? TRUE32 : FALSE32;
|
||||
}
|
||||
|
||||
BOOL32 targetSupportsDiffDQS(void)
|
||||
{
|
||||
return _nandBoardInfo.useDiffDQSMode ? TRUE32 : FALSE32;
|
||||
}
|
||||
|
||||
BOOL32 targetSupportsDiffRE(void)
|
||||
{
|
||||
return _nandBoardInfo.useDiffREMode ? TRUE32 : FALSE32;
|
||||
}
|
||||
|
||||
BOOL32 targetSupportsVREF(void)
|
||||
{
|
||||
return _nandBoardInfo.useVref ? TRUE32 : FALSE32;
|
||||
}
|
||||
|
||||
BOOL32 targetSupportsSHC(void)
|
||||
{
|
||||
return _nandBoardInfo.useSingleHostChannel;
|
||||
}
|
||||
|
||||
BOOL32 targetSupportsSingleCE(void)
|
||||
{
|
||||
return _nandBoardInfo.allowSingleChipEnable;
|
||||
}
|
||||
|
||||
// Run only NAND chip identification
|
||||
int flash_nand_id(void)
|
||||
{
|
||||
OAM_Init();
|
||||
|
||||
if (FIL_SUCCESS != FIL_Init())
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
// Copyright (C) 2008-2009 Apple, Inc. All rights reserved.
|
||||
//
|
||||
// This document is the property of Apple, Inc.
|
||||
// It is considered confidential and proprietary.
|
||||
//
|
||||
// This document may not be reproduced or transmitted in any form,
|
||||
// in whole or in part, without the express written permission of
|
||||
// Apple, Inc.
|
||||
//
|
||||
|
||||
#include "ANDTypes.h"
|
||||
#include "WMRTypes.h"
|
||||
#include "WMRFeatures.h"
|
||||
#if WMR_BUILDING_IBOOT
|
||||
#include <lib/devicetree.h>
|
||||
#endif
|
||||
|
||||
#ifndef _NANDID_H_
|
||||
#define _NANDID_H_
|
||||
|
||||
// =============================================================================
|
||||
// Preprocessor Constants
|
||||
|
||||
#define NAND_CHIP_ID_SIZE (8)
|
||||
#define VALID_NAND_CHIP_ID_SIZE (6)
|
||||
#define COMPARE_NAND_CHIP_ID_SIZE (4)
|
||||
#define LEGACY_NAND_CHIP_ID_SIZE (4)
|
||||
|
||||
#define NAND_MAX_CE_COUNT_PER_PACKAGE (8)
|
||||
#define NAND_MAX_PACKAGES_PER_CONFIG (2)
|
||||
#define NAND_MAX_CE_COUNT_TOTAL (NAND_MAX_PACKAGES_PER_CONFIG * NAND_MAX_CE_COUNT_PER_PACKAGE)
|
||||
|
||||
#define NAND_MAX_APPLE_NAME_SIZE (20)
|
||||
#define NAND_MAX_VENDOR_NAME_SIZE (20)
|
||||
#define NAND_MAX_PACKAGE_TYPE_SIZE (20)
|
||||
#define NAND_MAX_PACKAGE_SIZE_SIZE (20)
|
||||
|
||||
// =============================================================================
|
||||
// Drive Strength
|
||||
|
||||
typedef UInt8 NandDriveStrength;
|
||||
|
||||
#define NAND_DRIVE_STRENGTH_DEFAULT ((NandDriveStrength)0)
|
||||
|
||||
#define NAND_DRIVE_STRENGTH_X1 ((NandDriveStrength)1)
|
||||
#define NAND_DRIVE_STRENGTH_X2 ((NandDriveStrength)2)
|
||||
#define NAND_DRIVE_STRENGTH_X3 ((NandDriveStrength)3)
|
||||
#define NAND_DRIVE_STRENGTH_X4 ((NandDriveStrength)4)
|
||||
|
||||
// =============================================================================
|
||||
// Nand Chip Id
|
||||
|
||||
typedef UInt8 NandChipId[NAND_CHIP_ID_SIZE];
|
||||
|
||||
// =============================================================================
|
||||
// Nand Package Id
|
||||
|
||||
struct NandPackageIdStruct
|
||||
{
|
||||
// Unique identifier for this struct - start
|
||||
NandChipId chipId;
|
||||
UInt8 ceCnt;
|
||||
// Unique identifier for this struct - end
|
||||
};
|
||||
|
||||
typedef struct NandPackageIdStruct NandPackageId;
|
||||
|
||||
// =============================================================================
|
||||
// Nand Config Id
|
||||
|
||||
struct NandConfigIdStruct
|
||||
{
|
||||
// Unique identifier for this struct - start
|
||||
UInt8 connectedBusCnt;
|
||||
UInt8 packageCnt;
|
||||
NandPackageId packageIds[NAND_MAX_PACKAGES_PER_CONFIG];
|
||||
// Unique identifier for this struct - end
|
||||
};
|
||||
|
||||
typedef struct NandConfigIdStruct NandConfigId;
|
||||
|
||||
// =============================================================================
|
||||
// Nand Geometry
|
||||
|
||||
struct NandGeometryStruct
|
||||
{
|
||||
// Unique identifier for this struct - start
|
||||
NandChipId chipId;
|
||||
// Unique identifier for this struct - end
|
||||
|
||||
UInt16 blocksPerCS;
|
||||
UInt16 pagesPerBlock;
|
||||
UInt16 dataBytesPerPage;
|
||||
UInt16 spareBytesPerPage;
|
||||
|
||||
UInt8 eccPer512Bytes;
|
||||
CheckInitialBadType initialBBType;
|
||||
|
||||
UInt16 diesPerCS;
|
||||
};
|
||||
|
||||
typedef struct NandGeometryStruct NandGeometry;
|
||||
|
||||
#if (defined (AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT)
|
||||
// =============================================================================
|
||||
// Nand Description
|
||||
|
||||
struct NandDescriptionStruct
|
||||
{
|
||||
// Unique identifier for this struct - start
|
||||
NandPackageId packageId;
|
||||
// Unique identifier for this struct - end
|
||||
|
||||
char appleName[NAND_MAX_APPLE_NAME_SIZE];
|
||||
char vendorPartNumber[NAND_MAX_VENDOR_NAME_SIZE];
|
||||
char packageType[NAND_MAX_PACKAGE_TYPE_SIZE];
|
||||
char packageSize[NAND_MAX_PACKAGE_SIZE_SIZE];
|
||||
};
|
||||
|
||||
typedef struct NandDescriptionStruct NandDescription;
|
||||
|
||||
// =============================================================================
|
||||
// ChipId Description
|
||||
|
||||
struct NandChipIdDescriptionStruct
|
||||
{
|
||||
// Unique identifier for this struct - start
|
||||
NandChipId chipId;
|
||||
// Unique identifier for this struct - end
|
||||
|
||||
char die[NAND_MAX_VENDOR_NAME_SIZE];
|
||||
char vendor[NAND_MAX_VENDOR_NAME_SIZE];
|
||||
};
|
||||
|
||||
typedef struct NandChipIdDescriptionStruct NandChipIdDescription;
|
||||
#endif // (defined(AND_ENABLE_NAND_DESCRIPTION_TEXT) || AND_ENABLE_NAND_DESCRIPTION_TEXT)
|
||||
|
||||
// =============================================================================
|
||||
// Nand Timing
|
||||
|
||||
struct NandTimingStruct
|
||||
{
|
||||
// Unique identifier for this struct - start
|
||||
NandConfigId configId;
|
||||
// Unique identifier for this struct - end
|
||||
|
||||
// write cycle
|
||||
UInt8 writeCycleNanosecs;
|
||||
UInt8 writeSetupNanosecs;
|
||||
UInt8 writeHoldNanosecs;
|
||||
|
||||
// read cycle
|
||||
UInt8 readCycleNanosecs;
|
||||
UInt8 readSetupNanosecs;
|
||||
UInt8 readHoldNanosecs;
|
||||
|
||||
// read window
|
||||
UInt8 readDelayNanosecs;
|
||||
UInt8 readValidNanosecs;
|
||||
};
|
||||
|
||||
typedef struct NandTimingStruct NandTiming;
|
||||
|
||||
// =============================================================================
|
||||
// Nand Support
|
||||
|
||||
struct NandBoardSupportStruct
|
||||
{
|
||||
// Unique identifier for this struct - start
|
||||
NandConfigId configId;
|
||||
// Unique identifier for this struct - end
|
||||
|
||||
VendorSpecificType vsType;
|
||||
};
|
||||
|
||||
typedef struct NandBoardSupportStruct NandBoardSupport;
|
||||
|
||||
// =============================================================================
|
||||
// Board Package/Landing Map
|
||||
|
||||
typedef UInt32 NandLandingMask;
|
||||
|
||||
typedef NandLandingMask NandLandingMap[NAND_MAX_PACKAGES_PER_CONFIG + 1];
|
||||
|
||||
// =============================================================================
|
||||
// Nand Board Timing
|
||||
|
||||
struct NandBoardInfoStruct
|
||||
{
|
||||
NandDriveStrength controlDstr;
|
||||
NandDriveStrength dataDstr;
|
||||
NandDriveStrength chipEnableDstr;
|
||||
|
||||
UInt8 socToNandRiseNanosecs;
|
||||
UInt8 socToNandFallNanosecs;
|
||||
UInt8 nandToSocRiseNanosecs;
|
||||
UInt8 nandToSocFallNanosecs;
|
||||
|
||||
NandLandingMap landingMap;
|
||||
BOOL32 useToggleMode;
|
||||
BOOL32 useDiffDQSMode;
|
||||
BOOL32 useDiffREMode;
|
||||
BOOL32 useVref;
|
||||
BOOL32 useSingleHostChannel;
|
||||
BOOL32 allowSingleChipEnable;
|
||||
};
|
||||
|
||||
typedef struct NandBoardInfoStruct NandBoardInfo;
|
||||
|
||||
struct NandPpnStruct
|
||||
{
|
||||
UInt32 specVersion;
|
||||
UInt32 blocksPerCau;
|
||||
UInt32 causPerCe;
|
||||
UInt32 slcPagesPerBlock;
|
||||
UInt32 mlcPagesPerBlock;
|
||||
UInt32 matchOddEvenCaus;
|
||||
UInt32 bitsPerCau;
|
||||
UInt32 bitsPerPage;
|
||||
UInt32 bitsPerBlock;
|
||||
UInt32 maxTransactionSize;
|
||||
};
|
||||
|
||||
typedef struct NandPpnStruct NandPpn;
|
||||
|
||||
struct NandFormatStruct
|
||||
{
|
||||
UInt32 metaPerLogicalPage;
|
||||
UInt32 validMetaPerLogicalPage;
|
||||
UInt32 logicalPageSize;
|
||||
};
|
||||
typedef struct NandFormatStruct NandFormat;
|
||||
|
||||
// =============================================================================
|
||||
// Nand Info
|
||||
|
||||
struct NandInfoStruct
|
||||
{
|
||||
const NandBoardSupport* boardSupport;
|
||||
const NandBoardInfo* boardInfo;
|
||||
const NandTiming* configTiming;
|
||||
const NandGeometry* geometry;
|
||||
const NandPpn* ppn;
|
||||
const NandFormat* format;
|
||||
};
|
||||
|
||||
typedef struct NandInfoStruct NandInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
// =============================================================================
|
||||
// Public Function Declarations
|
||||
|
||||
BOOL32 findNandInfo(const NandChipId* chipIds,
|
||||
NandInfo* nandInfo,
|
||||
UInt32 numActiveDataBus);
|
||||
|
||||
void setNandIdPpnConfig(const NandChipId* chipIds,
|
||||
NandInfo* nandInfo,
|
||||
UInt32 busses,
|
||||
UInt32 ces);
|
||||
|
||||
void reportFMCTimingValues(UInt32 readSetupClocks,
|
||||
UInt32 readHoldClocks,
|
||||
UInt32 readDccycleClocks,
|
||||
UInt32 writeSetupClocks,
|
||||
UInt32 writeHoldClocks);
|
||||
|
||||
void reportToggleModeFMCTimingValues(UInt32 dqsHalfCycleClocks,
|
||||
UInt32 ceSetupClocks,
|
||||
UInt32 ceHoldClocks,
|
||||
UInt32 adlClocks,
|
||||
UInt32 whrClocks,
|
||||
UInt32 readPreClocks,
|
||||
UInt32 readPostClocks,
|
||||
UInt32 writePreClocks,
|
||||
UInt32 writePostClocks,
|
||||
UInt32 regDQSTimingCtrl);
|
||||
|
||||
void setToggleMode();
|
||||
|
||||
void setPPNOptions(BOOL32 retire_on_invalid_refresh);
|
||||
|
||||
void reportPpnFeatures(void *list, UInt32 size);
|
||||
|
||||
void reportDbgChipIds(void *list, UInt32 size);
|
||||
|
||||
void setECCLevels(UInt32 numCorrectableBits,
|
||||
UInt32 refreshThresholdBits);
|
||||
|
||||
BOOL32 checkPpnLandingMap(UInt32 validCEMap);
|
||||
|
||||
const NandFormat * getPPNFormat(void);
|
||||
|
||||
BOOL32 targetSupportsToggle(void);
|
||||
BOOL32 targetSupportsDiffDQS(void);
|
||||
BOOL32 targetSupportsDiffRE(void);
|
||||
BOOL32 targetSupportsVREF(void);
|
||||
BOOL32 targetSupportsSHC(void);
|
||||
BOOL32 targetSupportsSingleCE(void);
|
||||
|
||||
// =============================================================================
|
||||
// Public Variables
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif // _NANDID_H_
|
||||
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
GLOBAL_INCLUDES += \
|
||||
$(LOCAL_DIR) \
|
||||
drivers/flash_nand/raw/Whimory/Inc
|
||||
|
||||
MODULES += \
|
||||
drivers/flash_nand/OAM
|
||||
|
||||
ALL_OBJS += \
|
||||
$(LOCAL_DIR)/nandid.o
|
||||
Reference in new issue
Block a user