1/* 2 * Broadcom chipcommon NAND flash interface 3 * 4 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id:$ 19 */ 20 21#include <typedefs.h> 22#include <osl.h> 23#include <bcmutils.h> 24#include <siutils.h> 25#include <hndsoc.h> 26#include <sbhndcpu.h> 27#include <sbchipc.h> 28#include <bcmdevs.h> 29#include <hndsflash.h> 30 31/* Private global state */ 32static hndsflash_t *hndsflash; 33 34hndsflash_t *ccsflash_init(si_t *sih); 35hndsflash_t *spiflash_init(si_t *sih); 36 37/* Initialize nand flash access */ 38hndsflash_t * 39hndsflash_init(si_t *sih) 40{ 41 uint32 origidx; 42 43 ASSERT(sih); 44 45 /* Already initialized ? */ 46 if (hndsflash) 47 return hndsflash; 48 49 /* spin lock here */ 50 origidx = si_coreidx(sih); 51 52#ifdef __mips__ 53 if (!hndsflash) 54 hndsflash = ccsflash_init(sih); 55#endif /* __mips__ */ 56#ifdef __ARM_ARCH_7A__ 57 if (!hndsflash) 58 hndsflash = spiflash_init(sih); 59#endif /* __ARM_ARCH_7A__ */ 60 61 si_setcoreidx(sih, origidx); 62 return hndsflash; 63} 64 65/* Read len bytes starting at offset into buf. Returns number of bytes read. */ 66int 67hndsflash_read(hndsflash_t *sfl, uint offset, uint len, const uchar *buf) 68{ 69 ASSERT(sfl); 70 ASSERT(sfl->read); 71 72 return (sfl->read)(sfl, offset, len, buf); 73} 74 75/* Write len bytes starting at offset into buf. Returns number of bytes 76 * written. 77 */ 78int 79hndsflash_write(hndsflash_t *sfl, uint offset, uint len, const uchar *buf) 80{ 81 ASSERT(sfl); 82 ASSERT(sfl->write); 83 84 return (sfl->write)(sfl, offset, len, (const uchar *)buf); 85} 86 87/* Erase a region. Returns number of bytes scheduled for erasure. 88 * Caller should poll for completion. 89 */ 90int 91hndsflash_erase(hndsflash_t *sfl, uint offset) 92{ 93 ASSERT(sfl); 94 ASSERT(sfl->erase); 95 96 return (sfl->erase)(sfl, offset); 97} 98 99/* 100 * writes the appropriate range of flash, a NULL buf simply erases 101 * the region of flash 102 */ 103int hndsflash_commit(hndsflash_t *sfl, uint offset, uint len, const uchar *buf) 104{ 105 ASSERT(sfl); 106 ASSERT(sfl->commit); 107 108 return (sfl->commit)(sfl, offset, len, (const uchar *)buf); 109} 110 111/* Poll for command completion. Returns zero when complete. */ 112int hndsflash_poll(hndsflash_t *sfl, uint offset) 113{ 114 ASSERT(sfl); 115 116 if (!sfl->poll) 117 return 0; 118 119 return (sfl->poll)(sfl, offset); 120} 121