Lines Matching +full:mpfs +full:- +full:clock
1 // SPDX-License-Identifier: (GPL-2.0)
5 * Copyright (c) 2018-2022 Microchip Technology Inc. and its subsidiaries
108 u32 clk_gen; /* divider for spi output clock generated by the controller */
119 return readl(spi->regs + reg); in mchp_corespi_read()
124 writel(val, spi->regs + reg); in mchp_corespi_write()
138 …while (spi->rx_len >= spi->n_bytes && !(mchp_corespi_read(spi, REG_STATUS) & STATUS_RXFIFO_EMPTY))… in mchp_corespi_read_fifo()
141 spi->rx_len -= spi->n_bytes; in mchp_corespi_read_fifo()
143 if (!spi->rx_buf) in mchp_corespi_read_fifo()
146 if (spi->n_bytes == 4) in mchp_corespi_read_fifo()
147 *((u32 *)spi->rx_buf) = data; in mchp_corespi_read_fifo()
148 else if (spi->n_bytes == 2) in mchp_corespi_read_fifo()
149 *((u16 *)spi->rx_buf) = data; in mchp_corespi_read_fifo()
151 *spi->rx_buf = data; in mchp_corespi_read_fifo()
153 spi->rx_buf += spi->n_bytes; in mchp_corespi_read_fifo()
200 * would actually write zeros into the lower 16 bits on an mpfs250t-es, in mchp_corespi_set_xfer_size()
201 * despite documentation stating these bits were read-only. in mchp_corespi_set_xfer_size()
203 * on an mpfs250t-es and will be a NOP for the lower 16 bits on hardware in mchp_corespi_set_xfer_size()
218 fifo_max = DIV_ROUND_UP(min(spi->tx_len, FIFO_DEPTH), spi->n_bytes); in mchp_corespi_write_fifo()
224 if (spi->n_bytes == 4) in mchp_corespi_write_fifo()
225 word = spi->tx_buf ? *((u32 *)spi->tx_buf) : 0xaa; in mchp_corespi_write_fifo()
226 else if (spi->n_bytes == 2) in mchp_corespi_write_fifo()
227 word = spi->tx_buf ? *((u16 *)spi->tx_buf) : 0xaa; in mchp_corespi_write_fifo()
229 word = spi->tx_buf ? *spi->tx_buf : 0xaa; in mchp_corespi_write_fifo()
232 if (spi->tx_buf) in mchp_corespi_write_fifo()
233 spi->tx_buf += spi->n_bytes; in mchp_corespi_write_fifo()
237 spi->tx_len -= i * spi->n_bytes; in mchp_corespi_write_fifo()
265 struct mchp_corespi *corespi = spi_controller_get_devdata(spi->controller); in mchp_corespi_set_cs()
270 corespi->pending_slave_select = reg; in mchp_corespi_set_cs()
278 * doesn't see any spurious clock transitions whilst CS is enabled. in mchp_corespi_set_cs()
280 if (((spi->mode & SPI_CS_HIGH) == 0) == disable) in mchp_corespi_set_cs()
286 struct mchp_corespi *corespi = spi_controller_get_devdata(spi->controller); in mchp_corespi_setup()
297 if (spi->mode & SPI_CS_HIGH) { in mchp_corespi_setup()
300 corespi->pending_slave_select = reg; in mchp_corespi_setup()
332 /* max. possible spi clock rate is the apb clock rate */ in mchp_corespi_init()
333 clk_hz = clk_get_rate(spi->clk); in mchp_corespi_init()
334 host->max_speed_hz = clk_hz; in mchp_corespi_init()
343 spi->pending_slave_select = SSELOUT | SSEL_DIRECT; in mchp_corespi_init()
344 mchp_corespi_write(spi, REG_SLAVE_SELECT, spi->pending_slave_select); in mchp_corespi_init()
359 if (spi->clk_mode) in mchp_corespi_set_clk_gen()
364 mchp_corespi_write(spi, REG_CLK_GEN, spi->clk_gen); in mchp_corespi_set_clk_gen()
422 if (spi->rx_len) in mchp_corespi_interrupt()
426 if (!spi->rx_len && !spi->tx_len) in mchp_corespi_interrupt()
432 dev_err(&host->dev, in mchp_corespi_interrupt()
434 spi->rx_len, spi->tx_len); in mchp_corespi_interrupt()
440 dev_err(&host->dev, in mchp_corespi_interrupt()
442 spi->rx_len, spi->tx_len); in mchp_corespi_interrupt()
456 clk_hz = clk_get_rate(spi->clk); in mchp_corespi_calculate_clkgen()
458 return -EINVAL; in mchp_corespi_calculate_clkgen()
462 * There are two possible clock modes for the controller generated in mchp_corespi_calculate_clkgen()
463 * clock's division ratio: in mchp_corespi_calculate_clkgen()
469 * clk_gen is the register name for the clock divider on MPFS. in mchp_corespi_calculate_clkgen()
471 clk_gen = DIV_ROUND_UP(clk_hz, 2 * spi_hz) - 1; in mchp_corespi_calculate_clkgen()
474 clk_gen = fls(clk_gen) - 1; in mchp_corespi_calculate_clkgen()
477 return -EINVAL; in mchp_corespi_calculate_clkgen()
479 spi->clk_mode = 0; in mchp_corespi_calculate_clkgen()
481 spi->clk_mode = 1; in mchp_corespi_calculate_clkgen()
484 spi->clk_gen = clk_gen; in mchp_corespi_calculate_clkgen()
495 ret = mchp_corespi_calculate_clkgen(spi, (unsigned long)xfer->speed_hz); in mchp_corespi_transfer_one()
497 dev_err(&host->dev, "failed to set clk_gen for target %u Hz\n", xfer->speed_hz); in mchp_corespi_transfer_one()
503 spi->tx_buf = xfer->tx_buf; in mchp_corespi_transfer_one()
504 spi->rx_buf = xfer->rx_buf; in mchp_corespi_transfer_one()
505 spi->tx_len = xfer->len; in mchp_corespi_transfer_one()
506 spi->rx_len = xfer->len; in mchp_corespi_transfer_one()
507 spi->n_bytes = roundup_pow_of_two(DIV_ROUND_UP(xfer->bits_per_word, BITS_PER_BYTE)); in mchp_corespi_transfer_one()
509 mchp_corespi_set_framesize(spi, xfer->bits_per_word); in mchp_corespi_transfer_one()
513 mchp_corespi_write(spi, REG_SLAVE_SELECT, spi->pending_slave_select); in mchp_corespi_transfer_one()
515 while (spi->tx_len) in mchp_corespi_transfer_one()
524 struct spi_device *spi_dev = msg->spi; in mchp_corespi_prepare_message()
527 mchp_corespi_set_mode(spi, spi_dev->mode); in mchp_corespi_prepare_message()
540 host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi)); in mchp_corespi_probe()
542 return dev_err_probe(&pdev->dev, -ENOMEM, in mchp_corespi_probe()
547 if (of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs)) in mchp_corespi_probe()
550 host->num_chipselect = num_cs; in mchp_corespi_probe()
551 host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in mchp_corespi_probe()
552 host->use_gpio_descriptors = true; in mchp_corespi_probe()
553 host->setup = mchp_corespi_setup; in mchp_corespi_probe()
554 host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); in mchp_corespi_probe()
555 host->transfer_one = mchp_corespi_transfer_one; in mchp_corespi_probe()
556 host->prepare_message = mchp_corespi_prepare_message; in mchp_corespi_probe()
557 host->set_cs = mchp_corespi_set_cs; in mchp_corespi_probe()
558 host->dev.of_node = pdev->dev.of_node; in mchp_corespi_probe()
562 spi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in mchp_corespi_probe()
563 if (IS_ERR(spi->regs)) in mchp_corespi_probe()
564 return PTR_ERR(spi->regs); in mchp_corespi_probe()
566 spi->irq = platform_get_irq(pdev, 0); in mchp_corespi_probe()
567 if (spi->irq < 0) in mchp_corespi_probe()
568 return spi->irq; in mchp_corespi_probe()
570 ret = devm_request_irq(&pdev->dev, spi->irq, mchp_corespi_interrupt, in mchp_corespi_probe()
571 IRQF_SHARED, dev_name(&pdev->dev), host); in mchp_corespi_probe()
573 return dev_err_probe(&pdev->dev, ret, in mchp_corespi_probe()
576 spi->clk = devm_clk_get_enabled(&pdev->dev, NULL); in mchp_corespi_probe()
577 if (IS_ERR(spi->clk)) in mchp_corespi_probe()
578 return dev_err_probe(&pdev->dev, PTR_ERR(spi->clk), in mchp_corespi_probe()
583 ret = devm_spi_register_controller(&pdev->dev, host); in mchp_corespi_probe()
586 return dev_err_probe(&pdev->dev, ret, in mchp_corespi_probe()
590 dev_info(&pdev->dev, "Registered SPI controller %d\n", host->bus_num); in mchp_corespi_probe()
612 { .compatible = "microchip,mpfs-spi" },
621 .name = "microchip-corespi",