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 void ftl_free(void *buf) 17 { 18 kfree(buf); 19 } 20 21 ulong rkflash_bread(struct udevice *udev, lbaint_t start, 22 lbaint_t blkcnt, void *dst) 23 { 24 struct blk_desc *block_dev = dev_get_uclass_platdata(udev); 25 struct rkflash_info *priv = dev_get_priv(udev->parent); 26 27 debug("%s lba %x cnt %x", __func__, (u32)start, (u32)blkcnt); 28 if (blkcnt == 0) 29 return -EINVAL; 30 31 if ((start + blkcnt) > block_dev->lba) 32 return -EINVAL; 33 34 if (!priv->read) 35 return -EINVAL; 36 37 return (ulong)priv->read(udev->parent, (u32)start, (u32)blkcnt, dst); 38 } 39 40 ulong rkflash_bwrite(struct udevice *udev, lbaint_t start, 41 lbaint_t blkcnt, const void *src) 42 { 43 struct blk_desc *block_dev = dev_get_uclass_platdata(udev); 44 struct rkflash_info *priv = dev_get_priv(udev->parent); 45 46 if (blkcnt == 0) 47 return -EINVAL; 48 49 if ((start + blkcnt) > block_dev->lba) 50 return -EINVAL; 51 52 if (!priv->write) 53 return -EINVAL; 54 55 return (ulong)priv->write(udev->parent, (u32)start, (u32)blkcnt, src); 56 } 57 58 ulong rkflash_berase(struct udevice *udev, lbaint_t start, 59 lbaint_t blkcnt) 60 { 61 struct blk_desc *block_dev = dev_get_uclass_platdata(udev); 62 struct rkflash_info *priv = dev_get_priv(udev->parent); 63 64 if (blkcnt == 0) 65 return -EINVAL; 66 67 if ((start + blkcnt) > block_dev->lba) 68 return -EINVAL; 69 70 if (!priv->erase) 71 return -EINVAL; 72 73 return (ulong)priv->erase(udev->parent, (u32)start, (u32)blkcnt); 74 } 75 76 static int rkflash_blk_probe(struct udevice *udev) 77 { 78 struct rkflash_info *priv = dev_get_priv(udev->parent); 79 struct blk_desc *desc = dev_get_uclass_platdata(udev); 80 81 debug("%s %d %p ndev = %p %p\n", __func__, __LINE__, 82 udev, priv, udev->parent); 83 priv->child_dev = udev; 84 if (priv->flash_con_type == FLASH_CON_TYPE_SFC) 85 desc->if_type = IF_TYPE_RKSFC; 86 else if (priv->flash_con_type == FLASH_CON_TYPE_NANDC) 87 desc->if_type = IF_TYPE_RKNAND; 88 89 desc->lba = priv->density; 90 desc->log2blksz = 9; 91 desc->blksz = 512; 92 desc->bdev = udev; 93 desc->devnum = 0; 94 sprintf(desc->vendor, "0x%.4x", 0x0308); 95 memcpy(desc->product, "rkflash", sizeof("rkflash")); 96 memcpy(desc->revision, "V1.00", sizeof("V1.00")); 97 part_init(desc); 98 rkflash_test(udev); 99 100 return 0; 101 } 102 103 static const struct blk_ops rkflash_blk_ops = { 104 .read = rkflash_bread, 105 .write = rkflash_bwrite, 106 .erase = rkflash_berase, 107 }; 108 109 U_BOOT_DRIVER(rkflash_blk) = { 110 .name = "rkflash_blk", 111 .id = UCLASS_BLK, 112 .ops = &rkflash_blk_ops, 113 .probe = rkflash_blk_probe, 114 }; 115 116