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> 19cba65a77SJagan Teki 20cba65a77SJagan Teki #include "sf_internal.h" 21cba65a77SJagan Teki 22cba65a77SJagan Teki DECLARE_GLOBAL_DATA_PTR; 23cba65a77SJagan Teki 24cba65a77SJagan Teki static void spi_flash_addr(u32 addr, u8 *cmd) 25cba65a77SJagan Teki { 26cba65a77SJagan Teki /* cmd[0] is actual command */ 27cba65a77SJagan Teki cmd[1] = addr >> 16; 28cba65a77SJagan Teki cmd[2] = addr >> 8; 29cba65a77SJagan Teki cmd[3] = addr >> 0; 30cba65a77SJagan Teki } 31cba65a77SJagan Teki 32cba65a77SJagan Teki static int read_sr(struct spi_flash *flash, u8 *rs) 33cba65a77SJagan Teki { 34cba65a77SJagan Teki int ret; 35cba65a77SJagan Teki u8 cmd; 36cba65a77SJagan Teki 37cba65a77SJagan Teki cmd = CMD_READ_STATUS; 38cba65a77SJagan Teki ret = spi_flash_read_common(flash, &cmd, 1, rs, 1); 39cba65a77SJagan Teki if (ret < 0) { 40cba65a77SJagan Teki debug("SF: fail to read status register\n"); 41cba65a77SJagan Teki return ret; 42cba65a77SJagan Teki } 43cba65a77SJagan Teki 44cba65a77SJagan Teki return 0; 45cba65a77SJagan Teki } 46cba65a77SJagan Teki 47cba65a77SJagan Teki static int read_fsr(struct spi_flash *flash, u8 *fsr) 48cba65a77SJagan Teki { 49cba65a77SJagan Teki int ret; 50cba65a77SJagan Teki const u8 cmd = CMD_FLAG_STATUS; 51cba65a77SJagan Teki 52cba65a77SJagan Teki ret = spi_flash_read_common(flash, &cmd, 1, fsr, 1); 53cba65a77SJagan Teki if (ret < 0) { 54cba65a77SJagan Teki debug("SF: fail to read flag status register\n"); 55cba65a77SJagan Teki return ret; 56cba65a77SJagan Teki } 57cba65a77SJagan Teki 58cba65a77SJagan Teki return 0; 59cba65a77SJagan Teki } 60cba65a77SJagan Teki 61cba65a77SJagan Teki static int write_sr(struct spi_flash *flash, u8 ws) 62cba65a77SJagan Teki { 63cba65a77SJagan Teki u8 cmd; 64cba65a77SJagan Teki int ret; 65cba65a77SJagan Teki 66cba65a77SJagan Teki cmd = CMD_WRITE_STATUS; 67cba65a77SJagan Teki ret = spi_flash_write_common(flash, &cmd, 1, &ws, 1); 68cba65a77SJagan Teki if (ret < 0) { 69cba65a77SJagan Teki debug("SF: fail to write status register\n"); 70cba65a77SJagan Teki return ret; 71cba65a77SJagan Teki } 72cba65a77SJagan Teki 73cba65a77SJagan Teki return 0; 74cba65a77SJagan Teki } 75cba65a77SJagan Teki 76cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) 77cba65a77SJagan Teki static int read_cr(struct spi_flash *flash, u8 *rc) 78cba65a77SJagan Teki { 79cba65a77SJagan Teki int ret; 80cba65a77SJagan Teki u8 cmd; 81cba65a77SJagan Teki 82cba65a77SJagan Teki cmd = CMD_READ_CONFIG; 83cba65a77SJagan Teki ret = spi_flash_read_common(flash, &cmd, 1, rc, 1); 84cba65a77SJagan Teki if (ret < 0) { 85cba65a77SJagan Teki debug("SF: fail to read config register\n"); 86cba65a77SJagan Teki return ret; 87cba65a77SJagan Teki } 88cba65a77SJagan Teki 89cba65a77SJagan Teki return 0; 90cba65a77SJagan Teki } 91cba65a77SJagan Teki 92cba65a77SJagan Teki static int write_cr(struct spi_flash *flash, u8 wc) 93cba65a77SJagan Teki { 94cba65a77SJagan Teki u8 data[2]; 95cba65a77SJagan Teki u8 cmd; 96cba65a77SJagan Teki int ret; 97cba65a77SJagan Teki 98cba65a77SJagan Teki ret = read_sr(flash, &data[0]); 99cba65a77SJagan Teki if (ret < 0) 100cba65a77SJagan Teki return ret; 101cba65a77SJagan Teki 102cba65a77SJagan Teki cmd = CMD_WRITE_STATUS; 103cba65a77SJagan Teki data[1] = wc; 104cba65a77SJagan Teki ret = spi_flash_write_common(flash, &cmd, 1, &data, 2); 105cba65a77SJagan Teki if (ret) { 106cba65a77SJagan Teki debug("SF: fail to write config register\n"); 107cba65a77SJagan Teki return ret; 108cba65a77SJagan Teki } 109cba65a77SJagan Teki 110cba65a77SJagan Teki return 0; 111cba65a77SJagan Teki } 112cba65a77SJagan Teki #endif 113cba65a77SJagan Teki 114cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 115cba65a77SJagan Teki static int spi_flash_write_bar(struct spi_flash *flash, u32 offset) 116cba65a77SJagan Teki { 117cba65a77SJagan Teki u8 cmd, bank_sel; 118cba65a77SJagan Teki int ret; 119cba65a77SJagan Teki 120cba65a77SJagan Teki bank_sel = offset / (SPI_FLASH_16MB_BOUN << flash->shift); 121cba65a77SJagan Teki if (bank_sel == flash->bank_curr) 122cba65a77SJagan Teki goto bar_end; 123cba65a77SJagan Teki 124cba65a77SJagan Teki cmd = flash->bank_write_cmd; 125cba65a77SJagan Teki ret = spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); 126cba65a77SJagan Teki if (ret < 0) { 127cba65a77SJagan Teki debug("SF: fail to write bank register\n"); 128cba65a77SJagan Teki return ret; 129cba65a77SJagan Teki } 130cba65a77SJagan Teki 131cba65a77SJagan Teki bar_end: 132cba65a77SJagan Teki flash->bank_curr = bank_sel; 133cba65a77SJagan Teki return flash->bank_curr; 134cba65a77SJagan Teki } 135cba65a77SJagan Teki 136cba65a77SJagan Teki static int spi_flash_read_bar(struct spi_flash *flash, u8 idcode0) 137cba65a77SJagan Teki { 138cba65a77SJagan Teki u8 curr_bank = 0; 139cba65a77SJagan Teki int ret; 140cba65a77SJagan Teki 141cba65a77SJagan Teki if (flash->size <= SPI_FLASH_16MB_BOUN) 142cba65a77SJagan Teki goto bank_end; 143cba65a77SJagan Teki 144cba65a77SJagan Teki switch (idcode0) { 145cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_SPANSION: 146cba65a77SJagan Teki flash->bank_read_cmd = CMD_BANKADDR_BRRD; 147cba65a77SJagan Teki flash->bank_write_cmd = CMD_BANKADDR_BRWR; 148cba65a77SJagan Teki break; 149cba65a77SJagan Teki default: 150cba65a77SJagan Teki flash->bank_read_cmd = CMD_EXTNADDR_RDEAR; 151cba65a77SJagan Teki flash->bank_write_cmd = CMD_EXTNADDR_WREAR; 152cba65a77SJagan Teki } 153cba65a77SJagan Teki 154cba65a77SJagan Teki ret = spi_flash_read_common(flash, &flash->bank_read_cmd, 1, 155cba65a77SJagan Teki &curr_bank, 1); 156cba65a77SJagan Teki if (ret) { 157cba65a77SJagan Teki debug("SF: fail to read bank addr register\n"); 158cba65a77SJagan Teki return ret; 159cba65a77SJagan Teki } 160cba65a77SJagan Teki 161cba65a77SJagan Teki bank_end: 162cba65a77SJagan Teki flash->bank_curr = curr_bank; 163cba65a77SJagan Teki return 0; 164cba65a77SJagan Teki } 165cba65a77SJagan Teki #endif 166cba65a77SJagan Teki 167cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 168cba65a77SJagan Teki static void spi_flash_dual(struct spi_flash *flash, u32 *addr) 169cba65a77SJagan Teki { 170e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 171e228d6deSJagan Teki 172cba65a77SJagan Teki switch (flash->dual_flash) { 173cba65a77SJagan Teki case SF_DUAL_STACKED_FLASH: 174cba65a77SJagan Teki if (*addr >= (flash->size >> 1)) { 175cba65a77SJagan Teki *addr -= flash->size >> 1; 176e228d6deSJagan Teki spi->flags |= SPI_XFER_U_PAGE; 177cba65a77SJagan Teki } else { 178e228d6deSJagan Teki spi->flags &= ~SPI_XFER_U_PAGE; 179cba65a77SJagan Teki } 180cba65a77SJagan Teki break; 181cba65a77SJagan Teki case SF_DUAL_PARALLEL_FLASH: 182cba65a77SJagan Teki *addr >>= flash->shift; 183cba65a77SJagan Teki break; 184cba65a77SJagan Teki default: 185cba65a77SJagan Teki debug("SF: Unsupported dual_flash=%d\n", flash->dual_flash); 186cba65a77SJagan Teki break; 187cba65a77SJagan Teki } 188cba65a77SJagan Teki } 189cba65a77SJagan Teki #endif 190cba65a77SJagan Teki 191cba65a77SJagan Teki static int spi_flash_sr_ready(struct spi_flash *flash) 192cba65a77SJagan Teki { 193cba65a77SJagan Teki u8 sr; 194cba65a77SJagan Teki int ret; 195cba65a77SJagan Teki 196cba65a77SJagan Teki ret = read_sr(flash, &sr); 197cba65a77SJagan Teki if (ret < 0) 198cba65a77SJagan Teki return ret; 199cba65a77SJagan Teki 200cba65a77SJagan Teki return !(sr & STATUS_WIP); 201cba65a77SJagan Teki } 202cba65a77SJagan Teki 203cba65a77SJagan Teki static int spi_flash_fsr_ready(struct spi_flash *flash) 204cba65a77SJagan Teki { 205cba65a77SJagan Teki u8 fsr; 206cba65a77SJagan Teki int ret; 207cba65a77SJagan Teki 208cba65a77SJagan Teki ret = read_fsr(flash, &fsr); 209cba65a77SJagan Teki if (ret < 0) 210cba65a77SJagan Teki return ret; 211cba65a77SJagan Teki 212cba65a77SJagan Teki return fsr & STATUS_PEC; 213cba65a77SJagan Teki } 214cba65a77SJagan Teki 215cba65a77SJagan Teki static int spi_flash_ready(struct spi_flash *flash) 216cba65a77SJagan Teki { 217cba65a77SJagan Teki int sr, fsr; 218cba65a77SJagan Teki 219cba65a77SJagan Teki sr = spi_flash_sr_ready(flash); 220cba65a77SJagan Teki if (sr < 0) 221cba65a77SJagan Teki return sr; 222cba65a77SJagan Teki 223cba65a77SJagan Teki fsr = 1; 224cba65a77SJagan Teki if (flash->flags & SNOR_F_USE_FSR) { 225cba65a77SJagan Teki fsr = spi_flash_fsr_ready(flash); 226cba65a77SJagan Teki if (fsr < 0) 227cba65a77SJagan Teki return fsr; 228cba65a77SJagan Teki } 229cba65a77SJagan Teki 230cba65a77SJagan Teki return sr && fsr; 231cba65a77SJagan Teki } 232cba65a77SJagan Teki 233cba65a77SJagan Teki static int spi_flash_cmd_wait_ready(struct spi_flash *flash, 234cba65a77SJagan Teki unsigned long timeout) 235cba65a77SJagan Teki { 236cba65a77SJagan Teki int timebase, ret; 237cba65a77SJagan Teki 238cba65a77SJagan Teki timebase = get_timer(0); 239cba65a77SJagan Teki 240cba65a77SJagan Teki while (get_timer(timebase) < timeout) { 241cba65a77SJagan Teki ret = spi_flash_ready(flash); 242cba65a77SJagan Teki if (ret < 0) 243cba65a77SJagan Teki return ret; 244cba65a77SJagan Teki if (ret) 245cba65a77SJagan Teki return 0; 246cba65a77SJagan Teki } 247cba65a77SJagan Teki 248cba65a77SJagan Teki printf("SF: Timeout!\n"); 249cba65a77SJagan Teki 250cba65a77SJagan Teki return -ETIMEDOUT; 251cba65a77SJagan Teki } 252cba65a77SJagan Teki 253cba65a77SJagan Teki int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, 254cba65a77SJagan Teki size_t cmd_len, const void *buf, size_t buf_len) 255cba65a77SJagan Teki { 256cba65a77SJagan Teki struct spi_slave *spi = flash->spi; 257cba65a77SJagan Teki unsigned long timeout = SPI_FLASH_PROG_TIMEOUT; 258cba65a77SJagan Teki int ret; 259cba65a77SJagan Teki 260cba65a77SJagan Teki if (buf == NULL) 261cba65a77SJagan Teki timeout = SPI_FLASH_PAGE_ERASE_TIMEOUT; 262cba65a77SJagan Teki 263e228d6deSJagan Teki ret = spi_claim_bus(spi); 264cba65a77SJagan Teki if (ret) { 265cba65a77SJagan Teki debug("SF: unable to claim SPI bus\n"); 266cba65a77SJagan Teki return ret; 267cba65a77SJagan Teki } 268cba65a77SJagan Teki 269cba65a77SJagan Teki ret = spi_flash_cmd_write_enable(flash); 270cba65a77SJagan Teki if (ret < 0) { 271cba65a77SJagan Teki debug("SF: enabling write failed\n"); 272cba65a77SJagan Teki return ret; 273cba65a77SJagan Teki } 274cba65a77SJagan Teki 275cba65a77SJagan Teki ret = spi_flash_cmd_write(spi, cmd, cmd_len, buf, buf_len); 276cba65a77SJagan Teki if (ret < 0) { 277cba65a77SJagan Teki debug("SF: write cmd failed\n"); 278cba65a77SJagan Teki return ret; 279cba65a77SJagan Teki } 280cba65a77SJagan Teki 281cba65a77SJagan Teki ret = spi_flash_cmd_wait_ready(flash, timeout); 282cba65a77SJagan Teki if (ret < 0) { 283cba65a77SJagan Teki debug("SF: write %s timed out\n", 284cba65a77SJagan Teki timeout == SPI_FLASH_PROG_TIMEOUT ? 285cba65a77SJagan Teki "program" : "page erase"); 286cba65a77SJagan Teki return ret; 287cba65a77SJagan Teki } 288cba65a77SJagan Teki 289cba65a77SJagan Teki spi_release_bus(spi); 290cba65a77SJagan Teki 291cba65a77SJagan Teki return ret; 292cba65a77SJagan Teki } 293cba65a77SJagan Teki 294cba65a77SJagan Teki int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) 295cba65a77SJagan Teki { 296cba65a77SJagan Teki u32 erase_size, erase_addr; 297cba65a77SJagan Teki u8 cmd[SPI_FLASH_CMD_LEN]; 298cba65a77SJagan Teki int ret = -1; 299cba65a77SJagan Teki 300cba65a77SJagan Teki erase_size = flash->erase_size; 301cba65a77SJagan Teki if (offset % erase_size || len % erase_size) { 302cba65a77SJagan Teki debug("SF: Erase offset/length not multiple of erase size\n"); 303cba65a77SJagan Teki return -1; 304cba65a77SJagan Teki } 305cba65a77SJagan Teki 306cba65a77SJagan Teki if (flash->flash_is_locked) { 307cba65a77SJagan Teki if (flash->flash_is_locked(flash, offset, len) > 0) { 308cba65a77SJagan Teki printf("offset 0x%x is protected and cannot be erased\n", 309cba65a77SJagan Teki offset); 310cba65a77SJagan Teki return -EINVAL; 311cba65a77SJagan Teki } 312cba65a77SJagan Teki } 313cba65a77SJagan Teki 314cba65a77SJagan Teki cmd[0] = flash->erase_cmd; 315cba65a77SJagan Teki while (len) { 316cba65a77SJagan Teki erase_addr = offset; 317cba65a77SJagan Teki 318cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 319cba65a77SJagan Teki if (flash->dual_flash > SF_SINGLE_FLASH) 320cba65a77SJagan Teki spi_flash_dual(flash, &erase_addr); 321cba65a77SJagan Teki #endif 322cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 323cba65a77SJagan Teki ret = spi_flash_write_bar(flash, erase_addr); 324cba65a77SJagan Teki if (ret < 0) 325cba65a77SJagan Teki return ret; 326cba65a77SJagan Teki #endif 327cba65a77SJagan Teki spi_flash_addr(erase_addr, cmd); 328cba65a77SJagan Teki 329cba65a77SJagan Teki debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1], 330cba65a77SJagan Teki cmd[2], cmd[3], erase_addr); 331cba65a77SJagan Teki 332cba65a77SJagan Teki ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0); 333cba65a77SJagan Teki if (ret < 0) { 334cba65a77SJagan Teki debug("SF: erase failed\n"); 335cba65a77SJagan Teki break; 336cba65a77SJagan Teki } 337cba65a77SJagan Teki 338cba65a77SJagan Teki offset += erase_size; 339cba65a77SJagan Teki len -= erase_size; 340cba65a77SJagan Teki } 341cba65a77SJagan Teki 342cba65a77SJagan Teki return ret; 343cba65a77SJagan Teki } 344cba65a77SJagan Teki 345cba65a77SJagan Teki int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, 346cba65a77SJagan Teki size_t len, const void *buf) 347cba65a77SJagan Teki { 348e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 349cba65a77SJagan Teki unsigned long byte_addr, page_size; 350cba65a77SJagan Teki u32 write_addr; 351cba65a77SJagan Teki size_t chunk_len, actual; 352cba65a77SJagan Teki u8 cmd[SPI_FLASH_CMD_LEN]; 353cba65a77SJagan Teki int ret = -1; 354cba65a77SJagan Teki 355cba65a77SJagan Teki page_size = flash->page_size; 356cba65a77SJagan Teki 357cba65a77SJagan Teki if (flash->flash_is_locked) { 358cba65a77SJagan Teki if (flash->flash_is_locked(flash, offset, len) > 0) { 359cba65a77SJagan Teki printf("offset 0x%x is protected and cannot be written\n", 360cba65a77SJagan Teki offset); 361cba65a77SJagan Teki return -EINVAL; 362cba65a77SJagan Teki } 363cba65a77SJagan Teki } 364cba65a77SJagan Teki 365cba65a77SJagan Teki cmd[0] = flash->write_cmd; 366cba65a77SJagan Teki for (actual = 0; actual < len; actual += chunk_len) { 367cba65a77SJagan Teki write_addr = offset; 368cba65a77SJagan Teki 369cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 370cba65a77SJagan Teki if (flash->dual_flash > SF_SINGLE_FLASH) 371cba65a77SJagan Teki spi_flash_dual(flash, &write_addr); 372cba65a77SJagan Teki #endif 373cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 374cba65a77SJagan Teki ret = spi_flash_write_bar(flash, write_addr); 375cba65a77SJagan Teki if (ret < 0) 376cba65a77SJagan Teki return ret; 377cba65a77SJagan Teki #endif 378cba65a77SJagan Teki byte_addr = offset % page_size; 379cba65a77SJagan Teki chunk_len = min(len - actual, (size_t)(page_size - byte_addr)); 380cba65a77SJagan Teki 381e228d6deSJagan Teki if (spi->max_write_size) 382cba65a77SJagan Teki chunk_len = min(chunk_len, 383e228d6deSJagan Teki (size_t)spi->max_write_size); 384cba65a77SJagan Teki 385cba65a77SJagan Teki spi_flash_addr(write_addr, cmd); 386cba65a77SJagan Teki 387cba65a77SJagan Teki debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", 388cba65a77SJagan Teki buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); 389cba65a77SJagan Teki 390cba65a77SJagan Teki ret = spi_flash_write_common(flash, cmd, sizeof(cmd), 391cba65a77SJagan Teki buf + actual, chunk_len); 392cba65a77SJagan Teki if (ret < 0) { 393cba65a77SJagan Teki debug("SF: write failed\n"); 394cba65a77SJagan Teki break; 395cba65a77SJagan Teki } 396cba65a77SJagan Teki 397cba65a77SJagan Teki offset += chunk_len; 398cba65a77SJagan Teki } 399cba65a77SJagan Teki 400cba65a77SJagan Teki return ret; 401cba65a77SJagan Teki } 402cba65a77SJagan Teki 403cba65a77SJagan Teki int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, 404cba65a77SJagan Teki size_t cmd_len, void *data, size_t data_len) 405cba65a77SJagan Teki { 406cba65a77SJagan Teki struct spi_slave *spi = flash->spi; 407cba65a77SJagan Teki int ret; 408cba65a77SJagan Teki 409e228d6deSJagan Teki ret = spi_claim_bus(spi); 410cba65a77SJagan Teki if (ret) { 411cba65a77SJagan Teki debug("SF: unable to claim SPI bus\n"); 412cba65a77SJagan Teki return ret; 413cba65a77SJagan Teki } 414cba65a77SJagan Teki 415cba65a77SJagan Teki ret = spi_flash_cmd_read(spi, cmd, cmd_len, data, data_len); 416cba65a77SJagan Teki if (ret < 0) { 417cba65a77SJagan Teki debug("SF: read cmd failed\n"); 418cba65a77SJagan Teki return ret; 419cba65a77SJagan Teki } 420cba65a77SJagan Teki 421cba65a77SJagan Teki spi_release_bus(spi); 422cba65a77SJagan Teki 423cba65a77SJagan Teki return ret; 424cba65a77SJagan Teki } 425cba65a77SJagan Teki 426cba65a77SJagan Teki void __weak spi_flash_copy_mmap(void *data, void *offset, size_t len) 427cba65a77SJagan Teki { 428cba65a77SJagan Teki memcpy(data, offset, len); 429cba65a77SJagan Teki } 430cba65a77SJagan Teki 431cba65a77SJagan Teki int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, 432cba65a77SJagan Teki size_t len, void *data) 433cba65a77SJagan Teki { 434e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 435cba65a77SJagan Teki u8 *cmd, cmdsz; 436cba65a77SJagan Teki u32 remain_len, read_len, read_addr; 437cba65a77SJagan Teki int bank_sel = 0; 438cba65a77SJagan Teki int ret = -1; 439cba65a77SJagan Teki 440cba65a77SJagan Teki /* Handle memory-mapped SPI */ 441cba65a77SJagan Teki if (flash->memory_map) { 442e228d6deSJagan Teki ret = spi_claim_bus(spi); 443cba65a77SJagan Teki if (ret) { 444cba65a77SJagan Teki debug("SF: unable to claim SPI bus\n"); 445cba65a77SJagan Teki return ret; 446cba65a77SJagan Teki } 447e228d6deSJagan Teki spi_xfer(spi, 0, NULL, NULL, SPI_XFER_MMAP); 448cba65a77SJagan Teki spi_flash_copy_mmap(data, flash->memory_map + offset, len); 449e228d6deSJagan Teki spi_xfer(spi, 0, NULL, NULL, SPI_XFER_MMAP_END); 450e228d6deSJagan Teki spi_release_bus(spi); 451cba65a77SJagan Teki return 0; 452cba65a77SJagan Teki } 453cba65a77SJagan Teki 454cba65a77SJagan Teki cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; 455cba65a77SJagan Teki cmd = calloc(1, cmdsz); 456cba65a77SJagan Teki if (!cmd) { 457cba65a77SJagan Teki debug("SF: Failed to allocate cmd\n"); 458cba65a77SJagan Teki return -ENOMEM; 459cba65a77SJagan Teki } 460cba65a77SJagan Teki 461cba65a77SJagan Teki cmd[0] = flash->read_cmd; 462cba65a77SJagan Teki while (len) { 463cba65a77SJagan Teki read_addr = offset; 464cba65a77SJagan Teki 465cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 466cba65a77SJagan Teki if (flash->dual_flash > SF_SINGLE_FLASH) 467cba65a77SJagan Teki spi_flash_dual(flash, &read_addr); 468cba65a77SJagan Teki #endif 469cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 470cba65a77SJagan Teki ret = spi_flash_write_bar(flash, read_addr); 471cba65a77SJagan Teki if (ret < 0) 472cba65a77SJagan Teki return ret; 473cba65a77SJagan Teki bank_sel = flash->bank_curr; 474cba65a77SJagan Teki #endif 475cba65a77SJagan Teki remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) * 476cba65a77SJagan Teki (bank_sel + 1)) - offset; 477cba65a77SJagan Teki if (len < remain_len) 478cba65a77SJagan Teki read_len = len; 479cba65a77SJagan Teki else 480cba65a77SJagan Teki read_len = remain_len; 481cba65a77SJagan Teki 482cba65a77SJagan Teki spi_flash_addr(read_addr, cmd); 483cba65a77SJagan Teki 484cba65a77SJagan Teki ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len); 485cba65a77SJagan Teki if (ret < 0) { 486cba65a77SJagan Teki debug("SF: read failed\n"); 487cba65a77SJagan Teki break; 488cba65a77SJagan Teki } 489cba65a77SJagan Teki 490cba65a77SJagan Teki offset += read_len; 491cba65a77SJagan Teki len -= read_len; 492cba65a77SJagan Teki data += read_len; 493cba65a77SJagan Teki } 494cba65a77SJagan Teki 495cba65a77SJagan Teki free(cmd); 496cba65a77SJagan Teki return ret; 497cba65a77SJagan Teki } 498cba65a77SJagan Teki 499cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_SST 500cba65a77SJagan Teki static int sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf) 501cba65a77SJagan Teki { 502e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 503cba65a77SJagan Teki int ret; 504cba65a77SJagan Teki u8 cmd[4] = { 505cba65a77SJagan Teki CMD_SST_BP, 506cba65a77SJagan Teki offset >> 16, 507cba65a77SJagan Teki offset >> 8, 508cba65a77SJagan Teki offset, 509cba65a77SJagan Teki }; 510cba65a77SJagan Teki 511cba65a77SJagan Teki debug("BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", 512e228d6deSJagan Teki spi_w8r8(spi, CMD_READ_STATUS), buf, cmd[0], offset); 513cba65a77SJagan Teki 514cba65a77SJagan Teki ret = spi_flash_cmd_write_enable(flash); 515cba65a77SJagan Teki if (ret) 516cba65a77SJagan Teki return ret; 517cba65a77SJagan Teki 518e228d6deSJagan Teki ret = spi_flash_cmd_write(spi, cmd, sizeof(cmd), buf, 1); 519cba65a77SJagan Teki if (ret) 520cba65a77SJagan Teki return ret; 521cba65a77SJagan Teki 522cba65a77SJagan Teki return spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); 523cba65a77SJagan Teki } 524cba65a77SJagan Teki 525cba65a77SJagan Teki int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, 526cba65a77SJagan Teki const void *buf) 527cba65a77SJagan Teki { 528e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 529cba65a77SJagan Teki size_t actual, cmd_len; 530cba65a77SJagan Teki int ret; 531cba65a77SJagan Teki u8 cmd[4]; 532cba65a77SJagan Teki 533e228d6deSJagan Teki ret = spi_claim_bus(spi); 534cba65a77SJagan Teki if (ret) { 535cba65a77SJagan Teki debug("SF: Unable to claim SPI bus\n"); 536cba65a77SJagan Teki return ret; 537cba65a77SJagan Teki } 538cba65a77SJagan Teki 539cba65a77SJagan Teki /* If the data is not word aligned, write out leading single byte */ 540cba65a77SJagan Teki actual = offset % 2; 541cba65a77SJagan Teki if (actual) { 542cba65a77SJagan Teki ret = sst_byte_write(flash, offset, buf); 543cba65a77SJagan Teki if (ret) 544cba65a77SJagan Teki goto done; 545cba65a77SJagan Teki } 546cba65a77SJagan Teki offset += actual; 547cba65a77SJagan Teki 548cba65a77SJagan Teki ret = spi_flash_cmd_write_enable(flash); 549cba65a77SJagan Teki if (ret) 550cba65a77SJagan Teki goto done; 551cba65a77SJagan Teki 552cba65a77SJagan Teki cmd_len = 4; 553cba65a77SJagan Teki cmd[0] = CMD_SST_AAI_WP; 554cba65a77SJagan Teki cmd[1] = offset >> 16; 555cba65a77SJagan Teki cmd[2] = offset >> 8; 556cba65a77SJagan Teki cmd[3] = offset; 557cba65a77SJagan Teki 558cba65a77SJagan Teki for (; actual < len - 1; actual += 2) { 559cba65a77SJagan Teki debug("WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n", 560e228d6deSJagan Teki spi_w8r8(spi, CMD_READ_STATUS), buf + actual, 561cba65a77SJagan Teki cmd[0], offset); 562cba65a77SJagan Teki 563e228d6deSJagan Teki ret = spi_flash_cmd_write(spi, cmd, cmd_len, 564cba65a77SJagan Teki buf + actual, 2); 565cba65a77SJagan Teki if (ret) { 566cba65a77SJagan Teki debug("SF: sst word program failed\n"); 567cba65a77SJagan Teki break; 568cba65a77SJagan Teki } 569cba65a77SJagan Teki 570cba65a77SJagan Teki ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); 571cba65a77SJagan Teki if (ret) 572cba65a77SJagan Teki break; 573cba65a77SJagan Teki 574cba65a77SJagan Teki cmd_len = 1; 575cba65a77SJagan Teki offset += 2; 576cba65a77SJagan Teki } 577cba65a77SJagan Teki 578cba65a77SJagan Teki if (!ret) 579cba65a77SJagan Teki ret = spi_flash_cmd_write_disable(flash); 580cba65a77SJagan Teki 581cba65a77SJagan Teki /* If there is a single trailing byte, write it out */ 582cba65a77SJagan Teki if (!ret && actual != len) 583cba65a77SJagan Teki ret = sst_byte_write(flash, offset, buf + actual); 584cba65a77SJagan Teki 585cba65a77SJagan Teki done: 586cba65a77SJagan Teki debug("SF: sst: program %s %zu bytes @ 0x%zx\n", 587cba65a77SJagan Teki ret ? "failure" : "success", len, offset - actual); 588cba65a77SJagan Teki 589e228d6deSJagan Teki spi_release_bus(spi); 590cba65a77SJagan Teki return ret; 591cba65a77SJagan Teki } 592cba65a77SJagan Teki 593cba65a77SJagan Teki int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, 594cba65a77SJagan Teki const void *buf) 595cba65a77SJagan Teki { 596e228d6deSJagan Teki struct spi_slave *spi = flash->spi; 597cba65a77SJagan Teki size_t actual; 598cba65a77SJagan Teki int ret; 599cba65a77SJagan Teki 600e228d6deSJagan Teki ret = spi_claim_bus(spi); 601cba65a77SJagan Teki if (ret) { 602cba65a77SJagan Teki debug("SF: Unable to claim SPI bus\n"); 603cba65a77SJagan Teki return ret; 604cba65a77SJagan Teki } 605cba65a77SJagan Teki 606cba65a77SJagan Teki for (actual = 0; actual < len; actual++) { 607cba65a77SJagan Teki ret = sst_byte_write(flash, offset, buf + actual); 608cba65a77SJagan Teki if (ret) { 609cba65a77SJagan Teki debug("SF: sst byte program failed\n"); 610cba65a77SJagan Teki break; 611cba65a77SJagan Teki } 612cba65a77SJagan Teki offset++; 613cba65a77SJagan Teki } 614cba65a77SJagan Teki 615cba65a77SJagan Teki if (!ret) 616cba65a77SJagan Teki ret = spi_flash_cmd_write_disable(flash); 617cba65a77SJagan Teki 618cba65a77SJagan Teki debug("SF: sst: program %s %zu bytes @ 0x%zx\n", 619cba65a77SJagan Teki ret ? "failure" : "success", len, offset - actual); 620cba65a77SJagan Teki 621e228d6deSJagan Teki spi_release_bus(spi); 622cba65a77SJagan Teki return ret; 623cba65a77SJagan Teki } 624cba65a77SJagan Teki #endif 625cba65a77SJagan Teki 626cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) 627cba65a77SJagan Teki static void stm_get_locked_range(struct spi_flash *flash, u8 sr, loff_t *ofs, 628cba65a77SJagan Teki u32 *len) 629cba65a77SJagan Teki { 630cba65a77SJagan Teki u8 mask = SR_BP2 | SR_BP1 | SR_BP0; 631cba65a77SJagan Teki int shift = ffs(mask) - 1; 632cba65a77SJagan Teki int pow; 633cba65a77SJagan Teki 634cba65a77SJagan Teki if (!(sr & mask)) { 635cba65a77SJagan Teki /* No protection */ 636cba65a77SJagan Teki *ofs = 0; 637cba65a77SJagan Teki *len = 0; 638cba65a77SJagan Teki } else { 639cba65a77SJagan Teki pow = ((sr & mask) ^ mask) >> shift; 640cba65a77SJagan Teki *len = flash->size >> pow; 641cba65a77SJagan Teki *ofs = flash->size - *len; 642cba65a77SJagan Teki } 643cba65a77SJagan Teki } 644cba65a77SJagan Teki 645cba65a77SJagan Teki /* 646cba65a77SJagan Teki * Return 1 if the entire region is locked, 0 otherwise 647cba65a77SJagan Teki */ 648cba65a77SJagan Teki static int stm_is_locked_sr(struct spi_flash *flash, u32 ofs, u32 len, 649cba65a77SJagan Teki u8 sr) 650cba65a77SJagan Teki { 651cba65a77SJagan Teki loff_t lock_offs; 652cba65a77SJagan Teki u32 lock_len; 653cba65a77SJagan Teki 654cba65a77SJagan Teki stm_get_locked_range(flash, sr, &lock_offs, &lock_len); 655cba65a77SJagan Teki 656cba65a77SJagan Teki return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs); 657cba65a77SJagan Teki } 658cba65a77SJagan Teki 659cba65a77SJagan Teki /* 660cba65a77SJagan Teki * Check if a region of the flash is (completely) locked. See stm_lock() for 661cba65a77SJagan Teki * more info. 662cba65a77SJagan Teki * 663cba65a77SJagan Teki * Returns 1 if entire region is locked, 0 if any portion is unlocked, and 664cba65a77SJagan Teki * negative on errors. 665cba65a77SJagan Teki */ 666cba65a77SJagan Teki int stm_is_locked(struct spi_flash *flash, u32 ofs, size_t len) 667cba65a77SJagan Teki { 668cba65a77SJagan Teki int status; 669cba65a77SJagan Teki u8 sr; 670cba65a77SJagan Teki 671cba65a77SJagan Teki status = read_sr(flash, &sr); 672cba65a77SJagan Teki if (status < 0) 673cba65a77SJagan Teki return status; 674cba65a77SJagan Teki 675cba65a77SJagan Teki return stm_is_locked_sr(flash, ofs, len, sr); 676cba65a77SJagan Teki } 677cba65a77SJagan Teki 678cba65a77SJagan Teki /* 679cba65a77SJagan Teki * Lock a region of the flash. Compatible with ST Micro and similar flash. 680cba65a77SJagan Teki * Supports only the block protection bits BP{0,1,2} in the status register 681cba65a77SJagan Teki * (SR). Does not support these features found in newer SR bitfields: 682cba65a77SJagan Teki * - TB: top/bottom protect - only handle TB=0 (top protect) 683cba65a77SJagan Teki * - SEC: sector/block protect - only handle SEC=0 (block protect) 684cba65a77SJagan Teki * - CMP: complement protect - only support CMP=0 (range is not complemented) 685cba65a77SJagan Teki * 686cba65a77SJagan Teki * Sample table portion for 8MB flash (Winbond w25q64fw): 687cba65a77SJagan Teki * 688cba65a77SJagan Teki * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion 689cba65a77SJagan Teki * -------------------------------------------------------------------------- 690cba65a77SJagan Teki * X | X | 0 | 0 | 0 | NONE | NONE 691cba65a77SJagan Teki * 0 | 0 | 0 | 0 | 1 | 128 KB | Upper 1/64 692cba65a77SJagan Teki * 0 | 0 | 0 | 1 | 0 | 256 KB | Upper 1/32 693cba65a77SJagan Teki * 0 | 0 | 0 | 1 | 1 | 512 KB | Upper 1/16 694cba65a77SJagan Teki * 0 | 0 | 1 | 0 | 0 | 1 MB | Upper 1/8 695cba65a77SJagan Teki * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 696cba65a77SJagan Teki * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 697cba65a77SJagan Teki * X | X | 1 | 1 | 1 | 8 MB | ALL 698cba65a77SJagan Teki * 699cba65a77SJagan Teki * Returns negative on errors, 0 on success. 700cba65a77SJagan Teki */ 701cba65a77SJagan Teki int stm_lock(struct spi_flash *flash, u32 ofs, size_t len) 702cba65a77SJagan Teki { 703cba65a77SJagan Teki u8 status_old, status_new; 704cba65a77SJagan Teki u8 mask = SR_BP2 | SR_BP1 | SR_BP0; 705cba65a77SJagan Teki u8 shift = ffs(mask) - 1, pow, val; 706cba65a77SJagan Teki int ret; 707cba65a77SJagan Teki 708cba65a77SJagan Teki ret = read_sr(flash, &status_old); 709cba65a77SJagan Teki if (ret < 0) 710cba65a77SJagan Teki return ret; 711cba65a77SJagan Teki 712cba65a77SJagan Teki /* SPI NOR always locks to the end */ 713cba65a77SJagan Teki if (ofs + len != flash->size) { 714cba65a77SJagan Teki /* Does combined region extend to end? */ 715cba65a77SJagan Teki if (!stm_is_locked_sr(flash, ofs + len, flash->size - ofs - len, 716cba65a77SJagan Teki status_old)) 717cba65a77SJagan Teki return -EINVAL; 718cba65a77SJagan Teki len = flash->size - ofs; 719cba65a77SJagan Teki } 720cba65a77SJagan Teki 721cba65a77SJagan Teki /* 722cba65a77SJagan Teki * Need smallest pow such that: 723cba65a77SJagan Teki * 724cba65a77SJagan Teki * 1 / (2^pow) <= (len / size) 725cba65a77SJagan Teki * 726cba65a77SJagan Teki * so (assuming power-of-2 size) we do: 727cba65a77SJagan Teki * 728cba65a77SJagan Teki * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len)) 729cba65a77SJagan Teki */ 730cba65a77SJagan Teki pow = ilog2(flash->size) - ilog2(len); 731cba65a77SJagan Teki val = mask - (pow << shift); 732cba65a77SJagan Teki if (val & ~mask) 733cba65a77SJagan Teki return -EINVAL; 734cba65a77SJagan Teki 735cba65a77SJagan Teki /* Don't "lock" with no region! */ 736cba65a77SJagan Teki if (!(val & mask)) 737cba65a77SJagan Teki return -EINVAL; 738cba65a77SJagan Teki 739cba65a77SJagan Teki status_new = (status_old & ~mask) | val; 740cba65a77SJagan Teki 741cba65a77SJagan Teki /* Only modify protection if it will not unlock other areas */ 742cba65a77SJagan Teki if ((status_new & mask) <= (status_old & mask)) 743cba65a77SJagan Teki return -EINVAL; 744cba65a77SJagan Teki 745cba65a77SJagan Teki write_sr(flash, status_new); 746cba65a77SJagan Teki 747cba65a77SJagan Teki return 0; 748cba65a77SJagan Teki } 749cba65a77SJagan Teki 750cba65a77SJagan Teki /* 751cba65a77SJagan Teki * Unlock a region of the flash. See stm_lock() for more info 752cba65a77SJagan Teki * 753cba65a77SJagan Teki * Returns negative on errors, 0 on success. 754cba65a77SJagan Teki */ 755cba65a77SJagan Teki int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len) 756cba65a77SJagan Teki { 757cba65a77SJagan Teki uint8_t status_old, status_new; 758cba65a77SJagan Teki u8 mask = SR_BP2 | SR_BP1 | SR_BP0; 759cba65a77SJagan Teki u8 shift = ffs(mask) - 1, pow, val; 760cba65a77SJagan Teki int ret; 761cba65a77SJagan Teki 762cba65a77SJagan Teki ret = read_sr(flash, &status_old); 763cba65a77SJagan Teki if (ret < 0) 764cba65a77SJagan Teki return ret; 765cba65a77SJagan Teki 766cba65a77SJagan Teki /* Cannot unlock; would unlock larger region than requested */ 76750921583SFabio Estevam if (stm_is_locked_sr(flash, ofs - flash->erase_size, flash->erase_size, 76850921583SFabio Estevam status_old)) 769cba65a77SJagan Teki return -EINVAL; 770cba65a77SJagan Teki /* 771cba65a77SJagan Teki * Need largest pow such that: 772cba65a77SJagan Teki * 773cba65a77SJagan Teki * 1 / (2^pow) >= (len / size) 774cba65a77SJagan Teki * 775cba65a77SJagan Teki * so (assuming power-of-2 size) we do: 776cba65a77SJagan Teki * 777cba65a77SJagan Teki * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len)) 778cba65a77SJagan Teki */ 779cba65a77SJagan Teki pow = ilog2(flash->size) - order_base_2(flash->size - (ofs + len)); 780cba65a77SJagan Teki if (ofs + len == flash->size) { 781cba65a77SJagan Teki val = 0; /* fully unlocked */ 782cba65a77SJagan Teki } else { 783cba65a77SJagan Teki val = mask - (pow << shift); 784cba65a77SJagan Teki /* Some power-of-two sizes are not supported */ 785cba65a77SJagan Teki if (val & ~mask) 786cba65a77SJagan Teki return -EINVAL; 787cba65a77SJagan Teki } 788cba65a77SJagan Teki 789cba65a77SJagan Teki status_new = (status_old & ~mask) | val; 790cba65a77SJagan Teki 791cba65a77SJagan Teki /* Only modify protection if it will not lock other areas */ 792cba65a77SJagan Teki if ((status_new & mask) >= (status_old & mask)) 793cba65a77SJagan Teki return -EINVAL; 794cba65a77SJagan Teki 795cba65a77SJagan Teki write_sr(flash, status_new); 796cba65a77SJagan Teki 797cba65a77SJagan Teki return 0; 798cba65a77SJagan Teki } 799cba65a77SJagan Teki #endif 800cba65a77SJagan Teki 801cba65a77SJagan Teki 802cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_MACRONIX 803cba65a77SJagan Teki static int spi_flash_set_qeb_mxic(struct spi_flash *flash) 804cba65a77SJagan Teki { 805cba65a77SJagan Teki u8 qeb_status; 806cba65a77SJagan Teki int ret; 807cba65a77SJagan Teki 808cba65a77SJagan Teki ret = read_sr(flash, &qeb_status); 809cba65a77SJagan Teki if (ret < 0) 810cba65a77SJagan Teki return ret; 811cba65a77SJagan Teki 812cba65a77SJagan Teki if (qeb_status & STATUS_QEB_MXIC) { 813cba65a77SJagan Teki debug("SF: mxic: QEB is already set\n"); 814cba65a77SJagan Teki } else { 815cba65a77SJagan Teki ret = write_sr(flash, STATUS_QEB_MXIC); 816cba65a77SJagan Teki if (ret < 0) 817cba65a77SJagan Teki return ret; 818cba65a77SJagan Teki } 819cba65a77SJagan Teki 820cba65a77SJagan Teki return ret; 821cba65a77SJagan Teki } 822cba65a77SJagan Teki #endif 823cba65a77SJagan Teki 824cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) 825cba65a77SJagan Teki static int spi_flash_set_qeb_winspan(struct spi_flash *flash) 826cba65a77SJagan Teki { 827cba65a77SJagan Teki u8 qeb_status; 828cba65a77SJagan Teki int ret; 829cba65a77SJagan Teki 830cba65a77SJagan Teki ret = read_cr(flash, &qeb_status); 831cba65a77SJagan Teki if (ret < 0) 832cba65a77SJagan Teki return ret; 833cba65a77SJagan Teki 834cba65a77SJagan Teki if (qeb_status & STATUS_QEB_WINSPAN) { 835cba65a77SJagan Teki debug("SF: winspan: QEB is already set\n"); 836cba65a77SJagan Teki } else { 837cba65a77SJagan Teki ret = write_cr(flash, STATUS_QEB_WINSPAN); 838cba65a77SJagan Teki if (ret < 0) 839cba65a77SJagan Teki return ret; 840cba65a77SJagan Teki } 841cba65a77SJagan Teki 842cba65a77SJagan Teki return ret; 843cba65a77SJagan Teki } 844cba65a77SJagan Teki #endif 845cba65a77SJagan Teki 846cba65a77SJagan Teki static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) 847cba65a77SJagan Teki { 848cba65a77SJagan Teki switch (idcode0) { 849cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_MACRONIX 850cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_MACRONIX: 851cba65a77SJagan Teki return spi_flash_set_qeb_mxic(flash); 852cba65a77SJagan Teki #endif 853cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) 854cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_SPANSION: 855cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_WINBOND: 856cba65a77SJagan Teki return spi_flash_set_qeb_winspan(flash); 857cba65a77SJagan Teki #endif 858cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_STMICRO 859cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_STMICRO: 860cba65a77SJagan Teki debug("SF: QEB is volatile for %02x flash\n", idcode0); 861cba65a77SJagan Teki return 0; 862cba65a77SJagan Teki #endif 863cba65a77SJagan Teki default: 864cba65a77SJagan Teki printf("SF: Need set QEB func for %02x flash\n", idcode0); 865cba65a77SJagan Teki return -1; 866cba65a77SJagan Teki } 867cba65a77SJagan Teki } 868cba65a77SJagan Teki 869cba65a77SJagan Teki #if CONFIG_IS_ENABLED(OF_CONTROL) 870cba65a77SJagan Teki int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) 871cba65a77SJagan Teki { 872cba65a77SJagan Teki fdt_addr_t addr; 873cba65a77SJagan Teki fdt_size_t size; 874cba65a77SJagan Teki int node; 875cba65a77SJagan Teki 876cba65a77SJagan Teki /* If there is no node, do nothing */ 877cba65a77SJagan Teki node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); 878cba65a77SJagan Teki if (node < 0) 879cba65a77SJagan Teki return 0; 880cba65a77SJagan Teki 881cba65a77SJagan Teki addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); 882cba65a77SJagan Teki if (addr == FDT_ADDR_T_NONE) { 883cba65a77SJagan Teki debug("%s: Cannot decode address\n", __func__); 884cba65a77SJagan Teki return 0; 885cba65a77SJagan Teki } 886cba65a77SJagan Teki 887cba65a77SJagan Teki if (flash->size != size) { 888cba65a77SJagan Teki debug("%s: Memory map must cover entire device\n", __func__); 889cba65a77SJagan Teki return -1; 890cba65a77SJagan Teki } 891cba65a77SJagan Teki flash->memory_map = map_sysmem(addr, size); 892cba65a77SJagan Teki 893cba65a77SJagan Teki return 0; 894cba65a77SJagan Teki } 895cba65a77SJagan Teki #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ 896cba65a77SJagan Teki 897cba65a77SJagan Teki int spi_flash_scan(struct spi_flash *flash) 898cba65a77SJagan Teki { 899cba65a77SJagan Teki struct spi_slave *spi = flash->spi; 900cba65a77SJagan Teki const struct spi_flash_params *params; 901cba65a77SJagan Teki u16 jedec, ext_jedec; 902*d25dd942SJagan Teki u8 cmd, idcode[5]; 903cba65a77SJagan Teki int ret; 904*d25dd942SJagan Teki static u8 spi_read_cmds_array[] = { 905*d25dd942SJagan Teki CMD_READ_ARRAY_SLOW, 906*d25dd942SJagan Teki CMD_READ_ARRAY_FAST, 907*d25dd942SJagan Teki CMD_READ_DUAL_OUTPUT_FAST, 908*d25dd942SJagan Teki CMD_READ_DUAL_IO_FAST, 909*d25dd942SJagan Teki CMD_READ_QUAD_OUTPUT_FAST, 910*d25dd942SJagan Teki CMD_READ_QUAD_IO_FAST }; 911cba65a77SJagan Teki 912cba65a77SJagan Teki /* Read the ID codes */ 913cba65a77SJagan Teki ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); 914cba65a77SJagan Teki if (ret) { 915cba65a77SJagan Teki printf("SF: Failed to get idcodes\n"); 916cba65a77SJagan Teki return -EINVAL; 917cba65a77SJagan Teki } 918cba65a77SJagan Teki 919cba65a77SJagan Teki #ifdef DEBUG 920cba65a77SJagan Teki printf("SF: Got idcodes\n"); 921cba65a77SJagan Teki print_buffer(0, idcode, 1, sizeof(idcode), 0); 922cba65a77SJagan Teki #endif 923cba65a77SJagan Teki 924cba65a77SJagan Teki jedec = idcode[1] << 8 | idcode[2]; 925cba65a77SJagan Teki ext_jedec = idcode[3] << 8 | idcode[4]; 926cba65a77SJagan Teki 927cba65a77SJagan Teki /* Validate params from spi_flash_params table */ 928cba65a77SJagan Teki params = spi_flash_params_table; 929cba65a77SJagan Teki for (; params->name != NULL; params++) { 930cba65a77SJagan Teki if ((params->jedec >> 16) == idcode[0]) { 931cba65a77SJagan Teki if ((params->jedec & 0xFFFF) == jedec) { 932cba65a77SJagan Teki if (params->ext_jedec == 0) 933cba65a77SJagan Teki break; 934cba65a77SJagan Teki else if (params->ext_jedec == ext_jedec) 935cba65a77SJagan Teki break; 936cba65a77SJagan Teki } 937cba65a77SJagan Teki } 938cba65a77SJagan Teki } 939cba65a77SJagan Teki 940cba65a77SJagan Teki if (!params->name) { 941cba65a77SJagan Teki printf("SF: Unsupported flash IDs: "); 942cba65a77SJagan Teki printf("manuf %02x, jedec %04x, ext_jedec %04x\n", 943cba65a77SJagan Teki idcode[0], jedec, ext_jedec); 944cba65a77SJagan Teki return -EPROTONOSUPPORT; 945cba65a77SJagan Teki } 946cba65a77SJagan Teki 947cba65a77SJagan Teki /* Flash powers up read-only, so clear BP# bits */ 948cba65a77SJagan Teki if (idcode[0] == SPI_FLASH_CFI_MFR_ATMEL || 949cba65a77SJagan Teki idcode[0] == SPI_FLASH_CFI_MFR_MACRONIX || 950cba65a77SJagan Teki idcode[0] == SPI_FLASH_CFI_MFR_SST) 951cba65a77SJagan Teki write_sr(flash, 0); 952cba65a77SJagan Teki 953cba65a77SJagan Teki /* Assign spi data */ 954cba65a77SJagan Teki flash->name = params->name; 955cba65a77SJagan Teki flash->memory_map = spi->memory_map; 956e228d6deSJagan Teki flash->dual_flash = spi->option; 957cba65a77SJagan Teki 958cba65a77SJagan Teki /* Assign spi flash flags */ 959cba65a77SJagan Teki if (params->flags & SST_WR) 960cba65a77SJagan Teki flash->flags |= SNOR_F_SST_WR; 961cba65a77SJagan Teki 962cba65a77SJagan Teki /* Assign spi_flash ops */ 963cba65a77SJagan Teki #ifndef CONFIG_DM_SPI_FLASH 964cba65a77SJagan Teki flash->write = spi_flash_cmd_write_ops; 965cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_SST) 966cba65a77SJagan Teki if (flash->flags & SNOR_F_SST_WR) { 967cdf33938SJagan Teki if (spi->mode & SPI_TX_BYTE) 968cba65a77SJagan Teki flash->write = sst_write_bp; 969cba65a77SJagan Teki else 970cba65a77SJagan Teki flash->write = sst_write_wp; 971cba65a77SJagan Teki } 972cba65a77SJagan Teki #endif 973cba65a77SJagan Teki flash->erase = spi_flash_cmd_erase_ops; 974cba65a77SJagan Teki flash->read = spi_flash_cmd_read_ops; 975cba65a77SJagan Teki #endif 976cba65a77SJagan Teki 977cba65a77SJagan Teki /* lock hooks are flash specific - assign them based on idcode0 */ 978cba65a77SJagan Teki switch (idcode[0]) { 979cba65a77SJagan Teki #if defined(CONFIG_SPI_FLASH_STMICRO) || defined(CONFIG_SPI_FLASH_SST) 980cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_STMICRO: 981cba65a77SJagan Teki case SPI_FLASH_CFI_MFR_SST: 982cba65a77SJagan Teki flash->flash_lock = stm_lock; 983cba65a77SJagan Teki flash->flash_unlock = stm_unlock; 984cba65a77SJagan Teki flash->flash_is_locked = stm_is_locked; 985cba65a77SJagan Teki #endif 986cba65a77SJagan Teki break; 987cba65a77SJagan Teki default: 988cba65a77SJagan Teki debug("SF: Lock ops not supported for %02x flash\n", idcode[0]); 989cba65a77SJagan Teki } 990cba65a77SJagan Teki 991cba65a77SJagan Teki /* Compute the flash size */ 992cba65a77SJagan Teki flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0; 993cba65a77SJagan Teki /* 994cba65a77SJagan Teki * The Spansion S25FL032P and S25FL064P have 256b pages, yet use the 995cba65a77SJagan Teki * 0x4d00 Extended JEDEC code. The rest of the Spansion flashes with 996cba65a77SJagan Teki * the 0x4d00 Extended JEDEC code have 512b pages. All of the others 997cba65a77SJagan Teki * have 256b pages. 998cba65a77SJagan Teki */ 999cba65a77SJagan Teki if (ext_jedec == 0x4d00) { 1000cba65a77SJagan Teki if ((jedec == 0x0215) || (jedec == 0x216)) 1001cba65a77SJagan Teki flash->page_size = 256; 1002cba65a77SJagan Teki else 1003cba65a77SJagan Teki flash->page_size = 512; 1004cba65a77SJagan Teki } else { 1005cba65a77SJagan Teki flash->page_size = 256; 1006cba65a77SJagan Teki } 1007cba65a77SJagan Teki flash->page_size <<= flash->shift; 1008cba65a77SJagan Teki flash->sector_size = params->sector_size << flash->shift; 1009cba65a77SJagan Teki flash->size = flash->sector_size * params->nr_sectors << flash->shift; 1010cba65a77SJagan Teki #ifdef CONFIG_SF_DUAL_FLASH 1011cba65a77SJagan Teki if (flash->dual_flash & SF_DUAL_STACKED_FLASH) 1012cba65a77SJagan Teki flash->size <<= 1; 1013cba65a77SJagan Teki #endif 1014cba65a77SJagan Teki 1015cba65a77SJagan Teki /* Compute erase sector and command */ 1016cba65a77SJagan Teki if (params->flags & SECT_4K) { 1017cba65a77SJagan Teki flash->erase_cmd = CMD_ERASE_4K; 1018cba65a77SJagan Teki flash->erase_size = 4096 << flash->shift; 1019cba65a77SJagan Teki } else if (params->flags & SECT_32K) { 1020cba65a77SJagan Teki flash->erase_cmd = CMD_ERASE_32K; 1021cba65a77SJagan Teki flash->erase_size = 32768 << flash->shift; 1022cba65a77SJagan Teki } else { 1023cba65a77SJagan Teki flash->erase_cmd = CMD_ERASE_64K; 1024cba65a77SJagan Teki flash->erase_size = flash->sector_size; 1025cba65a77SJagan Teki } 1026cba65a77SJagan Teki 1027cba65a77SJagan Teki /* Now erase size becomes valid sector size */ 1028cba65a77SJagan Teki flash->sector_size = flash->erase_size; 1029cba65a77SJagan Teki 1030cba65a77SJagan Teki /* Look for the fastest read cmd */ 1031e228d6deSJagan Teki cmd = fls(params->e_rd_cmd & spi->op_mode_rx); 1032cba65a77SJagan Teki if (cmd) { 1033cba65a77SJagan Teki cmd = spi_read_cmds_array[cmd - 1]; 1034cba65a77SJagan Teki flash->read_cmd = cmd; 1035cba65a77SJagan Teki } else { 1036cba65a77SJagan Teki /* Go for default supported read cmd */ 1037cba65a77SJagan Teki flash->read_cmd = CMD_READ_ARRAY_FAST; 1038cba65a77SJagan Teki } 1039cba65a77SJagan Teki 1040cba65a77SJagan Teki /* Not require to look for fastest only two write cmds yet */ 1041cdf33938SJagan Teki if (params->flags & WR_QPP && spi->mode & SPI_TX_QUAD) 1042cba65a77SJagan Teki flash->write_cmd = CMD_QUAD_PAGE_PROGRAM; 1043cba65a77SJagan Teki else 1044cba65a77SJagan Teki /* Go for default supported write cmd */ 1045cba65a77SJagan Teki flash->write_cmd = CMD_PAGE_PROGRAM; 1046cba65a77SJagan Teki 1047cba65a77SJagan Teki /* Set the quad enable bit - only for quad commands */ 1048cba65a77SJagan Teki if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || 1049cba65a77SJagan Teki (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || 1050cba65a77SJagan Teki (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { 1051cba65a77SJagan Teki ret = spi_flash_set_qeb(flash, idcode[0]); 1052cba65a77SJagan Teki if (ret) { 1053cba65a77SJagan Teki debug("SF: Fail to set QEB for %02x\n", idcode[0]); 1054cba65a77SJagan Teki return -EINVAL; 1055cba65a77SJagan Teki } 1056cba65a77SJagan Teki } 1057cba65a77SJagan Teki 1058cba65a77SJagan Teki /* Read dummy_byte: dummy byte is determined based on the 1059cba65a77SJagan Teki * dummy cycles of a particular command. 1060cba65a77SJagan Teki * Fast commands - dummy_byte = dummy_cycles/8 1061cba65a77SJagan Teki * I/O commands- dummy_byte = (dummy_cycles * no.of lines)/8 1062cba65a77SJagan Teki * For I/O commands except cmd[0] everything goes on no.of lines 1063cba65a77SJagan Teki * based on particular command but incase of fast commands except 1064cba65a77SJagan Teki * data all go on single line irrespective of command. 1065cba65a77SJagan Teki */ 1066cba65a77SJagan Teki switch (flash->read_cmd) { 1067cba65a77SJagan Teki case CMD_READ_QUAD_IO_FAST: 1068cba65a77SJagan Teki flash->dummy_byte = 2; 1069cba65a77SJagan Teki break; 1070cba65a77SJagan Teki case CMD_READ_ARRAY_SLOW: 1071cba65a77SJagan Teki flash->dummy_byte = 0; 1072cba65a77SJagan Teki break; 1073cba65a77SJagan Teki default: 1074cba65a77SJagan Teki flash->dummy_byte = 1; 1075cba65a77SJagan Teki } 1076cba65a77SJagan Teki 1077cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_STMICRO 1078cba65a77SJagan Teki if (params->flags & E_FSR) 1079cba65a77SJagan Teki flash->flags |= SNOR_F_USE_FSR; 1080cba65a77SJagan Teki #endif 1081cba65a77SJagan Teki 1082cba65a77SJagan Teki /* Configure the BAR - discover bank cmds and read current bank */ 1083cba65a77SJagan Teki #ifdef CONFIG_SPI_FLASH_BAR 1084cba65a77SJagan Teki ret = spi_flash_read_bar(flash, idcode[0]); 1085cba65a77SJagan Teki if (ret < 0) 1086cba65a77SJagan Teki return ret; 1087cba65a77SJagan Teki #endif 1088cba65a77SJagan Teki 1089cba65a77SJagan Teki #if CONFIG_IS_ENABLED(OF_CONTROL) 1090cba65a77SJagan Teki ret = spi_flash_decode_fdt(gd->fdt_blob, flash); 1091cba65a77SJagan Teki if (ret) { 1092cba65a77SJagan Teki debug("SF: FDT decode error\n"); 1093cba65a77SJagan Teki return -EINVAL; 1094cba65a77SJagan Teki } 1095cba65a77SJagan Teki #endif 1096cba65a77SJagan Teki 1097cba65a77SJagan Teki #ifndef CONFIG_SPL_BUILD 1098cba65a77SJagan Teki printf("SF: Detected %s with page size ", flash->name); 1099cba65a77SJagan Teki print_size(flash->page_size, ", erase size "); 1100cba65a77SJagan Teki print_size(flash->erase_size, ", total "); 1101cba65a77SJagan Teki print_size(flash->size, ""); 1102cba65a77SJagan Teki if (flash->memory_map) 1103cba65a77SJagan Teki printf(", mapped at %p", flash->memory_map); 1104cba65a77SJagan Teki puts("\n"); 1105cba65a77SJagan Teki #endif 1106cba65a77SJagan Teki 1107cba65a77SJagan Teki #ifndef CONFIG_SPI_FLASH_BAR 1108cba65a77SJagan Teki if (((flash->dual_flash == SF_SINGLE_FLASH) && 1109cba65a77SJagan Teki (flash->size > SPI_FLASH_16MB_BOUN)) || 1110cba65a77SJagan Teki ((flash->dual_flash > SF_SINGLE_FLASH) && 1111cba65a77SJagan Teki (flash->size > SPI_FLASH_16MB_BOUN << 1))) { 1112cba65a77SJagan Teki puts("SF: Warning - Only lower 16MiB accessible,"); 1113cba65a77SJagan Teki puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); 1114cba65a77SJagan Teki } 1115cba65a77SJagan Teki #endif 1116cba65a77SJagan Teki 1117cba65a77SJagan Teki return ret; 1118cba65a77SJagan Teki } 1119