1cba65a77SJagan Teki /* 2cba65a77SJagan Teki * SPI Flash Core 3cba65a77SJagan Teki * 4cba65a77SJagan Teki * Copyright (C) 2015 Jagan Teki <jteki@openedev.com> 5cba65a77SJagan Teki * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc. 6cba65a77SJagan Teki * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik 7cba65a77SJagan Teki * Copyright (C) 2008 Atmel Corporation 8cba65a77SJagan Teki * 9cba65a77SJagan Teki * SPDX-License-Identifier: GPL-2.0+ 10cba65a77SJagan Teki */ 11cba65a77SJagan Teki 12cba65a77SJagan Teki #include <common.h> 13cba65a77SJagan Teki #include <errno.h> 14cba65a77SJagan Teki #include <malloc.h> 15cba65a77SJagan Teki #include <mapmem.h> 16cba65a77SJagan Teki #include <spi.h> 17cba65a77SJagan Teki #include <spi_flash.h> 18cba65a77SJagan Teki #include <linux/log2.h> 1958a870a7SEugeniy Paltsev #include <linux/sizes.h> 207bd1c59bSMugunthan V N #include <dma.h> 21cba65a77SJagan Teki 22cba65a77SJagan Teki #include "sf_internal.h" 23cba65a77SJagan Teki 24cba65a77SJagan Teki DECLARE_GLOBAL_DATA_PTR; 25cba65a77SJagan Teki 26cba65a77SJagan Teki static void spi_flash_addr(u32 addr, u8 *cmd) 27cba65a77SJagan Teki { 28cba65a77SJagan Teki /* cmd[0] is actual command */ 29cba65a77SJagan Teki cmd[1] = addr >> 16; 30cba65a77SJagan Teki cmd[2] = addr >> 8; 31cba65a77SJagan Teki cmd[3] = addr >> 0; 32cba65a77SJagan Teki } 33cba65a77SJagan Teki 34cba65a77SJagan Teki static int read_sr(struct spi_flash *flash, u8 *rs) 35cba65a77SJagan Teki { 36cba65a77SJagan Teki int ret; 37cba65a77SJagan Teki u8 cmd; 38cba65a77SJagan Teki 39cba65a77SJagan Teki cmd = CMD_READ_STATUS; 40cba65a77SJagan Teki ret = spi_flash_read_common(flash, &cmd, 1, rs, 1); 41cba65a77SJagan Teki if (ret < 0) { 42cba65a77SJagan Teki debug("SF: fail to read status register\n"); 43cba65a77SJagan Teki return ret; 44cba65a77SJagan Teki } 45cba65a77SJagan Teki 46cba65a77SJagan Teki return 0; 47cba65a77SJagan Teki } 48cba65a77SJagan Teki 49cba65a77SJagan Teki static int read_fsr(struct spi_flash *flash, u8 *fsr) 50cba65a77SJagan Teki { 51cba65a77SJagan Teki int ret; 52cba65a77SJagan Teki const u8 cmd = CMD_FLAG_STATUS; 53cba65a77SJagan Teki 54cba65a77SJagan Teki ret = spi_flash_read_common(flash, &cmd, 1, fsr, 1); 55cba65a77SJagan Teki if (ret < 0) { 56cba65a77SJagan Teki debug("SF: fail to read flag status register\n"); 57cba65a77SJagan Teki return ret; 58cba65a77SJagan Teki } 59cba65a77SJagan Teki 60cba65a77SJagan Teki return 0; 61cba65a77SJagan Teki } 62cba65a77SJagan Teki 63cba65a77SJagan Teki static int write_sr(struct spi_flash *flash, u8 ws) 64cba65a77SJagan Teki { 65cba65a77SJagan Teki u8 cmd; 66cba65a77SJagan Teki int ret; 67cba65a77SJagan Teki 68cba65a77SJagan Teki cmd = CMD_WRITE_STATUS; 69cba65a77SJagan Teki ret = spi_flash_write_common(flash, &cmd, 1, &ws, 1); 70cba65a77SJagan Teki if (ret < 0) { 71cba65a77SJagan Teki debug("SF: fail to write status register\n"); 72cba65a77SJagan Teki return ret; 73cba65a77SJagan Teki } 74cba65a77SJagan Teki 75cba65a77SJagan Teki return 0; 76cba65a77SJagan Teki } 77cba65a77SJagan Teki 78cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) 79cba65a77SJagan Teki static int read_cr(struct spi_flash *flash, u8 *rc) 80cba65a77SJagan Teki { 81cba65a77SJagan Teki int ret; 82cba65a77SJagan Teki u8 cmd; 83cba65a77SJagan Teki 84cba65a77SJagan Teki cmd = CMD_READ_CONFIG; 85cba65a77SJagan Teki ret = spi_flash_read_common(flash, &cmd, 1, rc, 1); 86cba65a77SJagan Teki if (ret < 0) { 87cba65a77SJagan Teki debug("SF: fail to read config register\n"); 88cba65a77SJagan Teki return ret; 89cba65a77SJagan Teki } 90cba65a77SJagan Teki 91cba65a77SJagan Teki return 0; 92cba65a77SJagan Teki } 93cba65a77SJagan Teki 94cba65a77SJagan Teki static int write_cr(struct spi_flash *flash, u8 wc) 95cba65a77SJagan Teki { 96cba65a77SJagan Teki u8 data[2]; 97cba65a77SJagan Teki u8 cmd; 98cba65a77SJagan Teki int ret; 99cba65a77SJagan Teki 100cba65a77SJagan Teki ret = read_sr(flash, &data[0]); 101cba65a77SJagan Teki if (ret < 0) 102cba65a77SJagan Teki return ret; 103cba65a77SJagan Teki 104cba65a77SJagan Teki cmd = CMD_WRITE_STATUS; 105cba65a77SJagan Teki data[1] = wc; 106cba65a77SJagan Teki ret = spi_flash_write_common(flash, &cmd, 1, &data, 2); 107cba65a77SJagan Teki if (ret) { 108cba65a77SJagan Teki debug("SF: fail to write config register\n"); 109cba65a77SJagan Teki return ret; 110cba65a77SJagan Teki } 111cba65a77SJagan Teki 112cba65a77SJagan Teki return 0; 113cba65a77SJagan Teki } 114cba65a77SJagan Teki #endif 115cba65a77SJagan Teki 116cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 1172e1c78b4SLukasz Majewski /* 1182e1c78b4SLukasz Majewski * This "clean_bar" is necessary in a situation when one was accessing 1192e1c78b4SLukasz Majewski * spi flash memory > 16 MiB by using Bank Address Register's BA24 bit. 1202e1c78b4SLukasz Majewski * 1212e1c78b4SLukasz Majewski * After it the BA24 bit shall be cleared to allow access to correct 1222e1c78b4SLukasz Majewski * memory region after SW reset (by calling "reset" command). 1232e1c78b4SLukasz Majewski * 1242e1c78b4SLukasz Majewski * Otherwise, the BA24 bit may be left set and then after reset, the 1252e1c78b4SLukasz Majewski * ROM would read/write/erase SPL from 16 MiB * bank_sel address. 1262e1c78b4SLukasz Majewski */ 1272e1c78b4SLukasz Majewski static int clean_bar(struct spi_flash *flash) 1282e1c78b4SLukasz Majewski { 1292e1c78b4SLukasz Majewski u8 cmd, bank_sel = 0; 1302e1c78b4SLukasz Majewski 1312e1c78b4SLukasz Majewski if (flash->bank_curr == 0) 1322e1c78b4SLukasz Majewski return 0; 1332e1c78b4SLukasz Majewski cmd = flash->bank_write_cmd; 1340df07db4SMarek Vasut flash->bank_curr = 0; 1352e1c78b4SLukasz Majewski 1362e1c78b4SLukasz Majewski return spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); 1372e1c78b4SLukasz Majewski } 1382e1c78b4SLukasz Majewski 1397b4ab88eSJagan Teki static int write_bar(struct spi_flash *flash, u32 offset) 140cba65a77SJagan Teki { 141cba65a77SJagan Teki u8 cmd, bank_sel; 142cba65a77SJagan Teki int ret; 143cba65a77SJagan Teki 144cba65a77SJagan Teki bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift); 145cba65a77SJagan Teki if (bank_sel == flash->bank_curr) 146cba65a77SJagan Teki goto bar_end; 147cba65a77SJagan Teki 148cba65a77SJagan Teki cmd = flash->bank_write_cmd; 149cba65a77SJagan Teki ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); 150cba65a77SJagan Teki if (ret < 0) { 151cba65a77SJagan Teki debug("SF: fail to write bank register\n"); 152cba65a77SJagan Teki return ret; 153cba65a77SJagan Teki } 154cba65a77SJagan Teki 155cba65a77SJagan Teki bar_end: 156cba65a77SJagan Teki flash->bank_curr = bank_sel; 157cba65a77SJagan Teki return flash->bank_curr; 158cba65a77SJagan Teki } 159cba65a77SJagan Teki 1607b4ab88eSJagan Teki static int read_bar(struct spi_flash *flash, const struct spi_flash_info *info) 161cba65a77SJagan Teki { 162cba65a77SJagan Teki u8 curr_bank = 0; 163cba65a77SJagan Teki int ret; 164cba65a77SJagan Teki 165cba65a77SJagan Teki if (flash->size <= SPI_FLASH_16MB_BOUN) 1666f309658SJagan Teki goto bar_end; 167cba65a77SJagan Teki 168f790ca7cSJagan Teki switch (JEDEC_MFR(info)) { 169cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_SPANSION: 170cba65a77SJagan Teki flash->bank_read_cmd = CMD_BANKADDR_BRRD; 171cba65a77SJagan Teki flash->bank_write_cmd = CMD_BANKADDR_BRWR; 172cba65a77SJagan Teki break; 173cba65a77SJagan Teki default: 174cba65a77SJagan Teki flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; 175cba65a77SJagan Teki flash->bank_write_cmd = CMD_EXTNADDR_WREAR; 176cba65a77SJagan Teki } 177cba65a77SJagan Teki 178cba65a77SJagan Teki ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, 179cba65a77SJagan Teki &curr_bank, 1); 180cba65a77SJagan Teki if (ret) { 181cba65a77SJagan Teki debug("SF: fail to read bank addr register\n"); 182cba65a77SJagan Teki return ret; 183cba65a77SJagan Teki } 184cba65a77SJagan Teki 1856f309658SJagan Teki bar_end: 186cba65a77SJagan Teki flash->bank_curr = curr_bank; 187cba65a77SJagan Teki return 0; 188cba65a77SJagan Teki } 189cba65a77SJagan Teki #endif 190cba65a77SJagan Teki 191cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 192cba65a77SJagan Teki static void spi_flash_dual(struct spi_flash *flash, u32 *addr) 193cba65a77SJagan Teki { 194cba65a77SJagan Teki switch (flash->dual_flash) { 195cba65a77SJagan Teki case SF_DUAL_STACKED_FLASH: 196cba65a77SJagan Teki if (*addr >= (flash->size >> 1)) { 197cba65a77SJagan Teki *addr -= flash->size >> 1; 19820343ff3SJagan Teki flash->flags |= SNOR_F_USE_UPAGE; 199cba65a77SJagan Teki } else { 20020343ff3SJagan Teki flash->flags &= ~SNOR_F_USE_UPAGE; 201cba65a77SJagan Teki } 202cba65a77SJagan Teki break; 203cba65a77SJagan Teki case SF_DUAL_PARALLEL_FLASH: 204cba65a77SJagan Teki *addr >>= flash->shift; 205cba65a77SJagan Teki break; 206cba65a77SJagan Teki default: 207cba65a77SJagan Teki debug("SF: Unsupported dual_flash=%d\n", flash->dual_flash); 208cba65a77SJagan Teki break; 209cba65a77SJagan Teki } 210cba65a77SJagan Teki } 211cba65a77SJagan Teki #endif 212cba65a77SJagan Teki 213cba65a77SJagan Teki static int spi_flash_sr_ready(struct spi_flash *flash) 214cba65a77SJagan Teki { 215cba65a77SJagan Teki u8 sr; 216cba65a77SJagan Teki int ret; 217cba65a77SJagan Teki 218cba65a77SJagan Teki ret = read_sr(flash, &sr); 219cba65a77SJagan Teki if (ret < 0) 220cba65a77SJagan Teki return ret; 221cba65a77SJagan Teki 222cba65a77SJagan Teki return !(sr & STATUS_WIP); 223cba65a77SJagan Teki } 224cba65a77SJagan Teki 225cba65a77SJagan Teki static int spi_flash_fsr_ready(struct spi_flash *flash) 226cba65a77SJagan Teki { 227cba65a77SJagan Teki u8 fsr; 228cba65a77SJagan Teki int ret; 229cba65a77SJagan Teki 230cba65a77SJagan Teki ret = read_fsr(flash, &fsr); 231cba65a77SJagan Teki if (ret < 0) 232cba65a77SJagan Teki return ret; 233cba65a77SJagan Teki 234cba65a77SJagan Teki return fsr & STATUS_PEC; 235cba65a77SJagan Teki } 236cba65a77SJagan Teki 237cba65a77SJagan Teki static int spi_flash_ready(struct spi_flash *flash) 238cba65a77SJagan Teki { 239cba65a77SJagan Teki int sr, fsr; 240cba65a77SJagan Teki 241cba65a77SJagan Teki sr = spi_flash_sr_ready(flash); 242cba65a77SJagan Teki if (sr < 0) 243cba65a77SJagan Teki return sr; 244cba65a77SJagan Teki 245cba65a77SJagan Teki fsr = 1; 246cba65a77SJagan Teki if (flash->flags & SNOR_F_USE_FSR) { 247cba65a77SJagan Teki fsr = spi_flash_fsr_ready(flash); 248cba65a77SJagan Teki if (fsr < 0) 249cba65a77SJagan Teki return fsr; 250cba65a77SJagan Teki } 251cba65a77SJagan Teki 252cba65a77SJagan Teki return sr && fsr; 253cba65a77SJagan Teki } 254cba65a77SJagan Teki 2557b4ab88eSJagan Teki static int spi_flash_wait_till_ready(struct spi_flash *flash, 256cba65a77SJagan Teki unsigned long timeout) 257cba65a77SJagan Teki { 25811b9a4d8SStephen Warren unsigned long timebase; 25911b9a4d8SStephen Warren int ret; 260cba65a77SJagan Teki 261cba65a77SJagan Teki timebase = get_timer(0); 262cba65a77SJagan Teki 263cba65a77SJagan Teki while (get_timer(timebase) < timeout) { 264cba65a77SJagan Teki ret = spi_flash_ready(flash); 265cba65a77SJagan Teki if (ret < 0) 266cba65a77SJagan Teki return ret; 267cba65a77SJagan Teki if (ret) 268cba65a77SJagan Teki return 0; 269cba65a77SJagan Teki } 270cba65a77SJagan Teki 271cba65a77SJagan Teki printf("SF: Timeout!\n"); 272cba65a77SJagan Teki 273cba65a77SJagan Teki return -ETIMEDOUT; 274cba65a77SJagan Teki } 275cba65a77SJagan Teki 276cba65a77SJagan Teki int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, 277cba65a77SJagan Teki size_t cmd_len, const void *buf, size_t buf_len) 278cba65a77SJagan Teki { 279cba65a77SJagan Teki struct spi_slave *spi = flash->spi; 280cba65a77SJagan Teki unsigned long timeout = SPI_FLASH_PROG_TIMEOUT; 281cba65a77SJagan Teki int ret; 282cba65a77SJagan Teki 283cba65a77SJagan Teki if (buf == NULL) 284cba65a77SJagan Teki timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT; 285cba65a77SJagan Teki 286e228d6deSJagan Teki ret = spi_claim_bus(spi); 287cba65a77SJagan Teki if (ret) { 288cba65a77SJagan Teki debug("SF: unable to claim SPI bus\n"); 289cba65a77SJagan Teki return ret; 290cba65a77SJagan Teki } 291cba65a77SJagan Teki 292cba65a77SJagan Teki ret = spi_flash_cmd_write_enable(flash); 293cba65a77SJagan Teki if (ret < 0) { 294cba65a77SJagan Teki debug("SF: enabling write failed\n"); 295cba65a77SJagan Teki return ret; 296cba65a77SJagan Teki } 297cba65a77SJagan Teki 298cba65a77SJagan Teki ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len); 299cba65a77SJagan Teki if (ret < 0) { 300cba65a77SJagan Teki debug("SF: write cmd failed\n"); 301cba65a77SJagan Teki return ret; 302cba65a77SJagan Teki } 303cba65a77SJagan Teki 3047b4ab88eSJagan Teki ret = spi_flash_wait_till_ready(flash, timeout); 305cba65a77SJagan Teki if (ret < 0) { 306cba65a77SJagan Teki debug("SF: write %s timed out\n", 307cba65a77SJagan Teki timeout == SPI_FLASH_PROG_TIMEOUT ? 308cba65a77SJagan Teki "program" : "page erase"); 309cba65a77SJagan Teki return ret; 310cba65a77SJagan Teki } 311cba65a77SJagan Teki 312cba65a77SJagan Teki spi_release_bus(spi); 313cba65a77SJagan Teki 314cba65a77SJagan Teki return ret; 315cba65a77SJagan Teki } 316cba65a77SJagan Teki 317cba65a77SJagan Teki int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) 318cba65a77SJagan Teki { 319cba65a77SJagan Teki u32 erase_size, erase_addr; 320cba65a77SJagan Teki u8 cmd[SPI_FLASH_CMD_LEN]; 321cba65a77SJagan Teki int ret = -1; 322cba65a77SJagan Teki 323cba65a77SJagan Teki erase_size = flash->erase_size; 324cba65a77SJagan Teki if (offset % erase_size || len % erase_size) { 325bf3fe928SLiam Beguin printf("SF: Erase offset/length not multiple of erase size\n"); 326cba65a77SJagan Teki return -1; 327cba65a77SJagan Teki } 328cba65a77SJagan Teki 329cba65a77SJagan Teki if (flash->flash_is_locked) { 330cba65a77SJagan Teki if (flash->flash_is_locked(flash, offset, len) > 0) { 331cba65a77SJagan Teki printf("offset 0x%x is protected and cannot be erased\n", 332cba65a77SJagan Teki offset); 333cba65a77SJagan Teki return -EINVAL; 334cba65a77SJagan Teki } 335cba65a77SJagan Teki } 336cba65a77SJagan Teki 337cba65a77SJagan Teki cmd[0] = flash->erase_cmd; 338cba65a77SJagan Teki while (len) { 339cba65a77SJagan Teki erase_addr = offset; 340cba65a77SJagan Teki 341cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 342cba65a77SJagan Teki if (flash->dual_flash > SF_SINGLE_FLASH) 343cba65a77SJagan Teki spi_flash_dual(flash, &erase_addr); 344cba65a77SJagan Teki #endif 345cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 3467b4ab88eSJagan Teki ret = write_bar(flash, erase_addr); 347cba65a77SJagan Teki if (ret < 0) 348cba65a77SJagan Teki return ret; 349cba65a77SJagan Teki #endif 350cba65a77SJagan Teki spi_flash_addr(erase_addr, cmd); 351cba65a77SJagan Teki 352cba65a77SJagan Teki debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], 353cba65a77SJagan Teki cmd[2], cmd[3], erase_addr); 354cba65a77SJagan Teki 355cba65a77SJagan Teki ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); 356cba65a77SJagan Teki if (ret < 0) { 357cba65a77SJagan Teki debug("SF: erase failed\n"); 358cba65a77SJagan Teki break; 359cba65a77SJagan Teki } 360cba65a77SJagan Teki 361cba65a77SJagan Teki offset += erase_size; 362cba65a77SJagan Teki len -= erase_size; 363cba65a77SJagan Teki } 364cba65a77SJagan Teki 3652e1c78b4SLukasz Majewski #ifdef CONFIG_SPI_FLASH_BAR 3662e1c78b4SLukasz Majewski ret = clean_bar(flash); 3672e1c78b4SLukasz Majewski #endif 3682e1c78b4SLukasz Majewski 369cba65a77SJagan Teki return ret; 370cba65a77SJagan Teki } 371cba65a77SJagan Teki 372cba65a77SJagan Teki int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, 373cba65a77SJagan Teki size_t len, const void *buf) 374cba65a77SJagan Teki { 375e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 376cba65a77SJagan Teki unsigned long byte_addr, page_size; 377cba65a77SJagan Teki u32 write_addr; 378cba65a77SJagan Teki size_t chunk_len, actual; 379cba65a77SJagan Teki u8 cmd[SPI_FLASH_CMD_LEN]; 380cba65a77SJagan Teki int ret = -1; 381cba65a77SJagan Teki 382cba65a77SJagan Teki page_size = flash->page_size; 383cba65a77SJagan Teki 384cba65a77SJagan Teki if (flash->flash_is_locked) { 385cba65a77SJagan Teki if (flash->flash_is_locked(flash, offset, len) > 0) { 386cba65a77SJagan Teki printf("offset 0x%x is protected and cannot be written\n", 387cba65a77SJagan Teki offset); 388cba65a77SJagan Teki return -EINVAL; 389cba65a77SJagan Teki } 390cba65a77SJagan Teki } 391cba65a77SJagan Teki 392cba65a77SJagan Teki cmd[0] = flash->write_cmd; 393cba65a77SJagan Teki for (actual = 0; actual < len; actual += chunk_len) { 394cba65a77SJagan Teki write_addr = offset; 395cba65a77SJagan Teki 396cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 397cba65a77SJagan Teki if (flash->dual_flash > SF_SINGLE_FLASH) 398cba65a77SJagan Teki spi_flash_dual(flash, &write_addr); 399cba65a77SJagan Teki #endif 400cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 4017b4ab88eSJagan Teki ret = write_bar(flash, write_addr); 402cba65a77SJagan Teki if (ret < 0) 403cba65a77SJagan Teki return ret; 404cba65a77SJagan Teki #endif 405cba65a77SJagan Teki byte_addr = offset % page_size; 406cba65a77SJagan Teki chunk_len = min(len - actual, (size_t)(page_size - byte_addr)); 407cba65a77SJagan Teki 408e228d6deSJagan Teki if (spi->max_write_size) 409cba65a77SJagan Teki chunk_len = min(chunk_len, 410d2a88c91SÁlvaro Fernández Rojas spi->max_write_size - sizeof(cmd)); 411cba65a77SJagan Teki 412cba65a77SJagan Teki spi_flash_addr(write_addr, cmd); 413cba65a77SJagan Teki 414cba65a77SJagan Teki debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", 415cba65a77SJagan Teki buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); 416cba65a77SJagan Teki 417cba65a77SJagan Teki ret = spi_flash_write_common(flash, cmd, sizeof(cmd), 418cba65a77SJagan Teki buf + actual, chunk_len); 419cba65a77SJagan Teki if (ret < 0) { 420cba65a77SJagan Teki debug("SF: write failed\n"); 421cba65a77SJagan Teki break; 422cba65a77SJagan Teki } 423cba65a77SJagan Teki 424cba65a77SJagan Teki offset += chunk_len; 425cba65a77SJagan Teki } 426cba65a77SJagan Teki 4272e1c78b4SLukasz Majewski #ifdef CONFIG_SPI_FLASH_BAR 4282e1c78b4SLukasz Majewski ret = clean_bar(flash); 4292e1c78b4SLukasz Majewski #endif 4302e1c78b4SLukasz Majewski 431cba65a77SJagan Teki return ret; 432cba65a77SJagan Teki } 433cba65a77SJagan Teki 434cba65a77SJagan Teki int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, 435cba65a77SJagan Teki size_t cmd_len, void *data, size_t data_len) 436cba65a77SJagan Teki { 437cba65a77SJagan Teki struct spi_slave *spi = flash->spi; 438cba65a77SJagan Teki int ret; 439cba65a77SJagan Teki 440e228d6deSJagan Teki ret = spi_claim_bus(spi); 441cba65a77SJagan Teki if (ret) { 442cba65a77SJagan Teki debug("SF: unable to claim SPI bus\n"); 443cba65a77SJagan Teki return ret; 444cba65a77SJagan Teki } 445cba65a77SJagan Teki 446cba65a77SJagan Teki ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); 447cba65a77SJagan Teki if (ret < 0) { 448cba65a77SJagan Teki debug("SF: read cmd failed\n"); 449cba65a77SJagan Teki return ret; 450cba65a77SJagan Teki } 451cba65a77SJagan Teki 452cba65a77SJagan Teki spi_release_bus(spi); 453cba65a77SJagan Teki 454cba65a77SJagan Teki return ret; 455cba65a77SJagan Teki } 456cba65a77SJagan Teki 4577bd1c59bSMugunthan V N /* 4587bd1c59bSMugunthan V N * TODO: remove the weak after all the other spi_flash_copy_mmap 4597bd1c59bSMugunthan V N * implementations removed from drivers 4607bd1c59bSMugunthan V N */ 461cba65a77SJagan Teki void __weak spi_flash_copy_mmap(void *data, void *offset, size_t len) 462cba65a77SJagan Teki { 4637bd1c59bSMugunthan V N #ifdef CONFIG_DMA 4647bd1c59bSMugunthan V N if (!dma_memcpy(data, offset, len)) 4657bd1c59bSMugunthan V N return; 4667bd1c59bSMugunthan V N #endif 467cba65a77SJagan Teki memcpy(data, offset, len); 468cba65a77SJagan Teki } 469cba65a77SJagan Teki 470cba65a77SJagan Teki int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, 471cba65a77SJagan Teki size_t len, void *data) 472cba65a77SJagan Teki { 473e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 474*50d09c0bSSimon Glass u8 cmdsz; 475cba65a77SJagan Teki u32 remain_len, read_len, read_addr; 476cba65a77SJagan Teki int bank_sel = 0; 477cba65a77SJagan Teki int ret = -1; 478cba65a77SJagan Teki 479cba65a77SJagan Teki /* Handle memory-mapped SPI */ 480cba65a77SJagan Teki if (flash->memory_map) { 481e228d6deSJagan Teki ret = spi_claim_bus(spi); 482cba65a77SJagan Teki if (ret) { 483cba65a77SJagan Teki debug("SF: unable to claim SPI bus\n"); 484cba65a77SJagan Teki return ret; 485cba65a77SJagan Teki } 486e228d6deSJagan Teki spi_xfer(spi, 0, NULL, NULL, SPI_XFER_MMAP); 487cba65a77SJagan Teki spi_flash_copy_mmap(data, flash->memory_map + offset, len); 488e228d6deSJagan Teki spi_xfer(spi, 0, NULL, NULL, SPI_XFER_MMAP_END); 489e228d6deSJagan Teki spi_release_bus(spi); 490cba65a77SJagan Teki return 0; 491cba65a77SJagan Teki } 492cba65a77SJagan Teki 493cba65a77SJagan Teki cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; 494*50d09c0bSSimon Glass u8 cmd[cmdsz]; 495cba65a77SJagan Teki 496cba65a77SJagan Teki cmd[0] = flash->read_cmd; 497cba65a77SJagan Teki while (len) { 498cba65a77SJagan Teki read_addr = offset; 499cba65a77SJagan Teki 500cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 501cba65a77SJagan Teki if (flash->dual_flash > SF_SINGLE_FLASH) 502cba65a77SJagan Teki spi_flash_dual(flash, &read_addr); 503cba65a77SJagan Teki #endif 504cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 5057b4ab88eSJagan Teki ret = write_bar(flash, read_addr); 506cba65a77SJagan Teki if (ret < 0) 507cba65a77SJagan Teki return ret; 508cba65a77SJagan Teki bank_sel = flash->bank_curr; 509cba65a77SJagan Teki #endif 510cba65a77SJagan Teki remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) * 511cba65a77SJagan Teki (bank_sel + 1)) - offset; 512cba65a77SJagan Teki if (len < remain_len) 513cba65a77SJagan Teki read_len = len; 514cba65a77SJagan Teki else 515cba65a77SJagan Teki read_len = remain_len; 516cba65a77SJagan Teki 517d68b9b84SÁlvaro Fernández Rojas if (spi->max_read_size) 518d68b9b84SÁlvaro Fernández Rojas read_len = min(read_len, spi->max_read_size); 519d68b9b84SÁlvaro Fernández Rojas 520cba65a77SJagan Teki spi_flash_addr(read_addr, cmd); 521cba65a77SJagan Teki 522cba65a77SJagan Teki ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len); 523cba65a77SJagan Teki if (ret < 0) { 524cba65a77SJagan Teki debug("SF: read failed\n"); 525cba65a77SJagan Teki break; 526cba65a77SJagan Teki } 527cba65a77SJagan Teki 528cba65a77SJagan Teki offset += read_len; 529cba65a77SJagan Teki len -= read_len; 530cba65a77SJagan Teki data += read_len; 531cba65a77SJagan Teki } 532cba65a77SJagan Teki 5332e1c78b4SLukasz Majewski #ifdef CONFIG_SPI_FLASH_BAR 5342e1c78b4SLukasz Majewski ret = clean_bar(flash); 5352e1c78b4SLukasz Majewski #endif 5362e1c78b4SLukasz Majewski 537cba65a77SJagan Teki return ret; 538cba65a77SJagan Teki } 539cba65a77SJagan Teki 540cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_SST 54158a870a7SEugeniy Paltsev static bool sst26_process_bpr(u32 bpr_size, u8 *cmd, u32 bit, enum lock_ctl ctl) 54258a870a7SEugeniy Paltsev { 54358a870a7SEugeniy Paltsev switch (ctl) { 54458a870a7SEugeniy Paltsev case SST26_CTL_LOCK: 54558a870a7SEugeniy Paltsev cmd[bpr_size - (bit / 8) - 1] |= BIT(bit % 8); 54658a870a7SEugeniy Paltsev break; 54758a870a7SEugeniy Paltsev case SST26_CTL_UNLOCK: 54858a870a7SEugeniy Paltsev cmd[bpr_size - (bit / 8) - 1] &= ~BIT(bit % 8); 54958a870a7SEugeniy Paltsev break; 55058a870a7SEugeniy Paltsev case SST26_CTL_CHECK: 55158a870a7SEugeniy Paltsev return !!(cmd[bpr_size - (bit / 8) - 1] & BIT(bit % 8)); 55258a870a7SEugeniy Paltsev } 55358a870a7SEugeniy Paltsev 55458a870a7SEugeniy Paltsev return false; 55558a870a7SEugeniy Paltsev } 55658a870a7SEugeniy Paltsev 55758a870a7SEugeniy Paltsev /* 55858a870a7SEugeniy Paltsev * sst26wf016/sst26wf032/sst26wf064 have next block protection: 55958a870a7SEugeniy Paltsev * 4x - 8 KByte blocks - read & write protection bits - upper addresses 56058a870a7SEugeniy Paltsev * 1x - 32 KByte blocks - write protection bits 56158a870a7SEugeniy Paltsev * rest - 64 KByte blocks - write protection bits 56258a870a7SEugeniy Paltsev * 1x - 32 KByte blocks - write protection bits 56358a870a7SEugeniy Paltsev * 4x - 8 KByte blocks - read & write protection bits - lower addresses 56458a870a7SEugeniy Paltsev * 56558a870a7SEugeniy Paltsev * We'll support only per 64k lock/unlock so lower and upper 64 KByte region 56658a870a7SEugeniy Paltsev * will be treated as single block. 56758a870a7SEugeniy Paltsev */ 56858a870a7SEugeniy Paltsev 56958a870a7SEugeniy Paltsev /* 57058a870a7SEugeniy Paltsev * Lock, unlock or check lock status of the flash region of the flash (depending 57158a870a7SEugeniy Paltsev * on the lock_ctl value) 57258a870a7SEugeniy Paltsev */ 57358a870a7SEugeniy Paltsev static int sst26_lock_ctl(struct spi_flash *flash, u32 ofs, size_t len, enum lock_ctl ctl) 57458a870a7SEugeniy Paltsev { 57558a870a7SEugeniy Paltsev u32 i, bpr_ptr, rptr_64k, lptr_64k, bpr_size; 57658a870a7SEugeniy Paltsev bool lower_64k = false, upper_64k = false; 57758a870a7SEugeniy Paltsev u8 cmd, bpr_buff[SST26_MAX_BPR_REG_LEN] = {}; 57858a870a7SEugeniy Paltsev int ret; 57958a870a7SEugeniy Paltsev 58058a870a7SEugeniy Paltsev /* Check length and offset for 64k alignment */ 58158a870a7SEugeniy Paltsev if ((ofs & (SZ_64K - 1)) || (len & (SZ_64K - 1))) 58258a870a7SEugeniy Paltsev return -EINVAL; 58358a870a7SEugeniy Paltsev 58458a870a7SEugeniy Paltsev if (ofs + len > flash->size) 58558a870a7SEugeniy Paltsev return -EINVAL; 58658a870a7SEugeniy Paltsev 58758a870a7SEugeniy Paltsev /* SST26 family has only 16 Mbit, 32 Mbit and 64 Mbit IC */ 58858a870a7SEugeniy Paltsev if (flash->size != SZ_2M && 58958a870a7SEugeniy Paltsev flash->size != SZ_4M && 59058a870a7SEugeniy Paltsev flash->size != SZ_8M) 59158a870a7SEugeniy Paltsev return -EINVAL; 59258a870a7SEugeniy Paltsev 59358a870a7SEugeniy Paltsev bpr_size = 2 + (flash->size / SZ_64K / 8); 59458a870a7SEugeniy Paltsev 59558a870a7SEugeniy Paltsev cmd = SST26_CMD_READ_BPR; 59658a870a7SEugeniy Paltsev ret = spi_flash_read_common(flash, &cmd, 1, bpr_buff, bpr_size); 59758a870a7SEugeniy Paltsev if (ret < 0) { 59858a870a7SEugeniy Paltsev printf("SF: fail to read block-protection register\n"); 59958a870a7SEugeniy Paltsev return ret; 60058a870a7SEugeniy Paltsev } 60158a870a7SEugeniy Paltsev 60258a870a7SEugeniy Paltsev rptr_64k = min_t(u32, ofs + len , flash->size - SST26_BOUND_REG_SIZE); 60358a870a7SEugeniy Paltsev lptr_64k = max_t(u32, ofs, SST26_BOUND_REG_SIZE); 60458a870a7SEugeniy Paltsev 60558a870a7SEugeniy Paltsev upper_64k = ((ofs + len) > (flash->size - SST26_BOUND_REG_SIZE)); 60658a870a7SEugeniy Paltsev lower_64k = (ofs < SST26_BOUND_REG_SIZE); 60758a870a7SEugeniy Paltsev 60858a870a7SEugeniy Paltsev /* Lower bits in block-protection register are about 64k region */ 60958a870a7SEugeniy Paltsev bpr_ptr = lptr_64k / SZ_64K - 1; 61058a870a7SEugeniy Paltsev 61158a870a7SEugeniy Paltsev /* Process 64K blocks region */ 61258a870a7SEugeniy Paltsev while (lptr_64k < rptr_64k) { 61358a870a7SEugeniy Paltsev if (sst26_process_bpr(bpr_size, bpr_buff, bpr_ptr, ctl)) 61458a870a7SEugeniy Paltsev return EACCES; 61558a870a7SEugeniy Paltsev 61658a870a7SEugeniy Paltsev bpr_ptr++; 61758a870a7SEugeniy Paltsev lptr_64k += SZ_64K; 61858a870a7SEugeniy Paltsev } 61958a870a7SEugeniy Paltsev 62058a870a7SEugeniy Paltsev /* 32K and 8K region bits in BPR are after 64k region bits */ 62158a870a7SEugeniy Paltsev bpr_ptr = (flash->size - 2 * SST26_BOUND_REG_SIZE) / SZ_64K; 62258a870a7SEugeniy Paltsev 62358a870a7SEugeniy Paltsev /* Process lower 32K block region */ 62458a870a7SEugeniy Paltsev if (lower_64k) 62558a870a7SEugeniy Paltsev if (sst26_process_bpr(bpr_size, bpr_buff, bpr_ptr, ctl)) 62658a870a7SEugeniy Paltsev return EACCES; 62758a870a7SEugeniy Paltsev 62858a870a7SEugeniy Paltsev bpr_ptr++; 62958a870a7SEugeniy Paltsev 63058a870a7SEugeniy Paltsev /* Process upper 32K block region */ 63158a870a7SEugeniy Paltsev if (upper_64k) 63258a870a7SEugeniy Paltsev if (sst26_process_bpr(bpr_size, bpr_buff, bpr_ptr, ctl)) 63358a870a7SEugeniy Paltsev return EACCES; 63458a870a7SEugeniy Paltsev 63558a870a7SEugeniy Paltsev bpr_ptr++; 63658a870a7SEugeniy Paltsev 63758a870a7SEugeniy Paltsev /* Process lower 8K block regions */ 63858a870a7SEugeniy Paltsev for (i = 0; i < SST26_BPR_8K_NUM; i++) { 63958a870a7SEugeniy Paltsev if (lower_64k) 64058a870a7SEugeniy Paltsev if (sst26_process_bpr(bpr_size, bpr_buff, bpr_ptr, ctl)) 64158a870a7SEugeniy Paltsev return EACCES; 64258a870a7SEugeniy Paltsev 64358a870a7SEugeniy Paltsev /* In 8K area BPR has both read and write protection bits */ 64458a870a7SEugeniy Paltsev bpr_ptr += 2; 64558a870a7SEugeniy Paltsev } 64658a870a7SEugeniy Paltsev 64758a870a7SEugeniy Paltsev /* Process upper 8K block regions */ 64858a870a7SEugeniy Paltsev for (i = 0; i < SST26_BPR_8K_NUM; i++) { 64958a870a7SEugeniy Paltsev if (upper_64k) 65058a870a7SEugeniy Paltsev if (sst26_process_bpr(bpr_size, bpr_buff, bpr_ptr, ctl)) 65158a870a7SEugeniy Paltsev return EACCES; 65258a870a7SEugeniy Paltsev 65358a870a7SEugeniy Paltsev /* In 8K area BPR has both read and write protection bits */ 65458a870a7SEugeniy Paltsev bpr_ptr += 2; 65558a870a7SEugeniy Paltsev } 65658a870a7SEugeniy Paltsev 65758a870a7SEugeniy Paltsev /* If we check region status we don't need to write BPR back */ 65858a870a7SEugeniy Paltsev if (ctl == SST26_CTL_CHECK) 65958a870a7SEugeniy Paltsev return 0; 66058a870a7SEugeniy Paltsev 66158a870a7SEugeniy Paltsev cmd = SST26_CMD_WRITE_BPR; 66258a870a7SEugeniy Paltsev ret = spi_flash_write_common(flash, &cmd, 1, bpr_buff, bpr_size); 66358a870a7SEugeniy Paltsev if (ret < 0) { 66458a870a7SEugeniy Paltsev printf("SF: fail to write block-protection register\n"); 66558a870a7SEugeniy Paltsev return ret; 66658a870a7SEugeniy Paltsev } 66758a870a7SEugeniy Paltsev 66858a870a7SEugeniy Paltsev return 0; 66958a870a7SEugeniy Paltsev } 67058a870a7SEugeniy Paltsev 67158a870a7SEugeniy Paltsev static int sst26_unlock(struct spi_flash *flash, u32 ofs, size_t len) 67258a870a7SEugeniy Paltsev { 67358a870a7SEugeniy Paltsev return sst26_lock_ctl(flash, ofs, len, SST26_CTL_UNLOCK); 67458a870a7SEugeniy Paltsev } 67558a870a7SEugeniy Paltsev 67658a870a7SEugeniy Paltsev static int sst26_lock(struct spi_flash *flash, u32 ofs, size_t len) 67758a870a7SEugeniy Paltsev { 67858a870a7SEugeniy Paltsev return sst26_lock_ctl(flash, ofs, len, SST26_CTL_LOCK); 67958a870a7SEugeniy Paltsev } 68058a870a7SEugeniy Paltsev 68158a870a7SEugeniy Paltsev /* 68258a870a7SEugeniy Paltsev * Returns EACCES (positive value) if region is locked, 0 if region is unlocked, 68358a870a7SEugeniy Paltsev * and negative on errors. 68458a870a7SEugeniy Paltsev */ 68558a870a7SEugeniy Paltsev static int sst26_is_locked(struct spi_flash *flash, u32 ofs, size_t len) 68658a870a7SEugeniy Paltsev { 68758a870a7SEugeniy Paltsev /* 68858a870a7SEugeniy Paltsev * is_locked function is used for check before reading or erasing flash 68958a870a7SEugeniy Paltsev * region, so offset and length might be not 64k allighned, so adjust 69058a870a7SEugeniy Paltsev * them to be 64k allighned as sst26_lock_ctl works only with 64k 69158a870a7SEugeniy Paltsev * allighned regions. 69258a870a7SEugeniy Paltsev */ 69358a870a7SEugeniy Paltsev ofs -= ofs & (SZ_64K - 1); 69458a870a7SEugeniy Paltsev len = len & (SZ_64K - 1) ? (len & ~(SZ_64K - 1)) + SZ_64K : len; 69558a870a7SEugeniy Paltsev 69658a870a7SEugeniy Paltsev return sst26_lock_ctl(flash, ofs, len, SST26_CTL_CHECK); 69758a870a7SEugeniy Paltsev } 69858a870a7SEugeniy Paltsev 699cba65a77SJagan Teki static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) 700cba65a77SJagan Teki { 701e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 702cba65a77SJagan Teki int ret; 703cba65a77SJagan Teki u8 cmd[4] = { 704cba65a77SJagan Teki CMD_SST_BP, 705cba65a77SJagan Teki offset >> 16, 706cba65a77SJagan Teki offset >> 8, 707cba65a77SJagan Teki offset, 708cba65a77SJagan Teki }; 709cba65a77SJagan Teki 710cba65a77SJagan Teki debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", 711e228d6deSJagan Teki spi_w8r8(spi, CMD_READ_STATUS), buf, cmd[0], offset); 712cba65a77SJagan Teki 713cba65a77SJagan Teki ret = spi_flash_cmd_write_enable(flash); 714cba65a77SJagan Teki if (ret) 715cba65a77SJagan Teki return ret; 716cba65a77SJagan Teki 717e228d6deSJagan Teki ret = spi_flash_cmd_write(spi, cmd, sizeof(cmd), buf, 1); 718cba65a77SJagan Teki if (ret) 719cba65a77SJagan Teki return ret; 720cba65a77SJagan Teki 7217b4ab88eSJagan Teki return spi_flash_wait_till_ready(flash, SPI_FLASH_PROG_TIMEOUT); 722cba65a77SJagan Teki } 723cba65a77SJagan Teki 724cba65a77SJagan Teki int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, 725cba65a77SJagan Teki const void *buf) 726cba65a77SJagan Teki { 727e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 728cba65a77SJagan Teki size_t actual, cmd_len; 729cba65a77SJagan Teki int ret; 730cba65a77SJagan Teki u8 cmd[4]; 731cba65a77SJagan Teki 732e228d6deSJagan Teki ret = spi_claim_bus(spi); 733cba65a77SJagan Teki if (ret) { 734cba65a77SJagan Teki debug("SF: Unable to claim SPI bus\n"); 735cba65a77SJagan Teki return ret; 736cba65a77SJagan Teki } 737cba65a77SJagan Teki 738cba65a77SJagan Teki /* If the data is not word aligned, write out leading single byte */ 739cba65a77SJagan Teki actual = offset % 2; 740cba65a77SJagan Teki if (actual) { 741cba65a77SJagan Teki ret = sst_byte_write(flash, offset, buf); 742cba65a77SJagan Teki if (ret) 743cba65a77SJagan Teki goto done; 744cba65a77SJagan Teki } 745cba65a77SJagan Teki offset += actual; 746cba65a77SJagan Teki 747cba65a77SJagan Teki ret = spi_flash_cmd_write_enable(flash); 748cba65a77SJagan Teki if (ret) 749cba65a77SJagan Teki goto done; 750cba65a77SJagan Teki 751cba65a77SJagan Teki cmd_len = 4; 752cba65a77SJagan Teki cmd[0] = CMD_SST_AAI_WP; 753cba65a77SJagan Teki cmd[1] = offset >> 16; 754cba65a77SJagan Teki cmd[2] = offset >> 8; 755cba65a77SJagan Teki cmd[3] = offset; 756cba65a77SJagan Teki 757cba65a77SJagan Teki for (; actual < len - 1; actual += 2) { 758cba65a77SJagan Teki debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", 759e228d6deSJagan Teki spi_w8r8(spi, CMD_READ_STATUS), buf + actual, 760cba65a77SJagan Teki cmd[0], offset); 761cba65a77SJagan Teki 762e228d6deSJagan Teki ret = spi_flash_cmd_write(spi, cmd, cmd_len, 763cba65a77SJagan Teki buf + actual, 2); 764cba65a77SJagan Teki if (ret) { 765cba65a77SJagan Teki debug("SF: sst word program failed\n"); 766cba65a77SJagan Teki break; 767cba65a77SJagan Teki } 768cba65a77SJagan Teki 7697b4ab88eSJagan Teki ret = spi_flash_wait_till_ready(flash, SPI_FLASH_PROG_TIMEOUT); 770cba65a77SJagan Teki if (ret) 771cba65a77SJagan Teki break; 772cba65a77SJagan Teki 773cba65a77SJagan Teki cmd_len = 1; 774cba65a77SJagan Teki offset += 2; 775cba65a77SJagan Teki } 776cba65a77SJagan Teki 777cba65a77SJagan Teki if (!ret) 778cba65a77SJagan Teki ret = spi_flash_cmd_write_disable(flash); 779cba65a77SJagan Teki 780cba65a77SJagan Teki /* If there is a single trailing byte, write it out */ 781cba65a77SJagan Teki if (!ret && actual != len) 782cba65a77SJagan Teki ret = sst_byte_write(flash, offset, buf + actual); 783cba65a77SJagan Teki 784cba65a77SJagan Teki done: 785cba65a77SJagan Teki debug("SF: sst: program %s %zu bytes @ 0x%zx\n", 786cba65a77SJagan Teki ret ? "failure" : "success", len, offset - actual); 787cba65a77SJagan Teki 788e228d6deSJagan Teki spi_release_bus(spi); 789cba65a77SJagan Teki return ret; 790cba65a77SJagan Teki } 791cba65a77SJagan Teki 792cba65a77SJagan Teki int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, 793cba65a77SJagan Teki const void *buf) 794cba65a77SJagan Teki { 795e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 796cba65a77SJagan Teki size_t actual; 797cba65a77SJagan Teki int ret; 798cba65a77SJagan Teki 799e228d6deSJagan Teki ret = spi_claim_bus(spi); 800cba65a77SJagan Teki if (ret) { 801cba65a77SJagan Teki debug("SF: Unable to claim SPI bus\n"); 802cba65a77SJagan Teki return ret; 803cba65a77SJagan Teki } 804cba65a77SJagan Teki 805cba65a77SJagan Teki for (actual = 0; actual < len; actual++) { 806cba65a77SJagan Teki ret = sst_byte_write(flash, offset, buf + actual); 807cba65a77SJagan Teki if (ret) { 808cba65a77SJagan Teki debug("SF: sst byte program failed\n"); 809cba65a77SJagan Teki break; 810cba65a77SJagan Teki } 811cba65a77SJagan Teki offset++; 812cba65a77SJagan Teki } 813cba65a77SJagan Teki 814cba65a77SJagan Teki if (!ret) 815cba65a77SJagan Teki ret = spi_flash_cmd_write_disable(flash); 816cba65a77SJagan Teki 817cba65a77SJagan Teki debug("SF: sst: program %s %zu bytes @ 0x%zx\n", 818cba65a77SJagan Teki ret ? "failure" : "success", len, offset - actual); 819cba65a77SJagan Teki 820e228d6deSJagan Teki spi_release_bus(spi); 821cba65a77SJagan Teki return ret; 822cba65a77SJagan Teki } 823cba65a77SJagan Teki #endif 824cba65a77SJagan Teki 825cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) 826cba65a77SJagan Teki static void stm_get_locked_range(struct spi_flash *flash, u8 sr, loff_t *ofs, 827ea9619aeSMarek Vasut u64 *len) 828cba65a77SJagan Teki { 829cba65a77SJagan Teki u8 mask = SR_BP2 | SR_BP1 | SR_BP0; 830cba65a77SJagan Teki int shift = ffs(mask) - 1; 831cba65a77SJagan Teki int pow; 832cba65a77SJagan Teki 833cba65a77SJagan Teki if (!(sr & mask)) { 834cba65a77SJagan Teki /* No protection */ 835cba65a77SJagan Teki *ofs = 0; 836cba65a77SJagan Teki *len = 0; 837cba65a77SJagan Teki } else { 838cba65a77SJagan Teki pow = ((sr & mask) ^ mask) >> shift; 839cba65a77SJagan Teki *len = flash->size >> pow; 840cba65a77SJagan Teki *ofs = flash->size - *len; 841cba65a77SJagan Teki } 842cba65a77SJagan Teki } 843cba65a77SJagan Teki 844cba65a77SJagan Teki /* 845cba65a77SJagan Teki * Return 1 if the entire region is locked, 0 otherwise 846cba65a77SJagan Teki */ 847ea9619aeSMarek Vasut static int stm_is_locked_sr(struct spi_flash *flash, loff_t ofs, u64 len, 848cba65a77SJagan Teki u8 sr) 849cba65a77SJagan Teki { 850cba65a77SJagan Teki loff_t lock_offs; 851ea9619aeSMarek Vasut u64 lock_len; 852cba65a77SJagan Teki 853cba65a77SJagan Teki stm_get_locked_range(flash, sr, &lock_offs, &lock_len); 854cba65a77SJagan Teki 855cba65a77SJagan Teki return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs); 856cba65a77SJagan Teki } 857cba65a77SJagan Teki 858cba65a77SJagan Teki /* 859cba65a77SJagan Teki * Check if a region of the flash is (completely) locked. See stm_lock() for 860cba65a77SJagan Teki * more info. 861cba65a77SJagan Teki * 862cba65a77SJagan Teki * Returns 1 if entire region is locked, 0 if any portion is unlocked, and 863cba65a77SJagan Teki * negative on errors. 864cba65a77SJagan Teki */ 865cba65a77SJagan Teki int stm_is_locked(struct spi_flash *flash, u32 ofs, size_t len) 866cba65a77SJagan Teki { 867cba65a77SJagan Teki int status; 868cba65a77SJagan Teki u8 sr; 869cba65a77SJagan Teki 870cba65a77SJagan Teki status = read_sr(flash, &sr); 871cba65a77SJagan Teki if (status < 0) 872cba65a77SJagan Teki return status; 873cba65a77SJagan Teki 874cba65a77SJagan Teki return stm_is_locked_sr(flash, ofs, len, sr); 875cba65a77SJagan Teki } 876cba65a77SJagan Teki 877cba65a77SJagan Teki /* 878cba65a77SJagan Teki * Lock a region of the flash. Compatible with ST Micro and similar flash. 879cba65a77SJagan Teki * Supports only the block protection bits BP{0,1,2} in the status register 880cba65a77SJagan Teki * (SR). Does not support these features found in newer SR bitfields: 881cba65a77SJagan Teki * - TB: top/bottom protect - only handle TB=0 (top protect) 882cba65a77SJagan Teki * - SEC: sector/block protect - only handle SEC=0 (block protect) 883cba65a77SJagan Teki * - CMP: complement protect - only support CMP=0 (range is not complemented) 884cba65a77SJagan Teki * 885cba65a77SJagan Teki * Sample table portion for 8MB flash (Winbond w25q64fw): 886cba65a77SJagan Teki * 887cba65a77SJagan Teki * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion 888cba65a77SJagan Teki * -------------------------------------------------------------------------- 889cba65a77SJagan Teki * X | X | 0 | 0 | 0 | NONE | NONE 890cba65a77SJagan Teki * 0 | 0 | 0 | 0 | 1 | 128 KB | Upper 1/64 891cba65a77SJagan Teki * 0 | 0 | 0 | 1 | 0 | 256 KB | Upper 1/32 892cba65a77SJagan Teki * 0 | 0 | 0 | 1 | 1 | 512 KB | Upper 1/16 893cba65a77SJagan Teki * 0 | 0 | 1 | 0 | 0 | 1 MB | Upper 1/8 894cba65a77SJagan Teki * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 895cba65a77SJagan Teki * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 896cba65a77SJagan Teki * X | X | 1 | 1 | 1 | 8 MB | ALL 897cba65a77SJagan Teki * 898cba65a77SJagan Teki * Returns negative on errors, 0 on success. 899cba65a77SJagan Teki */ 900cba65a77SJagan Teki int stm_lock(struct spi_flash *flash, u32 ofs, size_t len) 901cba65a77SJagan Teki { 902cba65a77SJagan Teki u8 status_old, status_new; 903cba65a77SJagan Teki u8 mask = SR_BP2 | SR_BP1 | SR_BP0; 904cba65a77SJagan Teki u8 shift = ffs(mask) - 1, pow, val; 905cba65a77SJagan Teki int ret; 906cba65a77SJagan Teki 907cba65a77SJagan Teki ret = read_sr(flash, &status_old); 908cba65a77SJagan Teki if (ret < 0) 909cba65a77SJagan Teki return ret; 910cba65a77SJagan Teki 911cba65a77SJagan Teki /* SPI NOR always locks to the end */ 912cba65a77SJagan Teki if (ofs + len != flash->size) { 913cba65a77SJagan Teki /* Does combined region extend to end? */ 914cba65a77SJagan Teki if (!stm_is_locked_sr(flash, ofs + len, flash->size - ofs - len, 915cba65a77SJagan Teki status_old)) 916cba65a77SJagan Teki return -EINVAL; 917cba65a77SJagan Teki len = flash->size - ofs; 918cba65a77SJagan Teki } 919cba65a77SJagan Teki 920cba65a77SJagan Teki /* 921cba65a77SJagan Teki * Need smallest pow such that: 922cba65a77SJagan Teki * 923cba65a77SJagan Teki * 1 / (2^pow) <= (len / size) 924cba65a77SJagan Teki * 925cba65a77SJagan Teki * so (assuming power-of-2 size) we do: 926cba65a77SJagan Teki * 927cba65a77SJagan Teki * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len)) 928cba65a77SJagan Teki */ 929cba65a77SJagan Teki pow = ilog2(flash->size) - ilog2(len); 930cba65a77SJagan Teki val = mask - (pow << shift); 931cba65a77SJagan Teki if (val & ~mask) 932cba65a77SJagan Teki return -EINVAL; 933cba65a77SJagan Teki 934cba65a77SJagan Teki /* Don't "lock" with no region! */ 935cba65a77SJagan Teki if (!(val & mask)) 936cba65a77SJagan Teki return -EINVAL; 937cba65a77SJagan Teki 938cba65a77SJagan Teki status_new = (status_old & ~mask) | val; 939cba65a77SJagan Teki 940cba65a77SJagan Teki /* Only modify protection if it will not unlock other areas */ 941cba65a77SJagan Teki if ((status_new & mask) <= (status_old & mask)) 942cba65a77SJagan Teki return -EINVAL; 943cba65a77SJagan Teki 944cba65a77SJagan Teki write_sr(flash, status_new); 945cba65a77SJagan Teki 946cba65a77SJagan Teki return 0; 947cba65a77SJagan Teki } 948cba65a77SJagan Teki 949cba65a77SJagan Teki /* 950cba65a77SJagan Teki * Unlock a region of the flash. See stm_lock() for more info 951cba65a77SJagan Teki * 952cba65a77SJagan Teki * Returns negative on errors, 0 on success. 953cba65a77SJagan Teki */ 954cba65a77SJagan Teki int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) 955cba65a77SJagan Teki { 956cba65a77SJagan Teki uint8_t status_old, status_new; 957cba65a77SJagan Teki u8 mask = SR_BP2 | SR_BP1 | SR_BP0; 958cba65a77SJagan Teki u8 shift = ffs(mask) - 1, pow, val; 959cba65a77SJagan Teki int ret; 960cba65a77SJagan Teki 961cba65a77SJagan Teki ret = read_sr(flash, &status_old); 962cba65a77SJagan Teki if (ret < 0) 963cba65a77SJagan Teki return ret; 964cba65a77SJagan Teki 965cba65a77SJagan Teki /* Cannot unlock; would unlock larger region than requested */ 96650921583SFabio Estevam if (stm_is_locked_sr(flash, ofs - flash->erase_size, flash->erase_size, 96750921583SFabio Estevam status_old)) 968cba65a77SJagan Teki return -EINVAL; 969cba65a77SJagan Teki /* 970cba65a77SJagan Teki * Need largest pow such that: 971cba65a77SJagan Teki * 972cba65a77SJagan Teki * 1 / (2^pow) >= (len / size) 973cba65a77SJagan Teki * 974cba65a77SJagan Teki * so (assuming power-of-2 size) we do: 975cba65a77SJagan Teki * 976cba65a77SJagan Teki * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len)) 977cba65a77SJagan Teki */ 978cba65a77SJagan Teki pow = ilog2(flash->size) - order_base_2(flash->size - (ofs + len)); 979cba65a77SJagan Teki if (ofs + len == flash->size) { 980cba65a77SJagan Teki val = 0; /* fully unlocked */ 981cba65a77SJagan Teki } else { 982cba65a77SJagan Teki val = mask - (pow << shift); 983cba65a77SJagan Teki /* Some power-of-two sizes are not supported */ 984cba65a77SJagan Teki if (val & ~mask) 985cba65a77SJagan Teki return -EINVAL; 986cba65a77SJagan Teki } 987cba65a77SJagan Teki 988cba65a77SJagan Teki status_new = (status_old & ~mask) | val; 989cba65a77SJagan Teki 990cba65a77SJagan Teki /* Only modify protection if it will not lock other areas */ 991cba65a77SJagan Teki if ((status_new & mask) >= (status_old & mask)) 992cba65a77SJagan Teki return -EINVAL; 993cba65a77SJagan Teki 994cba65a77SJagan Teki write_sr(flash, status_new); 995cba65a77SJagan Teki 996cba65a77SJagan Teki return 0; 997cba65a77SJagan Teki } 998cba65a77SJagan Teki #endif 999cba65a77SJagan Teki 1000cba65a77SJagan Teki 10016f775b34SAndy Yan #if defined(CONFIG_SPI_FLASH_MACRONIX) || defined(CONFIG_SPI_FLASH_GIGADEVICE) 10029275929cSJagan Teki static int macronix_quad_enable(struct spi_flash *flash) 1003cba65a77SJagan Teki { 1004cba65a77SJagan Teki u8 qeb_status; 1005cba65a77SJagan Teki int ret; 1006cba65a77SJagan Teki 1007cba65a77SJagan Teki ret = read_sr(flash, &qeb_status); 1008cba65a77SJagan Teki if (ret < 0) 1009cba65a77SJagan Teki return ret; 1010cba65a77SJagan Teki 1011bfcdc395SJagan Teki if (qeb_status & STATUS_QEB_MXIC) 1012bfcdc395SJagan Teki return 0; 1013bfcdc395SJagan Teki 1014d9a0ab6cSJagan Teki ret = write_sr(flash, qeb_status | STATUS_QEB_MXIC); 1015cba65a77SJagan Teki if (ret < 0) 1016cba65a77SJagan Teki return ret; 1017bfcdc395SJagan Teki 1018bfcdc395SJagan Teki /* read SR and check it */ 1019bfcdc395SJagan Teki ret = read_sr(flash, &qeb_status); 1020bfcdc395SJagan Teki if (!(ret >= 0 && (qeb_status & STATUS_QEB_MXIC))) { 1021bfcdc395SJagan Teki printf("SF: Macronix SR Quad bit not clear\n"); 1022bfcdc395SJagan Teki return -EINVAL; 1023cba65a77SJagan Teki } 1024cba65a77SJagan Teki 1025cba65a77SJagan Teki return ret; 1026cba65a77SJagan Teki } 1027cba65a77SJagan Teki #endif 1028cba65a77SJagan Teki 1029cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) 10309275929cSJagan Teki static int spansion_quad_enable(struct spi_flash *flash) 1031cba65a77SJagan Teki { 1032cba65a77SJagan Teki u8 qeb_status; 1033cba65a77SJagan Teki int ret; 1034cba65a77SJagan Teki 1035cba65a77SJagan Teki ret = read_cr(flash, &qeb_status); 1036cba65a77SJagan Teki if (ret < 0) 1037cba65a77SJagan Teki return ret; 1038cba65a77SJagan Teki 1039ffecb0fcSJagan Teki if (qeb_status & STATUS_QEB_WINSPAN) 1040ffecb0fcSJagan Teki return 0; 1041ffecb0fcSJagan Teki 1042d9a0ab6cSJagan Teki ret = write_cr(flash, qeb_status | STATUS_QEB_WINSPAN); 1043cba65a77SJagan Teki if (ret < 0) 1044cba65a77SJagan Teki return ret; 1045ffecb0fcSJagan Teki 1046ffecb0fcSJagan Teki /* read CR and check it */ 1047ffecb0fcSJagan Teki ret = read_cr(flash, &qeb_status); 1048ffecb0fcSJagan Teki if (!(ret >= 0 && (qeb_status & STATUS_QEB_WINSPAN))) { 1049ffecb0fcSJagan Teki printf("SF: Spansion CR Quad bit not clear\n"); 1050ffecb0fcSJagan Teki return -EINVAL; 1051cba65a77SJagan Teki } 1052cba65a77SJagan Teki 1053cba65a77SJagan Teki return ret; 1054cba65a77SJagan Teki } 1055cba65a77SJagan Teki #endif 1056cba65a77SJagan Teki 1057f790ca7cSJagan Teki static const struct spi_flash_info *spi_flash_read_id(struct spi_flash *flash) 1058cba65a77SJagan Teki { 1059f790ca7cSJagan Teki int tmp; 1060ed363b53SJagan Teki u8 id[SPI_FLASH_MAX_ID_LEN]; 1061f790ca7cSJagan Teki const struct spi_flash_info *info; 1062f790ca7cSJagan Teki 1063ed363b53SJagan Teki tmp = spi_flash_cmd(flash->spi, CMD_READ_ID, id, SPI_FLASH_MAX_ID_LEN); 1064f790ca7cSJagan Teki if (tmp < 0) { 1065f790ca7cSJagan Teki printf("SF: error %d reading JEDEC ID\n", tmp); 1066f790ca7cSJagan Teki return ERR_PTR(tmp); 1067f790ca7cSJagan Teki } 1068f790ca7cSJagan Teki 1069f790ca7cSJagan Teki info = spi_flash_ids; 1070f790ca7cSJagan Teki for (; info->name != NULL; info++) { 1071f790ca7cSJagan Teki if (info->id_len) { 1072f790ca7cSJagan Teki if (!memcmp(info->id, id, info->id_len)) 1073f790ca7cSJagan Teki return info; 1074f790ca7cSJagan Teki } 1075f790ca7cSJagan Teki } 1076f790ca7cSJagan Teki 1077f790ca7cSJagan Teki printf("SF: unrecognized JEDEC id bytes: %02x, %02x, %02x\n", 1078f790ca7cSJagan Teki id[0], id[1], id[2]); 1079f790ca7cSJagan Teki return ERR_PTR(-ENODEV); 1080f790ca7cSJagan Teki } 1081f790ca7cSJagan Teki 1082f790ca7cSJagan Teki static int set_quad_mode(struct spi_flash *flash, 1083f790ca7cSJagan Teki const struct spi_flash_info *info) 1084f790ca7cSJagan Teki { 1085f790ca7cSJagan Teki switch (JEDEC_MFR(info)) { 10866f775b34SAndy Yan #if defined(CONFIG_SPI_FLASH_MACRONIX) || defined(CONFIG_SPI_FLASH_GIGADEVICE) 1087cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_MACRONIX: 10886f775b34SAndy Yan case SPI_FLASH_CIF_MFR_GIGADEVICE: 10899275929cSJagan Teki return macronix_quad_enable(flash); 1090cba65a77SJagan Teki #endif 1091cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) 1092cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_SPANSION: 1093cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_WINBOND: 10949275929cSJagan Teki return spansion_quad_enable(flash); 1095cba65a77SJagan Teki #endif 1096cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_STMICRO 1097cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_STMICRO: 10989bcb0188SCyrille Pitchen debug("SF: QEB is volatile for %02x flash\n", JEDEC_MFR(info)); 10999bcb0188SCyrille Pitchen return 0; 1100cba65a77SJagan Teki #endif 1101cba65a77SJagan Teki default: 1102f790ca7cSJagan Teki printf("SF: Need set QEB func for %02x flash\n", 1103f790ca7cSJagan Teki JEDEC_MFR(info)); 1104cba65a77SJagan Teki return -1; 1105cba65a77SJagan Teki } 1106cba65a77SJagan Teki } 1107cba65a77SJagan Teki 1108cba65a77SJagan Teki #if CONFIG_IS_ENABLED(OF_CONTROL) 1109656f29d1SSimon Glass int spi_flash_decode_fdt(struct spi_flash *flash) 1110cba65a77SJagan Teki { 1111d178a1c5SSimon Glass #ifdef CONFIG_DM_SPI_FLASH 1112cba65a77SJagan Teki fdt_addr_t addr; 1113cba65a77SJagan Teki fdt_size_t size; 1114cba65a77SJagan Teki 1115656f29d1SSimon Glass addr = dev_read_addr_size(flash->dev, "memory-map", &size); 1116cba65a77SJagan Teki if (addr == FDT_ADDR_T_NONE) { 1117cba65a77SJagan Teki debug("%s: Cannot decode address\n", __func__); 1118cba65a77SJagan Teki return 0; 1119cba65a77SJagan Teki } 1120cba65a77SJagan Teki 1121db9225baSPhil Edworthy if (flash->size > size) { 1122cba65a77SJagan Teki debug("%s: Memory map must cover entire device\n", __func__); 1123cba65a77SJagan Teki return -1; 1124cba65a77SJagan Teki } 1125cba65a77SJagan Teki flash->memory_map = map_sysmem(addr, size); 1126d178a1c5SSimon Glass #endif 1127cba65a77SJagan Teki 1128cba65a77SJagan Teki return 0; 1129cba65a77SJagan Teki } 1130cba65a77SJagan Teki #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ 1131cba65a77SJagan Teki 1132cba65a77SJagan Teki int spi_flash_scan(struct spi_flash *flash) 1133cba65a77SJagan Teki { 1134cba65a77SJagan Teki struct spi_slave *spi = flash->spi; 1135f790ca7cSJagan Teki const struct spi_flash_info *info = NULL; 1136304decddSFabien Parent int ret; 1137cba65a77SJagan Teki 1138f790ca7cSJagan Teki info = spi_flash_read_id(flash); 1139f790ca7cSJagan Teki if (IS_ERR_OR_NULL(info)) 1140f790ca7cSJagan Teki return -ENOENT; 1141cba65a77SJagan Teki 1142294f2050SBin Meng /* 1143294f2050SBin Meng * Flash powers up read-only, so clear BP# bits. 1144294f2050SBin Meng * 1145294f2050SBin Meng * Note on some flash (like Macronix), QE (quad enable) bit is in the 1146294f2050SBin Meng * same status register as BP# bits, and we need preserve its original 1147294f2050SBin Meng * value during a reboot cycle as this is required by some platforms 1148294f2050SBin Meng * (like Intel ICH SPI controller working under descriptor mode). 1149294f2050SBin Meng */ 1150f790ca7cSJagan Teki if (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_ATMEL || 1151294f2050SBin Meng (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_SST) || 1152294f2050SBin Meng (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_MACRONIX)) { 1153294f2050SBin Meng u8 sr = 0; 1154294f2050SBin Meng 1155294f2050SBin Meng if (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_MACRONIX) { 1156294f2050SBin Meng read_sr(flash, &sr); 1157294f2050SBin Meng sr &= STATUS_QEB_MXIC; 1158294f2050SBin Meng } 1159294f2050SBin Meng write_sr(flash, sr); 1160294f2050SBin Meng } 1161cba65a77SJagan Teki 1162f790ca7cSJagan Teki flash->name = info->name; 1163cba65a77SJagan Teki flash->memory_map = spi->memory_map; 1164cba65a77SJagan Teki 1165f790ca7cSJagan Teki if (info->flags & SST_WR) 1166cba65a77SJagan Teki flash->flags |= SNOR_F_SST_WR; 1167cba65a77SJagan Teki 1168cba65a77SJagan Teki #ifndef CONFIG_DM_SPI_FLASH 1169cba65a77SJagan Teki flash->write = spi_flash_cmd_write_ops; 1170cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SST) 1171cba65a77SJagan Teki if (flash->flags & SNOR_F_SST_WR) { 1172cdf33938SJagan Teki if (spi->mode & SPI_TX_BYTE) 1173cba65a77SJagan Teki flash->write = sst_write_bp; 1174cba65a77SJagan Teki else 1175cba65a77SJagan Teki flash->write = sst_write_wp; 1176cba65a77SJagan Teki } 1177cba65a77SJagan Teki #endif 1178cba65a77SJagan Teki flash->erase = spi_flash_cmd_erase_ops; 1179cba65a77SJagan Teki flash->read = spi_flash_cmd_read_ops; 1180cba65a77SJagan Teki #endif 1181cba65a77SJagan Teki 1182cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) 1183dda06a43SJagan Teki /* NOR protection support for STmicro/Micron chips and similar */ 1184dda06a43SJagan Teki if (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_STMICRO || 1185dda06a43SJagan Teki JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_SST) { 1186cba65a77SJagan Teki flash->flash_lock = stm_lock; 1187cba65a77SJagan Teki flash->flash_unlock = stm_unlock; 1188cba65a77SJagan Teki flash->flash_is_locked = stm_is_locked; 1189cba65a77SJagan Teki } 1190dda06a43SJagan Teki #endif 1191cba65a77SJagan Teki 119258a870a7SEugeniy Paltsev /* sst26wf series block protection implementation differs from other series */ 119358a870a7SEugeniy Paltsev #if defined(CONFIG_SPI_FLASH_SST) 119458a870a7SEugeniy Paltsev if (JEDEC_MFR(info) == SPI_FLASH_CFI_MFR_SST && info->id[1] == 0x26) { 119558a870a7SEugeniy Paltsev flash->flash_lock = sst26_lock; 119658a870a7SEugeniy Paltsev flash->flash_unlock = sst26_unlock; 119758a870a7SEugeniy Paltsev flash->flash_is_locked = sst26_is_locked; 119858a870a7SEugeniy Paltsev } 119958a870a7SEugeniy Paltsev #endif 120058a870a7SEugeniy Paltsev 1201cba65a77SJagan Teki /* Compute the flash size */ 1202cba65a77SJagan Teki flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0; 1203f790ca7cSJagan Teki flash->page_size = info->page_size; 1204cba65a77SJagan Teki /* 12056eab7397SAshish Kumar * The Spansion S25FS512S, S25FL032P and S25FL064P have 256b pages, 12066eab7397SAshish Kumar * yet use the 0x4d00 Extended JEDEC code. The rest of the Spansion 12076eab7397SAshish Kumar * flashes with the 0x4d00 Extended JEDEC code have 512b pages. 12086eab7397SAshish Kumar * All of the others have 256b pages. 1209cba65a77SJagan Teki */ 1210f790ca7cSJagan Teki if (JEDEC_EXT(info) == 0x4d00) { 1211f790ca7cSJagan Teki if ((JEDEC_ID(info) != 0x0215) && 12126eab7397SAshish Kumar (JEDEC_ID(info) != 0x0216) && 12136eab7397SAshish Kumar (JEDEC_ID(info) != 0x0220)) 1214cba65a77SJagan Teki flash->page_size = 512; 1215cba65a77SJagan Teki } 1216cba65a77SJagan Teki flash->page_size <<= flash->shift; 1217f790ca7cSJagan Teki flash->sector_size = info->sector_size << flash->shift; 1218eccb6be0SJagan Teki flash->size = flash->sector_size * info->n_sectors << flash->shift; 1219cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 1220cba65a77SJagan Teki if (flash->dual_flash & SF_DUAL_STACKED_FLASH) 1221cba65a77SJagan Teki flash->size <<= 1; 1222cba65a77SJagan Teki #endif 1223cba65a77SJagan Teki 1224de059928SJagan Teki #ifdef CONFIG_SPI_FLASH_USE_4K_SECTORS 1225cba65a77SJagan Teki /* Compute erase sector and command */ 1226f790ca7cSJagan Teki if (info->flags & SECT_4K) { 1227cba65a77SJagan Teki flash->erase_cmd = CMD_ERASE_4K; 1228cba65a77SJagan Teki flash->erase_size = 4096 << flash->shift; 1229de059928SJagan Teki } else 1230de059928SJagan Teki #endif 1231de059928SJagan Teki { 1232cba65a77SJagan Teki flash->erase_cmd = CMD_ERASE_64K; 1233cba65a77SJagan Teki flash->erase_size = flash->sector_size; 1234cba65a77SJagan Teki } 1235cba65a77SJagan Teki 1236cba65a77SJagan Teki /* Now erase size becomes valid sector size */ 1237cba65a77SJagan Teki flash->sector_size = flash->erase_size; 1238cba65a77SJagan Teki 1239edd35f71SJagan Teki /* Look for read commands */ 1240cba65a77SJagan Teki flash->read_cmd = CMD_READ_ARRAY_FAST; 124108fe9c29SJagan Teki if (spi->mode & SPI_RX_SLOW) 1242edd35f71SJagan Teki flash->read_cmd = CMD_READ_ARRAY_SLOW; 1243f790ca7cSJagan Teki else if (spi->mode & SPI_RX_QUAD && info->flags & RD_QUAD) 1244edd35f71SJagan Teki flash->read_cmd = CMD_READ_QUAD_OUTPUT_FAST; 1245f790ca7cSJagan Teki else if (spi->mode & SPI_RX_DUAL && info->flags & RD_DUAL) 1246edd35f71SJagan Teki flash->read_cmd = CMD_READ_DUAL_OUTPUT_FAST; 1247cba65a77SJagan Teki 1248edd35f71SJagan Teki /* Look for write commands */ 1249f790ca7cSJagan Teki if (info->flags & WR_QPP && spi->mode & SPI_TX_QUAD) 1250cba65a77SJagan Teki flash->write_cmd = CMD_QUAD_PAGE_PROGRAM; 1251cba65a77SJagan Teki else 1252cba65a77SJagan Teki /* Go for default supported write cmd */ 1253cba65a77SJagan Teki flash->write_cmd = CMD_PAGE_PROGRAM; 1254cba65a77SJagan Teki 1255cba65a77SJagan Teki /* Set the quad enable bit - only for quad commands */ 1256cba65a77SJagan Teki if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || 1257cba65a77SJagan Teki (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || 1258cba65a77SJagan Teki (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { 1259f790ca7cSJagan Teki ret = set_quad_mode(flash, info); 1260cba65a77SJagan Teki if (ret) { 1261f790ca7cSJagan Teki debug("SF: Fail to set QEB for %02x\n", 1262f790ca7cSJagan Teki JEDEC_MFR(info)); 1263cba65a77SJagan Teki return -EINVAL; 1264cba65a77SJagan Teki } 1265cba65a77SJagan Teki } 1266cba65a77SJagan Teki 1267cba65a77SJagan Teki /* Read dummy_byte: dummy byte is determined based on the 1268cba65a77SJagan Teki * dummy cycles of a particular command. 1269cba65a77SJagan Teki * Fast commands - dummy_byte = dummy_cycles/8 1270cba65a77SJagan Teki * I/O commands- dummy_byte = (dummy_cycles * no.of lines)/8 1271cba65a77SJagan Teki * For I/O commands except cmd[0] everything goes on no.of lines 1272cba65a77SJagan Teki * based on particular command but incase of fast commands except 1273cba65a77SJagan Teki * data all go on single line irrespective of command. 1274cba65a77SJagan Teki */ 1275cba65a77SJagan Teki switch (flash->read_cmd) { 1276cba65a77SJagan Teki case CMD_READ_QUAD_IO_FAST: 1277cba65a77SJagan Teki flash->dummy_byte = 2; 1278cba65a77SJagan Teki break; 1279cba65a77SJagan Teki case CMD_READ_ARRAY_SLOW: 1280cba65a77SJagan Teki flash->dummy_byte = 0; 1281cba65a77SJagan Teki break; 1282cba65a77SJagan Teki default: 1283cba65a77SJagan Teki flash->dummy_byte = 1; 1284cba65a77SJagan Teki } 1285cba65a77SJagan Teki 1286cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_STMICRO 1287f790ca7cSJagan Teki if (info->flags & E_FSR) 1288cba65a77SJagan Teki flash->flags |= SNOR_F_USE_FSR; 1289cba65a77SJagan Teki #endif 1290cba65a77SJagan Teki 1291cba65a77SJagan Teki /* Configure the BAR - discover bank cmds and read current bank */ 1292cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 12937b4ab88eSJagan Teki ret = read_bar(flash, info); 1294cba65a77SJagan Teki if (ret < 0) 1295cba65a77SJagan Teki return ret; 1296cba65a77SJagan Teki #endif 1297cba65a77SJagan Teki 129871634f28SSimon Glass #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 1299656f29d1SSimon Glass ret = spi_flash_decode_fdt(flash); 1300cba65a77SJagan Teki if (ret) { 1301cba65a77SJagan Teki debug("SF: FDT decode error\n"); 1302cba65a77SJagan Teki return -EINVAL; 1303cba65a77SJagan Teki } 1304cba65a77SJagan Teki #endif 1305cba65a77SJagan Teki 1306cba65a77SJagan Teki #ifndef CONFIG_SPL_BUILD 1307cba65a77SJagan Teki printf("SF: Detected %s with page size ", flash->name); 1308cba65a77SJagan Teki print_size(flash->page_size, ", erase size "); 1309cba65a77SJagan Teki print_size(flash->erase_size, ", total "); 1310cba65a77SJagan Teki print_size(flash->size, ""); 1311cba65a77SJagan Teki if (flash->memory_map) 1312cba65a77SJagan Teki printf(", mapped at %p", flash->memory_map); 1313cba65a77SJagan Teki puts("\n"); 1314cba65a77SJagan Teki #endif 1315cba65a77SJagan Teki 1316cba65a77SJagan Teki #ifndef CONFIG_SPI_FLASH_BAR 1317cba65a77SJagan Teki if (((flash->dual_flash == SF_SINGLE_FLASH) && 1318cba65a77SJagan Teki (flash->size > SPI_FLASH_16MB_BOUN)) || 1319cba65a77SJagan Teki ((flash->dual_flash > SF_SINGLE_FLASH) && 1320cba65a77SJagan Teki (flash->size > SPI_FLASH_16MB_BOUN << 1))) { 1321cba65a77SJagan Teki puts("SF: Warning - Only lower 16MiB accessible,"); 1322cba65a77SJagan Teki puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); 1323cba65a77SJagan Teki } 1324cba65a77SJagan Teki #endif 1325cba65a77SJagan Teki 1326304decddSFabien Parent return 0; 1327cba65a77SJagan Teki } 1328