Lines Matching +full:lock +full:- +full:pr

1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2011-12 The Chromium OS Authors.
30 u8 value = readb(priv->base + reg); in ich_readb()
39 u16 value = readw(priv->base + reg); in ich_readw()
48 u32 value = readl(priv->base + reg); in ich_readl()
57 writeb(value, priv->base + reg); in ich_writeb()
63 writew(value, priv->base + reg); in ich_writew()
69 writel(value, priv->base + reg); in ich_writel()
76 memcpy_toio(priv->base + dest_reg, value, size); in write_reg()
82 memcpy_fromio(value, priv->base + src_reg, size); in read_reg()
91 ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask; in ich_set_bbar()
93 ich_writel(ctlr, ichspi_bbar, ctlr->bbar); in ich_set_bbar()
102 dm_pci_write_config32(dev->parent, 0xb0, 0x1000); in ich9_can_do_33mhz()
105 dm_pci_read_config32(dev->parent, 0xb4, &fdod); in ich9_can_do_33mhz()
121 pch_get_spi_base(dev->parent, &sbase_addr); in ich_init_controller()
125 if (plat->ich_version == ICHV_7) { in ich_init_controller()
128 ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu); in ich_init_controller()
129 ctlr->menubytes = sizeof(ich7_spi->opmenu); in ich_init_controller()
130 ctlr->optype = offsetof(struct ich7_spi_regs, optype); in ich_init_controller()
131 ctlr->addr = offsetof(struct ich7_spi_regs, spia); in ich_init_controller()
132 ctlr->data = offsetof(struct ich7_spi_regs, spid); in ich_init_controller()
133 ctlr->databytes = sizeof(ich7_spi->spid); in ich_init_controller()
134 ctlr->status = offsetof(struct ich7_spi_regs, spis); in ich_init_controller()
135 ctlr->control = offsetof(struct ich7_spi_regs, spic); in ich_init_controller()
136 ctlr->bbar = offsetof(struct ich7_spi_regs, bbar); in ich_init_controller()
137 ctlr->preop = offsetof(struct ich7_spi_regs, preop); in ich_init_controller()
138 ctlr->base = ich7_spi; in ich_init_controller()
139 } else if (plat->ich_version == ICHV_9) { in ich_init_controller()
142 ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu); in ich_init_controller()
143 ctlr->menubytes = sizeof(ich9_spi->opmenu); in ich_init_controller()
144 ctlr->optype = offsetof(struct ich9_spi_regs, optype); in ich_init_controller()
145 ctlr->addr = offsetof(struct ich9_spi_regs, faddr); in ich_init_controller()
146 ctlr->data = offsetof(struct ich9_spi_regs, fdata); in ich_init_controller()
147 ctlr->databytes = sizeof(ich9_spi->fdata); in ich_init_controller()
148 ctlr->status = offsetof(struct ich9_spi_regs, ssfs); in ich_init_controller()
149 ctlr->control = offsetof(struct ich9_spi_regs, ssfc); in ich_init_controller()
150 ctlr->speed = ctlr->control + 2; in ich_init_controller()
151 ctlr->bbar = offsetof(struct ich9_spi_regs, bbar); in ich_init_controller()
152 ctlr->preop = offsetof(struct ich9_spi_regs, preop); in ich_init_controller()
153 ctlr->bcr = offsetof(struct ich9_spi_regs, bcr); in ich_init_controller()
154 ctlr->pr = &ich9_spi->pr[0]; in ich_init_controller()
155 ctlr->base = ich9_spi; in ich_init_controller()
158 plat->ich_version); in ich_init_controller()
159 return -EINVAL; in ich_init_controller()
163 ctlr->max_speed = 20000000; in ich_init_controller()
164 if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev)) in ich_init_controller()
165 ctlr->max_speed = 33000000; in ich_init_controller()
167 plat->ich_version, ctlr->base, ctlr->max_speed); in ich_init_controller()
176 trans->out += bytes; in spi_use_out()
177 trans->bytesout -= bytes; in spi_use_out()
182 trans->in += bytes; in spi_use_in()
183 trans->bytesin -= bytes; in spi_use_in()
188 if (plat->ich_version == ICHV_7) { in spi_lock_down()
191 setbits_le16(&ich7_spi->spis, SPIS_LOCK); in spi_lock_down()
192 } else if (plat->ich_version == ICHV_9) { in spi_lock_down()
195 setbits_le16(&ich9_spi->hsfs, HSFS_FLOCKDN); in spi_lock_down()
201 int lock = 0; in spi_lock_status() local
203 if (plat->ich_version == ICHV_7) { in spi_lock_status()
206 lock = readw(&ich7_spi->spis) & SPIS_LOCK; in spi_lock_status()
207 } else if (plat->ich_version == ICHV_9) { in spi_lock_status()
210 lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN; in spi_lock_status()
213 return lock != 0; in spi_lock_status()
218 trans->type = 0xFF; in spi_setup_type()
221 if (trans->bytesin == 0) { in spi_setup_type()
222 if (trans->bytesout + data_bytes > 4) in spi_setup_type()
228 trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; in spi_setup_type()
230 trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; in spi_setup_type()
234 if (trans->bytesout == 1) { /* and bytesin is > 0 */ in spi_setup_type()
235 trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; in spi_setup_type()
239 if (trans->bytesout == 4) /* and bytesin is > 0 */ in spi_setup_type()
240 trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; in spi_setup_type()
243 if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { in spi_setup_type()
244 trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; in spi_setup_type()
245 --trans->bytesout; in spi_setup_type()
250 bool lock) in spi_setup_opcode() argument
253 uint8_t opmenu[ctlr->menubytes]; in spi_setup_opcode()
255 trans->opcode = trans->out[0]; in spi_setup_opcode()
257 if (!lock) { in spi_setup_opcode()
258 /* The lock is off, so just use index 0. */ in spi_setup_opcode()
259 ich_writeb(ctlr, trans->opcode, ctlr->opmenu); in spi_setup_opcode()
260 optypes = ich_readw(ctlr, ctlr->optype); in spi_setup_opcode()
261 optypes = (optypes & 0xfffc) | (trans->type & 0x3); in spi_setup_opcode()
262 ich_writew(ctlr, optypes, ctlr->optype); in spi_setup_opcode()
265 /* The lock is on. See if what we need is on the menu. */ in spi_setup_opcode()
270 if (trans->opcode == SPI_OPCODE_WREN) in spi_setup_opcode()
273 read_reg(ctlr, ctlr->opmenu, opmenu, sizeof(opmenu)); in spi_setup_opcode()
274 for (opcode_index = 0; opcode_index < ctlr->menubytes; in spi_setup_opcode()
276 if (opmenu[opcode_index] == trans->opcode) in spi_setup_opcode()
280 if (opcode_index == ctlr->menubytes) { in spi_setup_opcode()
282 trans->opcode); in spi_setup_opcode()
283 return -EINVAL; in spi_setup_opcode()
286 optypes = ich_readw(ctlr, ctlr->optype); in spi_setup_opcode()
288 if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && in spi_setup_opcode()
290 trans->bytesout >= 3) { in spi_setup_opcode()
292 trans->type = optype; in spi_setup_opcode()
294 if (optype != trans->type) { in spi_setup_opcode()
297 return -ENOSPC; in spi_setup_opcode()
306 switch (trans->type) { in spi_setup_offset()
312 trans->offset = ((uint32_t)trans->out[0] << 16) | in spi_setup_offset()
313 ((uint32_t)trans->out[1] << 8) | in spi_setup_offset()
314 ((uint32_t)trans->out[2] << 0); in spi_setup_offset()
318 printf("Unrecognized SPI transaction type %#x\n", trans->type); in spi_setup_offset()
319 return -EPROTO; in spi_setup_offset()
325 * below is true) or 0. In case the wait was for the bit(s) to set - write
328 * Return the last read status value on success or -1 on failure.
336 while (timeout--) { in ich_status_poll()
337 status = ich_readw(ctlr, ctlr->status); in ich_status_poll()
341 ctlr->status); in ich_status_poll()
350 return -ETIMEDOUT; in ich_status_poll()
362 ich_writew(ctlr, SPI_OPPREFIX, ctlr->preop); in ich_spi_config_opcode()
363 ich_writew(ctlr, SPI_OPTYPE, ctlr->optype); in ich_spi_config_opcode()
364 ich_writel(ctlr, SPI_OPMENU_LOWER, ctlr->opmenu); in ich_spi_config_opcode()
365 ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32)); in ich_spi_config_opcode()
379 struct spi_trans *trans = &ctlr->trans; in ich_spi_xfer()
382 bool lock = spi_lock_status(plat, ctlr->base); in ich_spi_xfer() local
388 return -EPROTONOSUPPORT; in ich_spi_xfer()
402 return -ENOSPC; in ich_spi_xfer()
404 memcpy(trans->cmd, dout, bytes); in ich_spi_xfer()
405 trans->cmd_len = bytes; in ich_spi_xfer()
417 if (trans->cmd_len) { in ich_spi_xfer()
418 trans->out = trans->cmd; in ich_spi_xfer()
419 trans->bytesout = trans->cmd_len; in ich_spi_xfer()
421 debug_trace("ICH SPI: Using %d bytes\n", trans->cmd_len); in ich_spi_xfer()
423 trans->out = dout; in ich_spi_xfer()
424 trans->bytesout = dout ? bytes : 0; in ich_spi_xfer()
427 trans->in = din; in ich_spi_xfer()
428 trans->bytesin = din ? bytes : 0; in ich_spi_xfer()
431 if (!trans->bytesout) { in ich_spi_xfer()
433 return -EPROTO; in ich_spi_xfer()
440 if (plat->ich_version == ICHV_7) in ich_spi_xfer()
441 ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); in ich_spi_xfer()
443 ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); in ich_spi_xfer()
446 opcode_index = spi_setup_opcode(ctlr, trans, lock); in ich_spi_xfer()
448 return -EINVAL; in ich_spi_xfer()
451 return -EINVAL; in ich_spi_xfer()
453 if (trans->opcode == SPI_OPCODE_WREN) { in ich_spi_xfer()
455 * Treat Write Enable as Atomic Pre-Op if possible in ich_spi_xfer()
459 if (!lock) in ich_spi_xfer()
460 ich_writew(ctlr, trans->opcode, ctlr->preop); in ich_spi_xfer()
464 if (ctlr->speed && ctlr->max_speed >= 33000000) { in ich_spi_xfer()
467 byte = ich_readb(ctlr, ctlr->speed); in ich_spi_xfer()
468 if (ctlr->cur_speed >= 33000000) in ich_spi_xfer()
472 ich_writeb(ctlr, byte, ctlr->speed); in ich_spi_xfer()
477 trans->out = dout; in ich_spi_xfer()
478 trans->bytesout = bytes; in ich_spi_xfer()
486 if (ich_readw(ctlr, ctlr->preop)) in ich_spi_xfer()
489 if (!trans->bytesout && !trans->bytesin) { in ich_spi_xfer()
492 ich_writel(ctlr, trans->offset & 0x00FFFFFF, in ich_spi_xfer()
493 ctlr->addr); in ich_spi_xfer()
501 ich_writew(ctlr, control, ctlr->control); in ich_spi_xfer()
510 return -EIO; in ich_spi_xfer()
523 if (trans->bytesout > ctlr->databytes) { in ich_spi_xfer()
525 return -EPROTO; in ich_spi_xfer()
532 while (trans->bytesout || trans->bytesin) { in ich_spi_xfer()
536 ich_writel(ctlr, trans->offset & 0x00FFFFFF, ctlr->addr); in ich_spi_xfer()
538 if (trans->bytesout) in ich_spi_xfer()
539 data_length = min(trans->bytesout, ctlr->databytes); in ich_spi_xfer()
541 data_length = min(trans->bytesin, ctlr->databytes); in ich_spi_xfer()
544 if (trans->bytesout) { in ich_spi_xfer()
545 write_reg(ctlr, trans->out, ctlr->data, data_length); in ich_spi_xfer()
548 trans->offset += data_length; in ich_spi_xfer()
552 control &= ~((ctlr->databytes - 1) << 8); in ich_spi_xfer()
554 control |= (data_length - 1) << 8; in ich_spi_xfer()
557 ich_writew(ctlr, control, ctlr->control); in ich_spi_xfer()
566 return -EIO; in ich_spi_xfer()
569 if (trans->bytesin) { in ich_spi_xfer()
570 read_reg(ctlr, ctlr->data, trans->in, data_length); in ich_spi_xfer()
573 trans->offset += data_length; in ich_spi_xfer()
578 if (!lock) in ich_spi_xfer()
579 ich_writew(ctlr, 0, ctlr->preop); in ich_spi_xfer()
595 ret = pch_set_spi_protect(dev->parent, false); in ich_spi_probe()
596 if (ret == -ENOSYS) { in ich_spi_probe()
597 bios_cntl = ich_readb(priv, priv->bcr); in ich_spi_probe()
600 ich_writeb(priv, bios_cntl, priv->bcr); in ich_spi_probe()
602 debug("%s: Failed to disable write-protect: err=%d\n", in ich_spi_probe()
607 /* Lock down SPI controller settings if required */ in ich_spi_probe()
608 if (plat->lockdown) { in ich_spi_probe()
610 spi_lock_down(plat, priv->base); in ich_spi_probe()
613 priv->cur_speed = priv->max_speed; in ich_spi_probe()
633 priv->cur_speed = speed; in ich_spi_set_speed()
656 slave->max_write_size = priv->databytes; in ich_spi_child_pre_probe()
661 if (plat->ich_version == ICHV_7) in ich_spi_child_pre_probe()
662 slave->mode = SPI_RX_SLOW | SPI_TX_BYTE; in ich_spi_child_pre_probe()
673 ret = fdt_node_check_compatible(gd->fdt_blob, node, "intel,ich7-spi"); in ich_spi_ofdata_to_platdata()
675 plat->ich_version = ICHV_7; in ich_spi_ofdata_to_platdata()
677 ret = fdt_node_check_compatible(gd->fdt_blob, node, in ich_spi_ofdata_to_platdata()
678 "intel,ich9-spi"); in ich_spi_ofdata_to_platdata()
680 plat->ich_version = ICHV_9; in ich_spi_ofdata_to_platdata()
683 plat->lockdown = fdtdec_get_bool(gd->fdt_blob, node, in ich_spi_ofdata_to_platdata()
684 "intel,spi-lock-down"); in ich_spi_ofdata_to_platdata()
700 { .compatible = "intel,ich7-spi" },
701 { .compatible = "intel,ich9-spi" },