1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <errno.h> 9*91f16700Schasinglulu #include <stddef.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <drivers/delay_timer.h> 13*91f16700Schasinglulu #include <drivers/raw_nand.h> 14*91f16700Schasinglulu #include <lib/utils.h> 15*91f16700Schasinglulu 16*91f16700Schasinglulu #include <platform_def.h> 17*91f16700Schasinglulu 18*91f16700Schasinglulu #define ONFI_SIGNATURE_ADDR 0x20U 19*91f16700Schasinglulu 20*91f16700Schasinglulu /* CRC calculation */ 21*91f16700Schasinglulu #define CRC_POLYNOM 0x8005U 22*91f16700Schasinglulu #define CRC_INIT_VALUE 0x4F4EU 23*91f16700Schasinglulu 24*91f16700Schasinglulu /* Status register */ 25*91f16700Schasinglulu #define NAND_STATUS_READY BIT(6) 26*91f16700Schasinglulu 27*91f16700Schasinglulu static struct rawnand_device rawnand_dev; 28*91f16700Schasinglulu 29*91f16700Schasinglulu #pragma weak plat_get_raw_nand_data 30*91f16700Schasinglulu int plat_get_raw_nand_data(struct rawnand_device *device) 31*91f16700Schasinglulu { 32*91f16700Schasinglulu return 0; 33*91f16700Schasinglulu } 34*91f16700Schasinglulu 35*91f16700Schasinglulu static int nand_send_cmd(uint8_t cmd, unsigned int tim) 36*91f16700Schasinglulu { 37*91f16700Schasinglulu struct nand_req req; 38*91f16700Schasinglulu 39*91f16700Schasinglulu zeromem(&req, sizeof(struct nand_req)); 40*91f16700Schasinglulu req.nand = rawnand_dev.nand_dev; 41*91f16700Schasinglulu req.type = NAND_REQ_CMD | cmd; 42*91f16700Schasinglulu req.inst_delay = tim; 43*91f16700Schasinglulu 44*91f16700Schasinglulu return rawnand_dev.ops->exec(&req); 45*91f16700Schasinglulu } 46*91f16700Schasinglulu 47*91f16700Schasinglulu static int nand_send_addr(uint8_t addr, unsigned int tim) 48*91f16700Schasinglulu { 49*91f16700Schasinglulu struct nand_req req; 50*91f16700Schasinglulu 51*91f16700Schasinglulu zeromem(&req, sizeof(struct nand_req)); 52*91f16700Schasinglulu req.nand = rawnand_dev.nand_dev; 53*91f16700Schasinglulu req.type = NAND_REQ_ADDR; 54*91f16700Schasinglulu req.addr = &addr; 55*91f16700Schasinglulu req.inst_delay = tim; 56*91f16700Schasinglulu 57*91f16700Schasinglulu return rawnand_dev.ops->exec(&req); 58*91f16700Schasinglulu } 59*91f16700Schasinglulu 60*91f16700Schasinglulu static int nand_send_wait(unsigned int delay, unsigned int tim) 61*91f16700Schasinglulu { 62*91f16700Schasinglulu struct nand_req req; 63*91f16700Schasinglulu 64*91f16700Schasinglulu zeromem(&req, sizeof(struct nand_req)); 65*91f16700Schasinglulu req.nand = rawnand_dev.nand_dev; 66*91f16700Schasinglulu req.type = NAND_REQ_WAIT; 67*91f16700Schasinglulu req.inst_delay = tim; 68*91f16700Schasinglulu req.delay_ms = delay; 69*91f16700Schasinglulu 70*91f16700Schasinglulu return rawnand_dev.ops->exec(&req); 71*91f16700Schasinglulu } 72*91f16700Schasinglulu 73*91f16700Schasinglulu 74*91f16700Schasinglulu static int nand_read_data(uint8_t *data, unsigned int length, bool use_8bit) 75*91f16700Schasinglulu { 76*91f16700Schasinglulu struct nand_req req; 77*91f16700Schasinglulu 78*91f16700Schasinglulu zeromem(&req, sizeof(struct nand_req)); 79*91f16700Schasinglulu req.nand = rawnand_dev.nand_dev; 80*91f16700Schasinglulu req.type = NAND_REQ_DATAIN | (use_8bit ? NAND_REQ_BUS_WIDTH_8 : 0U); 81*91f16700Schasinglulu req.addr = data; 82*91f16700Schasinglulu req.length = length; 83*91f16700Schasinglulu 84*91f16700Schasinglulu return rawnand_dev.ops->exec(&req); 85*91f16700Schasinglulu } 86*91f16700Schasinglulu 87*91f16700Schasinglulu int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer, 88*91f16700Schasinglulu unsigned int len) 89*91f16700Schasinglulu { 90*91f16700Schasinglulu int ret; 91*91f16700Schasinglulu uint8_t addr[2]; 92*91f16700Schasinglulu unsigned int i; 93*91f16700Schasinglulu 94*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_CHANGE_1ST, 0U); 95*91f16700Schasinglulu if (ret != 0) { 96*91f16700Schasinglulu return ret; 97*91f16700Schasinglulu } 98*91f16700Schasinglulu 99*91f16700Schasinglulu if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) { 100*91f16700Schasinglulu offset /= 2U; 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu addr[0] = offset; 104*91f16700Schasinglulu addr[1] = offset >> 8; 105*91f16700Schasinglulu 106*91f16700Schasinglulu for (i = 0; i < 2U; i++) { 107*91f16700Schasinglulu ret = nand_send_addr(addr[i], 0U); 108*91f16700Schasinglulu if (ret != 0) { 109*91f16700Schasinglulu return ret; 110*91f16700Schasinglulu } 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_CHANGE_2ND, NAND_TCCS_MIN); 114*91f16700Schasinglulu if (ret != 0) { 115*91f16700Schasinglulu return ret; 116*91f16700Schasinglulu } 117*91f16700Schasinglulu 118*91f16700Schasinglulu return nand_read_data((uint8_t *)buffer, len, false); 119*91f16700Schasinglulu } 120*91f16700Schasinglulu 121*91f16700Schasinglulu int nand_read_page_cmd(unsigned int page, unsigned int offset, 122*91f16700Schasinglulu uintptr_t buffer, unsigned int len) 123*91f16700Schasinglulu { 124*91f16700Schasinglulu uint8_t addr[5]; 125*91f16700Schasinglulu uint8_t i = 0U; 126*91f16700Schasinglulu uint8_t j; 127*91f16700Schasinglulu int ret; 128*91f16700Schasinglulu 129*91f16700Schasinglulu VERBOSE(">%s page %u offset %u buffer 0x%lx\n", __func__, page, offset, 130*91f16700Schasinglulu buffer); 131*91f16700Schasinglulu 132*91f16700Schasinglulu if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) { 133*91f16700Schasinglulu offset /= 2U; 134*91f16700Schasinglulu } 135*91f16700Schasinglulu 136*91f16700Schasinglulu addr[i++] = offset; 137*91f16700Schasinglulu addr[i++] = offset >> 8; 138*91f16700Schasinglulu 139*91f16700Schasinglulu addr[i++] = page; 140*91f16700Schasinglulu addr[i++] = page >> 8; 141*91f16700Schasinglulu if (rawnand_dev.nand_dev->size > SZ_128M) { 142*91f16700Schasinglulu addr[i++] = page >> 16; 143*91f16700Schasinglulu } 144*91f16700Schasinglulu 145*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_READ_1ST, 0U); 146*91f16700Schasinglulu if (ret != 0) { 147*91f16700Schasinglulu return ret; 148*91f16700Schasinglulu } 149*91f16700Schasinglulu 150*91f16700Schasinglulu for (j = 0U; j < i; j++) { 151*91f16700Schasinglulu ret = nand_send_addr(addr[j], 0U); 152*91f16700Schasinglulu if (ret != 0) { 153*91f16700Schasinglulu return ret; 154*91f16700Schasinglulu } 155*91f16700Schasinglulu } 156*91f16700Schasinglulu 157*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_READ_2ND, NAND_TWB_MAX); 158*91f16700Schasinglulu if (ret != 0) { 159*91f16700Schasinglulu return ret; 160*91f16700Schasinglulu } 161*91f16700Schasinglulu 162*91f16700Schasinglulu ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN); 163*91f16700Schasinglulu if (ret != 0) { 164*91f16700Schasinglulu return ret; 165*91f16700Schasinglulu } 166*91f16700Schasinglulu 167*91f16700Schasinglulu if (buffer != 0U) { 168*91f16700Schasinglulu ret = nand_read_data((uint8_t *)buffer, len, false); 169*91f16700Schasinglulu } 170*91f16700Schasinglulu 171*91f16700Schasinglulu return ret; 172*91f16700Schasinglulu } 173*91f16700Schasinglulu 174*91f16700Schasinglulu static int nand_status(uint8_t *status) 175*91f16700Schasinglulu { 176*91f16700Schasinglulu int ret; 177*91f16700Schasinglulu 178*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_STATUS, NAND_TWHR_MIN); 179*91f16700Schasinglulu if (ret != 0) { 180*91f16700Schasinglulu return ret; 181*91f16700Schasinglulu } 182*91f16700Schasinglulu 183*91f16700Schasinglulu if (status != NULL) { 184*91f16700Schasinglulu ret = nand_read_data(status, 1U, true); 185*91f16700Schasinglulu } 186*91f16700Schasinglulu 187*91f16700Schasinglulu return ret; 188*91f16700Schasinglulu } 189*91f16700Schasinglulu 190*91f16700Schasinglulu int nand_wait_ready(unsigned int delay_ms) 191*91f16700Schasinglulu { 192*91f16700Schasinglulu uint8_t status; 193*91f16700Schasinglulu int ret; 194*91f16700Schasinglulu uint64_t timeout; 195*91f16700Schasinglulu 196*91f16700Schasinglulu /* Wait before reading status */ 197*91f16700Schasinglulu udelay(1); 198*91f16700Schasinglulu 199*91f16700Schasinglulu ret = nand_status(NULL); 200*91f16700Schasinglulu if (ret != 0) { 201*91f16700Schasinglulu return ret; 202*91f16700Schasinglulu } 203*91f16700Schasinglulu 204*91f16700Schasinglulu timeout = timeout_init_us(delay_ms * 1000U); 205*91f16700Schasinglulu while (!timeout_elapsed(timeout)) { 206*91f16700Schasinglulu ret = nand_read_data(&status, 1U, true); 207*91f16700Schasinglulu if (ret != 0) { 208*91f16700Schasinglulu return ret; 209*91f16700Schasinglulu } 210*91f16700Schasinglulu 211*91f16700Schasinglulu if ((status & NAND_STATUS_READY) != 0U) { 212*91f16700Schasinglulu return nand_send_cmd(NAND_CMD_READ_1ST, 0U); 213*91f16700Schasinglulu } 214*91f16700Schasinglulu 215*91f16700Schasinglulu udelay(10); 216*91f16700Schasinglulu } 217*91f16700Schasinglulu 218*91f16700Schasinglulu return -ETIMEDOUT; 219*91f16700Schasinglulu } 220*91f16700Schasinglulu 221*91f16700Schasinglulu static int nand_reset(void) 222*91f16700Schasinglulu { 223*91f16700Schasinglulu int ret; 224*91f16700Schasinglulu 225*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_RESET, NAND_TWB_MAX); 226*91f16700Schasinglulu if (ret != 0) { 227*91f16700Schasinglulu return ret; 228*91f16700Schasinglulu } 229*91f16700Schasinglulu 230*91f16700Schasinglulu return nand_send_wait(PSEC_TO_MSEC(NAND_TRST_MAX), 0U); 231*91f16700Schasinglulu } 232*91f16700Schasinglulu 233*91f16700Schasinglulu #if NAND_ONFI_DETECT 234*91f16700Schasinglulu static uint16_t nand_check_crc(uint16_t crc, uint8_t *data_in, 235*91f16700Schasinglulu unsigned int data_len) 236*91f16700Schasinglulu { 237*91f16700Schasinglulu uint32_t i; 238*91f16700Schasinglulu uint32_t j; 239*91f16700Schasinglulu uint32_t bit; 240*91f16700Schasinglulu 241*91f16700Schasinglulu for (i = 0U; i < data_len; i++) { 242*91f16700Schasinglulu uint8_t cur_param = *data_in++; 243*91f16700Schasinglulu 244*91f16700Schasinglulu for (j = BIT(7); j != 0U; j >>= 1) { 245*91f16700Schasinglulu bit = crc & BIT(15); 246*91f16700Schasinglulu crc <<= 1; 247*91f16700Schasinglulu 248*91f16700Schasinglulu if ((cur_param & j) != 0U) { 249*91f16700Schasinglulu bit ^= BIT(15); 250*91f16700Schasinglulu } 251*91f16700Schasinglulu 252*91f16700Schasinglulu if (bit != 0U) { 253*91f16700Schasinglulu crc ^= CRC_POLYNOM; 254*91f16700Schasinglulu } 255*91f16700Schasinglulu } 256*91f16700Schasinglulu 257*91f16700Schasinglulu crc &= GENMASK(15, 0); 258*91f16700Schasinglulu } 259*91f16700Schasinglulu 260*91f16700Schasinglulu return crc; 261*91f16700Schasinglulu } 262*91f16700Schasinglulu 263*91f16700Schasinglulu static int nand_read_id(uint8_t addr, uint8_t *id, unsigned int size) 264*91f16700Schasinglulu { 265*91f16700Schasinglulu int ret; 266*91f16700Schasinglulu 267*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_READID, 0U); 268*91f16700Schasinglulu if (ret != 0) { 269*91f16700Schasinglulu return ret; 270*91f16700Schasinglulu } 271*91f16700Schasinglulu 272*91f16700Schasinglulu ret = nand_send_addr(addr, NAND_TWHR_MIN); 273*91f16700Schasinglulu if (ret != 0) { 274*91f16700Schasinglulu return ret; 275*91f16700Schasinglulu } 276*91f16700Schasinglulu 277*91f16700Schasinglulu return nand_read_data(id, size, true); 278*91f16700Schasinglulu } 279*91f16700Schasinglulu 280*91f16700Schasinglulu static int nand_read_param_page(void) 281*91f16700Schasinglulu { 282*91f16700Schasinglulu struct nand_param_page page; 283*91f16700Schasinglulu uint8_t addr = 0U; 284*91f16700Schasinglulu int ret; 285*91f16700Schasinglulu 286*91f16700Schasinglulu ret = nand_send_cmd(NAND_CMD_READ_PARAM_PAGE, 0U); 287*91f16700Schasinglulu if (ret != 0) { 288*91f16700Schasinglulu return ret; 289*91f16700Schasinglulu } 290*91f16700Schasinglulu 291*91f16700Schasinglulu ret = nand_send_addr(addr, NAND_TWB_MAX); 292*91f16700Schasinglulu if (ret != 0) { 293*91f16700Schasinglulu return ret; 294*91f16700Schasinglulu } 295*91f16700Schasinglulu 296*91f16700Schasinglulu ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN); 297*91f16700Schasinglulu if (ret != 0) { 298*91f16700Schasinglulu return ret; 299*91f16700Schasinglulu } 300*91f16700Schasinglulu 301*91f16700Schasinglulu ret = nand_read_data((uint8_t *)&page, sizeof(page), true); 302*91f16700Schasinglulu if (ret != 0) { 303*91f16700Schasinglulu return ret; 304*91f16700Schasinglulu } 305*91f16700Schasinglulu 306*91f16700Schasinglulu if (strncmp((char *)&page.page_sig, "ONFI", 4) != 0) { 307*91f16700Schasinglulu WARN("Error ONFI detection\n"); 308*91f16700Schasinglulu return -EINVAL; 309*91f16700Schasinglulu } 310*91f16700Schasinglulu 311*91f16700Schasinglulu if (nand_check_crc(CRC_INIT_VALUE, (uint8_t *)&page, 254U) != 312*91f16700Schasinglulu page.crc16) { 313*91f16700Schasinglulu WARN("Error reading param\n"); 314*91f16700Schasinglulu return -EINVAL; 315*91f16700Schasinglulu } 316*91f16700Schasinglulu 317*91f16700Schasinglulu if ((page.features & ONFI_FEAT_BUS_WIDTH_16) != 0U) { 318*91f16700Schasinglulu rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_16; 319*91f16700Schasinglulu } else { 320*91f16700Schasinglulu rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_8; 321*91f16700Schasinglulu } 322*91f16700Schasinglulu 323*91f16700Schasinglulu rawnand_dev.nand_dev->block_size = page.num_pages_per_blk * 324*91f16700Schasinglulu page.bytes_per_page; 325*91f16700Schasinglulu rawnand_dev.nand_dev->page_size = page.bytes_per_page; 326*91f16700Schasinglulu rawnand_dev.nand_dev->size = page.num_pages_per_blk * 327*91f16700Schasinglulu page.bytes_per_page * 328*91f16700Schasinglulu page.num_blk_in_lun * page.num_lun; 329*91f16700Schasinglulu 330*91f16700Schasinglulu if (page.nb_ecc_bits != GENMASK_32(7, 0)) { 331*91f16700Schasinglulu rawnand_dev.nand_dev->ecc.max_bit_corr = page.nb_ecc_bits; 332*91f16700Schasinglulu rawnand_dev.nand_dev->ecc.size = SZ_512; 333*91f16700Schasinglulu } 334*91f16700Schasinglulu 335*91f16700Schasinglulu VERBOSE("Page size %u, block_size %u, Size %llu, ecc %u, buswidth %u\n", 336*91f16700Schasinglulu rawnand_dev.nand_dev->page_size, 337*91f16700Schasinglulu rawnand_dev.nand_dev->block_size, rawnand_dev.nand_dev->size, 338*91f16700Schasinglulu rawnand_dev.nand_dev->ecc.max_bit_corr, 339*91f16700Schasinglulu rawnand_dev.nand_dev->buswidth); 340*91f16700Schasinglulu 341*91f16700Schasinglulu return 0; 342*91f16700Schasinglulu } 343*91f16700Schasinglulu 344*91f16700Schasinglulu static int detect_onfi(void) 345*91f16700Schasinglulu { 346*91f16700Schasinglulu int ret; 347*91f16700Schasinglulu char id[4]; 348*91f16700Schasinglulu 349*91f16700Schasinglulu ret = nand_read_id(ONFI_SIGNATURE_ADDR, (uint8_t *)id, sizeof(id)); 350*91f16700Schasinglulu if (ret != 0) { 351*91f16700Schasinglulu return ret; 352*91f16700Schasinglulu } 353*91f16700Schasinglulu 354*91f16700Schasinglulu if (strncmp(id, "ONFI", sizeof(id)) != 0) { 355*91f16700Schasinglulu WARN("NAND Non ONFI detected\n"); 356*91f16700Schasinglulu return -ENODEV; 357*91f16700Schasinglulu } 358*91f16700Schasinglulu 359*91f16700Schasinglulu return nand_read_param_page(); 360*91f16700Schasinglulu } 361*91f16700Schasinglulu #endif 362*91f16700Schasinglulu 363*91f16700Schasinglulu static int nand_mtd_block_is_bad(unsigned int block) 364*91f16700Schasinglulu { 365*91f16700Schasinglulu unsigned int nbpages_per_block = rawnand_dev.nand_dev->block_size / 366*91f16700Schasinglulu rawnand_dev.nand_dev->page_size; 367*91f16700Schasinglulu uint8_t bbm_marker[2]; 368*91f16700Schasinglulu uint8_t page; 369*91f16700Schasinglulu int ret; 370*91f16700Schasinglulu 371*91f16700Schasinglulu for (page = 0U; page < 2U; page++) { 372*91f16700Schasinglulu ret = nand_read_page_cmd(block * nbpages_per_block, 373*91f16700Schasinglulu rawnand_dev.nand_dev->page_size, 374*91f16700Schasinglulu (uintptr_t)bbm_marker, 375*91f16700Schasinglulu sizeof(bbm_marker)); 376*91f16700Schasinglulu if (ret != 0) { 377*91f16700Schasinglulu return ret; 378*91f16700Schasinglulu } 379*91f16700Schasinglulu 380*91f16700Schasinglulu if ((bbm_marker[0] != GENMASK_32(7, 0)) || 381*91f16700Schasinglulu (bbm_marker[1] != GENMASK_32(7, 0))) { 382*91f16700Schasinglulu WARN("Block %u is bad\n", block); 383*91f16700Schasinglulu return 1; 384*91f16700Schasinglulu } 385*91f16700Schasinglulu } 386*91f16700Schasinglulu 387*91f16700Schasinglulu return 0; 388*91f16700Schasinglulu } 389*91f16700Schasinglulu 390*91f16700Schasinglulu static int nand_mtd_read_page_raw(struct nand_device *nand, unsigned int page, 391*91f16700Schasinglulu uintptr_t buffer) 392*91f16700Schasinglulu { 393*91f16700Schasinglulu return nand_read_page_cmd(page, 0U, buffer, 394*91f16700Schasinglulu rawnand_dev.nand_dev->page_size); 395*91f16700Schasinglulu } 396*91f16700Schasinglulu 397*91f16700Schasinglulu void nand_raw_ctrl_init(const struct nand_ctrl_ops *ops) 398*91f16700Schasinglulu { 399*91f16700Schasinglulu rawnand_dev.ops = ops; 400*91f16700Schasinglulu } 401*91f16700Schasinglulu 402*91f16700Schasinglulu int nand_raw_init(unsigned long long *size, unsigned int *erase_size) 403*91f16700Schasinglulu { 404*91f16700Schasinglulu int ret; 405*91f16700Schasinglulu 406*91f16700Schasinglulu rawnand_dev.nand_dev = get_nand_device(); 407*91f16700Schasinglulu if (rawnand_dev.nand_dev == NULL) { 408*91f16700Schasinglulu return -EINVAL; 409*91f16700Schasinglulu } 410*91f16700Schasinglulu 411*91f16700Schasinglulu rawnand_dev.nand_dev->mtd_block_is_bad = nand_mtd_block_is_bad; 412*91f16700Schasinglulu rawnand_dev.nand_dev->mtd_read_page = nand_mtd_read_page_raw; 413*91f16700Schasinglulu rawnand_dev.nand_dev->ecc.mode = NAND_ECC_NONE; 414*91f16700Schasinglulu 415*91f16700Schasinglulu if ((rawnand_dev.ops->setup == NULL) || 416*91f16700Schasinglulu (rawnand_dev.ops->exec == NULL)) { 417*91f16700Schasinglulu return -ENODEV; 418*91f16700Schasinglulu } 419*91f16700Schasinglulu 420*91f16700Schasinglulu ret = nand_reset(); 421*91f16700Schasinglulu if (ret != 0) { 422*91f16700Schasinglulu return ret; 423*91f16700Schasinglulu } 424*91f16700Schasinglulu 425*91f16700Schasinglulu #if NAND_ONFI_DETECT 426*91f16700Schasinglulu if (detect_onfi() != 0) { 427*91f16700Schasinglulu WARN("Detect ONFI failed\n"); 428*91f16700Schasinglulu } 429*91f16700Schasinglulu #endif 430*91f16700Schasinglulu 431*91f16700Schasinglulu if (plat_get_raw_nand_data(&rawnand_dev) != 0) { 432*91f16700Schasinglulu return -EINVAL; 433*91f16700Schasinglulu } 434*91f16700Schasinglulu 435*91f16700Schasinglulu assert((rawnand_dev.nand_dev->page_size != 0U) && 436*91f16700Schasinglulu (rawnand_dev.nand_dev->block_size != 0U) && 437*91f16700Schasinglulu (rawnand_dev.nand_dev->size != 0U)); 438*91f16700Schasinglulu 439*91f16700Schasinglulu *size = rawnand_dev.nand_dev->size; 440*91f16700Schasinglulu *erase_size = rawnand_dev.nand_dev->block_size; 441*91f16700Schasinglulu 442*91f16700Schasinglulu rawnand_dev.ops->setup(rawnand_dev.nand_dev); 443*91f16700Schasinglulu 444*91f16700Schasinglulu return 0; 445*91f16700Schasinglulu } 446