mirror of
https://github.com/gnuton/asuswrt-merlin.ng.git
synced 2025-05-19 16:02:36 +02:00
129 lines
3 KiB
C
129 lines
3 KiB
C
/*
|
|
* Broadcom chipcommon NAND flash interface
|
|
*
|
|
* Copyright (C) 2021, Broadcom. All Rights Reserved.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
*
|
|
* <<Broadcom-WL-IPTag/Open:>>
|
|
*
|
|
* $Id: hndsflash.c 596126 2015-10-29 19:53:48Z $
|
|
*/
|
|
|
|
#include <typedefs.h>
|
|
#include <osl.h>
|
|
#include <bcmutils.h>
|
|
#include <siutils.h>
|
|
#include <hndsoc.h>
|
|
#include <sbhndcpu.h>
|
|
#include <sbchipc.h>
|
|
#include <bcmdevs.h>
|
|
#include <hndsflash.h>
|
|
|
|
/* Private global state */
|
|
static hndsflash_t *hndsflash;
|
|
|
|
hndsflash_t *ccsflash_init(si_t *sih);
|
|
hndsflash_t *spiflash_init(si_t *sih);
|
|
|
|
/* Initialize nand flash access */
|
|
hndsflash_t *
|
|
hndsflash_init(si_t *sih)
|
|
{
|
|
uint32 origidx;
|
|
|
|
ASSERT(sih);
|
|
|
|
/* Already initialized ? */
|
|
if (hndsflash)
|
|
return hndsflash;
|
|
|
|
/* spin lock here */
|
|
origidx = si_coreidx(sih);
|
|
|
|
#ifdef __mips__
|
|
if (!hndsflash)
|
|
hndsflash = ccsflash_init(sih);
|
|
#endif /* __mips__ */
|
|
#ifdef __ARM_ARCH_7A__
|
|
if (!hndsflash) {
|
|
/* 4708 (Northstar series) */
|
|
if (sih->ccrev == 42)
|
|
hndsflash = spiflash_init(sih);
|
|
/* 53573/47189 series */
|
|
else if (sih->ccrev == 54)
|
|
hndsflash = ccsflash_init(sih);
|
|
}
|
|
#endif /* __ARM_ARCH_7A__ */
|
|
|
|
si_setcoreidx(sih, origidx);
|
|
return hndsflash;
|
|
}
|
|
|
|
/* Read len bytes starting at offset into buf. Returns number of bytes read. */
|
|
int
|
|
hndsflash_read(hndsflash_t *sfl, uint offset, uint len, const uchar *buf)
|
|
{
|
|
ASSERT(sfl);
|
|
ASSERT(sfl->read);
|
|
|
|
return (sfl->read)(sfl, offset, len, buf);
|
|
}
|
|
|
|
/* Write len bytes starting at offset into buf. Returns number of bytes
|
|
* written.
|
|
*/
|
|
int
|
|
hndsflash_write(hndsflash_t *sfl, uint offset, uint len, const uchar *buf)
|
|
{
|
|
ASSERT(sfl);
|
|
ASSERT(sfl->write);
|
|
|
|
return (sfl->write)(sfl, offset, len, (const uchar *)buf);
|
|
}
|
|
|
|
/* Erase a region. Returns number of bytes scheduled for erasure.
|
|
* Caller should poll for completion.
|
|
*/
|
|
int
|
|
hndsflash_erase(hndsflash_t *sfl, uint offset)
|
|
{
|
|
ASSERT(sfl);
|
|
ASSERT(sfl->erase);
|
|
|
|
return (sfl->erase)(sfl, offset);
|
|
}
|
|
|
|
/*
|
|
* writes the appropriate range of flash, a NULL buf simply erases
|
|
* the region of flash
|
|
*/
|
|
int hndsflash_commit(hndsflash_t *sfl, uint offset, uint len, const uchar *buf)
|
|
{
|
|
ASSERT(sfl);
|
|
ASSERT(sfl->commit);
|
|
|
|
return (sfl->commit)(sfl, offset, len, (const uchar *)buf);
|
|
}
|
|
|
|
/* Poll for command completion. Returns zero when complete. */
|
|
int hndsflash_poll(hndsflash_t *sfl, uint offset)
|
|
{
|
|
ASSERT(sfl);
|
|
|
|
if (!sfl->poll)
|
|
return 0;
|
|
|
|
return (sfl->poll)(sfl, offset);
|
|
}
|