blob: cf47de1fd4ec076faf8b3d31b2ee0165bd884bc0 [file] [log] [blame]
stepand4b13752007-10-15 21:45:29 +00001/*
2 * This file is part of the flashrom project.
3 *
Craig Hesling65eb8812019-08-01 09:33:56 -07004 * Copyright (C) 2007, 2008, 2009 Carl-Daniel Hailfinger
stepandbd3af12008-06-27 16:28:34 +00005 * Copyright (C) 2008 coresystems GmbH
stepand4b13752007-10-15 21:45:29 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
stepand4b13752007-10-15 21:45:29 +000016 */
17
18/*
19 * Contains the generic SPI framework
20 */
21
oxygene70aa6502011-03-08 07:17:44 +000022#include <strings.h>
hailfinger132df7b2010-09-15 00:13:02 +000023#include <string.h>
stepand4b13752007-10-15 21:45:29 +000024#include "flash.h"
hailfinger66966da2009-06-15 14:14:48 +000025#include "flashchips.h"
snelson8913d082010-02-26 05:48:29 +000026#include "chipdrivers.h"
hailfinger428f6852010-07-27 22:41:39 +000027#include "programmer.h"
hailfinger78031562008-05-13 14:58:23 +000028#include "spi.h"
stepand4b13752007-10-15 21:45:29 +000029
Craig Hesling65eb8812019-08-01 09:33:56 -070030const struct spi_master spi_master_none = {
Craig Hesling65eb8812019-08-01 09:33:56 -070031 .max_data_read = MAX_DATA_UNSPECIFIED,
32 .max_data_write = MAX_DATA_UNSPECIFIED,
33 .command = NULL,
34 .multicommand = NULL,
35 .read = NULL,
36 .write_256 = NULL,
37};
38
39const struct spi_master *spi_master = &spi_master_none;
40
Souvik Ghoshd75cd672016-06-17 14:21:39 -070041int spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
uwefa98ca12008-10-18 21:14:13 +000042 const unsigned char *writearr, unsigned char *readarr)
hailfinger35cc8162007-10-16 21:09:06 +000043{
Craig Hesling65eb8812019-08-01 09:33:56 -070044 if (!spi_master->command) {
Duncan Laurie870d8af2019-01-09 18:05:23 -080045 msg_pdbg("%s called, but SPI is unsupported on this "
David Hendricksac1d25c2016-08-09 17:00:58 -070046 "hardware. Please report a bug at "
47 "flashrom@flashrom.org\n", __func__);
48 return 1;
49 }
50
Craig Hesling65eb8812019-08-01 09:33:56 -070051 return spi_master->command(flash, writecnt, readcnt,
David Hendricksac1d25c2016-08-09 17:00:58 -070052 writearr, readarr);
hailfinger35cc8162007-10-16 21:09:06 +000053}
54
Souvik Ghoshd75cd672016-06-17 14:21:39 -070055int spi_send_multicommand(const struct flashctx *flash, struct spi_command *cmds)
hailfinger68002c22009-07-10 21:08:55 +000056{
Craig Hesling65eb8812019-08-01 09:33:56 -070057 if (!spi_master->multicommand) {
Duncan Laurie870d8af2019-01-09 18:05:23 -080058 msg_pdbg("%s called, but SPI is unsupported on this "
David Hendricksac1d25c2016-08-09 17:00:58 -070059 "hardware. Please report a bug at "
60 "flashrom@flashrom.org\n", __func__);
61 return 1;
62 }
63
Craig Hesling65eb8812019-08-01 09:33:56 -070064 return spi_master->multicommand(flash, cmds);
hailfinger948b81f2009-07-22 15:36:50 +000065}
66
Souvik Ghoshd75cd672016-06-17 14:21:39 -070067int default_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
hailfinger948b81f2009-07-22 15:36:50 +000068 const unsigned char *writearr, unsigned char *readarr)
69{
70 struct spi_command cmd[] = {
71 {
72 .writecnt = writecnt,
73 .readcnt = readcnt,
74 .writearr = writearr,
75 .readarr = readarr,
76 }, {
77 .writecnt = 0,
78 .writearr = NULL,
79 .readcnt = 0,
80 .readarr = NULL,
81 }};
82
Souvik Ghoshd75cd672016-06-17 14:21:39 -070083 return spi_send_multicommand(flash, cmd);
hailfinger948b81f2009-07-22 15:36:50 +000084}
85
Souvik Ghoshd75cd672016-06-17 14:21:39 -070086int default_spi_send_multicommand(const struct flashctx *flash, struct spi_command *cmds)
hailfinger948b81f2009-07-22 15:36:50 +000087{
88 int result = 0;
hailfingerbb092112009-09-18 15:50:56 +000089 for (; (cmds->writecnt || cmds->readcnt) && !result; cmds++) {
Souvik Ghoshd75cd672016-06-17 14:21:39 -070090 result = spi_send_command(flash, cmds->writecnt, cmds->readcnt,
hailfingerbb092112009-09-18 15:50:56 +000091 cmds->writearr, cmds->readarr);
hailfinger948b81f2009-07-22 15:36:50 +000092 }
93 return result;
hailfinger68002c22009-07-10 21:08:55 +000094}
95
Souvik Ghoshd75cd672016-06-17 14:21:39 -070096int default_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
mkarcher8fb57592011-05-11 17:07:02 +000097{
Craig Hesling65eb8812019-08-01 09:33:56 -070098 unsigned int max_data = spi_master->max_data_read;
David Hendricks1ed1d352011-11-23 17:54:37 -080099 int rc;
mkarcher8fb57592011-05-11 17:07:02 +0000100 if (max_data == MAX_DATA_UNSPECIFIED) {
101 msg_perr("%s called, but SPI read chunk size not defined "
102 "on this hardware. Please report a bug at "
103 "flashrom@flashrom.org\n", __func__);
104 return 1;
105 }
Edward O'Callaghan27486212019-07-26 21:59:55 +1000106 rc = spi_read_chunked(flash, buf, start, len, max_data);
David Hendricks1ed1d352011-11-23 17:54:37 -0800107 /* translate SPI-specific access denied error to generic error */
108 if (rc == SPI_ACCESS_DENIED)
109 rc = ACCESS_DENIED;
110 return rc;
mkarcher8fb57592011-05-11 17:07:02 +0000111}
112
Patrick Georgiab8353e2017-02-03 18:32:01 +0100113int default_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
mkarcher8fb57592011-05-11 17:07:02 +0000114{
Craig Hesling65eb8812019-08-01 09:33:56 -0700115 unsigned int max_data = spi_master->max_data_write;
David Hendricks1ed1d352011-11-23 17:54:37 -0800116 int rc;
mkarcher8fb57592011-05-11 17:07:02 +0000117 if (max_data == MAX_DATA_UNSPECIFIED) {
118 msg_perr("%s called, but SPI write chunk size not defined "
119 "on this hardware. Please report a bug at "
120 "flashrom@flashrom.org\n", __func__);
121 return 1;
122 }
David Hendricks1ed1d352011-11-23 17:54:37 -0800123 rc = spi_write_chunked(flash, buf, start, len, max_data);
124 /* translate SPI-specific access denied error to generic error */
125 if (rc == SPI_ACCESS_DENIED)
126 rc = ACCESS_DENIED;
127 return rc;
mkarcher8fb57592011-05-11 17:07:02 +0000128}
129
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700130int spi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
hailfingerb8f7e882008-01-19 00:04:46 +0000131{
Craig Hesling65eb8812019-08-01 09:33:56 -0700132 if (!spi_master->read) {
David Hendricksac1d25c2016-08-09 17:00:58 -0700133 msg_perr("%s called, but SPI read is unsupported on this "
134 "hardware. Please report a bug at "
135 "flashrom@flashrom.org\n", __func__);
136 return 1;
137 }
138
Edward O'Callaghandfb71542020-05-14 18:41:42 +1000139 return spi_master->read(flash, buf, start, len);
hailfingerb8f7e882008-01-19 00:04:46 +0000140}
141
hailfingered063f52009-05-09 02:30:21 +0000142/*
hailfingered063f52009-05-09 02:30:21 +0000143 * Program chip using page (256 bytes) programming.
144 * Some SPI masters can't do this, they use single byte programming instead.
hailfingerc7d06c62010-07-14 16:19:05 +0000145 * The redirect to single byte programming is achieved by setting
146 * .write_256 = spi_chip_write_1
hailfingered063f52009-05-09 02:30:21 +0000147 */
hailfingerc7d06c62010-07-14 16:19:05 +0000148/* real chunksize is up to 256, logical chunksize is 256 */
Patrick Georgiab8353e2017-02-03 18:32:01 +0100149int spi_chip_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
hailfinger2c361e42008-05-13 23:03:12 +0000150{
Craig Hesling65eb8812019-08-01 09:33:56 -0700151 if (!spi_master->write_256) {
David Hendricksac1d25c2016-08-09 17:00:58 -0700152 msg_perr("%s called, but SPI page write is unsupported on this "
153 "hardware. Please report a bug at "
154 "flashrom@flashrom.org\n", __func__);
155 return 1;
156 }
157
Craig Hesling65eb8812019-08-01 09:33:56 -0700158 return spi_master->write_256(flash, buf, start, len);
hailfingerc7d06c62010-07-14 16:19:05 +0000159}
160
Edward O'Callaghaneeaac6b2020-10-12 19:51:56 +1100161int spi_aai_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
162{
163 return flash->mst->spi.write_aai(flash, buf, start, len);
164}
165
Edward O'Callaghan20ba6152019-08-26 23:21:09 +1000166int register_spi_master(const struct spi_master *mst)
mkarcherd264e9e2011-05-11 17:07:07 +0000167{
Edward O'Callaghan20ba6152019-08-26 23:21:09 +1000168 struct registered_master rmst;
169
170 // TODO(quasisec): Kill off these global states.
171 spi_master = mst;
Craig Hesling65eb8812019-08-01 09:33:56 -0700172 buses_supported |= BUS_SPI;
Edward O'Callaghan20ba6152019-08-26 23:21:09 +1000173
174 rmst.buses_supported = BUS_SPI;
175 rmst.spi = *mst;
176
177 return register_master(&rmst);
David Hendricks91040832011-07-08 20:01:09 -0700178}