1*054229abSJason Zhu /* 2*054229abSJason Zhu * (C) Copyright 2019 Rockchip Electronics Co., Ltd 3*054229abSJason Zhu * 4*054229abSJason Zhu * SPDX-License-Identifier: GPL-2.0+ 5*054229abSJason Zhu */ 6*054229abSJason Zhu 7*054229abSJason Zhu #include <common.h> 8*054229abSJason Zhu #include <dm.h> 9*054229abSJason Zhu #include <errno.h> 10*054229abSJason Zhu #include <nand.h> 11*054229abSJason Zhu #include <dm/device-internal.h> 12*054229abSJason Zhu 13*054229abSJason Zhu ulong mtd_dread(struct udevice *udev, lbaint_t start, 14*054229abSJason Zhu lbaint_t blkcnt, void *dst) 15*054229abSJason Zhu { 16*054229abSJason Zhu struct blk_desc *desc = dev_get_uclass_platdata(udev); 17*054229abSJason Zhu 18*054229abSJason Zhu if (!desc) 19*054229abSJason Zhu return 0; 20*054229abSJason Zhu 21*054229abSJason Zhu if (blkcnt == 0) 22*054229abSJason Zhu return 0; 23*054229abSJason Zhu 24*054229abSJason Zhu if (desc->devnum == BLK_MTD_NAND) { 25*054229abSJason Zhu int ret = 0; 26*054229abSJason Zhu size_t rwsize = blkcnt * 512; 27*054229abSJason Zhu struct mtd_info *mtd = dev_get_priv(udev->parent); 28*054229abSJason Zhu struct nand_chip *chip = mtd_to_nand(mtd); 29*054229abSJason Zhu loff_t off = (loff_t)(start * 512); 30*054229abSJason Zhu 31*054229abSJason Zhu if (!mtd) { 32*054229abSJason Zhu puts("\nno mtd available\n"); 33*054229abSJason Zhu return 0; 34*054229abSJason Zhu } 35*054229abSJason Zhu 36*054229abSJason Zhu if (!chip) { 37*054229abSJason Zhu puts("\nno chip available\n"); 38*054229abSJason Zhu return 0; 39*054229abSJason Zhu } 40*054229abSJason Zhu 41*054229abSJason Zhu ret = nand_read_skip_bad(&chip->mtd, off, &rwsize, 42*054229abSJason Zhu NULL, chip->mtd.size, 43*054229abSJason Zhu (u_char *)(dst)); 44*054229abSJason Zhu if (ret) 45*054229abSJason Zhu return 0; 46*054229abSJason Zhu else 47*054229abSJason Zhu return blkcnt; 48*054229abSJason Zhu } else if (desc->devnum == BLK_MTD_SPI_NAND) { 49*054229abSJason Zhu /* Not implemented */ 50*054229abSJason Zhu return 0; 51*054229abSJason Zhu } else if (desc->devnum == BLK_MTD_SPI_NOR) { 52*054229abSJason Zhu /* Not implemented */ 53*054229abSJason Zhu return 0; 54*054229abSJason Zhu } else { 55*054229abSJason Zhu return 0; 56*054229abSJason Zhu } 57*054229abSJason Zhu } 58*054229abSJason Zhu 59*054229abSJason Zhu ulong mtd_dwrite(struct udevice *udev, lbaint_t start, 60*054229abSJason Zhu lbaint_t blkcnt, const void *src) 61*054229abSJason Zhu { 62*054229abSJason Zhu /* Not implemented */ 63*054229abSJason Zhu return 0; 64*054229abSJason Zhu } 65*054229abSJason Zhu 66*054229abSJason Zhu ulong mtd_derase(struct udevice *udev, lbaint_t start, 67*054229abSJason Zhu lbaint_t blkcnt) 68*054229abSJason Zhu { 69*054229abSJason Zhu /* Not implemented */ 70*054229abSJason Zhu return 0; 71*054229abSJason Zhu } 72*054229abSJason Zhu 73*054229abSJason Zhu static int mtd_blk_probe(struct udevice *udev) 74*054229abSJason Zhu { 75*054229abSJason Zhu struct blk_desc *desc = dev_get_uclass_platdata(udev); 76*054229abSJason Zhu 77*054229abSJason Zhu sprintf(desc->vendor, "0x%.4x", 0x2207); 78*054229abSJason Zhu memcpy(desc->product, "MTD", sizeof("MTD")); 79*054229abSJason Zhu memcpy(desc->revision, "V1.00", sizeof("V1.00")); 80*054229abSJason Zhu 81*054229abSJason Zhu return 0; 82*054229abSJason Zhu } 83*054229abSJason Zhu 84*054229abSJason Zhu static const struct blk_ops mtd_blk_ops = { 85*054229abSJason Zhu .read = mtd_dread, 86*054229abSJason Zhu #ifndef CONFIG_SPL_BUILD 87*054229abSJason Zhu .write = mtd_dwrite, 88*054229abSJason Zhu .erase = mtd_derase, 89*054229abSJason Zhu #endif 90*054229abSJason Zhu }; 91*054229abSJason Zhu 92*054229abSJason Zhu U_BOOT_DRIVER(mtd_blk) = { 93*054229abSJason Zhu .name = "mtd_blk", 94*054229abSJason Zhu .id = UCLASS_BLK, 95*054229abSJason Zhu .ops = &mtd_blk_ops, 96*054229abSJason Zhu .probe = mtd_blk_probe, 97*054229abSJason Zhu }; 98