1054229abSJason Zhu /* 2054229abSJason Zhu * (C) Copyright 2019 Rockchip Electronics Co., Ltd 3054229abSJason Zhu * 4054229abSJason Zhu * SPDX-License-Identifier: GPL-2.0+ 5054229abSJason Zhu */ 6054229abSJason Zhu 7054229abSJason Zhu #include <common.h> 8054229abSJason Zhu #include <dm.h> 9054229abSJason Zhu #include <errno.h> 10054229abSJason Zhu #include <nand.h> 11054229abSJason Zhu #include <dm/device-internal.h> 12054229abSJason Zhu 13054229abSJason Zhu ulong mtd_dread(struct udevice *udev, lbaint_t start, 14054229abSJason Zhu lbaint_t blkcnt, void *dst) 15054229abSJason Zhu { 16054229abSJason Zhu struct blk_desc *desc = dev_get_uclass_platdata(udev); 17054229abSJason Zhu 18054229abSJason Zhu if (!desc) 19054229abSJason Zhu return 0; 20054229abSJason Zhu 21054229abSJason Zhu if (blkcnt == 0) 22054229abSJason Zhu return 0; 23054229abSJason Zhu 24054229abSJason Zhu if (desc->devnum == BLK_MTD_NAND) { 25054229abSJason Zhu int ret = 0; 26054229abSJason Zhu size_t rwsize = blkcnt * 512; 27054229abSJason Zhu struct mtd_info *mtd = dev_get_priv(udev->parent); 28054229abSJason Zhu struct nand_chip *chip = mtd_to_nand(mtd); 29054229abSJason Zhu loff_t off = (loff_t)(start * 512); 30054229abSJason Zhu 31054229abSJason Zhu if (!mtd) { 32054229abSJason Zhu puts("\nno mtd available\n"); 33054229abSJason Zhu return 0; 34054229abSJason Zhu } 35054229abSJason Zhu 36054229abSJason Zhu if (!chip) { 37054229abSJason Zhu puts("\nno chip available\n"); 38054229abSJason Zhu return 0; 39054229abSJason Zhu } 40054229abSJason Zhu 41054229abSJason Zhu ret = nand_read_skip_bad(&chip->mtd, off, &rwsize, 42054229abSJason Zhu NULL, chip->mtd.size, 43054229abSJason Zhu (u_char *)(dst)); 44054229abSJason Zhu if (ret) 45054229abSJason Zhu return 0; 46054229abSJason Zhu else 47054229abSJason Zhu return blkcnt; 48054229abSJason Zhu } else if (desc->devnum == BLK_MTD_SPI_NAND) { 49054229abSJason Zhu /* Not implemented */ 50054229abSJason Zhu return 0; 51054229abSJason Zhu } else if (desc->devnum == BLK_MTD_SPI_NOR) { 52054229abSJason Zhu /* Not implemented */ 53054229abSJason Zhu return 0; 54054229abSJason Zhu } else { 55054229abSJason Zhu return 0; 56054229abSJason Zhu } 57054229abSJason Zhu } 58054229abSJason Zhu 59054229abSJason Zhu ulong mtd_dwrite(struct udevice *udev, lbaint_t start, 60054229abSJason Zhu lbaint_t blkcnt, const void *src) 61054229abSJason Zhu { 62054229abSJason Zhu /* Not implemented */ 63054229abSJason Zhu return 0; 64054229abSJason Zhu } 65054229abSJason Zhu 66054229abSJason Zhu ulong mtd_derase(struct udevice *udev, lbaint_t start, 67054229abSJason Zhu lbaint_t blkcnt) 68054229abSJason Zhu { 69054229abSJason Zhu /* Not implemented */ 70054229abSJason Zhu return 0; 71054229abSJason Zhu } 72054229abSJason Zhu 73054229abSJason Zhu static int mtd_blk_probe(struct udevice *udev) 74054229abSJason Zhu { 75054229abSJason Zhu struct blk_desc *desc = dev_get_uclass_platdata(udev); 76f1892190SJason Zhu struct mtd_info *mtd = dev_get_priv(udev->parent); 77054229abSJason Zhu 78054229abSJason Zhu sprintf(desc->vendor, "0x%.4x", 0x2207); 79*e6482de4SJason Zhu memcpy(desc->product, mtd->name, strlen(mtd->name)); 80054229abSJason Zhu memcpy(desc->revision, "V1.00", sizeof("V1.00")); 81f1892190SJason Zhu if (mtd->type == MTD_NANDFLASH) { 82f1892190SJason Zhu /* Reserve 4 blocks for BBT(Bad Block Table) */ 83f1892190SJason Zhu desc->lba = (mtd->size >> 9) - (mtd->erasesize >> 9) * 4; 84f1892190SJason Zhu } else { 85f1892190SJason Zhu desc->lba = mtd->size >> 9; 86f1892190SJason Zhu } 87054229abSJason Zhu 88054229abSJason Zhu return 0; 89054229abSJason Zhu } 90054229abSJason Zhu 91054229abSJason Zhu static const struct blk_ops mtd_blk_ops = { 92054229abSJason Zhu .read = mtd_dread, 93054229abSJason Zhu #ifndef CONFIG_SPL_BUILD 94054229abSJason Zhu .write = mtd_dwrite, 95054229abSJason Zhu .erase = mtd_derase, 96054229abSJason Zhu #endif 97054229abSJason Zhu }; 98054229abSJason Zhu 99054229abSJason Zhu U_BOOT_DRIVER(mtd_blk) = { 100054229abSJason Zhu .name = "mtd_blk", 101054229abSJason Zhu .id = UCLASS_BLK, 102054229abSJason Zhu .ops = &mtd_blk_ops, 103054229abSJason Zhu .probe = mtd_blk_probe, 104054229abSJason Zhu }; 105