xref: /rk3399_rockchip-uboot/drivers/rkflash/rkflash_api.c (revision c84f0ed80a3fa9a7c470bbcb6747b763280506fa)
1ad309a88SDingqiang Lin /*
2ad309a88SDingqiang Lin  * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
3ad309a88SDingqiang Lin  *
4ba0501acSDingqiang Lin  * SPDX-License-Identifier:	GPL-2.0
5ad309a88SDingqiang Lin  */
6ba0501acSDingqiang 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
14ba0501acSDingqiang 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 
22ba0501acSDingqiang 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 
30ba0501acSDingqiang Lin int rksfc_nor_read(struct udevice *udev, u32 sec, u32 n_sec, void *p_data)
31ad309a88SDingqiang Lin {
32ba0501acSDingqiang Lin 	u32 ret;
33ba0501acSDingqiang Lin 	u32 offset, count = 0;
34ba0501acSDingqiang 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 
38ba0501acSDingqiang Lin 	if (sec + n_sec - 1 < FLASH_VENDOR_PART_START ||
39ba0501acSDingqiang Lin 	    sec > FLASH_VENDOR_PART_END) {
40ba0501acSDingqiang Lin 		ret = snor_read(p_dev, sec, n_sec, p_data);
41ba0501acSDingqiang Lin 		if (ret != n_sec)
42ba0501acSDingqiang Lin 			return ret;
43ba0501acSDingqiang Lin 	} else {
44ba0501acSDingqiang Lin 		memset(p_data, 0, 512 * n_sec);
45ba0501acSDingqiang Lin 		if (sec < FLASH_VENDOR_PART_START) {
46ba0501acSDingqiang Lin 			count = FLASH_VENDOR_PART_START - sec;
47ba0501acSDingqiang Lin 			buf = (char *)p_data;
48ba0501acSDingqiang Lin 			ret = snor_read(p_dev, sec, count, buf);
49ba0501acSDingqiang Lin 			if (ret != count)
50ba0501acSDingqiang Lin 				return ret;
51ba0501acSDingqiang Lin 		}
52ba0501acSDingqiang Lin 		if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) {
53ba0501acSDingqiang Lin 			count = sec + n_sec - 1 - FLASH_VENDOR_PART_END;
54ba0501acSDingqiang Lin 			offset = FLASH_VENDOR_PART_END - sec + 1;
55ba0501acSDingqiang Lin 			buf = (char *)p_data + offset * 512;
56ba0501acSDingqiang Lin 			ret = snor_read(p_dev,
57ba0501acSDingqiang Lin 					FLASH_VENDOR_PART_END + 1,
58ba0501acSDingqiang Lin 					count, buf);
59ba0501acSDingqiang Lin 			if (ret != count)
60ba0501acSDingqiang Lin 				return ret;
61ba0501acSDingqiang Lin 		}
62ba0501acSDingqiang Lin 	}
63ba0501acSDingqiang Lin 
64ba0501acSDingqiang Lin 	return n_sec;
65ba0501acSDingqiang Lin }
66ba0501acSDingqiang Lin 
67ba0501acSDingqiang Lin int rksfc_nor_write(struct udevice *udev,
68ba0501acSDingqiang Lin 		    u32 sec,
69ba0501acSDingqiang Lin 		    u32 n_sec,
70ba0501acSDingqiang Lin 		    const void *p_data)
71ba0501acSDingqiang Lin {
72ba0501acSDingqiang Lin 	u32 ret;
73ba0501acSDingqiang Lin 	u32 offset, count = 0;
74ba0501acSDingqiang Lin 	char *buf = (char *)p_data;
75ba0501acSDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(udev);
76ba0501acSDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
77ba0501acSDingqiang Lin 
78ba0501acSDingqiang Lin 	if (sec + n_sec - 1 < FLASH_VENDOR_PART_START ||
79ba0501acSDingqiang Lin 	    sec > FLASH_VENDOR_PART_END) {
80*c84f0ed8SJon Lin 		ret = snor_write(p_dev, sec, n_sec, (void *)p_data);
81ba0501acSDingqiang Lin 		if (ret != n_sec)
82ba0501acSDingqiang Lin 			return ret;
83ba0501acSDingqiang Lin 	} else {
84ba0501acSDingqiang Lin 		if (sec < FLASH_VENDOR_PART_START) {
85ba0501acSDingqiang Lin 			count = FLASH_VENDOR_PART_START - sec;
86ba0501acSDingqiang Lin 			buf = (char *)p_data;
87ba0501acSDingqiang Lin 			ret = snor_write(p_dev, sec, count, buf);
88ba0501acSDingqiang Lin 			if (ret != count)
89ba0501acSDingqiang Lin 				return ret;
90ba0501acSDingqiang Lin 		}
91ba0501acSDingqiang Lin 		if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) {
92ba0501acSDingqiang Lin 			count = sec + n_sec - 1 - FLASH_VENDOR_PART_END;
93ba0501acSDingqiang Lin 			offset = FLASH_VENDOR_PART_END - sec + 1;
94ba0501acSDingqiang Lin 			buf = (char *)p_data + offset * 512;
95ba0501acSDingqiang Lin 			ret = snor_write(p_dev,
96ba0501acSDingqiang Lin 					 FLASH_VENDOR_PART_END + 1,
97ba0501acSDingqiang Lin 					 count, buf);
98ba0501acSDingqiang Lin 			if (ret != count)
99ba0501acSDingqiang Lin 				return ret;
100ba0501acSDingqiang Lin 		}
101ba0501acSDingqiang Lin 	}
102ba0501acSDingqiang Lin 
103ba0501acSDingqiang Lin 	return n_sec;
104ba0501acSDingqiang Lin }
105ba0501acSDingqiang Lin 
106ba0501acSDingqiang Lin int rksfc_nor_vendor_read(struct blk_desc *dev_desc,
107ba0501acSDingqiang Lin 			  u32 sec,
108ba0501acSDingqiang Lin 			  u32 n_sec,
109ba0501acSDingqiang Lin 			  void *p_data)
110ba0501acSDingqiang Lin {
111ba0501acSDingqiang Lin 	struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent);
112ba0501acSDingqiang Lin 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
113ba0501acSDingqiang Lin 
114ad309a88SDingqiang Lin 	return snor_read(p_dev, sec, n_sec, p_data);
115ad309a88SDingqiang Lin }
116ad309a88SDingqiang Lin 
117ba0501acSDingqiang Lin int rksfc_nor_vendor_write(struct blk_desc *dev_desc,
118ba0501acSDingqiang Lin 			   u32 sec,
119ba0501acSDingqiang Lin 			   u32 n_sec,
120ba0501acSDingqiang Lin 			   void *p_data)
121ad309a88SDingqiang Lin {
122ba0501acSDingqiang 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 }
127ba0501acSDingqiang Lin 
128ad309a88SDingqiang Lin #endif
129ad309a88SDingqiang Lin 
130ba0501acSDingqiang Lin #ifdef CONFIG_RKSFC_NAND
131ba0501acSDingqiang Lin int rksfc_nand_init(struct udevice *udev)
132ba0501acSDingqiang Lin {
133ba0501acSDingqiang Lin 	int ret;
134ba0501acSDingqiang Lin 
135ba0501acSDingqiang Lin 	ret = sfc_nand_init();
136*c84f0ed8SJon Lin 	if (ret) {
137ba0501acSDingqiang Lin 		return ret;
138*c84f0ed8SJon Lin 	} else {
139*c84f0ed8SJon Lin 		sfc_nand_ftl_ops_init();
140*c84f0ed8SJon Lin 
141ba0501acSDingqiang Lin 		return sftl_init();
142ba0501acSDingqiang Lin 	}
143*c84f0ed8SJon Lin }
144ba0501acSDingqiang Lin 
145ba0501acSDingqiang Lin int rksfc_nand_read(struct udevice *udev, u32 index, u32 count, void *buf)
146ba0501acSDingqiang Lin {
147ba0501acSDingqiang Lin 	int ret;
148ba0501acSDingqiang Lin 
149ba0501acSDingqiang Lin 	ret = sftl_read(index, count, (u8 *)buf);
150ba0501acSDingqiang Lin 	if (!ret)
151ba0501acSDingqiang Lin 		return count;
152ba0501acSDingqiang Lin 	else
153ba0501acSDingqiang Lin 		return -EIO;
154ba0501acSDingqiang Lin }
155ba0501acSDingqiang Lin 
156ba0501acSDingqiang Lin int rksfc_nand_write(struct udevice *udev,
157ba0501acSDingqiang Lin 		     u32 index,
158ba0501acSDingqiang Lin 		     u32 count,
159ba0501acSDingqiang Lin 		     const void *buf)
160ba0501acSDingqiang Lin {
161ba0501acSDingqiang Lin 	int ret;
162ba0501acSDingqiang Lin 
163ba0501acSDingqiang Lin 	ret = sftl_write(index, count, (u8 *)buf);
164ba0501acSDingqiang Lin 	if (!ret)
165ba0501acSDingqiang Lin 		return count;
166ba0501acSDingqiang Lin 	else
167ba0501acSDingqiang Lin 		return -EIO;
168ba0501acSDingqiang Lin }
169ba0501acSDingqiang Lin 
170ba0501acSDingqiang Lin u32 rksfc_nand_get_density(struct udevice *udev)
171ba0501acSDingqiang Lin {
172ba0501acSDingqiang Lin 	return sftl_get_density();
173ba0501acSDingqiang Lin }
17440bd3f86SDingqiang Lin 
17540bd3f86SDingqiang Lin int rksfc_nand_vendor_read(struct blk_desc *dev_desc,
17640bd3f86SDingqiang Lin 			   u32 sec,
17740bd3f86SDingqiang Lin 			   u32 n_sec,
17840bd3f86SDingqiang Lin 			   void *p_data)
17940bd3f86SDingqiang Lin {
18040bd3f86SDingqiang Lin 	int ret;
18140bd3f86SDingqiang Lin 
18240bd3f86SDingqiang Lin 	ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data);
18340bd3f86SDingqiang Lin 	if (!ret)
18440bd3f86SDingqiang Lin 		return n_sec;
18540bd3f86SDingqiang Lin 	else
18640bd3f86SDingqiang Lin 		return -EIO;
18740bd3f86SDingqiang Lin }
18840bd3f86SDingqiang Lin 
18940bd3f86SDingqiang Lin int rksfc_nand_vendor_write(struct blk_desc *dev_desc,
19040bd3f86SDingqiang Lin 			    u32 sec,
19140bd3f86SDingqiang Lin 			    u32 n_sec,
19240bd3f86SDingqiang Lin 			    void *p_data)
19340bd3f86SDingqiang Lin {
19440bd3f86SDingqiang Lin 	int ret;
19540bd3f86SDingqiang Lin 
19640bd3f86SDingqiang Lin 	ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data);
19740bd3f86SDingqiang Lin 	if (!ret)
19840bd3f86SDingqiang Lin 		return n_sec;
19940bd3f86SDingqiang Lin 	else
20040bd3f86SDingqiang Lin 		return -EIO;
20140bd3f86SDingqiang Lin }
20240bd3f86SDingqiang Lin 
203ba0501acSDingqiang Lin #endif
204ba0501acSDingqiang Lin 
205ba0501acSDingqiang Lin #ifdef CONFIG_RKNANDC_NAND
206ba0501acSDingqiang Lin int rknand_flash_init(struct udevice *udev)
207ba0501acSDingqiang Lin {
208ba0501acSDingqiang Lin 	return sftl_init();
209ba0501acSDingqiang Lin }
210ba0501acSDingqiang Lin 
211ba0501acSDingqiang Lin int rknand_flash_read(struct udevice *udev, u32 index, u32 count, void *buf)
212ba0501acSDingqiang Lin {
213ba0501acSDingqiang Lin 	int ret;
214ba0501acSDingqiang Lin 
215ba0501acSDingqiang Lin 	ret = sftl_read(index, count, (u8 *)buf);
216ba0501acSDingqiang Lin 	if (!ret)
217ba0501acSDingqiang Lin 		return count;
218ba0501acSDingqiang Lin 	else
219ba0501acSDingqiang Lin 		return -EIO;
220ba0501acSDingqiang Lin }
221ba0501acSDingqiang Lin 
222ba0501acSDingqiang Lin int rknand_flash_write(struct udevice *udev,
223ba0501acSDingqiang Lin 		       u32 index,
224ba0501acSDingqiang Lin 		       u32 count,
225ba0501acSDingqiang Lin 		       const void *buf)
226ba0501acSDingqiang Lin {
227ba0501acSDingqiang Lin 	int ret;
228ba0501acSDingqiang Lin 
229ba0501acSDingqiang Lin 	ret = sftl_write(index, count, (u8 *)buf);
230ba0501acSDingqiang Lin 	if (!ret)
231ba0501acSDingqiang Lin 		return count;
232ba0501acSDingqiang Lin 	else
233ba0501acSDingqiang Lin 		return -EIO;
234ba0501acSDingqiang Lin }
235ba0501acSDingqiang Lin 
236ba0501acSDingqiang Lin u32 rknand_flash_get_density(struct udevice *udev)
237ba0501acSDingqiang Lin {
238ba0501acSDingqiang Lin 	return sftl_get_density();
239ba0501acSDingqiang Lin }
24040bd3f86SDingqiang Lin 
24140bd3f86SDingqiang Lin int rknand_flash_vendor_read(struct blk_desc *dev_desc,
24240bd3f86SDingqiang Lin 			     u32 sec,
24340bd3f86SDingqiang Lin 			     u32 n_sec,
24440bd3f86SDingqiang Lin 			     void *p_data)
24540bd3f86SDingqiang Lin {
24640bd3f86SDingqiang Lin 	int ret;
24740bd3f86SDingqiang Lin 
24840bd3f86SDingqiang Lin 	ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data);
24940bd3f86SDingqiang Lin 	if (!ret)
25040bd3f86SDingqiang Lin 		return n_sec;
25140bd3f86SDingqiang Lin 	else
25240bd3f86SDingqiang Lin 		return -EIO;
25340bd3f86SDingqiang Lin }
25440bd3f86SDingqiang Lin 
25540bd3f86SDingqiang Lin int rknand_flash_vendor_write(struct blk_desc *dev_desc,
25640bd3f86SDingqiang Lin 			      u32 sec,
25740bd3f86SDingqiang Lin 			      u32 n_sec,
25840bd3f86SDingqiang Lin 			      void *p_data)
25940bd3f86SDingqiang Lin {
26040bd3f86SDingqiang Lin 	int ret;
26140bd3f86SDingqiang Lin 
26240bd3f86SDingqiang Lin 	ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data);
26340bd3f86SDingqiang Lin 	if (!ret)
26440bd3f86SDingqiang Lin 		return n_sec;
26540bd3f86SDingqiang Lin 	else
26640bd3f86SDingqiang Lin 		return -EIO;
26740bd3f86SDingqiang Lin }
26840bd3f86SDingqiang Lin 
269ba0501acSDingqiang Lin #endif
270