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