Lines Matching +full:host +full:- +full:to +full:- +full:chip

1 // SPDX-License-Identifier: GPL-2.0-only
8 // This code is based on spi-dw-core.c.
120 u8 div_post; /* value from 0 to 255 */
121 u8 div_pre; /* value from 2 to 254 (even only!) */
165 struct spi_controller *host; in hisi_spi_debugfs_init() local
167 host = container_of(hs->dev, struct spi_controller, dev); in hisi_spi_debugfs_init()
168 snprintf(name, 32, "hisi_spi%d", host->bus_num); in hisi_spi_debugfs_init()
169 hs->debugfs = debugfs_create_dir(name, NULL); in hisi_spi_debugfs_init()
170 if (IS_ERR(hs->debugfs)) in hisi_spi_debugfs_init()
171 return -ENOMEM; in hisi_spi_debugfs_init()
173 hs->regset.regs = hisi_spi_regs; in hisi_spi_debugfs_init()
174 hs->regset.nregs = ARRAY_SIZE(hisi_spi_regs); in hisi_spi_debugfs_init()
175 hs->regset.base = hs->regs; in hisi_spi_debugfs_init()
176 debugfs_create_regset32("registers", 0400, hs->debugfs, &hs->regset); in hisi_spi_debugfs_init()
183 return readl(hs->regs + HISI_SPI_SR) & SR_BUSY; in hisi_spi_busy()
188 return readl(hs->regs + HISI_SPI_SR) & SR_RXNE; in hisi_spi_rx_not_empty()
193 return readl(hs->regs + HISI_SPI_SR) & SR_TXNF; in hisi_spi_tx_not_full()
202 readl(hs->regs + HISI_SPI_DOUT); in hisi_spi_flush_fifo()
203 } while (hisi_spi_busy(hs) && limit--); in hisi_spi_flush_fifo()
209 writel(0, hs->regs + HISI_SPI_ENR); in hisi_spi_disable()
210 writel(IMR_MASK, hs->regs + HISI_SPI_IMR); in hisi_spi_disable()
211 writel(ICR_MASK, hs->regs + HISI_SPI_ICR); in hisi_spi_disable()
216 if (transfer->bits_per_word <= 8) in hisi_spi_n_bytes()
218 else if (transfer->bits_per_word <= 16) in hisi_spi_n_bytes()
226 u32 max = min_t(u32, hs->rx_len, hs->fifo_len); in hisi_spi_reader()
229 while (hisi_spi_rx_not_empty(hs) && max--) { in hisi_spi_reader()
230 rxw = readl(hs->regs + HISI_SPI_DOUT); in hisi_spi_reader()
232 if (hs->rx) { in hisi_spi_reader()
233 switch (hs->n_bytes) { in hisi_spi_reader()
235 *(u8 *)(hs->rx) = rxw; in hisi_spi_reader()
238 *(u16 *)(hs->rx) = rxw; in hisi_spi_reader()
241 *(u32 *)(hs->rx) = rxw; in hisi_spi_reader()
244 hs->rx += hs->n_bytes; in hisi_spi_reader()
246 --hs->rx_len; in hisi_spi_reader()
252 u32 max = min_t(u32, hs->tx_len, hs->fifo_len); in hisi_spi_writer()
255 while (hisi_spi_tx_not_full(hs) && max--) { in hisi_spi_writer()
257 if (hs->tx) { in hisi_spi_writer()
258 switch (hs->n_bytes) { in hisi_spi_writer()
260 txw = *(u8 *)(hs->tx); in hisi_spi_writer()
263 txw = *(u16 *)(hs->tx); in hisi_spi_writer()
266 txw = *(u32 *)(hs->tx); in hisi_spi_writer()
269 hs->tx += hs->n_bytes; in hisi_spi_writer()
271 writel(txw, hs->regs + HISI_SPI_DIN); in hisi_spi_writer()
272 --hs->tx_len; in hisi_spi_writer()
276 static void __hisi_calc_div_reg(struct hisi_chip_data *chip) in __hisi_calc_div_reg() argument
278 chip->div_pre = DIV_PRE_MAX; in __hisi_calc_div_reg()
279 while (chip->div_pre >= DIV_PRE_MIN) { in __hisi_calc_div_reg()
280 if (chip->clk_div % chip->div_pre == 0) in __hisi_calc_div_reg()
283 chip->div_pre -= 2; in __hisi_calc_div_reg()
286 if (chip->div_pre > chip->clk_div) in __hisi_calc_div_reg()
287 chip->div_pre = chip->clk_div; in __hisi_calc_div_reg()
289 chip->div_post = (chip->clk_div / chip->div_pre) - 1; in __hisi_calc_div_reg()
292 static u32 hisi_calc_effective_speed(struct spi_controller *host, in hisi_calc_effective_speed() argument
293 struct hisi_chip_data *chip, u32 speed_hz) in hisi_calc_effective_speed() argument
298 chip->clk_div = DIV_ROUND_UP(host->max_speed_hz, speed_hz) + 1; in hisi_calc_effective_speed()
299 chip->clk_div &= 0xfffe; in hisi_calc_effective_speed()
300 if (chip->clk_div > CLK_DIV_MAX) in hisi_calc_effective_speed()
301 chip->clk_div = CLK_DIV_MAX; in hisi_calc_effective_speed()
303 effective_speed = host->max_speed_hz / chip->clk_div; in hisi_calc_effective_speed()
304 if (chip->speed_hz != effective_speed) { in hisi_calc_effective_speed()
305 __hisi_calc_div_reg(chip); in hisi_calc_effective_speed()
306 chip->speed_hz = effective_speed; in hisi_calc_effective_speed()
316 cr |= FIELD_PREP(CR_CPHA_MASK, (spi->mode & SPI_CPHA) ? 1 : 0); in hisi_spi_prepare_cr()
317 cr |= FIELD_PREP(CR_CPOL_MASK, (spi->mode & SPI_CPOL) ? 1 : 0); in hisi_spi_prepare_cr()
318 cr |= FIELD_PREP(CR_LOOP_MASK, (spi->mode & SPI_LOOP) ? 1 : 0); in hisi_spi_prepare_cr()
330 hs->regs + HISI_SPI_FIFOC); in hisi_spi_hw_init()
332 hs->fifo_len = 256; in hisi_spi_hw_init()
337 struct spi_controller *host = dev_id; in hisi_spi_irq() local
338 struct hisi_spi *hs = spi_controller_get_devdata(host); in hisi_spi_irq()
339 u32 irq_status = readl(hs->regs + HISI_SPI_ISR) & ISR_MASK; in hisi_spi_irq()
344 if (!host->cur_msg) in hisi_spi_irq()
349 dev_err(hs->dev, "interrupt_transfer: fifo overflow\n"); in hisi_spi_irq()
350 host->cur_msg->status = -EIO; in hisi_spi_irq()
356 * nothing left to receive, finalize the transfer. in hisi_spi_irq()
359 if (!hs->rx_len) in hisi_spi_irq()
370 spi_finalize_current_transfer(host); in hisi_spi_irq()
374 static int hisi_spi_transfer_one(struct spi_controller *host, in hisi_spi_transfer_one() argument
377 struct hisi_spi *hs = spi_controller_get_devdata(host); in hisi_spi_transfer_one()
378 struct hisi_chip_data *chip = spi_get_ctldata(spi); in hisi_spi_transfer_one() local
379 u32 cr = chip->cr; in hisi_spi_transfer_one()
382 transfer->effective_speed_hz = in hisi_spi_transfer_one()
383 hisi_calc_effective_speed(host, chip, transfer->speed_hz); in hisi_spi_transfer_one()
384 cr |= FIELD_PREP(CR_DIV_PRE_MASK, chip->div_pre); in hisi_spi_transfer_one()
385 cr |= FIELD_PREP(CR_DIV_POST_MASK, chip->div_post); in hisi_spi_transfer_one()
386 cr |= FIELD_PREP(CR_BPW_MASK, transfer->bits_per_word - 1); in hisi_spi_transfer_one()
387 writel(cr, hs->regs + HISI_SPI_CR); in hisi_spi_transfer_one()
391 hs->n_bytes = hisi_spi_n_bytes(transfer); in hisi_spi_transfer_one()
392 hs->tx = transfer->tx_buf; in hisi_spi_transfer_one()
393 hs->tx_len = transfer->len / hs->n_bytes; in hisi_spi_transfer_one()
394 hs->rx = transfer->rx_buf; in hisi_spi_transfer_one()
395 hs->rx_len = hs->tx_len; in hisi_spi_transfer_one()
399 * before the interrupt to start. in hisi_spi_transfer_one()
404 writel(~(u32)IMR_MASK, hs->regs + HISI_SPI_IMR); in hisi_spi_transfer_one()
405 writel(1, hs->regs + HISI_SPI_ENR); in hisi_spi_transfer_one()
410 static void hisi_spi_handle_err(struct spi_controller *host, in hisi_spi_handle_err() argument
413 struct hisi_spi *hs = spi_controller_get_devdata(host); in hisi_spi_handle_err()
419 * already in timeout to complete. in hisi_spi_handle_err()
426 struct hisi_chip_data *chip; in hisi_spi_setup() local
429 chip = spi_get_ctldata(spi); in hisi_spi_setup()
430 if (!chip) { in hisi_spi_setup()
431 chip = kzalloc(sizeof(*chip), GFP_KERNEL); in hisi_spi_setup()
432 if (!chip) in hisi_spi_setup()
433 return -ENOMEM; in hisi_spi_setup()
434 spi_set_ctldata(spi, chip); in hisi_spi_setup()
437 chip->cr = hisi_spi_prepare_cr(spi); in hisi_spi_setup()
444 struct hisi_chip_data *chip = spi_get_ctldata(spi); in hisi_spi_cleanup() local
446 kfree(chip); in hisi_spi_cleanup()
452 struct device *dev = &pdev->dev; in hisi_spi_probe()
453 struct spi_controller *host; in hisi_spi_probe() local
461 host = devm_spi_alloc_host(dev, sizeof(*hs)); in hisi_spi_probe()
462 if (!host) in hisi_spi_probe()
463 return -ENOMEM; in hisi_spi_probe()
465 platform_set_drvdata(pdev, host); in hisi_spi_probe()
467 hs = spi_controller_get_devdata(host); in hisi_spi_probe()
468 hs->dev = dev; in hisi_spi_probe()
469 hs->irq = irq; in hisi_spi_probe()
471 hs->regs = devm_platform_ioremap_resource(pdev, 0); in hisi_spi_probe()
472 if (IS_ERR(hs->regs)) in hisi_spi_probe()
473 return PTR_ERR(hs->regs); in hisi_spi_probe()
475 /* Specify maximum SPI clocking speed (host only) by firmware */ in hisi_spi_probe()
476 ret = device_property_read_u32(dev, "spi-max-frequency", in hisi_spi_probe()
477 &host->max_speed_hz); in hisi_spi_probe()
479 dev_err(dev, "failed to get max SPI clocking speed, ret=%d\n", in hisi_spi_probe()
481 return -EINVAL; in hisi_spi_probe()
484 if (host->max_speed_hz == 0) in hisi_spi_probe()
485 return dev_err_probe(dev, -EINVAL, "spi-max-frequency can't be 0\n"); in hisi_spi_probe()
487 ret = device_property_read_u16(dev, "num-cs", in hisi_spi_probe()
488 &host->num_chipselect); in hisi_spi_probe()
490 host->num_chipselect = DEFAULT_NUM_CS; in hisi_spi_probe()
492 host->use_gpio_descriptors = true; in hisi_spi_probe()
493 host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; in hisi_spi_probe()
494 host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); in hisi_spi_probe()
495 host->bus_num = pdev->id; in hisi_spi_probe()
496 host->setup = hisi_spi_setup; in hisi_spi_probe()
497 host->cleanup = hisi_spi_cleanup; in hisi_spi_probe()
498 host->transfer_one = hisi_spi_transfer_one; in hisi_spi_probe()
499 host->handle_err = hisi_spi_handle_err; in hisi_spi_probe()
500 host->dev.fwnode = dev->fwnode; in hisi_spi_probe()
501 host->min_speed_hz = DIV_ROUND_UP(host->max_speed_hz, CLK_DIV_MAX); in hisi_spi_probe()
505 ret = devm_request_irq(dev, hs->irq, hisi_spi_irq, 0, dev_name(dev), in hisi_spi_probe()
506 host); in hisi_spi_probe()
508 dev_err(dev, "failed to get IRQ=%d, ret=%d\n", hs->irq, ret); in hisi_spi_probe()
512 ret = spi_register_controller(host); in hisi_spi_probe()
514 dev_err(dev, "failed to register spi host, ret=%d\n", ret); in hisi_spi_probe()
519 dev_info(dev, "failed to create debugfs dir\n"); in hisi_spi_probe()
521 dev_info(dev, "hw version:0x%x max-freq:%u kHz\n", in hisi_spi_probe()
522 readl(hs->regs + HISI_SPI_VERSION), in hisi_spi_probe()
523 host->max_speed_hz / 1000); in hisi_spi_probe()
530 struct spi_controller *host = platform_get_drvdata(pdev); in hisi_spi_remove() local
531 struct hisi_spi *hs = spi_controller_get_devdata(host); in hisi_spi_remove()
533 debugfs_remove_recursive(hs->debugfs); in hisi_spi_remove()
534 spi_unregister_controller(host); in hisi_spi_remove()
547 .name = "hisi-kunpeng-spi",