Home | History | Annotate | Download | only in spi
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (c) 2011-12 The Chromium OS Authors.
      4  *
      5  * This file is derived from the flashrom project.
      6  */
      7 
      8 #include <common.h>
      9 #include <dm.h>
     10 #include <errno.h>
     11 #include <malloc.h>
     12 #include <pch.h>
     13 #include <pci.h>
     14 #include <pci_ids.h>
     15 #include <spi.h>
     16 #include <asm/io.h>
     17 
     18 #include "ich.h"
     19 
     20 DECLARE_GLOBAL_DATA_PTR;
     21 
     22 #ifdef DEBUG_TRACE
     23 #define debug_trace(fmt, args...) debug(fmt, ##args)
     24 #else
     25 #define debug_trace(x, args...)
     26 #endif
     27 
     28 static u8 ich_readb(struct ich_spi_priv *priv, int reg)
     29 {
     30 	u8 value = readb(priv->base + reg);
     31 
     32 	debug_trace("read %2.2x from %4.4x\n", value, reg);
     33 
     34 	return value;
     35 }
     36 
     37 static u16 ich_readw(struct ich_spi_priv *priv, int reg)
     38 {
     39 	u16 value = readw(priv->base + reg);
     40 
     41 	debug_trace("read %4.4x from %4.4x\n", value, reg);
     42 
     43 	return value;
     44 }
     45 
     46 static u32 ich_readl(struct ich_spi_priv *priv, int reg)
     47 {
     48 	u32 value = readl(priv->base + reg);
     49 
     50 	debug_trace("read %8.8x from %4.4x\n", value, reg);
     51 
     52 	return value;
     53 }
     54 
     55 static void ich_writeb(struct ich_spi_priv *priv, u8 value, int reg)
     56 {
     57 	writeb(value, priv->base + reg);
     58 	debug_trace("wrote %2.2x to %4.4x\n", value, reg);
     59 }
     60 
     61 static void ich_writew(struct ich_spi_priv *priv, u16 value, int reg)
     62 {
     63 	writew(value, priv->base + reg);
     64 	debug_trace("wrote %4.4x to %4.4x\n", value, reg);
     65 }
     66 
     67 static void ich_writel(struct ich_spi_priv *priv, u32 value, int reg)
     68 {
     69 	writel(value, priv->base + reg);
     70 	debug_trace("wrote %8.8x to %4.4x\n", value, reg);
     71 }
     72 
     73 static void write_reg(struct ich_spi_priv *priv, const void *value,
     74 		      int dest_reg, uint32_t size)
     75 {
     76 	memcpy_toio(priv->base + dest_reg, value, size);
     77 }
     78 
     79 static void read_reg(struct ich_spi_priv *priv, int src_reg, void *value,
     80 		     uint32_t size)
     81 {
     82 	memcpy_fromio(value, priv->base + src_reg, size);
     83 }
     84 
     85 static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t minaddr)
     86 {
     87 	const uint32_t bbar_mask = 0x00ffff00;
     88 	uint32_t ichspi_bbar;
     89 
     90 	minaddr &= bbar_mask;
     91 	ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask;
     92 	ichspi_bbar |= minaddr;
     93 	ich_writel(ctlr, ichspi_bbar, ctlr->bbar);
     94 }
     95 
     96 /* @return 1 if the SPI flash supports the 33MHz speed */
     97 static int ich9_can_do_33mhz(struct udevice *dev)
     98 {
     99 	u32 fdod, speed;
    100 
    101 	/* Observe SPI Descriptor Component Section 0 */
    102 	dm_pci_write_config32(dev->parent, 0xb0, 0x1000);
    103 
    104 	/* Extract the Write/Erase SPI Frequency from descriptor */
    105 	dm_pci_read_config32(dev->parent, 0xb4, &fdod);
    106 
    107 	/* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */
    108 	speed = (fdod >> 21) & 7;
    109 
    110 	return speed == 1;
    111 }
    112 
    113 static int ich_init_controller(struct udevice *dev,
    114 			       struct ich_spi_platdata *plat,
    115 			       struct ich_spi_priv *ctlr)
    116 {
    117 	ulong sbase_addr;
    118 	void *sbase;
    119 
    120 	/* SBASE is similar */
    121 	pch_get_spi_base(dev->parent, &sbase_addr);
    122 	sbase = (void *)sbase_addr;
    123 	debug("%s: sbase=%p\n", __func__, sbase);
    124 
    125 	if (plat->ich_version == ICHV_7) {
    126 		struct ich7_spi_regs *ich7_spi = sbase;
    127 
    128 		ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
    129 		ctlr->menubytes = sizeof(ich7_spi->opmenu);
    130 		ctlr->optype = offsetof(struct ich7_spi_regs, optype);
    131 		ctlr->addr = offsetof(struct ich7_spi_regs, spia);
    132 		ctlr->data = offsetof(struct ich7_spi_regs, spid);
    133 		ctlr->databytes = sizeof(ich7_spi->spid);
    134 		ctlr->status = offsetof(struct ich7_spi_regs, spis);
    135 		ctlr->control = offsetof(struct ich7_spi_regs, spic);
    136 		ctlr->bbar = offsetof(struct ich7_spi_regs, bbar);
    137 		ctlr->preop = offsetof(struct ich7_spi_regs, preop);
    138 		ctlr->base = ich7_spi;
    139 	} else if (plat->ich_version == ICHV_9) {
    140 		struct ich9_spi_regs *ich9_spi = sbase;
    141 
    142 		ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
    143 		ctlr->menubytes = sizeof(ich9_spi->opmenu);
    144 		ctlr->optype = offsetof(struct ich9_spi_regs, optype);
    145 		ctlr->addr = offsetof(struct ich9_spi_regs, faddr);
    146 		ctlr->data = offsetof(struct ich9_spi_regs, fdata);
    147 		ctlr->databytes = sizeof(ich9_spi->fdata);
    148 		ctlr->status = offsetof(struct ich9_spi_regs, ssfs);
    149 		ctlr->control = offsetof(struct ich9_spi_regs, ssfc);
    150 		ctlr->speed = ctlr->control + 2;
    151 		ctlr->bbar = offsetof(struct ich9_spi_regs, bbar);
    152 		ctlr->preop = offsetof(struct ich9_spi_regs, preop);
    153 		ctlr->bcr = offsetof(struct ich9_spi_regs, bcr);
    154 		ctlr->pr = &ich9_spi->pr[0];
    155 		ctlr->base = ich9_spi;
    156 	} else {
    157 		debug("ICH SPI: Unrecognised ICH version %d\n",
    158 		      plat->ich_version);
    159 		return -EINVAL;
    160 	}
    161 
    162 	/* Work out the maximum speed we can support */
    163 	ctlr->max_speed = 20000000;
    164 	if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev))
    165 		ctlr->max_speed = 33000000;
    166 	debug("ICH SPI: Version ID %d detected at %p, speed %ld\n",
    167 	      plat->ich_version, ctlr->base, ctlr->max_speed);
    168 
    169 	ich_set_bbar(ctlr, 0);
    170 
    171 	return 0;
    172 }
    173 
    174 static inline void spi_use_out(struct spi_trans *trans, unsigned bytes)
    175 {
    176 	trans->out += bytes;
    177 	trans->bytesout -= bytes;
    178 }
    179 
    180 static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
    181 {
    182 	trans->in += bytes;
    183 	trans->bytesin -= bytes;
    184 }
    185 
    186 static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase)
    187 {
    188 	if (plat->ich_version == ICHV_7) {
    189 		struct ich7_spi_regs *ich7_spi = sbase;
    190 
    191 		setbits_le16(&ich7_spi->spis, SPIS_LOCK);
    192 	} else if (plat->ich_version == ICHV_9) {
    193 		struct ich9_spi_regs *ich9_spi = sbase;
    194 
    195 		setbits_le16(&ich9_spi->hsfs, HSFS_FLOCKDN);
    196 	}
    197 }
    198 
    199 static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase)
    200 {
    201 	int lock = 0;
    202 
    203 	if (plat->ich_version == ICHV_7) {
    204 		struct ich7_spi_regs *ich7_spi = sbase;
    205 
    206 		lock = readw(&ich7_spi->spis) & SPIS_LOCK;
    207 	} else if (plat->ich_version == ICHV_9) {
    208 		struct ich9_spi_regs *ich9_spi = sbase;
    209 
    210 		lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
    211 	}
    212 
    213 	return lock != 0;
    214 }
    215 
    216 static void spi_setup_type(struct spi_trans *trans, int data_bytes)
    217 {
    218 	trans->type = 0xFF;
    219 
    220 	/* Try to guess spi type from read/write sizes */
    221 	if (trans->bytesin == 0) {
    222 		if (trans->bytesout + data_bytes > 4)
    223 			/*
    224 			 * If bytesin = 0 and bytesout > 4, we presume this is
    225 			 * a write data operation, which is accompanied by an
    226 			 * address.
    227 			 */
    228 			trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
    229 		else
    230 			trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
    231 		return;
    232 	}
    233 
    234 	if (trans->bytesout == 1) {	/* and bytesin is > 0 */
    235 		trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
    236 		return;
    237 	}
    238 
    239 	if (trans->bytesout == 4)	/* and bytesin is > 0 */
    240 		trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
    241 
    242 	/* Fast read command is called with 5 bytes instead of 4 */
    243 	if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
    244 		trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
    245 		--trans->bytesout;
    246 	}
    247 }
    248 
    249 static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
    250 			    bool lock)
    251 {
    252 	uint16_t optypes;
    253 	uint8_t opmenu[ctlr->menubytes];
    254 
    255 	trans->opcode = trans->out[0];
    256 	spi_use_out(trans, 1);
    257 	if (!lock) {
    258 		/* The lock is off, so just use index 0. */
    259 		ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
    260 		optypes = ich_readw(ctlr, ctlr->optype);
    261 		optypes = (optypes & 0xfffc) | (trans->type & 0x3);
    262 		ich_writew(ctlr, optypes, ctlr->optype);
    263 		return 0;
    264 	} else {
    265 		/* The lock is on. See if what we need is on the menu. */
    266 		uint8_t optype;
    267 		uint16_t opcode_index;
    268 
    269 		/* Write Enable is handled as atomic prefix */
    270 		if (trans->opcode == SPI_OPCODE_WREN)
    271 			return 0;
    272 
    273 		read_reg(ctlr, ctlr->opmenu, opmenu, sizeof(opmenu));
    274 		for (opcode_index = 0; opcode_index < ctlr->menubytes;
    275 				opcode_index++) {
    276 			if (opmenu[opcode_index] == trans->opcode)
    277 				break;
    278 		}
    279 
    280 		if (opcode_index == ctlr->menubytes) {
    281 			printf("ICH SPI: Opcode %x not found\n",
    282 			       trans->opcode);
    283 			return -EINVAL;
    284 		}
    285 
    286 		optypes = ich_readw(ctlr, ctlr->optype);
    287 		optype = (optypes >> (opcode_index * 2)) & 0x3;
    288 		if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
    289 		    optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
    290 		    trans->bytesout >= 3) {
    291 			/* We guessed wrong earlier. Fix it up. */
    292 			trans->type = optype;
    293 		}
    294 		if (optype != trans->type) {
    295 			printf("ICH SPI: Transaction doesn't fit type %d\n",
    296 			       optype);
    297 			return -ENOSPC;
    298 		}
    299 		return opcode_index;
    300 	}
    301 }
    302 
    303 static int spi_setup_offset(struct spi_trans *trans)
    304 {
    305 	/* Separate the SPI address and data */
    306 	switch (trans->type) {
    307 	case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
    308 	case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
    309 		return 0;
    310 	case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
    311 	case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
    312 		trans->offset = ((uint32_t)trans->out[0] << 16) |
    313 				((uint32_t)trans->out[1] << 8) |
    314 				((uint32_t)trans->out[2] << 0);
    315 		spi_use_out(trans, 3);
    316 		return 1;
    317 	default:
    318 		printf("Unrecognized SPI transaction type %#x\n", trans->type);
    319 		return -EPROTO;
    320 	}
    321 }
    322 
    323 /*
    324  * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
    325  * below is true) or 0. In case the wait was for the bit(s) to set - write
    326  * those bits back, which would cause resetting them.
    327  *
    328  * Return the last read status value on success or -1 on failure.
    329  */
    330 static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask,
    331 			   int wait_til_set)
    332 {
    333 	int timeout = 600000; /* This will result in 6s */
    334 	u16 status = 0;
    335 
    336 	while (timeout--) {
    337 		status = ich_readw(ctlr, ctlr->status);
    338 		if (wait_til_set ^ ((status & bitmask) == 0)) {
    339 			if (wait_til_set) {
    340 				ich_writew(ctlr, status & bitmask,
    341 					   ctlr->status);
    342 			}
    343 			return status;
    344 		}
    345 		udelay(10);
    346 	}
    347 
    348 	printf("ICH SPI: SCIP timeout, read %x, expected %x\n",
    349 	       status, bitmask);
    350 	return -ETIMEDOUT;
    351 }
    352 
    353 void ich_spi_config_opcode(struct udevice *dev)
    354 {
    355 	struct ich_spi_priv *ctlr = dev_get_priv(dev);
    356 
    357 	/*
    358 	 * PREOP, OPTYPE, OPMENU1/OPMENU2 registers can be locked down
    359 	 * to prevent accidental or intentional writes. Before they get
    360 	 * locked down, these registers should be initialized properly.
    361 	 */
    362 	ich_writew(ctlr, SPI_OPPREFIX, ctlr->preop);
    363 	ich_writew(ctlr, SPI_OPTYPE, ctlr->optype);
    364 	ich_writel(ctlr, SPI_OPMENU_LOWER, ctlr->opmenu);
    365 	ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
    366 }
    367 
    368 static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
    369 			const void *dout, void *din, unsigned long flags)
    370 {
    371 	struct udevice *bus = dev_get_parent(dev);
    372 	struct ich_spi_platdata *plat = dev_get_platdata(bus);
    373 	struct ich_spi_priv *ctlr = dev_get_priv(bus);
    374 	uint16_t control;
    375 	int16_t opcode_index;
    376 	int with_address;
    377 	int status;
    378 	int bytes = bitlen / 8;
    379 	struct spi_trans *trans = &ctlr->trans;
    380 	unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
    381 	int using_cmd = 0;
    382 	bool lock = spi_lock_status(plat, ctlr->base);
    383 	int ret;
    384 
    385 	/* We don't support writing partial bytes */
    386 	if (bitlen % 8) {
    387 		debug("ICH SPI: Accessing partial bytes not supported\n");
    388 		return -EPROTONOSUPPORT;
    389 	}
    390 
    391 	/* An empty end transaction can be ignored */
    392 	if (type == SPI_XFER_END && !dout && !din)
    393 		return 0;
    394 
    395 	if (type & SPI_XFER_BEGIN)
    396 		memset(trans, '\0', sizeof(*trans));
    397 
    398 	/* Dp we need to come back later to finish it? */
    399 	if (dout && type == SPI_XFER_BEGIN) {
    400 		if (bytes > ICH_MAX_CMD_LEN) {
    401 			debug("ICH SPI: Command length limit exceeded\n");
    402 			return -ENOSPC;
    403 		}
    404 		memcpy(trans->cmd, dout, bytes);
    405 		trans->cmd_len = bytes;
    406 		debug_trace("ICH SPI: Saved %d bytes\n", bytes);
    407 		return 0;
    408 	}
    409 
    410 	/*
    411 	 * We process a 'middle' spi_xfer() call, which has no
    412 	 * SPI_XFER_BEGIN/END, as an independent transaction as if it had
    413 	 * an end. We therefore repeat the command. This is because ICH
    414 	 * seems to have no support for this, or because interest (in digging
    415 	 * out the details and creating a special case in the code) is low.
    416 	 */
    417 	if (trans->cmd_len) {
    418 		trans->out = trans->cmd;
    419 		trans->bytesout = trans->cmd_len;
    420 		using_cmd = 1;
    421 		debug_trace("ICH SPI: Using %d bytes\n", trans->cmd_len);
    422 	} else {
    423 		trans->out = dout;
    424 		trans->bytesout = dout ? bytes : 0;
    425 	}
    426 
    427 	trans->in = din;
    428 	trans->bytesin = din ? bytes : 0;
    429 
    430 	/* There has to always at least be an opcode */
    431 	if (!trans->bytesout) {
    432 		debug("ICH SPI: No opcode for transfer\n");
    433 		return -EPROTO;
    434 	}
    435 
    436 	ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
    437 	if (ret < 0)
    438 		return ret;
    439 
    440 	if (plat->ich_version == ICHV_7)
    441 		ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
    442 	else
    443 		ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
    444 
    445 	spi_setup_type(trans, using_cmd ? bytes : 0);
    446 	opcode_index = spi_setup_opcode(ctlr, trans, lock);
    447 	if (opcode_index < 0)
    448 		return -EINVAL;
    449 	with_address = spi_setup_offset(trans);
    450 	if (with_address < 0)
    451 		return -EINVAL;
    452 
    453 	if (trans->opcode == SPI_OPCODE_WREN) {
    454 		/*
    455 		 * Treat Write Enable as Atomic Pre-Op if possible
    456 		 * in order to prevent the Management Engine from
    457 		 * issuing a transaction between WREN and DATA.
    458 		 */
    459 		if (!lock)
    460 			ich_writew(ctlr, trans->opcode, ctlr->preop);
    461 		return 0;
    462 	}
    463 
    464 	if (ctlr->speed && ctlr->max_speed >= 33000000) {
    465 		int byte;
    466 
    467 		byte = ich_readb(ctlr, ctlr->speed);
    468 		if (ctlr->cur_speed >= 33000000)
    469 			byte |= SSFC_SCF_33MHZ;
    470 		else
    471 			byte &= ~SSFC_SCF_33MHZ;
    472 		ich_writeb(ctlr, byte, ctlr->speed);
    473 	}
    474 
    475 	/* See if we have used up the command data */
    476 	if (using_cmd && dout && bytes) {
    477 		trans->out = dout;
    478 		trans->bytesout = bytes;
    479 		debug_trace("ICH SPI: Moving to data, %d bytes\n", bytes);
    480 	}
    481 
    482 	/* Preset control fields */
    483 	control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
    484 
    485 	/* Issue atomic preop cycle if needed */
    486 	if (ich_readw(ctlr, ctlr->preop))
    487 		control |= SPIC_ACS;
    488 
    489 	if (!trans->bytesout && !trans->bytesin) {
    490 		/* SPI addresses are 24 bit only */
    491 		if (with_address) {
    492 			ich_writel(ctlr, trans->offset & 0x00FFFFFF,
    493 				   ctlr->addr);
    494 		}
    495 		/*
    496 		 * This is a 'no data' command (like Write Enable), its
    497 		 * bitesout size was 1, decremented to zero while executing
    498 		 * spi_setup_opcode() above. Tell the chip to send the
    499 		 * command.
    500 		 */
    501 		ich_writew(ctlr, control, ctlr->control);
    502 
    503 		/* wait for the result */
    504 		status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
    505 		if (status < 0)
    506 			return status;
    507 
    508 		if (status & SPIS_FCERR) {
    509 			debug("ICH SPI: Command transaction error\n");
    510 			return -EIO;
    511 		}
    512 
    513 		return 0;
    514 	}
    515 
    516 	/*
    517 	 * Check if this is a write command atempting to transfer more bytes
    518 	 * than the controller can handle. Iterations for writes are not
    519 	 * supported here because each SPI write command needs to be preceded
    520 	 * and followed by other SPI commands, and this sequence is controlled
    521 	 * by the SPI chip driver.
    522 	 */
    523 	if (trans->bytesout > ctlr->databytes) {
    524 		debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n");
    525 		return -EPROTO;
    526 	}
    527 
    528 	/*
    529 	 * Read or write up to databytes bytes at a time until everything has
    530 	 * been sent.
    531 	 */
    532 	while (trans->bytesout || trans->bytesin) {
    533 		uint32_t data_length;
    534 
    535 		/* SPI addresses are 24 bit only */
    536 		ich_writel(ctlr, trans->offset & 0x00FFFFFF, ctlr->addr);
    537 
    538 		if (trans->bytesout)
    539 			data_length = min(trans->bytesout, ctlr->databytes);
    540 		else
    541 			data_length = min(trans->bytesin, ctlr->databytes);
    542 
    543 		/* Program data into FDATA0 to N */
    544 		if (trans->bytesout) {
    545 			write_reg(ctlr, trans->out, ctlr->data, data_length);
    546 			spi_use_out(trans, data_length);
    547 			if (with_address)
    548 				trans->offset += data_length;
    549 		}
    550 
    551 		/* Add proper control fields' values */
    552 		control &= ~((ctlr->databytes - 1) << 8);
    553 		control |= SPIC_DS;
    554 		control |= (data_length - 1) << 8;
    555 
    556 		/* write it */
    557 		ich_writew(ctlr, control, ctlr->control);
    558 
    559 		/* Wait for Cycle Done Status or Flash Cycle Error */
    560 		status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
    561 		if (status < 0)
    562 			return status;
    563 
    564 		if (status & SPIS_FCERR) {
    565 			debug("ICH SPI: Data transaction error %x\n", status);
    566 			return -EIO;
    567 		}
    568 
    569 		if (trans->bytesin) {
    570 			read_reg(ctlr, ctlr->data, trans->in, data_length);
    571 			spi_use_in(trans, data_length);
    572 			if (with_address)
    573 				trans->offset += data_length;
    574 		}
    575 	}
    576 
    577 	/* Clear atomic preop now that xfer is done */
    578 	if (!lock)
    579 		ich_writew(ctlr, 0, ctlr->preop);
    580 
    581 	return 0;
    582 }
    583 
    584 static int ich_spi_probe(struct udevice *dev)
    585 {
    586 	struct ich_spi_platdata *plat = dev_get_platdata(dev);
    587 	struct ich_spi_priv *priv = dev_get_priv(dev);
    588 	uint8_t bios_cntl;
    589 	int ret;
    590 
    591 	ret = ich_init_controller(dev, plat, priv);
    592 	if (ret)
    593 		return ret;
    594 	/* Disable the BIOS write protect so write commands are allowed */
    595 	ret = pch_set_spi_protect(dev->parent, false);
    596 	if (ret == -ENOSYS) {
    597 		bios_cntl = ich_readb(priv, priv->bcr);
    598 		bios_cntl &= ~BIT(5);	/* clear Enable InSMM_STS (EISS) */
    599 		bios_cntl |= 1;		/* Write Protect Disable (WPD) */
    600 		ich_writeb(priv, bios_cntl, priv->bcr);
    601 	} else if (ret) {
    602 		debug("%s: Failed to disable write-protect: err=%d\n",
    603 		      __func__, ret);
    604 		return ret;
    605 	}
    606 
    607 	/* Lock down SPI controller settings if required */
    608 	if (plat->lockdown) {
    609 		ich_spi_config_opcode(dev);
    610 		spi_lock_down(plat, priv->base);
    611 	}
    612 
    613 	priv->cur_speed = priv->max_speed;
    614 
    615 	return 0;
    616 }
    617 
    618 static int ich_spi_remove(struct udevice *bus)
    619 {
    620 	/*
    621 	 * Configure SPI controller so that the Linux MTD driver can fully
    622 	 * access the SPI NOR chip
    623 	 */
    624 	ich_spi_config_opcode(bus);
    625 
    626 	return 0;
    627 }
    628 
    629 static int ich_spi_set_speed(struct udevice *bus, uint speed)
    630 {
    631 	struct ich_spi_priv *priv = dev_get_priv(bus);
    632 
    633 	priv->cur_speed = speed;
    634 
    635 	return 0;
    636 }
    637 
    638 static int ich_spi_set_mode(struct udevice *bus, uint mode)
    639 {
    640 	debug("%s: mode=%d\n", __func__, mode);
    641 
    642 	return 0;
    643 }
    644 
    645 static int ich_spi_child_pre_probe(struct udevice *dev)
    646 {
    647 	struct udevice *bus = dev_get_parent(dev);
    648 	struct ich_spi_platdata *plat = dev_get_platdata(bus);
    649 	struct ich_spi_priv *priv = dev_get_priv(bus);
    650 	struct spi_slave *slave = dev_get_parent_priv(dev);
    651 
    652 	/*
    653 	 * Yes this controller can only write a small number of bytes at
    654 	 * once! The limit is typically 64 bytes.
    655 	 */
    656 	slave->max_write_size = priv->databytes;
    657 	/*
    658 	 * ICH 7 SPI controller only supports array read command
    659 	 * and byte program command for SST flash
    660 	 */
    661 	if (plat->ich_version == ICHV_7)
    662 		slave->mode = SPI_RX_SLOW | SPI_TX_BYTE;
    663 
    664 	return 0;
    665 }
    666 
    667 static int ich_spi_ofdata_to_platdata(struct udevice *dev)
    668 {
    669 	struct ich_spi_platdata *plat = dev_get_platdata(dev);
    670 	int node = dev_of_offset(dev);
    671 	int ret;
    672 
    673 	ret = fdt_node_check_compatible(gd->fdt_blob, node, "intel,ich7-spi");
    674 	if (ret == 0) {
    675 		plat->ich_version = ICHV_7;
    676 	} else {
    677 		ret = fdt_node_check_compatible(gd->fdt_blob, node,
    678 						"intel,ich9-spi");
    679 		if (ret == 0)
    680 			plat->ich_version = ICHV_9;
    681 	}
    682 
    683 	plat->lockdown = fdtdec_get_bool(gd->fdt_blob, node,
    684 					 "intel,spi-lock-down");
    685 
    686 	return ret;
    687 }
    688 
    689 static const struct dm_spi_ops ich_spi_ops = {
    690 	.xfer		= ich_spi_xfer,
    691 	.set_speed	= ich_spi_set_speed,
    692 	.set_mode	= ich_spi_set_mode,
    693 	/*
    694 	 * cs_info is not needed, since we require all chip selects to be
    695 	 * in the device tree explicitly
    696 	 */
    697 };
    698 
    699 static const struct udevice_id ich_spi_ids[] = {
    700 	{ .compatible = "intel,ich7-spi" },
    701 	{ .compatible = "intel,ich9-spi" },
    702 	{ }
    703 };
    704 
    705 U_BOOT_DRIVER(ich_spi) = {
    706 	.name	= "ich_spi",
    707 	.id	= UCLASS_SPI,
    708 	.of_match = ich_spi_ids,
    709 	.ops	= &ich_spi_ops,
    710 	.ofdata_to_platdata = ich_spi_ofdata_to_platdata,
    711 	.platdata_auto_alloc_size = sizeof(struct ich_spi_platdata),
    712 	.priv_auto_alloc_size = sizeof(struct ich_spi_priv),
    713 	.child_pre_probe = ich_spi_child_pre_probe,
    714 	.probe	= ich_spi_probe,
    715 	.remove	= ich_spi_remove,
    716 	.flags	= DM_FLAG_OS_PREPARE,
    717 };
    718