1 /* 2 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <dm/device-internal.h> 10 #include <dm/lists.h> 11 #include <dm/root.h> 12 13 #include "rkflash_blk.h" 14 #include "rkflash_debug.h" 15 16 ulong rkflash_bread(struct udevice *udev, lbaint_t start, 17 lbaint_t blkcnt, void *dst) 18 { 19 struct blk_desc *block_dev = dev_get_uclass_platdata(udev); 20 struct rkflash_info *priv = dev_get_priv(udev->parent); 21 22 debug("%s lba %x cnt %x\n", __func__, (u32)start, (u32)blkcnt); 23 if (blkcnt == 0) 24 return 0; 25 26 if ((start + blkcnt) > block_dev->lba) 27 return -EINVAL; 28 29 if (!priv->read) 30 return -EINVAL; 31 32 return (ulong)priv->read(udev->parent, (u32)start, (u32)blkcnt, dst); 33 } 34 35 ulong rkflash_bwrite(struct udevice *udev, lbaint_t start, 36 lbaint_t blkcnt, const void *src) 37 { 38 struct blk_desc *block_dev = dev_get_uclass_platdata(udev); 39 struct rkflash_info *priv = dev_get_priv(udev->parent); 40 41 if (blkcnt == 0) 42 return 0; 43 44 if ((start + blkcnt) > block_dev->lba) 45 return -EINVAL; 46 47 if (!priv->write) 48 return -EINVAL; 49 50 return (ulong)priv->write(udev->parent, (u32)start, (u32)blkcnt, src); 51 } 52 53 ulong rkflash_berase(struct udevice *udev, lbaint_t start, 54 lbaint_t blkcnt) 55 { 56 struct blk_desc *block_dev = dev_get_uclass_platdata(udev); 57 struct rkflash_info *priv = dev_get_priv(udev->parent); 58 59 if (blkcnt == 0) 60 return 0; 61 62 if ((start + blkcnt) > block_dev->lba) 63 return -EINVAL; 64 65 if (!priv->erase) 66 return -EINVAL; 67 68 return (ulong)priv->erase(udev->parent, (u32)start, (u32)blkcnt); 69 } 70 71 static int rkflash_blk_probe(struct udevice *udev) 72 { 73 struct rkflash_info *priv = dev_get_priv(udev->parent); 74 struct blk_desc *desc = dev_get_uclass_platdata(udev); 75 char *product; 76 77 if (desc->if_type != priv->flash_con_type) 78 return -ENODEV; 79 80 switch (priv->flash_con_type) { 81 case IF_TYPE_RKNAND: 82 product = "rkflash-NandFlash"; 83 break; 84 case IF_TYPE_SPINAND: 85 product = "rkflash-SpiNand"; 86 break; 87 case IF_TYPE_SPINOR: 88 product = "rkflash-SpiNor"; 89 break; 90 default: 91 product = "unknown"; 92 break; 93 } 94 debug("%s %d %p ndev = %p %p\n", __func__, __LINE__, 95 udev, priv, udev->parent); 96 priv->child_dev = udev; 97 desc->lba = priv->density; 98 desc->log2blksz = 9; 99 desc->bdev = udev; 100 sprintf(desc->vendor, "0x%.4x", 0x0308); 101 memcpy(desc->product, product, strlen(product)); 102 memcpy(desc->revision, "V1.00", sizeof("V1.00")); 103 part_init(desc); 104 rkflash_test(udev); 105 106 return 0; 107 } 108 109 static const struct blk_ops rkflash_blk_ops = { 110 .read = rkflash_bread, 111 .write = rkflash_bwrite, 112 .erase = rkflash_berase, 113 }; 114 115 U_BOOT_DRIVER(rkflash_blk) = { 116 .name = "rkflash_blk", 117 .id = UCLASS_BLK, 118 .ops = &rkflash_blk_ops, 119 .probe = rkflash_blk_probe, 120 }; 121 122