blob: fd3c0a2422d0bf1d41c69698566a95f5bc20495e [file] [log] [blame]
Chris Douglassb34739b2014-02-14 13:51:26 -05001/*
Martin Rotheffaf8f2019-10-20 20:29:22 -06002 * This file is part of the coreboot project.
Chris Douglassb34739b2014-02-14 13:51:26 -05003 *
Martin Rotheffaf8f2019-10-20 20:29:22 -06004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15/*
16 * Driver for Adesto Technologies SPI flash
Chris Douglassb34739b2014-02-14 13:51:26 -050017 * based on winbond.c
Chris Douglassb34739b2014-02-14 13:51:26 -050018 */
19
Furquan Shaikhc28984d2016-11-20 21:04:00 -080020#include <console/console.h>
Elyes HAOUAS361a9352019-12-18 21:26:33 +010021#include <commonlib/helpers.h>
Furquan Shaikh810e2cd2016-12-05 20:32:24 -080022#include <string.h>
Chris Douglassb34739b2014-02-14 13:51:26 -050023#include <spi_flash.h>
Furquan Shaikhc28984d2016-11-20 21:04:00 -080024#include <spi-generic.h>
Edward O'Callaghanc4561e22014-06-26 15:02:40 +100025
Chris Douglassb34739b2014-02-14 13:51:26 -050026#include "spi_flash_internal.h"
27
28/* at25dfxx-specific commands */
29#define CMD_AT25DF_WREN 0x06 /* Write Enable */
30#define CMD_AT25DF_WRDI 0x04 /* Write Disable */
31#define CMD_AT25DF_RDSR 0x05 /* Read Status Register */
32#define CMD_AT25DF_WRSR 0x01 /* Write Status Register */
33#define CMD_AT25DF_READ 0x03 /* Read Data Bytes */
34#define CMD_AT25DF_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */
35#define CMD_AT25DF_PP 0x02 /* Page Program */
36#define CMD_AT25DF_SE 0x20 /* Sector (4K) Erase */
37#define CMD_AT25DF_BE 0xd8 /* Block (64K) Erase */
38#define CMD_AT25DF_CE 0xc7 /* Chip Erase */
39#define CMD_AT25DF_DP 0xb9 /* Deep Power-down */
40#define CMD_AT25DF_RES 0xab /* Release from DP, and Read Signature */
41
42struct adesto_spi_flash_params {
43 uint16_t id;
44 /* Log2 of page size in power-of-two mode */
45 uint8_t l2_page_size;
46 uint16_t pages_per_sector;
47 uint16_t sectors_per_block;
48 uint16_t nr_blocks;
49 const char *name;
50};
51
Chris Douglassb34739b2014-02-14 13:51:26 -050052static const struct adesto_spi_flash_params adesto_spi_flash_table[] = {
53 {
Mike Banon8a1cbf02019-01-12 19:45:19 +030054 .id = 0x4218,
55 .l2_page_size = 8,
56 .pages_per_sector = 16,
57 .sectors_per_block = 16,
58 .nr_blocks = 256,
59 .name = "AT25SL128A",
60 },
61 {
Chris Douglassb34739b2014-02-14 13:51:26 -050062 .id = 0x4501,
63 .l2_page_size = 8,
64 .pages_per_sector = 16,
65 .sectors_per_block = 16,
66 .nr_blocks = 16,
Mike Banon8a1cbf02019-01-12 19:45:19 +030067 .name = "AT25DF081A", /* Yes, 81A id < 81 */
68 },
69 {
70 .id = 0x4502,
71 .l2_page_size = 8,
72 .pages_per_sector = 16,
73 .sectors_per_block = 16,
74 .nr_blocks = 16,
Chris Douglassb34739b2014-02-14 13:51:26 -050075 .name = "AT25DF081",
76 },
77 {
Mike Banon8a1cbf02019-01-12 19:45:19 +030078 .id = 0x4602,
79 .l2_page_size = 8,
80 .pages_per_sector = 16,
81 .sectors_per_block = 16,
82 .nr_blocks = 32,
83 .name = "AT25DF161",
84 },
85 {
86 .id = 0x4603,
87 .l2_page_size = 8,
88 .pages_per_sector = 16,
89 .sectors_per_block = 16,
90 .nr_blocks = 32,
91 .name = "AT25DL161",
92 },
93 {
94 .id = 0x4700,
Chris Douglassb34739b2014-02-14 13:51:26 -050095 .l2_page_size = 8,
96 .pages_per_sector = 16,
97 .sectors_per_block = 16,
98 .nr_blocks = 64,
99 .name = "AT25DF321",
100 },
101 {
Mike Banon8a1cbf02019-01-12 19:45:19 +0300102 .id = 0x4701,
103 .l2_page_size = 8,
104 .pages_per_sector = 16,
105 .sectors_per_block = 16,
106 .nr_blocks = 64,
107 .name = "AT25DF321A",
108 },
109 {
Chris Douglassb34739b2014-02-14 13:51:26 -0500110 .id = 0x4800,
111 .l2_page_size = 8,
112 .pages_per_sector = 16,
113 .sectors_per_block = 16,
114 .nr_blocks = 128,
115 .name = "AT25DF641",
116 },
Mike Banon8a1cbf02019-01-12 19:45:19 +0300117 {
118 .id = 0x8501,
119 .l2_page_size = 8,
120 .pages_per_sector = 16,
121 .sectors_per_block = 16,
122 .nr_blocks = 16,
123 .name = "AT25SF081",
124 },
125 {
126 .id = 0x8600,
127 .l2_page_size = 8,
128 .pages_per_sector = 16,
129 .sectors_per_block = 16,
130 .nr_blocks = 32,
131 .name = "AT25DQ161",
132 },
133 {
134 .id = 0x8601,
135 .l2_page_size = 8,
136 .pages_per_sector = 16,
137 .sectors_per_block = 16,
138 .nr_blocks = 32,
139 .name = "AT25SF161",
140 },
141 {
142 .id = 0x8700,
143 .l2_page_size = 8,
144 .pages_per_sector = 16,
145 .sectors_per_block = 16,
146 .nr_blocks = 64,
147 .name = "AT25DQ321",
148 },
Chris Douglassb34739b2014-02-14 13:51:26 -0500149};
150
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700151static const struct spi_flash_ops spi_flash_ops = {
Aaron Durbincb01aa52020-01-11 11:44:47 -0700152 .read = spi_flash_cmd_read,
Aaron Durbind701ef72019-12-27 15:16:17 -0700153 .write = spi_flash_cmd_write_page_program,
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700154 .erase = spi_flash_cmd_erase,
Aaron Durbin937931e2020-01-11 16:52:42 -0700155 .status = spi_flash_cmd_status,
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700156};
157
Furquan Shaikhbd9e32e2017-05-15 23:28:41 -0700158int spi_flash_probe_adesto(const struct spi_slave *spi, u8 *idcode,
Furquan Shaikh30221b42017-05-15 14:35:15 -0700159 struct spi_flash *flash)
Chris Douglassb34739b2014-02-14 13:51:26 -0500160{
161 const struct adesto_spi_flash_params *params;
Chris Douglassb34739b2014-02-14 13:51:26 -0500162 unsigned int i;
163
164 for (i = 0; i < ARRAY_SIZE(adesto_spi_flash_table); i++) {
165 params = &adesto_spi_flash_table[i];
166 if (params->id == ((idcode[1] << 8) | idcode[2]))
167 break;
168 }
169
170 if (i == ARRAY_SIZE(adesto_spi_flash_table)) {
171 printk(BIOS_WARNING, "SF: Unsupported adesto ID %02x%02x\n",
172 idcode[1], idcode[2]);
Furquan Shaikh30221b42017-05-15 14:35:15 -0700173 return -1;
Chris Douglassb34739b2014-02-14 13:51:26 -0500174 }
175
Furquan Shaikhfc1a1232017-05-12 00:19:56 -0700176 memcpy(&flash->spi, spi, sizeof(*spi));
177 flash->name = params->name;
Chris Douglassb34739b2014-02-14 13:51:26 -0500178 /* Assuming power-of-two page size initially. */
Furquan Shaikhfc1a1232017-05-12 00:19:56 -0700179 flash->page_size = 1 << params->l2_page_size;
180 flash->sector_size = flash->page_size * params->pages_per_sector;
181 flash->size = flash->sector_size *params->sectors_per_block *
182 params->nr_blocks;
183 flash->erase_cmd = CMD_AT25DF_SE;
Aaron Durbin937931e2020-01-11 16:52:42 -0700184 flash->status_cmd = CMD_AT25DF_RDSR;
Aaron Durbind701ef72019-12-27 15:16:17 -0700185 flash->pp_cmd = CMD_AT25DF_PP;
186 flash->wren_cmd = CMD_AT25DF_WREN;
Chris Douglassb34739b2014-02-14 13:51:26 -0500187
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700188 flash->ops = &spi_flash_ops;
Chris Douglassb34739b2014-02-14 13:51:26 -0500189
Furquan Shaikh30221b42017-05-15 14:35:15 -0700190 return 0;
Chris Douglassb34739b2014-02-14 13:51:26 -0500191}