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