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