xref: /rk3399_rockchip-uboot/drivers/rkflash/rkflash_api.c (revision ba0501aca290ca5c87ce48b247d37c934d6108cf)
1ad309a88SDingqiang Lin /*
2ad309a88SDingqiang Lin  * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
3ad309a88SDingqiang Lin  *
4*ba0501acSDingqiang Lin  * SPDX-License-Identifier:	GPL-2.0
5ad309a88SDingqiang Lin  */
6*ba0501acSDingqiang Lin 
7ad309a88SDingqiang Lin #include <common.h>
8ad309a88SDingqiang Lin #include <dm.h>
9ad309a88SDingqiang Lin 
10ad309a88SDingqiang Lin #include "rkflash_api.h"
11ad309a88SDingqiang Lin #include "rkflash_blk.h"
12ad309a88SDingqiang Lin 
13ad309a88SDingqiang Lin #ifdef CONFIG_RKSFC_NOR
14*ba0501acSDingqiang Lin int rksfc_nor_init(struct udevice *udev)
15ad309a88SDingqiang Lin {
16ad309a88SDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(udev);
17ad309a88SDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
18ad309a88SDingqiang Lin 
19ad309a88SDingqiang Lin 	return snor_init(p_dev);
20ad309a88SDingqiang Lin }
21ad309a88SDingqiang Lin 
22*ba0501acSDingqiang Lin u32 rksfc_nor_get_capacity(struct udevice *udev)
23ad309a88SDingqiang Lin {
24ad309a88SDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(udev);
25ad309a88SDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
26ad309a88SDingqiang Lin 
27ad309a88SDingqiang Lin 	return snor_get_capacity(p_dev);
28ad309a88SDingqiang Lin }
29ad309a88SDingqiang Lin 
30*ba0501acSDingqiang Lin int rksfc_nor_read(struct udevice *udev, u32 sec, u32 n_sec, void *p_data)
31ad309a88SDingqiang Lin {
32*ba0501acSDingqiang Lin 	u32 ret;
33*ba0501acSDingqiang Lin 	u32 offset, count = 0;
34*ba0501acSDingqiang Lin 	char *buf = (char *)p_data;
35ad309a88SDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(udev);
36ad309a88SDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
37ad309a88SDingqiang Lin 
38*ba0501acSDingqiang Lin 	if (sec + n_sec - 1 < FLASH_VENDOR_PART_START ||
39*ba0501acSDingqiang Lin 	    sec > FLASH_VENDOR_PART_END) {
40*ba0501acSDingqiang Lin 		ret = snor_read(p_dev, sec, n_sec, p_data);
41*ba0501acSDingqiang Lin 		if (ret != n_sec)
42*ba0501acSDingqiang Lin 			return ret;
43*ba0501acSDingqiang Lin 	} else {
44*ba0501acSDingqiang Lin 		memset(p_data, 0, 512 * n_sec);
45*ba0501acSDingqiang Lin 		if (sec < FLASH_VENDOR_PART_START) {
46*ba0501acSDingqiang Lin 			count = FLASH_VENDOR_PART_START - sec;
47*ba0501acSDingqiang Lin 			buf = (char *)p_data;
48*ba0501acSDingqiang Lin 			ret = snor_read(p_dev, sec, count, buf);
49*ba0501acSDingqiang Lin 			if (ret != count)
50*ba0501acSDingqiang Lin 				return ret;
51*ba0501acSDingqiang Lin 		}
52*ba0501acSDingqiang Lin 		if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) {
53*ba0501acSDingqiang Lin 			count = sec + n_sec - 1 - FLASH_VENDOR_PART_END;
54*ba0501acSDingqiang Lin 			offset = FLASH_VENDOR_PART_END - sec + 1;
55*ba0501acSDingqiang Lin 			buf = (char *)p_data + offset * 512;
56*ba0501acSDingqiang Lin 			ret = snor_read(p_dev,
57*ba0501acSDingqiang Lin 					FLASH_VENDOR_PART_END + 1,
58*ba0501acSDingqiang Lin 					count, buf);
59*ba0501acSDingqiang Lin 			if (ret != count)
60*ba0501acSDingqiang Lin 				return ret;
61*ba0501acSDingqiang Lin 		}
62*ba0501acSDingqiang Lin 	}
63*ba0501acSDingqiang Lin 
64*ba0501acSDingqiang Lin 	return n_sec;
65*ba0501acSDingqiang Lin }
66*ba0501acSDingqiang Lin 
67*ba0501acSDingqiang Lin int rksfc_nor_write(struct udevice *udev,
68*ba0501acSDingqiang Lin 		    u32 sec,
69*ba0501acSDingqiang Lin 		    u32 n_sec,
70*ba0501acSDingqiang Lin 		    const void *p_data)
71*ba0501acSDingqiang Lin {
72*ba0501acSDingqiang Lin 	u32 ret;
73*ba0501acSDingqiang Lin 	u32 offset, count = 0;
74*ba0501acSDingqiang Lin 	char *buf = (char *)p_data;
75*ba0501acSDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(udev);
76*ba0501acSDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
77*ba0501acSDingqiang Lin 
78*ba0501acSDingqiang Lin 	if (sec + n_sec - 1 < FLASH_VENDOR_PART_START ||
79*ba0501acSDingqiang Lin 	    sec > FLASH_VENDOR_PART_END) {
80*ba0501acSDingqiang Lin 		ret = snor_write(p_dev, sec, n_sec, p_data);
81*ba0501acSDingqiang Lin 		if (ret != n_sec)
82*ba0501acSDingqiang Lin 			return ret;
83*ba0501acSDingqiang Lin 	} else {
84*ba0501acSDingqiang Lin 		if (sec < FLASH_VENDOR_PART_START) {
85*ba0501acSDingqiang Lin 			count = FLASH_VENDOR_PART_START - sec;
86*ba0501acSDingqiang Lin 			buf = (char *)p_data;
87*ba0501acSDingqiang Lin 			ret = snor_write(p_dev, sec, count, buf);
88*ba0501acSDingqiang Lin 			if (ret != count)
89*ba0501acSDingqiang Lin 				return ret;
90*ba0501acSDingqiang Lin 		}
91*ba0501acSDingqiang Lin 		if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) {
92*ba0501acSDingqiang Lin 			count = sec + n_sec - 1 - FLASH_VENDOR_PART_END;
93*ba0501acSDingqiang Lin 			offset = FLASH_VENDOR_PART_END - sec + 1;
94*ba0501acSDingqiang Lin 			buf = (char *)p_data + offset * 512;
95*ba0501acSDingqiang Lin 			ret = snor_write(p_dev,
96*ba0501acSDingqiang Lin 					 FLASH_VENDOR_PART_END + 1,
97*ba0501acSDingqiang Lin 					 count, buf);
98*ba0501acSDingqiang Lin 			if (ret != count)
99*ba0501acSDingqiang Lin 				return ret;
100*ba0501acSDingqiang Lin 		}
101*ba0501acSDingqiang Lin 	}
102*ba0501acSDingqiang Lin 
103*ba0501acSDingqiang Lin 	return n_sec;
104*ba0501acSDingqiang Lin }
105*ba0501acSDingqiang Lin 
106*ba0501acSDingqiang Lin int rksfc_nor_vendor_read(struct blk_desc *dev_desc,
107*ba0501acSDingqiang Lin 			  u32 sec,
108*ba0501acSDingqiang Lin 			  u32 n_sec,
109*ba0501acSDingqiang Lin 			  void *p_data)
110*ba0501acSDingqiang Lin {
111*ba0501acSDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent);
112*ba0501acSDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
113*ba0501acSDingqiang Lin 
114ad309a88SDingqiang Lin 	return snor_read(p_dev, sec, n_sec, p_data);
115ad309a88SDingqiang Lin }
116ad309a88SDingqiang Lin 
117*ba0501acSDingqiang Lin int rksfc_nor_vendor_write(struct blk_desc *dev_desc,
118*ba0501acSDingqiang Lin 			   u32 sec,
119*ba0501acSDingqiang Lin 			   u32 n_sec,
120*ba0501acSDingqiang Lin 			   void *p_data)
121ad309a88SDingqiang Lin {
122*ba0501acSDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent);
123ad309a88SDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
124ad309a88SDingqiang Lin 
125ad309a88SDingqiang Lin 	return snor_write(p_dev, sec, n_sec, p_data);
126ad309a88SDingqiang Lin }
127*ba0501acSDingqiang Lin 
128ad309a88SDingqiang Lin #endif
129ad309a88SDingqiang Lin 
130*ba0501acSDingqiang Lin #ifdef CONFIG_RKSFC_NAND
131*ba0501acSDingqiang Lin int rksfc_nand_init(struct udevice *udev)
132*ba0501acSDingqiang Lin {
133*ba0501acSDingqiang Lin 	int ret;
134*ba0501acSDingqiang Lin 
135*ba0501acSDingqiang Lin 	ret = sfc_nand_init();
136*ba0501acSDingqiang Lin 	if (ret)
137*ba0501acSDingqiang Lin 		return ret;
138*ba0501acSDingqiang Lin 	else
139*ba0501acSDingqiang Lin 		return sftl_init();
140*ba0501acSDingqiang Lin }
141*ba0501acSDingqiang Lin 
142*ba0501acSDingqiang Lin int rksfc_nand_read(struct udevice *udev, u32 index, u32 count, void *buf)
143*ba0501acSDingqiang Lin {
144*ba0501acSDingqiang Lin 	int ret;
145*ba0501acSDingqiang Lin 
146*ba0501acSDingqiang Lin 	ret = sftl_read(index, count, (u8 *)buf);
147*ba0501acSDingqiang Lin 	if (!ret)
148*ba0501acSDingqiang Lin 		return count;
149*ba0501acSDingqiang Lin 	else
150*ba0501acSDingqiang Lin 		return -EIO;
151*ba0501acSDingqiang Lin }
152*ba0501acSDingqiang Lin 
153*ba0501acSDingqiang Lin int rksfc_nand_write(struct udevice *udev,
154*ba0501acSDingqiang Lin 		     u32 index,
155*ba0501acSDingqiang Lin 		     u32 count,
156*ba0501acSDingqiang Lin 		     const void *buf)
157*ba0501acSDingqiang Lin {
158*ba0501acSDingqiang Lin 	int ret;
159*ba0501acSDingqiang Lin 
160*ba0501acSDingqiang Lin 	ret = sftl_write(index, count, (u8 *)buf);
161*ba0501acSDingqiang Lin 	if (!ret)
162*ba0501acSDingqiang Lin 		return count;
163*ba0501acSDingqiang Lin 	else
164*ba0501acSDingqiang Lin 		return -EIO;
165*ba0501acSDingqiang Lin }
166*ba0501acSDingqiang Lin 
167*ba0501acSDingqiang Lin u32 rksfc_nand_get_density(struct udevice *udev)
168*ba0501acSDingqiang Lin {
169*ba0501acSDingqiang Lin 	return sftl_get_density();
170*ba0501acSDingqiang Lin }
171*ba0501acSDingqiang Lin #endif
172*ba0501acSDingqiang Lin 
173*ba0501acSDingqiang Lin #ifdef CONFIG_RKNANDC_NAND
174*ba0501acSDingqiang Lin int rknand_flash_init(struct udevice *udev)
175*ba0501acSDingqiang Lin {
176*ba0501acSDingqiang Lin 	return sftl_init();
177*ba0501acSDingqiang Lin }
178*ba0501acSDingqiang Lin 
179*ba0501acSDingqiang Lin int rknand_flash_read(struct udevice *udev, u32 index, u32 count, void *buf)
180*ba0501acSDingqiang Lin {
181*ba0501acSDingqiang Lin 	int ret;
182*ba0501acSDingqiang Lin 
183*ba0501acSDingqiang Lin 	ret = sftl_read(index, count, (u8 *)buf);
184*ba0501acSDingqiang Lin 	if (!ret)
185*ba0501acSDingqiang Lin 		return count;
186*ba0501acSDingqiang Lin 	else
187*ba0501acSDingqiang Lin 		return -EIO;
188*ba0501acSDingqiang Lin }
189*ba0501acSDingqiang Lin 
190*ba0501acSDingqiang Lin int rknand_flash_write(struct udevice *udev,
191*ba0501acSDingqiang Lin 		       u32 index,
192*ba0501acSDingqiang Lin 		       u32 count,
193*ba0501acSDingqiang Lin 		       const void *buf)
194*ba0501acSDingqiang Lin {
195*ba0501acSDingqiang Lin 	int ret;
196*ba0501acSDingqiang Lin 
197*ba0501acSDingqiang Lin 	ret = sftl_write(index, count, (u8 *)buf);
198*ba0501acSDingqiang Lin 	if (!ret)
199*ba0501acSDingqiang Lin 		return count;
200*ba0501acSDingqiang Lin 	else
201*ba0501acSDingqiang Lin 		return -EIO;
202*ba0501acSDingqiang Lin }
203*ba0501acSDingqiang Lin 
204*ba0501acSDingqiang Lin u32 rknand_flash_get_density(struct udevice *udev)
205*ba0501acSDingqiang Lin {
206*ba0501acSDingqiang Lin 	return sftl_get_density();
207*ba0501acSDingqiang Lin }
208*ba0501acSDingqiang Lin #endif
209