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