xref: /rk3399_rockchip-uboot/drivers/rkflash/rksfc_base.c (revision 8e2bab3fc592f2c222a220d894a033e964c97a7a)
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 <clk.h>
9 #include <dm.h>
10 #include <dm/device-internal.h>
11 #include <asm/arch/clock.h>
12 #include <rksfc.h>
13 
14 #include "rkflash_blk.h"
15 #include "rkflash_api.h"
16 
17 static struct flash_operation sfc_nor_op = {
18 #ifdef	CONFIG_RKSFC_NOR
19 	IF_TYPE_SPINOR,
20 	rksfc_nor_init,
21 	rksfc_nor_get_capacity,
22 	rksfc_nor_read,
23 	rksfc_nor_write,
24 	NULL,
25 	rksfc_nor_vendor_read,
26 	rksfc_nor_vendor_write,
27 #else
28 	-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
29 #endif
30 };
31 
32 static struct flash_operation sfc_nand_op = {
33 #ifdef CONFIG_RKSFC_NAND
34 	IF_TYPE_SPINAND,
35 	rksfc_nand_init,
36 	rksfc_nand_get_density,
37 	rksfc_nand_read,
38 	rksfc_nand_write,
39 	NULL,
40 	NULL,
41 	NULL,
42 #else
43 	-1, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
44 #endif
45 };
46 
47 static struct flash_operation *spi_flash_op[2] = {
48 	&sfc_nor_op,
49 	&sfc_nand_op,
50 };
51 
52 int rksfc_scan_namespace(void)
53 {
54 	struct uclass *uc;
55 	struct udevice *dev;
56 	int ret;
57 
58 	ret = uclass_get(UCLASS_SPI_FLASH, &uc);
59 	if (ret)
60 		return ret;
61 
62 	uclass_foreach_dev(dev, uc) {
63 		debug("%s %d %p\n", __func__, __LINE__, dev);
64 		ret = device_probe(dev);
65 		if (ret)
66 			return ret;
67 	}
68 
69 	return 0;
70 }
71 
72 static int rksfc_blk_bind(struct udevice *udev)
73 {
74 	struct udevice *bdev;
75 	int ret;
76 
77 	ret = blk_create_devicef(udev, "rkflash_blk", "blk",
78 				 IF_TYPE_SPINAND,
79 				 0, 512, 0, &bdev);
80 	ret = blk_create_devicef(udev, "rkflash_blk", "blk",
81 				 IF_TYPE_SPINOR,
82 				 1, 512, 0, &bdev);
83 
84 	if (ret) {
85 		debug("Cannot create block device\n");
86 		return ret;
87 	}
88 
89 	return 0;
90 }
91 
92 static int rockchip_rksfc_ofdata_to_platdata(struct udevice *dev)
93 {
94 	struct rkflash_info *priv = dev_get_priv(dev);
95 
96 	priv->ioaddr = dev_read_addr_ptr(dev);
97 
98 	return 0;
99 }
100 
101 static int rockchip_rksfc_probe(struct udevice *udev)
102 {
103 	int ret = 0;
104 	int i;
105 	struct rkflash_info *priv = dev_get_priv(udev);
106 
107 	debug("%s %d %p ndev = %p\n", __func__, __LINE__, udev, priv);
108 
109 	sfc_init(priv->ioaddr);
110 	for (i = 0; i < 2; i++) {
111 		if (spi_flash_op[i]->id <= 0) {
112 			debug("%s no optional spi flash for type %x\n",
113 			      __func__, i);
114 			continue;
115 		}
116 		ret = spi_flash_op[i]->flash_init(udev);
117 		if (!ret) {
118 			priv->flash_con_type = spi_flash_op[i]->id;
119 			priv->density =
120 				spi_flash_op[i]->flash_get_capacity(udev);
121 			priv->read = spi_flash_op[i]->flash_read;
122 			priv->write = spi_flash_op[i]->flash_write;
123 			debug("%s probe success\n", __func__);
124 			break;
125 		}
126 	}
127 
128 	return ret;
129 }
130 
131 UCLASS_DRIVER(rksfc) = {
132 	.id		= UCLASS_SPI_FLASH,
133 	.name		= "rksfc",
134 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
135 };
136 
137 static const struct udevice_id rockchip_sfc_ids[] = {
138 	{ .compatible = "rockchip,rksfc" },
139 	{ }
140 };
141 
142 U_BOOT_DRIVER(rksfc) = {
143 	.name		= "rksfc",
144 	.id		= UCLASS_SPI_FLASH,
145 	.of_match	= rockchip_sfc_ids,
146 	.bind		= rksfc_blk_bind,
147 	.probe		= rockchip_rksfc_probe,
148 	.priv_auto_alloc_size = sizeof(struct rkflash_info),
149 	.ofdata_to_platdata = rockchip_rksfc_ofdata_to_platdata,
150 };
151 
152