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