xref: /rk3399_rockchip-uboot/drivers/rkflash/rkflash_blk.c (revision dd472d4ff5b10cfcbdc7e46ec8efef420dc7b003)
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