• Home
  • Raw
  • Download

Lines Matching +full:master +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-or-later
10 * CPM SPI and QE buffer descriptors mode support:
19 #include <linux/dma-mapping.h>
45 #include "spi-fsl-lib.h"
46 #include "spi-fsl-cpm.h"
47 #include "spi-fsl-spi.h"
81 if (dev->of_node) { in fsl_spi_get_type()
82 match = of_match_node(of_fsl_spi_match, dev->of_node); in fsl_spi_get_type()
83 if (match && match->data) in fsl_spi_get_type()
84 return ((struct fsl_spi_match_data *)match->data)->type; in fsl_spi_get_type()
91 struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); in fsl_spi_change_mode()
92 struct spi_mpc8xxx_cs *cs = spi->controller_state; in fsl_spi_change_mode()
93 struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; in fsl_spi_change_mode()
94 __be32 __iomem *mode = &reg_base->mode; in fsl_spi_change_mode() local
97 if (cs->hw_mode == mpc8xxx_spi_read_reg(mode)) in fsl_spi_change_mode()
103 /* Turn off SPI unit prior changing mode */ in fsl_spi_change_mode()
104 mpc8xxx_spi_write_reg(mode, cs->hw_mode & ~SPMODE_ENABLE); in fsl_spi_change_mode()
106 /* When in CPM mode, we need to reinit tx and rx. */ in fsl_spi_change_mode()
107 if (mspi->flags & SPI_CPM_MODE) { in fsl_spi_change_mode()
110 mpc8xxx_spi_write_reg(mode, cs->hw_mode); in fsl_spi_change_mode()
116 struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); in fsl_spi_chipselect()
118 struct spi_mpc8xxx_cs *cs = spi->controller_state; in fsl_spi_chipselect()
120 pdata = spi->dev.parent->parent->platform_data; in fsl_spi_chipselect()
123 if (pdata->cs_control) in fsl_spi_chipselect()
124 pdata->cs_control(spi, false); in fsl_spi_chipselect()
128 mpc8xxx_spi->rx_shift = cs->rx_shift; in fsl_spi_chipselect()
129 mpc8xxx_spi->tx_shift = cs->tx_shift; in fsl_spi_chipselect()
130 mpc8xxx_spi->get_rx = cs->get_rx; in fsl_spi_chipselect()
131 mpc8xxx_spi->get_tx = cs->get_tx; in fsl_spi_chipselect()
135 if (pdata->cs_control) in fsl_spi_chipselect()
136 pdata->cs_control(spi, true); in fsl_spi_chipselect()
167 *tx_shift = 32 - bits_per_word; /* MSB in bit 31 */ in fsl_spi_grlib_set_shifts()
169 *rx_shift = 16 - bits_per_word; /* MSB in bit 15 */ in fsl_spi_grlib_set_shifts()
179 cs->rx_shift = 0; in mspi_apply_cpu_mode_quirks()
180 cs->tx_shift = 0; in mspi_apply_cpu_mode_quirks()
182 cs->get_rx = mpc8xxx_spi_rx_buf_u8; in mspi_apply_cpu_mode_quirks()
183 cs->get_tx = mpc8xxx_spi_tx_buf_u8; in mspi_apply_cpu_mode_quirks()
185 cs->get_rx = mpc8xxx_spi_rx_buf_u16; in mspi_apply_cpu_mode_quirks()
186 cs->get_tx = mpc8xxx_spi_tx_buf_u16; in mspi_apply_cpu_mode_quirks()
188 cs->get_rx = mpc8xxx_spi_rx_buf_u32; in mspi_apply_cpu_mode_quirks()
189 cs->get_tx = mpc8xxx_spi_tx_buf_u32; in mspi_apply_cpu_mode_quirks()
191 return -EINVAL; in mspi_apply_cpu_mode_quirks()
193 if (mpc8xxx_spi->set_shifts) in mspi_apply_cpu_mode_quirks()
194 mpc8xxx_spi->set_shifts(&cs->rx_shift, &cs->tx_shift, in mspi_apply_cpu_mode_quirks()
196 !(spi->mode & SPI_LSB_FIRST)); in mspi_apply_cpu_mode_quirks()
198 mpc8xxx_spi->rx_shift = cs->rx_shift; in mspi_apply_cpu_mode_quirks()
199 mpc8xxx_spi->tx_shift = cs->tx_shift; in mspi_apply_cpu_mode_quirks()
200 mpc8xxx_spi->get_rx = cs->get_rx; in mspi_apply_cpu_mode_quirks()
201 mpc8xxx_spi->get_tx = cs->get_tx; in mspi_apply_cpu_mode_quirks()
213 struct spi_mpc8xxx_cs *cs = spi->controller_state; in fsl_spi_setup_transfer()
215 mpc8xxx_spi = spi_master_get_devdata(spi->master); in fsl_spi_setup_transfer()
218 bits_per_word = t->bits_per_word; in fsl_spi_setup_transfer()
219 hz = t->speed_hz; in fsl_spi_setup_transfer()
222 /* spi_transfer level calls that work per-word */ in fsl_spi_setup_transfer()
224 bits_per_word = spi->bits_per_word; in fsl_spi_setup_transfer()
227 hz = spi->max_speed_hz; in fsl_spi_setup_transfer()
229 if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) in fsl_spi_setup_transfer()
240 bits_per_word = bits_per_word - 1; in fsl_spi_setup_transfer()
243 cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16 in fsl_spi_setup_transfer()
246 cs->hw_mode |= SPMODE_LEN(bits_per_word); in fsl_spi_setup_transfer()
248 if ((mpc8xxx_spi->spibrg / hz) > 64) { in fsl_spi_setup_transfer()
249 cs->hw_mode |= SPMODE_DIV16; in fsl_spi_setup_transfer()
250 pm = (mpc8xxx_spi->spibrg - 1) / (hz * 64) + 1; in fsl_spi_setup_transfer()
253 dev_name(&spi->dev), hz, mpc8xxx_spi->spibrg / 1024); in fsl_spi_setup_transfer()
257 pm = (mpc8xxx_spi->spibrg - 1) / (hz * 4) + 1; in fsl_spi_setup_transfer()
260 pm--; in fsl_spi_setup_transfer()
262 cs->hw_mode |= SPMODE_PM(pm); in fsl_spi_setup_transfer()
272 struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; in fsl_spi_cpu_bufs()
274 mspi->count = len; in fsl_spi_cpu_bufs()
277 mpc8xxx_spi_write_reg(&reg_base->mask, SPIM_NE); in fsl_spi_cpu_bufs()
280 word = mspi->get_tx(mspi); in fsl_spi_cpu_bufs()
281 mpc8xxx_spi_write_reg(&reg_base->transmit, word); in fsl_spi_cpu_bufs()
289 struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); in fsl_spi_bufs()
291 unsigned int len = t->len; in fsl_spi_bufs()
295 reg_base = mpc8xxx_spi->reg_base; in fsl_spi_bufs()
296 bits_per_word = spi->bits_per_word; in fsl_spi_bufs()
297 if (t->bits_per_word) in fsl_spi_bufs()
298 bits_per_word = t->bits_per_word; in fsl_spi_bufs()
303 return -EINVAL; in fsl_spi_bufs()
309 return -EINVAL; in fsl_spi_bufs()
313 mpc8xxx_spi->tx = t->tx_buf; in fsl_spi_bufs()
314 mpc8xxx_spi->rx = t->rx_buf; in fsl_spi_bufs()
316 reinit_completion(&mpc8xxx_spi->done); in fsl_spi_bufs()
318 if (mpc8xxx_spi->flags & SPI_CPM_MODE) in fsl_spi_bufs()
325 wait_for_completion(&mpc8xxx_spi->done); in fsl_spi_bufs()
328 mpc8xxx_spi_write_reg(&reg_base->mask, 0); in fsl_spi_bufs()
330 if (mpc8xxx_spi->flags & SPI_CPM_MODE) in fsl_spi_bufs()
333 return mpc8xxx_spi->count; in fsl_spi_bufs()
336 static int fsl_spi_do_one_msg(struct spi_master *master, in fsl_spi_do_one_msg() argument
339 struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); in fsl_spi_do_one_msg()
340 struct spi_device *spi = m->spi; in fsl_spi_do_one_msg()
347 * In CPU mode, optimize large byte transfers to use larger in fsl_spi_do_one_msg()
350 list_for_each_entry(t, &m->transfers, transfer_list) { in fsl_spi_do_one_msg()
351 if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) { in fsl_spi_do_one_msg()
352 if (t->len < 256 || t->bits_per_word != 8) in fsl_spi_do_one_msg()
354 if ((t->len & 3) == 0) in fsl_spi_do_one_msg()
355 t->bits_per_word = 32; in fsl_spi_do_one_msg()
356 else if ((t->len & 1) == 0) in fsl_spi_do_one_msg()
357 t->bits_per_word = 16; in fsl_spi_do_one_msg()
367 if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8) in fsl_spi_do_one_msg()
368 return -EINVAL; in fsl_spi_do_one_msg()
369 if (t->bits_per_word == 16 || t->bits_per_word == 32) in fsl_spi_do_one_msg()
370 t->bits_per_word = 8; /* pretend its 8 bits */ in fsl_spi_do_one_msg()
371 if (t->bits_per_word == 8 && t->len >= 256 && in fsl_spi_do_one_msg()
372 (mpc8xxx_spi->flags & SPI_CPM1)) in fsl_spi_do_one_msg()
373 t->bits_per_word = 16; in fsl_spi_do_one_msg()
379 list_for_each_entry(t, &m->transfers, transfer_list) { in fsl_spi_do_one_msg()
382 cs_change = t->cs_change; in fsl_spi_do_one_msg()
383 if (first->speed_hz != t->speed_hz) { in fsl_spi_do_one_msg()
384 dev_err(&spi->dev, in fsl_spi_do_one_msg()
386 return -EINVAL; in fsl_spi_do_one_msg()
390 last_bpw = -1; in fsl_spi_do_one_msg()
392 status = -EINVAL; in fsl_spi_do_one_msg()
393 list_for_each_entry(t, &m->transfers, transfer_list) { in fsl_spi_do_one_msg()
394 if (cs_change || last_bpw != t->bits_per_word) in fsl_spi_do_one_msg()
398 last_bpw = t->bits_per_word; in fsl_spi_do_one_msg()
404 cs_change = t->cs_change; in fsl_spi_do_one_msg()
405 if (t->len) in fsl_spi_do_one_msg()
406 status = fsl_spi_bufs(spi, t, m->is_dma_mapped); in fsl_spi_do_one_msg()
408 status = -EMSGSIZE; in fsl_spi_do_one_msg()
411 m->actual_length += t->len; in fsl_spi_do_one_msg()
422 m->status = status; in fsl_spi_do_one_msg()
430 spi_finalize_current_message(master); in fsl_spi_do_one_msg()
443 if (!spi->max_speed_hz) in fsl_spi_setup()
444 return -EINVAL; in fsl_spi_setup()
449 return -ENOMEM; in fsl_spi_setup()
453 mpc8xxx_spi = spi_master_get_devdata(spi->master); in fsl_spi_setup()
455 reg_base = mpc8xxx_spi->reg_base; in fsl_spi_setup()
457 hw_mode = cs->hw_mode; /* Save original settings */ in fsl_spi_setup()
458 cs->hw_mode = mpc8xxx_spi_read_reg(&reg_base->mode); in fsl_spi_setup()
460 cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH in fsl_spi_setup()
463 if (spi->mode & SPI_CPHA) in fsl_spi_setup()
464 cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK; in fsl_spi_setup()
465 if (spi->mode & SPI_CPOL) in fsl_spi_setup()
466 cs->hw_mode |= SPMODE_CI_INACTIVEHIGH; in fsl_spi_setup()
467 if (!(spi->mode & SPI_LSB_FIRST)) in fsl_spi_setup()
468 cs->hw_mode |= SPMODE_REV; in fsl_spi_setup()
469 if (spi->mode & SPI_LOOP) in fsl_spi_setup()
470 cs->hw_mode |= SPMODE_LOOP; in fsl_spi_setup()
474 cs->hw_mode = hw_mode; /* Restore settings */ in fsl_spi_setup()
480 /* Initialize chipselect - might be active for SPI_CS_HIGH mode */ in fsl_spi_setup()
496 struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; in fsl_spi_cpu_irq()
500 u32 rx_data = mpc8xxx_spi_read_reg(&reg_base->receive); in fsl_spi_cpu_irq()
502 if (mspi->rx) in fsl_spi_cpu_irq()
503 mspi->get_rx(rx_data, mspi); in fsl_spi_cpu_irq()
509 mpc8xxx_spi_read_reg(&reg_base->event)) & in fsl_spi_cpu_irq()
514 mpc8xxx_spi_write_reg(&reg_base->event, events); in fsl_spi_cpu_irq()
516 mspi->count -= 1; in fsl_spi_cpu_irq()
517 if (mspi->count) { in fsl_spi_cpu_irq()
518 u32 word = mspi->get_tx(mspi); in fsl_spi_cpu_irq()
520 mpc8xxx_spi_write_reg(&reg_base->transmit, word); in fsl_spi_cpu_irq()
522 complete(&mspi->done); in fsl_spi_cpu_irq()
531 struct fsl_spi_reg __iomem *reg_base = mspi->reg_base; in fsl_spi_irq()
534 events = mpc8xxx_spi_read_reg(&reg_base->event); in fsl_spi_irq()
538 dev_dbg(mspi->dev, "%s: events %x\n", __func__, events); in fsl_spi_irq()
540 if (mspi->flags & SPI_CPM_MODE) in fsl_spi_irq()
550 struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); in fsl_spi_grlib_cs_control()
551 struct fsl_spi_reg __iomem *reg_base = mpc8xxx_spi->reg_base; in fsl_spi_grlib_cs_control()
553 u16 cs = spi->chip_select; in fsl_spi_grlib_cs_control()
555 if (spi->cs_gpiod) { in fsl_spi_grlib_cs_control()
556 gpiod_set_value(spi->cs_gpiod, on); in fsl_spi_grlib_cs_control()
557 } else if (cs < mpc8xxx_spi->native_chipselects) { in fsl_spi_grlib_cs_control()
558 slvsel = mpc8xxx_spi_read_reg(&reg_base->slvsel); in fsl_spi_grlib_cs_control()
560 mpc8xxx_spi_write_reg(&reg_base->slvsel, slvsel); in fsl_spi_grlib_cs_control()
567 struct spi_master *master = dev_get_drvdata(dev); in fsl_spi_grlib_probe() local
568 struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); in fsl_spi_grlib_probe()
569 struct fsl_spi_reg __iomem *reg_base = mpc8xxx_spi->reg_base; in fsl_spi_grlib_probe()
573 capabilities = mpc8xxx_spi_read_reg(&reg_base->cap); in fsl_spi_grlib_probe()
575 mpc8xxx_spi->set_shifts = fsl_spi_grlib_set_shifts; in fsl_spi_grlib_probe()
578 mpc8xxx_spi->max_bits_per_word = mbits + 1; in fsl_spi_grlib_probe()
580 mpc8xxx_spi->native_chipselects = 0; in fsl_spi_grlib_probe()
582 mpc8xxx_spi->native_chipselects = SPCAP_SSSZ(capabilities); in fsl_spi_grlib_probe()
583 mpc8xxx_spi_write_reg(&reg_base->slvsel, 0xffffffff); in fsl_spi_grlib_probe()
585 master->num_chipselect = mpc8xxx_spi->native_chipselects; in fsl_spi_grlib_probe()
586 pdata->cs_control = fsl_spi_grlib_cs_control; in fsl_spi_grlib_probe()
593 struct spi_master *master; in fsl_spi_probe() local
599 master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); in fsl_spi_probe()
600 if (master == NULL) { in fsl_spi_probe()
601 ret = -ENOMEM; in fsl_spi_probe()
605 dev_set_drvdata(dev, master); in fsl_spi_probe()
609 master->setup = fsl_spi_setup; in fsl_spi_probe()
610 master->cleanup = fsl_spi_cleanup; in fsl_spi_probe()
611 master->transfer_one_message = fsl_spi_do_one_msg; in fsl_spi_probe()
612 master->use_gpio_descriptors = true; in fsl_spi_probe()
614 mpc8xxx_spi = spi_master_get_devdata(master); in fsl_spi_probe()
615 mpc8xxx_spi->max_bits_per_word = 32; in fsl_spi_probe()
616 mpc8xxx_spi->type = fsl_spi_get_type(dev); in fsl_spi_probe()
622 mpc8xxx_spi->reg_base = devm_ioremap_resource(dev, mem); in fsl_spi_probe()
623 if (IS_ERR(mpc8xxx_spi->reg_base)) { in fsl_spi_probe()
624 ret = PTR_ERR(mpc8xxx_spi->reg_base); in fsl_spi_probe()
628 if (mpc8xxx_spi->type == TYPE_GRLIB) in fsl_spi_probe()
631 if (mpc8xxx_spi->flags & SPI_CPM_MODE) in fsl_spi_probe()
632 master->bits_per_word_mask = in fsl_spi_probe()
635 master->bits_per_word_mask = in fsl_spi_probe()
638 master->bits_per_word_mask &= in fsl_spi_probe()
639 SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word); in fsl_spi_probe()
641 if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) in fsl_spi_probe()
642 mpc8xxx_spi->set_shifts = fsl_spi_qe_cpu_set_shifts; in fsl_spi_probe()
644 if (mpc8xxx_spi->set_shifts) in fsl_spi_probe()
646 mpc8xxx_spi->set_shifts(&mpc8xxx_spi->rx_shift, in fsl_spi_probe()
647 &mpc8xxx_spi->tx_shift, 8, 1); in fsl_spi_probe()
650 ret = devm_request_irq(dev, mpc8xxx_spi->irq, fsl_spi_irq, in fsl_spi_probe()
656 reg_base = mpc8xxx_spi->reg_base; in fsl_spi_probe()
659 mpc8xxx_spi_write_reg(&reg_base->mode, 0); in fsl_spi_probe()
660 mpc8xxx_spi_write_reg(&reg_base->mask, 0); in fsl_spi_probe()
661 mpc8xxx_spi_write_reg(&reg_base->command, 0); in fsl_spi_probe()
662 mpc8xxx_spi_write_reg(&reg_base->event, 0xffffffff); in fsl_spi_probe()
665 regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; in fsl_spi_probe()
666 if (mpc8xxx_spi->max_bits_per_word < 8) { in fsl_spi_probe()
668 regval |= SPMODE_LEN(mpc8xxx_spi->max_bits_per_word - 1); in fsl_spi_probe()
670 if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) in fsl_spi_probe()
673 mpc8xxx_spi_write_reg(&reg_base->mode, regval); in fsl_spi_probe()
675 ret = devm_spi_register_master(dev, master); in fsl_spi_probe()
679 dev_info(dev, "at 0x%p (irq = %d), %s mode\n", reg_base, in fsl_spi_probe()
680 mpc8xxx_spi->irq, mpc8xxx_spi_strmode(mpc8xxx_spi->flags)); in fsl_spi_probe()
682 return master; in fsl_spi_probe()
687 spi_master_put(master); in fsl_spi_probe()
694 if (spi->cs_gpiod) { in fsl_spi_cs_control()
695 gpiod_set_value(spi->cs_gpiod, on); in fsl_spi_cs_control()
697 struct device *dev = spi->dev.parent->parent; in fsl_spi_cs_control()
701 if (WARN_ON_ONCE(!pinfo->immr_spi_cs)) in fsl_spi_cs_control()
703 iowrite32be(on ? 0 : SPI_BOOT_SEL_BIT, pinfo->immr_spi_cs); in fsl_spi_cs_control()
709 struct device *dev = &ofdev->dev; in of_fsl_spi_probe()
710 struct device_node *np = ofdev->dev.of_node; in of_fsl_spi_probe()
711 struct spi_master *master; in of_fsl_spi_probe() local
725 type = fsl_spi_get_type(&ofdev->dev); in of_fsl_spi_probe()
733 pinfo->immr_spi_cs = ioremap(get_immrbase() + IMMR_SPI_CS_OFFSET, 4); in of_fsl_spi_probe()
734 if (!pinfo->immr_spi_cs) in of_fsl_spi_probe()
735 return -ENOMEM; in of_fsl_spi_probe()
749 pdata->max_chipselect = 1; in of_fsl_spi_probe()
751 pdata->max_chipselect = ret + spisel_boot; in of_fsl_spi_probe()
752 pdata->cs_control = fsl_spi_cs_control; in of_fsl_spi_probe()
766 master = fsl_spi_probe(dev, &mem, irq); in of_fsl_spi_probe()
768 return PTR_ERR_OR_ZERO(master); in of_fsl_spi_probe()
773 iounmap(pinfo->immr_spi_cs); in of_fsl_spi_probe()
780 struct spi_master *master = platform_get_drvdata(ofdev); in of_fsl_spi_remove() local
781 struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); in of_fsl_spi_remove()
799 * This is "legacy" platform driver, was used by the MPC8323E-RDB boards
800 * only. The driver should go away soon, since newer MPC8323E-RDB's device
808 struct spi_master *master; in plat_mpc8xxx_spi_probe() local
810 if (!dev_get_platdata(&pdev->dev)) in plat_mpc8xxx_spi_probe()
811 return -EINVAL; in plat_mpc8xxx_spi_probe()
815 return -EINVAL; in plat_mpc8xxx_spi_probe()
819 return -EINVAL; in plat_mpc8xxx_spi_probe()
821 master = fsl_spi_probe(&pdev->dev, mem, irq); in plat_mpc8xxx_spi_probe()
822 return PTR_ERR_OR_ZERO(master); in plat_mpc8xxx_spi_probe()
827 struct spi_master *master = platform_get_drvdata(pdev); in plat_mpc8xxx_spi_remove() local
828 struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); in plat_mpc8xxx_spi_remove()