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 <hndnand.h> 30#include <hndpmu.h> 31 32/* Private global state */ 33static hndnand_t *hndnand = NULL; 34 35extern hndnand_t *nflash_init(si_t *sih); 36extern hndnand_t *nandcore_init(si_t *sih); 37 38/* Initialize nand flash access */ 39hndnand_t * 40hndnand_init(si_t *sih) 41{ 42 uint32 origidx; 43 44 ASSERT(sih); 45 46 /* Already initialized ? */ 47 if (hndnand) 48 return hndnand; 49 50 origidx = si_coreidx(sih); 51 52#ifdef __mips__ 53 if (!hndnand) 54 hndnand = nflash_init(sih); 55#endif 56#ifdef __ARM_ARCH_7A__ 57 if (!hndnand) 58 hndnand = nandcore_init(sih); 59#endif 60 61 si_setcoreidx(sih, origidx); 62 return hndnand; 63} 64 65void 66hndnand_enable(hndnand_t *nfl, int enable) 67{ 68 ASSERT(nfl); 69 70 if (nfl->enable) { 71 /* Should spinlock here */ 72 (nfl->enable)(nfl, enable); 73 } 74 75 return; 76} 77 78/* Read len bytes starting at offset into buf. Returns number of bytes read. */ 79int 80hndnand_read(hndnand_t *nfl, uint64 offset, uint len, uchar *buf) 81{ 82 ASSERT(nfl); 83 ASSERT(nfl->read); 84 85 return (nfl->read)(nfl, offset, len, buf); 86} 87 88/* Write len bytes starting at offset into buf. Returns number of bytes 89 * written. 90 */ 91int 92hndnand_write(hndnand_t *nfl, uint64 offset, uint len, const uchar *buf) 93{ 94 ASSERT(nfl); 95 ASSERT(nfl->write); 96 97 return (nfl->write)(nfl, offset, len, buf); 98} 99 100/* Erase a region. Returns number of bytes scheduled for erasure. 101 * Caller should poll for completion. 102 */ 103int 104hndnand_erase(hndnand_t *nfl, uint64 offset) 105{ 106 ASSERT(nfl); 107 ASSERT(nfl->erase); 108 109 return (nfl->erase)(nfl, offset); 110} 111 112int 113hndnand_checkbadb(hndnand_t *nfl, uint64 offset) 114{ 115 ASSERT(nfl); 116 ASSERT(nfl->checkbadb); 117 118 return (nfl->checkbadb)(nfl, offset); 119} 120 121int 122hndnand_mark_badb(hndnand_t *nfl, uint64 offset) 123{ 124 ASSERT(nfl); 125 ASSERT(nfl->markbadb); 126 127 return (nfl->markbadb)(nfl, offset); 128} 129 130#ifndef _CFE_ 131int 132hndnand_dev_ready(hndnand_t *nfl) 133{ 134 ASSERT(nfl); 135 ASSERT(nfl->dev_ready); 136 137 return (nfl->dev_ready)(nfl); 138} 139 140int 141hndnand_select_chip(hndnand_t *nfl, int chip) 142{ 143 ASSERT(nfl); 144 ASSERT(nfl->select_chip); 145 146 return (nfl->select_chip)(nfl, chip); 147} 148 149int hndnand_cmdfunc(hndnand_t *nfl, uint64 addr, int cmd) 150{ 151 ASSERT(nfl); 152 ASSERT(nfl->cmdfunc); 153 154 return (nfl->cmdfunc)(nfl, addr, cmd); 155} 156 157int 158hndnand_waitfunc(hndnand_t *nfl, int *status) 159{ 160 ASSERT(nfl); 161 ASSERT(nfl->waitfunc); 162 163 return (nfl->waitfunc)(nfl, status); 164} 165 166int 167hndnand_read_oob(hndnand_t *nfl, uint64 addr, uint8 *oob) 168{ 169 ASSERT(nfl); 170 ASSERT(nfl->read_oob); 171 172 return (nfl->read_oob)(nfl, addr, oob); 173} 174 175int 176hndnand_write_oob(hndnand_t *nfl, uint64 addr, uint8 *oob) 177{ 178 ASSERT(nfl); 179 ASSERT(nfl->write_oob); 180 181 return (nfl->write_oob)(nfl, addr, oob); 182} 183int 184hndnand_read_page(hndnand_t *nfl, uint64 addr, uint8 *buf, uint8 *oob, bool ecc, 185 uint32 *herr, uint32 *serr) 186{ 187 ASSERT(nfl); 188 ASSERT(nfl->read_page); 189 190 return (nfl->read_page)(nfl, addr, buf, oob, ecc, herr, serr); 191} 192 193int 194hndnand_write_page(hndnand_t *nfl, uint64 addr, const uint8 *buf, uint8 *oob, bool ecc) 195{ 196 ASSERT(nfl); 197 ASSERT(nfl->write_page); 198 199 return (nfl->write_page)(nfl, addr, buf, oob, ecc); 200} 201 202int 203hndnand_cmd_read_byte(hndnand_t *nfl, int cmd, int arg) 204{ 205 ASSERT(nfl); 206 ASSERT(nfl->cmd_read_byte); 207 208 return (nfl->cmd_read_byte)(nfl, cmd, arg); 209} 210#endif /* _CFE_ */ 211