xref: /rk3399_rockchip-uboot/drivers/mtd/spi/sf_probe.c (revision ff063ed4808e4ead3021eaf53ee4fdb80c9e91f8)
1898e76c9SJagannadha Sutradharudu Teki /*
2898e76c9SJagannadha Sutradharudu Teki  * SPI flash probing
3898e76c9SJagannadha Sutradharudu Teki  *
4898e76c9SJagannadha Sutradharudu Teki  * Copyright (C) 2008 Atmel Corporation
5898e76c9SJagannadha Sutradharudu Teki  * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
6898e76c9SJagannadha Sutradharudu Teki  * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
7898e76c9SJagannadha Sutradharudu Teki  *
80c88a84aSJagannadha Sutradharudu Teki  * SPDX-License-Identifier:	GPL-2.0+
9898e76c9SJagannadha Sutradharudu Teki  */
10898e76c9SJagannadha Sutradharudu Teki 
11898e76c9SJagannadha Sutradharudu Teki #include <common.h>
12898e76c9SJagannadha Sutradharudu Teki #include <fdtdec.h>
13898e76c9SJagannadha Sutradharudu Teki #include <malloc.h>
14898e76c9SJagannadha Sutradharudu Teki #include <spi.h>
15898e76c9SJagannadha Sutradharudu Teki #include <spi_flash.h>
16ffdb20beSMike Frysinger #include <asm/io.h>
17898e76c9SJagannadha Sutradharudu Teki 
18898e76c9SJagannadha Sutradharudu Teki #include "sf_internal.h"
19898e76c9SJagannadha Sutradharudu Teki 
20898e76c9SJagannadha Sutradharudu Teki DECLARE_GLOBAL_DATA_PTR;
21898e76c9SJagannadha Sutradharudu Teki 
224e09cc1eSJagannadha Sutradharudu Teki /* Read commands array */
234e09cc1eSJagannadha Sutradharudu Teki static u8 spi_read_cmds_array[] = {
244e09cc1eSJagannadha Sutradharudu Teki 	CMD_READ_ARRAY_SLOW,
254e09cc1eSJagannadha Sutradharudu Teki 	CMD_READ_DUAL_OUTPUT_FAST,
264e09cc1eSJagannadha Sutradharudu Teki 	CMD_READ_DUAL_IO_FAST,
273163aaa6SJagannadha Sutradharudu Teki 	CMD_READ_QUAD_OUTPUT_FAST,
28c4ba0d82SJagannadha Sutradharudu Teki 	CMD_READ_QUAD_IO_FAST,
294e09cc1eSJagannadha Sutradharudu Teki };
304e09cc1eSJagannadha Sutradharudu Teki 
31d08a1bafSJagannadha Sutradharudu Teki static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0)
32d08a1bafSJagannadha Sutradharudu Teki {
33d08a1bafSJagannadha Sutradharudu Teki 	switch (idcode0) {
34d08a1bafSJagannadha Sutradharudu Teki #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
35d08a1bafSJagannadha Sutradharudu Teki 	case SPI_FLASH_CFI_MFR_SPANSION:
36d08a1bafSJagannadha Sutradharudu Teki 	case SPI_FLASH_CFI_MFR_WINBOND:
37d08a1bafSJagannadha Sutradharudu Teki 		return spi_flash_set_qeb_winspan(flash);
38d08a1bafSJagannadha Sutradharudu Teki #endif
39d08a1bafSJagannadha Sutradharudu Teki #ifdef CONFIG_SPI_FLASH_STMICRO
40d08a1bafSJagannadha Sutradharudu Teki 	case SPI_FLASH_CFI_MFR_STMICRO:
41d08a1bafSJagannadha Sutradharudu Teki 		debug("SF: QEB is volatile for %02x flash\n", idcode0);
42d08a1bafSJagannadha Sutradharudu Teki 		return 0;
43d08a1bafSJagannadha Sutradharudu Teki #endif
44d08a1bafSJagannadha Sutradharudu Teki 	default:
45d08a1bafSJagannadha Sutradharudu Teki 		printf("SF: Need set QEB func for %02x flash\n", idcode0);
46d08a1bafSJagannadha Sutradharudu Teki 		return -1;
47d08a1bafSJagannadha Sutradharudu Teki 	}
48d08a1bafSJagannadha Sutradharudu Teki }
49d08a1bafSJagannadha Sutradharudu Teki 
50ce22b922SJagannadha Sutradharudu Teki static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,
51ce22b922SJagannadha Sutradharudu Teki 		u8 *idcode)
52898e76c9SJagannadha Sutradharudu Teki {
53898e76c9SJagannadha Sutradharudu Teki 	const struct spi_flash_params *params;
54898e76c9SJagannadha Sutradharudu Teki 	struct spi_flash *flash;
554e09cc1eSJagannadha Sutradharudu Teki 	u8 cmd;
56898e76c9SJagannadha Sutradharudu Teki 	u16 jedec = idcode[1] << 8 | idcode[2];
57898e76c9SJagannadha Sutradharudu Teki 	u16 ext_jedec = idcode[3] << 8 | idcode[4];
58898e76c9SJagannadha Sutradharudu Teki 
5933adfb5fSJagannadha Sutradharudu Teki 	params = spi_flash_params_table;
6033adfb5fSJagannadha Sutradharudu Teki 	for (; params->name != NULL; params++) {
61898e76c9SJagannadha Sutradharudu Teki 		if ((params->jedec >> 16) == idcode[0]) {
62898e76c9SJagannadha Sutradharudu Teki 			if ((params->jedec & 0xFFFF) == jedec) {
63898e76c9SJagannadha Sutradharudu Teki 				if (params->ext_jedec == 0)
64898e76c9SJagannadha Sutradharudu Teki 					break;
65898e76c9SJagannadha Sutradharudu Teki 				else if (params->ext_jedec == ext_jedec)
66898e76c9SJagannadha Sutradharudu Teki 					break;
67898e76c9SJagannadha Sutradharudu Teki 			}
68898e76c9SJagannadha Sutradharudu Teki 		}
69898e76c9SJagannadha Sutradharudu Teki 	}
70898e76c9SJagannadha Sutradharudu Teki 
7133adfb5fSJagannadha Sutradharudu Teki 	if (!params->name) {
72898e76c9SJagannadha Sutradharudu Teki 		printf("SF: Unsupported flash IDs: ");
73898e76c9SJagannadha Sutradharudu Teki 		printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
74898e76c9SJagannadha Sutradharudu Teki 		       idcode[0], jedec, ext_jedec);
75898e76c9SJagannadha Sutradharudu Teki 		return NULL;
76898e76c9SJagannadha Sutradharudu Teki 	}
77898e76c9SJagannadha Sutradharudu Teki 
78898e76c9SJagannadha Sutradharudu Teki 	flash = malloc(sizeof(*flash));
79898e76c9SJagannadha Sutradharudu Teki 	if (!flash) {
80898e76c9SJagannadha Sutradharudu Teki 		debug("SF: Failed to allocate spi_flash\n");
81898e76c9SJagannadha Sutradharudu Teki 		return NULL;
82898e76c9SJagannadha Sutradharudu Teki 	}
83898e76c9SJagannadha Sutradharudu Teki 	memset(flash, '\0', sizeof(*flash));
84898e76c9SJagannadha Sutradharudu Teki 
85469146c0SJagannadha Sutradharudu Teki 	/* Assign spi data */
86898e76c9SJagannadha Sutradharudu Teki 	flash->spi = spi;
87898e76c9SJagannadha Sutradharudu Teki 	flash->name = params->name;
88ce22b922SJagannadha Sutradharudu Teki 	flash->memory_map = spi->memory_map;
89898e76c9SJagannadha Sutradharudu Teki 
90898e76c9SJagannadha Sutradharudu Teki 	/* Assign spi_flash ops */
91898e76c9SJagannadha Sutradharudu Teki 	flash->write = spi_flash_cmd_write_ops;
92898e76c9SJagannadha Sutradharudu Teki #ifdef CONFIG_SPI_FLASH_SST
93898e76c9SJagannadha Sutradharudu Teki 	if (params->flags & SST_WP)
94898e76c9SJagannadha Sutradharudu Teki 		flash->write = sst_write_wp;
95898e76c9SJagannadha Sutradharudu Teki #endif
96898e76c9SJagannadha Sutradharudu Teki 	flash->erase = spi_flash_cmd_erase_ops;
97898e76c9SJagannadha Sutradharudu Teki 	flash->read = spi_flash_cmd_read_ops;
98898e76c9SJagannadha Sutradharudu Teki 
99898e76c9SJagannadha Sutradharudu Teki 	/* Compute the flash size */
100898e76c9SJagannadha Sutradharudu Teki 	flash->page_size = (ext_jedec == 0x4d00) ? 512 : 256;
101898e76c9SJagannadha Sutradharudu Teki 	flash->sector_size = params->sector_size;
102898e76c9SJagannadha Sutradharudu Teki 	flash->size = flash->sector_size * params->nr_sectors;
103898e76c9SJagannadha Sutradharudu Teki 
104898e76c9SJagannadha Sutradharudu Teki 	/* Compute erase sector and command */
105898e76c9SJagannadha Sutradharudu Teki 	if (params->flags & SECT_4K) {
106898e76c9SJagannadha Sutradharudu Teki 		flash->erase_cmd = CMD_ERASE_4K;
107898e76c9SJagannadha Sutradharudu Teki 		flash->erase_size = 4096;
108898e76c9SJagannadha Sutradharudu Teki 	} else if (params->flags & SECT_32K) {
109898e76c9SJagannadha Sutradharudu Teki 		flash->erase_cmd = CMD_ERASE_32K;
110898e76c9SJagannadha Sutradharudu Teki 		flash->erase_size = 32768;
111898e76c9SJagannadha Sutradharudu Teki 	} else {
112898e76c9SJagannadha Sutradharudu Teki 		flash->erase_cmd = CMD_ERASE_64K;
113898e76c9SJagannadha Sutradharudu Teki 		flash->erase_size = flash->sector_size;
114898e76c9SJagannadha Sutradharudu Teki 	}
115898e76c9SJagannadha Sutradharudu Teki 
1164e09cc1eSJagannadha Sutradharudu Teki 	/* Look for the fastest read cmd */
1174e09cc1eSJagannadha Sutradharudu Teki 	cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx);
1184e09cc1eSJagannadha Sutradharudu Teki 	if (cmd) {
1194e09cc1eSJagannadha Sutradharudu Teki 		cmd = spi_read_cmds_array[cmd - 1];
1204e09cc1eSJagannadha Sutradharudu Teki 		flash->read_cmd = cmd;
1214e09cc1eSJagannadha Sutradharudu Teki 	} else {
1224e09cc1eSJagannadha Sutradharudu Teki 		/* Go for for default supported read cmd */
1234e09cc1eSJagannadha Sutradharudu Teki 		flash->read_cmd = CMD_READ_ARRAY_FAST;
1244e09cc1eSJagannadha Sutradharudu Teki 	}
1254e09cc1eSJagannadha Sutradharudu Teki 
1263163aaa6SJagannadha Sutradharudu Teki 	/* Not require to look for fastest only two write cmds yet */
1273163aaa6SJagannadha Sutradharudu Teki 	if (params->flags & WR_QPP && flash->spi->op_mode_tx & SPI_OPM_TX_QPP)
1283163aaa6SJagannadha Sutradharudu Teki 		flash->write_cmd = CMD_QUAD_PAGE_PROGRAM;
1293163aaa6SJagannadha Sutradharudu Teki 	else
1303163aaa6SJagannadha Sutradharudu Teki 		/* Go for default supported write cmd */
1313163aaa6SJagannadha Sutradharudu Teki 		flash->write_cmd = CMD_PAGE_PROGRAM;
1323163aaa6SJagannadha Sutradharudu Teki 
133d08a1bafSJagannadha Sutradharudu Teki 	/* Set the quad enable bit - only for quad commands */
134d08a1bafSJagannadha Sutradharudu Teki 	if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) ||
135c4ba0d82SJagannadha Sutradharudu Teki 	    (flash->read_cmd == CMD_READ_QUAD_IO_FAST) ||
136d08a1bafSJagannadha Sutradharudu Teki 	    (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) {
137d08a1bafSJagannadha Sutradharudu Teki 		if (spi_flash_set_qeb(flash, idcode[0])) {
138d08a1bafSJagannadha Sutradharudu Teki 			debug("SF: Fail to set QEB for %02x\n", idcode[0]);
139d08a1bafSJagannadha Sutradharudu Teki 			return NULL;
140d08a1bafSJagannadha Sutradharudu Teki 		}
141d08a1bafSJagannadha Sutradharudu Teki 	}
142d08a1bafSJagannadha Sutradharudu Teki 
143*ff063ed4SJagannadha Sutradharudu Teki 	/* Read dummy_byte: dummy byte is determined based on the
144*ff063ed4SJagannadha Sutradharudu Teki 	 * dummy cycles of a particular command.
145*ff063ed4SJagannadha Sutradharudu Teki 	 * Fast commands - dummy_byte = dummy_cycles/8
146*ff063ed4SJagannadha Sutradharudu Teki 	 * I/O commands- dummy_byte = (dummy_cycles * no.of lines)/8
147*ff063ed4SJagannadha Sutradharudu Teki 	 * For I/O commands except cmd[0] everything goes on no.of lines
148*ff063ed4SJagannadha Sutradharudu Teki 	 * based on particular command but incase of fast commands except
149*ff063ed4SJagannadha Sutradharudu Teki 	 * data all go on single line irrespective of command.
150*ff063ed4SJagannadha Sutradharudu Teki 	 */
151*ff063ed4SJagannadha Sutradharudu Teki 	switch (flash->read_cmd) {
152*ff063ed4SJagannadha Sutradharudu Teki 	case CMD_READ_QUAD_IO_FAST:
153*ff063ed4SJagannadha Sutradharudu Teki 		flash->dummy_byte = 2;
154*ff063ed4SJagannadha Sutradharudu Teki 		break;
155*ff063ed4SJagannadha Sutradharudu Teki 	case CMD_READ_ARRAY_SLOW:
156*ff063ed4SJagannadha Sutradharudu Teki 		flash->dummy_byte = 0;
157*ff063ed4SJagannadha Sutradharudu Teki 		break;
158*ff063ed4SJagannadha Sutradharudu Teki 	default:
159*ff063ed4SJagannadha Sutradharudu Teki 		flash->dummy_byte = 1;
160*ff063ed4SJagannadha Sutradharudu Teki 	}
161*ff063ed4SJagannadha Sutradharudu Teki 
162898e76c9SJagannadha Sutradharudu Teki 	/* Poll cmd seclection */
163898e76c9SJagannadha Sutradharudu Teki 	flash->poll_cmd = CMD_READ_STATUS;
164898e76c9SJagannadha Sutradharudu Teki #ifdef CONFIG_SPI_FLASH_STMICRO
165898e76c9SJagannadha Sutradharudu Teki 	if (params->flags & E_FSR)
166898e76c9SJagannadha Sutradharudu Teki 		flash->poll_cmd = CMD_FLAG_STATUS;
167898e76c9SJagannadha Sutradharudu Teki #endif
168898e76c9SJagannadha Sutradharudu Teki 
169898e76c9SJagannadha Sutradharudu Teki 	/* Configure the BAR - discover bank cmds and read current bank */
170ce22b922SJagannadha Sutradharudu Teki #ifdef CONFIG_SPI_FLASH_BAR
171898e76c9SJagannadha Sutradharudu Teki 	u8 curr_bank = 0;
172898e76c9SJagannadha Sutradharudu Teki 	if (flash->size > SPI_FLASH_16MB_BOUN) {
173898e76c9SJagannadha Sutradharudu Teki 		flash->bank_read_cmd = (idcode[0] == 0x01) ?
174898e76c9SJagannadha Sutradharudu Teki 					CMD_BANKADDR_BRRD : CMD_EXTNADDR_RDEAR;
175898e76c9SJagannadha Sutradharudu Teki 		flash->bank_write_cmd = (idcode[0] == 0x01) ?
176898e76c9SJagannadha Sutradharudu Teki 					CMD_BANKADDR_BRWR : CMD_EXTNADDR_WREAR;
177898e76c9SJagannadha Sutradharudu Teki 
178898e76c9SJagannadha Sutradharudu Teki 		if (spi_flash_read_common(flash, &flash->bank_read_cmd, 1,
179898e76c9SJagannadha Sutradharudu Teki 					  &curr_bank, 1)) {
180898e76c9SJagannadha Sutradharudu Teki 			debug("SF: fail to read bank addr register\n");
181898e76c9SJagannadha Sutradharudu Teki 			return NULL;
182898e76c9SJagannadha Sutradharudu Teki 		}
183898e76c9SJagannadha Sutradharudu Teki 		flash->bank_curr = curr_bank;
184898e76c9SJagannadha Sutradharudu Teki 	} else {
185898e76c9SJagannadha Sutradharudu Teki 		flash->bank_curr = curr_bank;
186898e76c9SJagannadha Sutradharudu Teki 	}
187898e76c9SJagannadha Sutradharudu Teki #endif
188898e76c9SJagannadha Sutradharudu Teki 
189898e76c9SJagannadha Sutradharudu Teki 	/* Flash powers up read-only, so clear BP# bits */
190898e76c9SJagannadha Sutradharudu Teki #if defined(CONFIG_SPI_FLASH_ATMEL) || \
191898e76c9SJagannadha Sutradharudu Teki 	defined(CONFIG_SPI_FLASH_MACRONIX) || \
192898e76c9SJagannadha Sutradharudu Teki 	defined(CONFIG_SPI_FLASH_SST)
193898e76c9SJagannadha Sutradharudu Teki 		spi_flash_cmd_write_status(flash, 0);
194898e76c9SJagannadha Sutradharudu Teki #endif
195898e76c9SJagannadha Sutradharudu Teki 
196898e76c9SJagannadha Sutradharudu Teki 	return flash;
197898e76c9SJagannadha Sutradharudu Teki }
198898e76c9SJagannadha Sutradharudu Teki 
199898e76c9SJagannadha Sutradharudu Teki #ifdef CONFIG_OF_CONTROL
200898e76c9SJagannadha Sutradharudu Teki int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
201898e76c9SJagannadha Sutradharudu Teki {
202898e76c9SJagannadha Sutradharudu Teki 	fdt_addr_t addr;
203898e76c9SJagannadha Sutradharudu Teki 	fdt_size_t size;
204898e76c9SJagannadha Sutradharudu Teki 	int node;
205898e76c9SJagannadha Sutradharudu Teki 
206898e76c9SJagannadha Sutradharudu Teki 	/* If there is no node, do nothing */
207898e76c9SJagannadha Sutradharudu Teki 	node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
208898e76c9SJagannadha Sutradharudu Teki 	if (node < 0)
209898e76c9SJagannadha Sutradharudu Teki 		return 0;
210898e76c9SJagannadha Sutradharudu Teki 
211898e76c9SJagannadha Sutradharudu Teki 	addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
212898e76c9SJagannadha Sutradharudu Teki 	if (addr == FDT_ADDR_T_NONE) {
213898e76c9SJagannadha Sutradharudu Teki 		debug("%s: Cannot decode address\n", __func__);
214898e76c9SJagannadha Sutradharudu Teki 		return 0;
215898e76c9SJagannadha Sutradharudu Teki 	}
216898e76c9SJagannadha Sutradharudu Teki 
217898e76c9SJagannadha Sutradharudu Teki 	if (flash->size != size) {
218898e76c9SJagannadha Sutradharudu Teki 		debug("%s: Memory map must cover entire device\n", __func__);
219898e76c9SJagannadha Sutradharudu Teki 		return -1;
220898e76c9SJagannadha Sutradharudu Teki 	}
221ffdb20beSMike Frysinger 	flash->memory_map = map_sysmem(addr, size);
222898e76c9SJagannadha Sutradharudu Teki 
223898e76c9SJagannadha Sutradharudu Teki 	return 0;
224898e76c9SJagannadha Sutradharudu Teki }
225898e76c9SJagannadha Sutradharudu Teki #endif /* CONFIG_OF_CONTROL */
226898e76c9SJagannadha Sutradharudu Teki 
2270efc0249SSimon Glass static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
228898e76c9SJagannadha Sutradharudu Teki {
229898e76c9SJagannadha Sutradharudu Teki 	struct spi_flash *flash = NULL;
230898e76c9SJagannadha Sutradharudu Teki 	u8 idcode[5];
231898e76c9SJagannadha Sutradharudu Teki 	int ret;
232898e76c9SJagannadha Sutradharudu Teki 
233898e76c9SJagannadha Sutradharudu Teki 	/* Setup spi_slave */
234898e76c9SJagannadha Sutradharudu Teki 	if (!spi) {
235898e76c9SJagannadha Sutradharudu Teki 		printf("SF: Failed to set up slave\n");
236898e76c9SJagannadha Sutradharudu Teki 		return NULL;
237898e76c9SJagannadha Sutradharudu Teki 	}
238898e76c9SJagannadha Sutradharudu Teki 
239898e76c9SJagannadha Sutradharudu Teki 	/* Claim spi bus */
240898e76c9SJagannadha Sutradharudu Teki 	ret = spi_claim_bus(spi);
241898e76c9SJagannadha Sutradharudu Teki 	if (ret) {
242898e76c9SJagannadha Sutradharudu Teki 		debug("SF: Failed to claim SPI bus: %d\n", ret);
243898e76c9SJagannadha Sutradharudu Teki 		goto err_claim_bus;
244898e76c9SJagannadha Sutradharudu Teki 	}
245898e76c9SJagannadha Sutradharudu Teki 
246898e76c9SJagannadha Sutradharudu Teki 	/* Read the ID codes */
247898e76c9SJagannadha Sutradharudu Teki 	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
248898e76c9SJagannadha Sutradharudu Teki 	if (ret) {
249898e76c9SJagannadha Sutradharudu Teki 		printf("SF: Failed to get idcodes\n");
250898e76c9SJagannadha Sutradharudu Teki 		goto err_read_id;
251898e76c9SJagannadha Sutradharudu Teki 	}
252898e76c9SJagannadha Sutradharudu Teki 
253898e76c9SJagannadha Sutradharudu Teki #ifdef DEBUG
254898e76c9SJagannadha Sutradharudu Teki 	printf("SF: Got idcodes\n");
255898e76c9SJagannadha Sutradharudu Teki 	print_buffer(0, idcode, 1, sizeof(idcode), 0);
256898e76c9SJagannadha Sutradharudu Teki #endif
257898e76c9SJagannadha Sutradharudu Teki 
258898e76c9SJagannadha Sutradharudu Teki 	/* Validate params from spi_flash_params table */
259898e76c9SJagannadha Sutradharudu Teki 	flash = spi_flash_validate_params(spi, idcode);
260898e76c9SJagannadha Sutradharudu Teki 	if (!flash)
261898e76c9SJagannadha Sutradharudu Teki 		goto err_read_id;
262898e76c9SJagannadha Sutradharudu Teki 
263898e76c9SJagannadha Sutradharudu Teki #ifdef CONFIG_OF_CONTROL
264898e76c9SJagannadha Sutradharudu Teki 	if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
265898e76c9SJagannadha Sutradharudu Teki 		debug("SF: FDT decode error\n");
266898e76c9SJagannadha Sutradharudu Teki 		goto err_read_id;
267898e76c9SJagannadha Sutradharudu Teki 	}
268898e76c9SJagannadha Sutradharudu Teki #endif
269898e76c9SJagannadha Sutradharudu Teki #ifndef CONFIG_SPL_BUILD
270898e76c9SJagannadha Sutradharudu Teki 	printf("SF: Detected %s with page size ", flash->name);
271898e76c9SJagannadha Sutradharudu Teki 	print_size(flash->page_size, ", erase size ");
272898e76c9SJagannadha Sutradharudu Teki 	print_size(flash->erase_size, ", total ");
273898e76c9SJagannadha Sutradharudu Teki 	print_size(flash->size, "");
274898e76c9SJagannadha Sutradharudu Teki 	if (flash->memory_map)
275898e76c9SJagannadha Sutradharudu Teki 		printf(", mapped at %p", flash->memory_map);
276898e76c9SJagannadha Sutradharudu Teki 	puts("\n");
277898e76c9SJagannadha Sutradharudu Teki #endif
278898e76c9SJagannadha Sutradharudu Teki #ifndef CONFIG_SPI_FLASH_BAR
279898e76c9SJagannadha Sutradharudu Teki 	if (flash->size > SPI_FLASH_16MB_BOUN) {
280898e76c9SJagannadha Sutradharudu Teki 		puts("SF: Warning - Only lower 16MiB accessible,");
281898e76c9SJagannadha Sutradharudu Teki 		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
282898e76c9SJagannadha Sutradharudu Teki 	}
283898e76c9SJagannadha Sutradharudu Teki #endif
284898e76c9SJagannadha Sutradharudu Teki 
285898e76c9SJagannadha Sutradharudu Teki 	/* Release spi bus */
286898e76c9SJagannadha Sutradharudu Teki 	spi_release_bus(spi);
287898e76c9SJagannadha Sutradharudu Teki 
288898e76c9SJagannadha Sutradharudu Teki 	return flash;
289898e76c9SJagannadha Sutradharudu Teki 
290898e76c9SJagannadha Sutradharudu Teki err_read_id:
291898e76c9SJagannadha Sutradharudu Teki 	spi_release_bus(spi);
292898e76c9SJagannadha Sutradharudu Teki err_claim_bus:
293898e76c9SJagannadha Sutradharudu Teki 	spi_free_slave(spi);
294898e76c9SJagannadha Sutradharudu Teki 	return NULL;
295898e76c9SJagannadha Sutradharudu Teki }
296898e76c9SJagannadha Sutradharudu Teki 
2970efc0249SSimon Glass struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
2980efc0249SSimon Glass 		unsigned int max_hz, unsigned int spi_mode)
2990efc0249SSimon Glass {
3000efc0249SSimon Glass 	struct spi_slave *spi;
3010efc0249SSimon Glass 
3020efc0249SSimon Glass 	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
3030efc0249SSimon Glass 	return spi_flash_probe_slave(spi);
3040efc0249SSimon Glass }
3050efc0249SSimon Glass 
3060efc0249SSimon Glass #ifdef CONFIG_OF_SPI_FLASH
3070efc0249SSimon Glass struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
3080efc0249SSimon Glass 				      int spi_node)
3090efc0249SSimon Glass {
3100efc0249SSimon Glass 	struct spi_slave *spi;
3110efc0249SSimon Glass 
3120efc0249SSimon Glass 	spi = spi_setup_slave_fdt(blob, slave_node, spi_node);
3130efc0249SSimon Glass 	return spi_flash_probe_slave(spi);
3140efc0249SSimon Glass }
3150efc0249SSimon Glass #endif
3160efc0249SSimon Glass 
317898e76c9SJagannadha Sutradharudu Teki void spi_flash_free(struct spi_flash *flash)
318898e76c9SJagannadha Sutradharudu Teki {
319898e76c9SJagannadha Sutradharudu Teki 	spi_free_slave(flash->spi);
320898e76c9SJagannadha Sutradharudu Teki 	free(flash);
321898e76c9SJagannadha Sutradharudu Teki }
322