xref: /OK3568_Linux_fs/u-boot/drivers/rkflash/rkflash_blk.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
rkflash_bread(struct udevice * udev,lbaint_t start,lbaint_t blkcnt,void * dst)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 
rkflash_bwrite(struct udevice * udev,lbaint_t start,lbaint_t blkcnt,const void * src)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 
rkflash_berase(struct udevice * udev,lbaint_t start,lbaint_t blkcnt)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 
rkflash_blk_probe(struct udevice * udev)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