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