xref: /OK3568_Linux_fs/u-boot/drivers/mtd/spi/sf_probe.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * SPI flash probing
3  *
4  * Copyright (C) 2008 Atmel Corporation
5  * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
6  * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
7  *
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 
11 #include <common.h>
12 #include <blk.h>
13 #include <dm.h>
14 #include <errno.h>
15 #include <malloc.h>
16 #include <spi.h>
17 #include <spi_flash.h>
18 
19 #include "sf_internal.h"
20 
21 /**
22  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
23  *
24  * @flashp: Pointer to place to put flash info, which may be NULL if the
25  * space should be allocated
26  */
spi_flash_probe_slave(struct spi_flash * flash)27 static int spi_flash_probe_slave(struct spi_flash *flash)
28 {
29 	struct spi_slave *spi = flash->spi;
30 	int ret;
31 
32 	/* Setup spi_slave */
33 	if (!spi) {
34 		printf("SF: Failed to set up slave\n");
35 		return -ENODEV;
36 	}
37 
38 	/* Claim spi bus */
39 	ret = spi_claim_bus(spi);
40 	if (ret) {
41 		debug("SF: Failed to claim SPI bus: %d\n", ret);
42 		return ret;
43 	}
44 
45 #if !CONFIG_IS_ENABLED(SPI_FLASH_TINY)
46 	flash->mtd.name = (char *)ofnode_read_string(spi->dev->node, "label");
47 #endif
48 
49 	ret = spi_nor_scan(flash);
50 	if (ret)
51 		goto err_read_id;
52 
53 #ifdef CONFIG_SPI_FLASH_MTD
54 	ret = spi_flash_mtd_register(flash);
55 #endif
56 
57 err_read_id:
58 	spi_release_bus(spi);
59 	return ret;
60 }
61 
62 #ifndef CONFIG_DM_SPI_FLASH
spi_flash_probe(unsigned int busnum,unsigned int cs,unsigned int max_hz,unsigned int spi_mode)63 struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
64 				  unsigned int max_hz, unsigned int spi_mode)
65 {
66 	struct spi_slave *bus;
67 	struct spi_flash *flash;
68 
69 	bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
70 	if (!bus)
71 		return NULL;
72 
73 	/* Allocate space if needed (not used by sf-uclass */
74 	flash = calloc(1, sizeof(*flash));
75 	if (!flash) {
76 		debug("SF: Failed to allocate spi_flash\n");
77 		return NULL;
78 	}
79 
80 	flash->spi = bus;
81 	if (spi_flash_probe_slave(flash)) {
82 		spi_free_slave(bus);
83 		free(flash);
84 		return NULL;
85 	}
86 
87 	return flash;
88 }
89 
spi_flash_free(struct spi_flash * flash)90 void spi_flash_free(struct spi_flash *flash)
91 {
92 #ifdef CONFIG_SPI_FLASH_MTD
93 	spi_flash_mtd_unregister();
94 #endif
95 	spi_free_slave(flash->spi);
96 	free(flash);
97 }
98 
99 #else /* defined CONFIG_DM_SPI_FLASH */
100 
spi_flash_std_read(struct udevice * dev,u32 offset,size_t len,void * buf)101 static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
102 			      void *buf)
103 {
104 	struct spi_flash *flash = dev_get_uclass_priv(dev);
105 	struct mtd_info *mtd = &flash->mtd;
106 	size_t retlen;
107 
108 	return log_ret(mtd->_read(mtd, offset, len, &retlen, buf));
109 }
110 
spi_flash_std_write(struct udevice * dev,u32 offset,size_t len,const void * buf)111 static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
112 			       const void *buf)
113 {
114 	struct spi_flash *flash = dev_get_uclass_priv(dev);
115 	struct mtd_info *mtd = &flash->mtd;
116 	size_t retlen;
117 
118 	return mtd->_write(mtd, offset, len, &retlen, buf);
119 }
120 
spi_flash_std_erase(struct udevice * dev,u32 offset,size_t len)121 static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
122 {
123 	struct spi_flash *flash = dev_get_uclass_priv(dev);
124 	struct mtd_info *mtd = &flash->mtd;
125 	struct erase_info instr;
126 
127 	if (offset % mtd->erasesize || len % mtd->erasesize) {
128 		printf("SF: Erase offset/length not multiple of erase size\n");
129 		return -EINVAL;
130 	}
131 
132 	memset(&instr, 0, sizeof(instr));
133 	instr.addr = offset;
134 	instr.len = len;
135 
136 	return mtd->_erase(mtd, &instr);
137 }
138 
spi_flash_std_get_sw_write_prot(struct udevice * dev)139 static int spi_flash_std_get_sw_write_prot(struct udevice *dev)
140 {
141 	struct spi_flash *flash = dev_get_uclass_priv(dev);
142 
143 	return spi_flash_cmd_get_sw_write_prot(flash);
144 }
145 
spi_flash_std_bind(struct udevice * udev)146 static int spi_flash_std_bind(struct udevice *udev)
147 {
148 	int ret = 0;
149 
150 #ifdef CONFIG_MTD_BLK
151 	struct udevice *bdev;
152 
153 	ret = blk_create_devicef(udev, "mtd_blk", "blk", IF_TYPE_MTD,
154 				 BLK_MTD_SPI_NOR, 512, 0, &bdev);
155 	if (ret)
156 		printf("Cannot create block device\n");
157 #endif
158 	return ret;
159 }
160 
spi_flash_std_probe(struct udevice * dev)161 static int spi_flash_std_probe(struct udevice *dev)
162 {
163 	struct spi_slave *slave = dev_get_parent_priv(dev);
164 	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
165 	struct spi_flash *flash;
166 
167 	flash = dev_get_uclass_priv(dev);
168 	flash->dev = dev;
169 	flash->spi = slave;
170 	debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
171 	return spi_flash_probe_slave(flash);
172 }
173 
spi_flash_std_remove(struct udevice * dev)174 static int spi_flash_std_remove(struct udevice *dev)
175 {
176 #ifdef CONFIG_SPI_FLASH_MTD
177 	spi_flash_mtd_unregister();
178 #endif
179 	return 0;
180 }
181 
182 static const struct dm_spi_flash_ops spi_flash_std_ops = {
183 	.read = spi_flash_std_read,
184 	.write = spi_flash_std_write,
185 	.erase = spi_flash_std_erase,
186 	.get_sw_write_prot = spi_flash_std_get_sw_write_prot,
187 };
188 
189 static const struct udevice_id spi_flash_std_ids[] = {
190 	{ .compatible = "jedec,spi-nor" },
191 	{ }
192 };
193 
194 U_BOOT_DRIVER(spi_flash_std) = {
195 	.name		= "spi_flash_std",
196 	.id		= UCLASS_SPI_FLASH,
197 	.of_match	= spi_flash_std_ids,
198 	.bind		= spi_flash_std_bind,
199 	.probe		= spi_flash_std_probe,
200 	.remove		= spi_flash_std_remove,
201 	.priv_auto_alloc_size = sizeof(struct spi_flash),
202 	.ops		= &spi_flash_std_ops,
203 };
204 
205 #endif /* CONFIG_DM_SPI_FLASH */
206