xref: /rk3399_rockchip-uboot/drivers/mtd/mtd_blk.c (revision e6482de4e5bfec4f9a5b2f9a94eb78c320705f1e)
1054229abSJason Zhu /*
2054229abSJason Zhu  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3054229abSJason Zhu  *
4054229abSJason Zhu  * SPDX-License-Identifier:	GPL-2.0+
5054229abSJason Zhu  */
6054229abSJason Zhu 
7054229abSJason Zhu #include <common.h>
8054229abSJason Zhu #include <dm.h>
9054229abSJason Zhu #include <errno.h>
10054229abSJason Zhu #include <nand.h>
11054229abSJason Zhu #include <dm/device-internal.h>
12054229abSJason Zhu 
13054229abSJason Zhu ulong mtd_dread(struct udevice *udev, lbaint_t start,
14054229abSJason Zhu 		lbaint_t blkcnt, void *dst)
15054229abSJason Zhu {
16054229abSJason Zhu 	struct blk_desc *desc = dev_get_uclass_platdata(udev);
17054229abSJason Zhu 
18054229abSJason Zhu 	if (!desc)
19054229abSJason Zhu 		return 0;
20054229abSJason Zhu 
21054229abSJason Zhu 	if (blkcnt == 0)
22054229abSJason Zhu 		return 0;
23054229abSJason Zhu 
24054229abSJason Zhu 	if (desc->devnum == BLK_MTD_NAND) {
25054229abSJason Zhu 		int ret = 0;
26054229abSJason Zhu 		size_t rwsize = blkcnt * 512;
27054229abSJason Zhu 		struct mtd_info *mtd = dev_get_priv(udev->parent);
28054229abSJason Zhu 		struct nand_chip *chip = mtd_to_nand(mtd);
29054229abSJason Zhu 		loff_t off = (loff_t)(start * 512);
30054229abSJason Zhu 
31054229abSJason Zhu 		if (!mtd) {
32054229abSJason Zhu 			puts("\nno mtd available\n");
33054229abSJason Zhu 			return 0;
34054229abSJason Zhu 		}
35054229abSJason Zhu 
36054229abSJason Zhu 		if (!chip) {
37054229abSJason Zhu 			puts("\nno chip available\n");
38054229abSJason Zhu 			return 0;
39054229abSJason Zhu 		}
40054229abSJason Zhu 
41054229abSJason Zhu 		ret = nand_read_skip_bad(&chip->mtd, off, &rwsize,
42054229abSJason Zhu 					 NULL, chip->mtd.size,
43054229abSJason Zhu 					 (u_char *)(dst));
44054229abSJason Zhu 		if (ret)
45054229abSJason Zhu 			return 0;
46054229abSJason Zhu 		else
47054229abSJason Zhu 			return blkcnt;
48054229abSJason Zhu 	} else if (desc->devnum == BLK_MTD_SPI_NAND) {
49054229abSJason Zhu 		/* Not implemented */
50054229abSJason Zhu 		return 0;
51054229abSJason Zhu 	} else if (desc->devnum == BLK_MTD_SPI_NOR) {
52054229abSJason Zhu 		/* Not implemented */
53054229abSJason Zhu 		return 0;
54054229abSJason Zhu 	} else {
55054229abSJason Zhu 		return 0;
56054229abSJason Zhu 	}
57054229abSJason Zhu }
58054229abSJason Zhu 
59054229abSJason Zhu ulong mtd_dwrite(struct udevice *udev, lbaint_t start,
60054229abSJason Zhu 		 lbaint_t blkcnt, const void *src)
61054229abSJason Zhu {
62054229abSJason Zhu 	/* Not implemented */
63054229abSJason Zhu 	return 0;
64054229abSJason Zhu }
65054229abSJason Zhu 
66054229abSJason Zhu ulong mtd_derase(struct udevice *udev, lbaint_t start,
67054229abSJason Zhu 		 lbaint_t blkcnt)
68054229abSJason Zhu {
69054229abSJason Zhu 	/* Not implemented */
70054229abSJason Zhu 	return 0;
71054229abSJason Zhu }
72054229abSJason Zhu 
73054229abSJason Zhu static int mtd_blk_probe(struct udevice *udev)
74054229abSJason Zhu {
75054229abSJason Zhu 	struct blk_desc *desc = dev_get_uclass_platdata(udev);
76f1892190SJason Zhu 	struct mtd_info *mtd = dev_get_priv(udev->parent);
77054229abSJason Zhu 
78054229abSJason Zhu 	sprintf(desc->vendor, "0x%.4x", 0x2207);
79*e6482de4SJason Zhu 	memcpy(desc->product, mtd->name, strlen(mtd->name));
80054229abSJason Zhu 	memcpy(desc->revision, "V1.00", sizeof("V1.00"));
81f1892190SJason Zhu 	if (mtd->type == MTD_NANDFLASH) {
82f1892190SJason Zhu 		/* Reserve 4 blocks for BBT(Bad Block Table) */
83f1892190SJason Zhu 		desc->lba = (mtd->size >> 9) - (mtd->erasesize >> 9) * 4;
84f1892190SJason Zhu 	} else {
85f1892190SJason Zhu 		desc->lba = mtd->size >> 9;
86f1892190SJason Zhu 	}
87054229abSJason Zhu 
88054229abSJason Zhu 	return 0;
89054229abSJason Zhu }
90054229abSJason Zhu 
91054229abSJason Zhu static const struct blk_ops mtd_blk_ops = {
92054229abSJason Zhu 	.read	= mtd_dread,
93054229abSJason Zhu #ifndef CONFIG_SPL_BUILD
94054229abSJason Zhu 	.write	= mtd_dwrite,
95054229abSJason Zhu 	.erase	= mtd_derase,
96054229abSJason Zhu #endif
97054229abSJason Zhu };
98054229abSJason Zhu 
99054229abSJason Zhu U_BOOT_DRIVER(mtd_blk) = {
100054229abSJason Zhu 	.name		= "mtd_blk",
101054229abSJason Zhu 	.id		= UCLASS_BLK,
102054229abSJason Zhu 	.ops		= &mtd_blk_ops,
103054229abSJason Zhu 	.probe		= mtd_blk_probe,
104054229abSJason Zhu };
105