183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0 */
2d25ce7d2SHaavard Skinnemoen /*
3a5e8199aSJagannadha Sutradharudu Teki * Common SPI flash Interface
4d25ce7d2SHaavard Skinnemoen *
5d25ce7d2SHaavard Skinnemoen * Copyright (C) 2008 Atmel Corporation
6a5e8199aSJagannadha Sutradharudu Teki * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
7d25ce7d2SHaavard Skinnemoen */
8a5e8199aSJagannadha Sutradharudu Teki
9d25ce7d2SHaavard Skinnemoen #ifndef _SPI_FLASH_H_
10d25ce7d2SHaavard Skinnemoen #define _SPI_FLASH_H_
11d25ce7d2SHaavard Skinnemoen
124c2dbefdSSimon Glass #include <dm.h> /* Because we dereference struct udevice here */
13e06ab654SMike Frysinger #include <linux/types.h>
14c4e88623SVignesh R #include <linux/mtd/spi-nor.h>
15d25ce7d2SHaavard Skinnemoen
16abe66b1bSPatrick Delaunay /* by default ENV use the same parameters than SF command */
17abe66b1bSPatrick Delaunay #ifndef CONFIG_ENV_SPI_BUS
18abe66b1bSPatrick Delaunay # define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS
19abe66b1bSPatrick Delaunay #endif
20abe66b1bSPatrick Delaunay #ifndef CONFIG_ENV_SPI_CS
21abe66b1bSPatrick Delaunay # define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS
22abe66b1bSPatrick Delaunay #endif
23abe66b1bSPatrick Delaunay #ifndef CONFIG_ENV_SPI_MAX_HZ
24abe66b1bSPatrick Delaunay # define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
25abe66b1bSPatrick Delaunay #endif
26abe66b1bSPatrick Delaunay #ifndef CONFIG_ENV_SPI_MODE
27abe66b1bSPatrick Delaunay # define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE
28abe66b1bSPatrick Delaunay #endif
29abe66b1bSPatrick Delaunay
30ff0960f9SSimon Glass struct spi_slave;
3133adfb5fSJagannadha Sutradharudu Teki
324c2dbefdSSimon Glass struct dm_spi_flash_ops {
334c2dbefdSSimon Glass int (*read)(struct udevice *dev, u32 offset, size_t len, void *buf);
344c2dbefdSSimon Glass int (*write)(struct udevice *dev, u32 offset, size_t len,
354c2dbefdSSimon Glass const void *buf);
364c2dbefdSSimon Glass int (*erase)(struct udevice *dev, u32 offset, size_t len);
37a58986caSSimon Glass /**
38a58986caSSimon Glass * get_sw_write_prot() - Check state of software write-protect feature
39a58986caSSimon Glass *
40a58986caSSimon Glass * SPI flash chips can lock a region of the flash defined by a
41a58986caSSimon Glass * 'protected area'. This function checks if this protected area is
42a58986caSSimon Glass * defined.
43a58986caSSimon Glass *
44a58986caSSimon Glass * @dev: SPI flash device
45a58986caSSimon Glass * @return 0 if no region is write-protected, 1 if a region is
46a58986caSSimon Glass * write-protected, -ENOSYS if the driver does not implement this,
47a58986caSSimon Glass * other -ve value on error
48a58986caSSimon Glass */
49a58986caSSimon Glass int (*get_sw_write_prot)(struct udevice *dev);
50*591e1cf0SChin-Ting Kuo int (*flash_ctrl_wlock)(struct udevice *dev, u32 offset, size_t len);
51*591e1cf0SChin-Ting Kuo int (*flash_ctrl_wunlock)(struct udevice *dev, u32 offset, size_t len);
524c2dbefdSSimon Glass };
534c2dbefdSSimon Glass
544c2dbefdSSimon Glass /* Access the serial operations for a device */
554c2dbefdSSimon Glass #define sf_get_ops(dev) ((struct dm_spi_flash_ops *)(dev)->driver->ops)
564c2dbefdSSimon Glass
574c2dbefdSSimon Glass #ifdef CONFIG_DM_SPI_FLASH
588d987abcSSimon Glass /**
598d987abcSSimon Glass * spi_flash_read_dm() - Read data from SPI flash
608d987abcSSimon Glass *
618d987abcSSimon Glass * @dev: SPI flash device
628d987abcSSimon Glass * @offset: Offset into device in bytes to read from
638d987abcSSimon Glass * @len: Number of bytes to read
648d987abcSSimon Glass * @buf: Buffer to put the data that is read
658d987abcSSimon Glass * @return 0 if OK, -ve on error
668d987abcSSimon Glass */
678d987abcSSimon Glass int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf);
688d987abcSSimon Glass
698d987abcSSimon Glass /**
708d987abcSSimon Glass * spi_flash_write_dm() - Write data to SPI flash
718d987abcSSimon Glass *
728d987abcSSimon Glass * @dev: SPI flash device
738d987abcSSimon Glass * @offset: Offset into device in bytes to write to
748d987abcSSimon Glass * @len: Number of bytes to write
758d987abcSSimon Glass * @buf: Buffer containing bytes to write
768d987abcSSimon Glass * @return 0 if OK, -ve on error
778d987abcSSimon Glass */
788d987abcSSimon Glass int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
798d987abcSSimon Glass const void *buf);
808d987abcSSimon Glass
818d987abcSSimon Glass /**
828d987abcSSimon Glass * spi_flash_erase_dm() - Erase blocks of the SPI flash
838d987abcSSimon Glass *
848d987abcSSimon Glass * Note that @len must be a muiltiple of the flash sector size.
858d987abcSSimon Glass *
868d987abcSSimon Glass * @dev: SPI flash device
878d987abcSSimon Glass * @offset: Offset into device in bytes to start erasing
888d987abcSSimon Glass * @len: Number of bytes to erase
898d987abcSSimon Glass * @return 0 if OK, -ve on error
908d987abcSSimon Glass */
918d987abcSSimon Glass int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len);
928d987abcSSimon Glass
93a58986caSSimon Glass /**
94a58986caSSimon Glass * spl_flash_get_sw_write_prot() - Check state of software write-protect feature
95a58986caSSimon Glass *
96a58986caSSimon Glass * SPI flash chips can lock a region of the flash defined by a
97a58986caSSimon Glass * 'protected area'. This function checks if this protected area is
98a58986caSSimon Glass * defined.
99a58986caSSimon Glass *
100a58986caSSimon Glass * @dev: SPI flash device
101a58986caSSimon Glass * @return 0 if no region is write-protected, 1 if a region is
102a58986caSSimon Glass * write-protected, -ENOSYS if the driver does not implement this,
103a58986caSSimon Glass * other -ve value on error
104a58986caSSimon Glass */
105a58986caSSimon Glass int spl_flash_get_sw_write_prot(struct udevice *dev);
106*591e1cf0SChin-Ting Kuo int spi_flash_ctrl_wlock_dm(struct udevice *dev, u32 offset, size_t len);
107*591e1cf0SChin-Ting Kuo int spi_flash_ctrl_wunlock_dm(struct udevice *dev, u32 offset, size_t len);
108a58986caSSimon Glass
1094c2dbefdSSimon Glass int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
1104c2dbefdSSimon Glass unsigned int max_hz, unsigned int spi_mode,
1114c2dbefdSSimon Glass struct udevice **devp);
1124c2dbefdSSimon Glass
1134c2dbefdSSimon Glass /* Compatibility function - this is the old U-Boot API */
1144c2dbefdSSimon Glass struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
1154c2dbefdSSimon Glass unsigned int max_hz, unsigned int spi_mode);
1164c2dbefdSSimon Glass
1174c2dbefdSSimon Glass /* Compatibility function - this is the old U-Boot API */
1184c2dbefdSSimon Glass void spi_flash_free(struct spi_flash *flash);
1194c2dbefdSSimon Glass
spi_flash_read(struct spi_flash * flash,u32 offset,size_t len,void * buf)1204c2dbefdSSimon Glass static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
1214c2dbefdSSimon Glass size_t len, void *buf)
1224c2dbefdSSimon Glass {
1238d987abcSSimon Glass return spi_flash_read_dm(flash->dev, offset, len, buf);
1244c2dbefdSSimon Glass }
1254c2dbefdSSimon Glass
spi_flash_write(struct spi_flash * flash,u32 offset,size_t len,const void * buf)1264c2dbefdSSimon Glass static inline int spi_flash_write(struct spi_flash *flash, u32 offset,
1274c2dbefdSSimon Glass size_t len, const void *buf)
1284c2dbefdSSimon Glass {
1298d987abcSSimon Glass return spi_flash_write_dm(flash->dev, offset, len, buf);
1304c2dbefdSSimon Glass }
1314c2dbefdSSimon Glass
spi_flash_erase(struct spi_flash * flash,u32 offset,size_t len)1324c2dbefdSSimon Glass static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
1334c2dbefdSSimon Glass size_t len)
1344c2dbefdSSimon Glass {
1358d987abcSSimon Glass return spi_flash_erase_dm(flash->dev, offset, len);
1364c2dbefdSSimon Glass }
1374c2dbefdSSimon Glass
spi_flash_ctrl_wlock(struct spi_flash * flash,u32 offset,size_t len)138*591e1cf0SChin-Ting Kuo static inline int spi_flash_ctrl_wlock(struct spi_flash *flash,
139*591e1cf0SChin-Ting Kuo u32 offset, size_t len)
140*591e1cf0SChin-Ting Kuo {
141*591e1cf0SChin-Ting Kuo return spi_flash_ctrl_wlock_dm(flash->dev, offset, len);
142*591e1cf0SChin-Ting Kuo }
143*591e1cf0SChin-Ting Kuo
spi_flash_ctrl_wunlock(struct spi_flash * flash,u32 offset,size_t len)144*591e1cf0SChin-Ting Kuo static inline int spi_flash_ctrl_wunlock(struct spi_flash *flash,
145*591e1cf0SChin-Ting Kuo u32 offset, size_t len)
146*591e1cf0SChin-Ting Kuo {
147*591e1cf0SChin-Ting Kuo return spi_flash_ctrl_wunlock_dm(flash->dev, offset, len);
148*591e1cf0SChin-Ting Kuo }
149*591e1cf0SChin-Ting Kuo
1504c2dbefdSSimon Glass struct sandbox_state;
1514c2dbefdSSimon Glass
1524c2dbefdSSimon Glass int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
153008dcddfSSimon Glass struct udevice *bus, ofnode node, const char *spec);
1544c2dbefdSSimon Glass
1554c2dbefdSSimon Glass void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs);
1564c2dbefdSSimon Glass
1574c2dbefdSSimon Glass #else
158d25ce7d2SHaavard Skinnemoen struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
159d25ce7d2SHaavard Skinnemoen unsigned int max_hz, unsigned int spi_mode);
1600efc0249SSimon Glass
161d25ce7d2SHaavard Skinnemoen void spi_flash_free(struct spi_flash *flash);
162d25ce7d2SHaavard Skinnemoen
spi_flash_read(struct spi_flash * flash,u32 offset,size_t len,void * buf)163d25ce7d2SHaavard Skinnemoen static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
164d25ce7d2SHaavard Skinnemoen size_t len, void *buf)
165d25ce7d2SHaavard Skinnemoen {
166c4e88623SVignesh R struct mtd_info *mtd = &flash->mtd;
167c4e88623SVignesh R size_t retlen;
168c4e88623SVignesh R
169c4e88623SVignesh R return mtd->_read(mtd, offset, len, &retlen, buf);
170d25ce7d2SHaavard Skinnemoen }
171d25ce7d2SHaavard Skinnemoen
spi_flash_write(struct spi_flash * flash,u32 offset,size_t len,const void * buf)172d25ce7d2SHaavard Skinnemoen static inline int spi_flash_write(struct spi_flash *flash, u32 offset,
173d25ce7d2SHaavard Skinnemoen size_t len, const void *buf)
174d25ce7d2SHaavard Skinnemoen {
175c4e88623SVignesh R struct mtd_info *mtd = &flash->mtd;
176c4e88623SVignesh R size_t retlen;
177c4e88623SVignesh R
178c4e88623SVignesh R return mtd->_write(mtd, offset, len, &retlen, buf);
179d25ce7d2SHaavard Skinnemoen }
180d25ce7d2SHaavard Skinnemoen
spi_flash_erase(struct spi_flash * flash,u32 offset,size_t len)181d25ce7d2SHaavard Skinnemoen static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
182d25ce7d2SHaavard Skinnemoen size_t len)
183d25ce7d2SHaavard Skinnemoen {
184c4e88623SVignesh R struct mtd_info *mtd = &flash->mtd;
185c4e88623SVignesh R struct erase_info instr;
186c4e88623SVignesh R
187c4e88623SVignesh R if (offset % mtd->erasesize || len % mtd->erasesize) {
188c4e88623SVignesh R printf("SF: Erase offset/length not multiple of erase size\n");
189c4e88623SVignesh R return -EINVAL;
190c4e88623SVignesh R }
191c4e88623SVignesh R
192c4e88623SVignesh R memset(&instr, 0, sizeof(instr));
193c4e88623SVignesh R instr.addr = offset;
194c4e88623SVignesh R instr.len = len;
195c4e88623SVignesh R
196c4e88623SVignesh R return mtd->_erase(mtd, &instr);
197d25ce7d2SHaavard Skinnemoen }
1984c2dbefdSSimon Glass #endif
199d25ce7d2SHaavard Skinnemoen
spi_flash_protect(struct spi_flash * flash,u32 ofs,u32 len,bool prot)200c3c016cfSFabio Estevam static inline int spi_flash_protect(struct spi_flash *flash, u32 ofs, u32 len,
201c3c016cfSFabio Estevam bool prot)
202c3c016cfSFabio Estevam {
203439fcb9bSBin Meng if (!flash->flash_lock || !flash->flash_unlock)
204c3c016cfSFabio Estevam return -EOPNOTSUPP;
205c3c016cfSFabio Estevam
206c3c016cfSFabio Estevam if (prot)
207c3c016cfSFabio Estevam return flash->flash_lock(flash, ofs, len);
208c3c016cfSFabio Estevam else
209c3c016cfSFabio Estevam return flash->flash_unlock(flash, ofs, len);
210c3c016cfSFabio Estevam }
211c3c016cfSFabio Estevam
212d25ce7d2SHaavard Skinnemoen #endif /* _SPI_FLASH_H_ */
213