Lines Matching refs:bs

163 static void bcm2835_debugfs_create(struct bcm2835_spi *bs,  in bcm2835_debugfs_create()  argument
174 bs->debugfs_dir = dir; in bcm2835_debugfs_create()
178 &bs->count_transfer_polling); in bcm2835_debugfs_create()
180 &bs->count_transfer_irq); in bcm2835_debugfs_create()
182 &bs->count_transfer_irq_after_polling); in bcm2835_debugfs_create()
184 &bs->count_transfer_dma); in bcm2835_debugfs_create()
187 static void bcm2835_debugfs_remove(struct bcm2835_spi *bs) in bcm2835_debugfs_remove() argument
189 debugfs_remove_recursive(bs->debugfs_dir); in bcm2835_debugfs_remove()
190 bs->debugfs_dir = NULL; in bcm2835_debugfs_remove()
193 static void bcm2835_debugfs_create(struct bcm2835_spi *bs, in bcm2835_debugfs_create() argument
198 static void bcm2835_debugfs_remove(struct bcm2835_spi *bs) in bcm2835_debugfs_remove() argument
203 static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned int reg) in bcm2835_rd() argument
205 return readl(bs->regs + reg); in bcm2835_rd()
208 static inline void bcm2835_wr(struct bcm2835_spi *bs, unsigned int reg, u32 val) in bcm2835_wr() argument
210 writel(val, bs->regs + reg); in bcm2835_wr()
213 static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs) in bcm2835_rd_fifo() argument
217 while ((bs->rx_len) && in bcm2835_rd_fifo()
218 (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD)) { in bcm2835_rd_fifo()
219 byte = bcm2835_rd(bs, BCM2835_SPI_FIFO); in bcm2835_rd_fifo()
220 if (bs->rx_buf) in bcm2835_rd_fifo()
221 *bs->rx_buf++ = byte; in bcm2835_rd_fifo()
222 bs->rx_len--; in bcm2835_rd_fifo()
226 static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs) in bcm2835_wr_fifo() argument
230 while ((bs->tx_len) && in bcm2835_wr_fifo()
231 (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_TXD)) { in bcm2835_wr_fifo()
232 byte = bs->tx_buf ? *bs->tx_buf++ : 0; in bcm2835_wr_fifo()
233 bcm2835_wr(bs, BCM2835_SPI_FIFO, byte); in bcm2835_wr_fifo()
234 bs->tx_len--; in bcm2835_wr_fifo()
248 static inline void bcm2835_rd_fifo_count(struct bcm2835_spi *bs, int count) in bcm2835_rd_fifo_count() argument
253 bs->rx_len -= count; in bcm2835_rd_fifo_count()
256 val = bcm2835_rd(bs, BCM2835_SPI_FIFO); in bcm2835_rd_fifo_count()
258 memcpy(bs->rx_buf, &val, len); in bcm2835_rd_fifo_count()
259 bs->rx_buf += len; in bcm2835_rd_fifo_count()
274 static inline void bcm2835_wr_fifo_count(struct bcm2835_spi *bs, int count) in bcm2835_wr_fifo_count() argument
279 bs->tx_len -= count; in bcm2835_wr_fifo_count()
282 if (bs->tx_buf) { in bcm2835_wr_fifo_count()
284 memcpy(&val, bs->tx_buf, len); in bcm2835_wr_fifo_count()
285 bs->tx_buf += len; in bcm2835_wr_fifo_count()
289 bcm2835_wr(bs, BCM2835_SPI_FIFO, val); in bcm2835_wr_fifo_count()
302 static inline void bcm2835_wait_tx_fifo_empty(struct bcm2835_spi *bs) in bcm2835_wait_tx_fifo_empty() argument
304 while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE)) in bcm2835_wait_tx_fifo_empty()
313 static inline void bcm2835_rd_fifo_blind(struct bcm2835_spi *bs, int count) in bcm2835_rd_fifo_blind() argument
317 count = min(count, bs->rx_len); in bcm2835_rd_fifo_blind()
318 bs->rx_len -= count; in bcm2835_rd_fifo_blind()
321 val = bcm2835_rd(bs, BCM2835_SPI_FIFO); in bcm2835_rd_fifo_blind()
322 if (bs->rx_buf) in bcm2835_rd_fifo_blind()
323 *bs->rx_buf++ = val; in bcm2835_rd_fifo_blind()
332 static inline void bcm2835_wr_fifo_blind(struct bcm2835_spi *bs, int count) in bcm2835_wr_fifo_blind() argument
336 count = min(count, bs->tx_len); in bcm2835_wr_fifo_blind()
337 bs->tx_len -= count; in bcm2835_wr_fifo_blind()
340 val = bs->tx_buf ? *bs->tx_buf++ : 0; in bcm2835_wr_fifo_blind()
341 bcm2835_wr(bs, BCM2835_SPI_FIFO, val); in bcm2835_wr_fifo_blind()
345 static void bcm2835_spi_reset_hw(struct bcm2835_spi *bs) in bcm2835_spi_reset_hw() argument
347 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); in bcm2835_spi_reset_hw()
365 bcm2835_wr(bs, BCM2835_SPI_CS, cs); in bcm2835_spi_reset_hw()
367 bcm2835_wr(bs, BCM2835_SPI_DLEN, 0); in bcm2835_spi_reset_hw()
372 struct bcm2835_spi *bs = dev_id; in bcm2835_spi_interrupt() local
373 u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); in bcm2835_spi_interrupt()
384 bcm2835_rd_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_interrupt()
386 bcm2835_rd_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE_3_4); in bcm2835_spi_interrupt()
388 if (bs->tx_len && cs & BCM2835_SPI_CS_DONE) in bcm2835_spi_interrupt()
389 bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_interrupt()
392 bcm2835_rd_fifo(bs); in bcm2835_spi_interrupt()
394 bcm2835_wr_fifo(bs); in bcm2835_spi_interrupt()
396 if (!bs->rx_len) { in bcm2835_spi_interrupt()
398 bcm2835_spi_reset_hw(bs); in bcm2835_spi_interrupt()
400 spi_finalize_current_transfer(bs->ctlr); in bcm2835_spi_interrupt()
411 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one_irq() local
414 bs->count_transfer_irq++; in bcm2835_spi_transfer_one_irq()
420 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); in bcm2835_spi_transfer_one_irq()
424 bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_transfer_one_irq()
425 bcm2835_wr_fifo(bs); in bcm2835_spi_transfer_one_irq()
429 bcm2835_wr(bs, BCM2835_SPI_CS, cs); in bcm2835_spi_transfer_one_irq()
483 struct bcm2835_spi *bs, in bcm2835_spi_transfer_prologue() argument
488 bs->tfr = tfr; in bcm2835_spi_transfer_prologue()
489 bs->tx_prologue = 0; in bcm2835_spi_transfer_prologue()
490 bs->rx_prologue = 0; in bcm2835_spi_transfer_prologue()
491 bs->tx_spillover = false; in bcm2835_spi_transfer_prologue()
493 if (bs->tx_buf && !sg_is_last(&tfr->tx_sg.sgl[0])) in bcm2835_spi_transfer_prologue()
494 bs->tx_prologue = sg_dma_len(&tfr->tx_sg.sgl[0]) & 3; in bcm2835_spi_transfer_prologue()
496 if (bs->rx_buf && !sg_is_last(&tfr->rx_sg.sgl[0])) { in bcm2835_spi_transfer_prologue()
497 bs->rx_prologue = sg_dma_len(&tfr->rx_sg.sgl[0]) & 3; in bcm2835_spi_transfer_prologue()
499 if (bs->rx_prologue > bs->tx_prologue) { in bcm2835_spi_transfer_prologue()
500 if (!bs->tx_buf || sg_is_last(&tfr->tx_sg.sgl[0])) { in bcm2835_spi_transfer_prologue()
501 bs->tx_prologue = bs->rx_prologue; in bcm2835_spi_transfer_prologue()
503 bs->tx_prologue += 4; in bcm2835_spi_transfer_prologue()
504 bs->tx_spillover = in bcm2835_spi_transfer_prologue()
511 if (!bs->tx_prologue) in bcm2835_spi_transfer_prologue()
515 if (bs->rx_prologue) { in bcm2835_spi_transfer_prologue()
516 bcm2835_wr(bs, BCM2835_SPI_DLEN, bs->rx_prologue); in bcm2835_spi_transfer_prologue()
517 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA in bcm2835_spi_transfer_prologue()
519 bcm2835_wr_fifo_count(bs, bs->rx_prologue); in bcm2835_spi_transfer_prologue()
520 bcm2835_wait_tx_fifo_empty(bs); in bcm2835_spi_transfer_prologue()
521 bcm2835_rd_fifo_count(bs, bs->rx_prologue); in bcm2835_spi_transfer_prologue()
522 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_RX in bcm2835_spi_transfer_prologue()
528 bs->rx_prologue, DMA_FROM_DEVICE); in bcm2835_spi_transfer_prologue()
530 sg_dma_address(&tfr->rx_sg.sgl[0]) += bs->rx_prologue; in bcm2835_spi_transfer_prologue()
531 sg_dma_len(&tfr->rx_sg.sgl[0]) -= bs->rx_prologue; in bcm2835_spi_transfer_prologue()
534 if (!bs->tx_buf) in bcm2835_spi_transfer_prologue()
541 tx_remaining = bs->tx_prologue - bs->rx_prologue; in bcm2835_spi_transfer_prologue()
543 bcm2835_wr(bs, BCM2835_SPI_DLEN, tx_remaining); in bcm2835_spi_transfer_prologue()
544 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA in bcm2835_spi_transfer_prologue()
546 bcm2835_wr_fifo_count(bs, tx_remaining); in bcm2835_spi_transfer_prologue()
547 bcm2835_wait_tx_fifo_empty(bs); in bcm2835_spi_transfer_prologue()
548 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_TX in bcm2835_spi_transfer_prologue()
552 if (likely(!bs->tx_spillover)) { in bcm2835_spi_transfer_prologue()
553 sg_dma_address(&tfr->tx_sg.sgl[0]) += bs->tx_prologue; in bcm2835_spi_transfer_prologue()
554 sg_dma_len(&tfr->tx_sg.sgl[0]) -= bs->tx_prologue; in bcm2835_spi_transfer_prologue()
570 static void bcm2835_spi_undo_prologue(struct bcm2835_spi *bs) in bcm2835_spi_undo_prologue() argument
572 struct spi_transfer *tfr = bs->tfr; in bcm2835_spi_undo_prologue()
574 if (!bs->tx_prologue) in bcm2835_spi_undo_prologue()
577 if (bs->rx_prologue) { in bcm2835_spi_undo_prologue()
578 sg_dma_address(&tfr->rx_sg.sgl[0]) -= bs->rx_prologue; in bcm2835_spi_undo_prologue()
579 sg_dma_len(&tfr->rx_sg.sgl[0]) += bs->rx_prologue; in bcm2835_spi_undo_prologue()
582 if (!bs->tx_buf) in bcm2835_spi_undo_prologue()
585 if (likely(!bs->tx_spillover)) { in bcm2835_spi_undo_prologue()
586 sg_dma_address(&tfr->tx_sg.sgl[0]) -= bs->tx_prologue; in bcm2835_spi_undo_prologue()
587 sg_dma_len(&tfr->tx_sg.sgl[0]) += bs->tx_prologue; in bcm2835_spi_undo_prologue()
589 sg_dma_len(&tfr->tx_sg.sgl[0]) = bs->tx_prologue - 4; in bcm2835_spi_undo_prologue()
594 bs->tx_prologue = 0; in bcm2835_spi_undo_prologue()
606 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_dma_rx_done() local
614 bs->tx_dma_active = false; in bcm2835_spi_dma_rx_done()
615 bs->rx_dma_active = false; in bcm2835_spi_dma_rx_done()
616 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_dma_rx_done()
619 bcm2835_spi_reset_hw(bs); in bcm2835_spi_dma_rx_done()
634 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_dma_tx_done() local
637 while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE)) in bcm2835_spi_dma_tx_done()
638 bcm2835_wr(bs, BCM2835_SPI_CS, bs->target->clear_rx_cs); in bcm2835_spi_dma_tx_done()
640 bs->tx_dma_active = false; in bcm2835_spi_dma_tx_done()
648 if (cmpxchg(&bs->rx_dma_active, true, false)) in bcm2835_spi_dma_tx_done()
651 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_dma_tx_done()
652 bcm2835_spi_reset_hw(bs); in bcm2835_spi_dma_tx_done()
669 struct bcm2835_spi *bs, in bcm2835_spi_prepare_sg() argument
710 bs->target = target; in bcm2835_spi_prepare_sg()
771 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one_dma() local
776 bs->count_transfer_dma++; in bcm2835_spi_transfer_one_dma()
782 bcm2835_spi_transfer_prologue(ctlr, tfr, bs, cs); in bcm2835_spi_transfer_one_dma()
785 if (bs->tx_buf) { in bcm2835_spi_transfer_one_dma()
786 ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, target, true); in bcm2835_spi_transfer_one_dma()
788 cookie = dmaengine_submit(bs->fill_tx_desc); in bcm2835_spi_transfer_one_dma()
795 bcm2835_wr(bs, BCM2835_SPI_DLEN, bs->tx_len); in bcm2835_spi_transfer_one_dma()
798 bcm2835_wr(bs, BCM2835_SPI_CS, in bcm2835_spi_transfer_one_dma()
801 bs->tx_dma_active = true; in bcm2835_spi_transfer_one_dma()
811 if (bs->rx_buf) { in bcm2835_spi_transfer_one_dma()
812 ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, target, false); in bcm2835_spi_transfer_one_dma()
820 bs->tx_dma_active = false; in bcm2835_spi_transfer_one_dma()
826 bs->rx_dma_active = true; in bcm2835_spi_transfer_one_dma()
833 if (!bs->rx_buf && !bs->tx_dma_active && in bcm2835_spi_transfer_one_dma()
834 cmpxchg(&bs->rx_dma_active, true, false)) { in bcm2835_spi_transfer_one_dma()
836 bcm2835_spi_reset_hw(bs); in bcm2835_spi_transfer_one_dma()
843 bcm2835_spi_reset_hw(bs); in bcm2835_spi_transfer_one_dma()
844 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_transfer_one_dma()
861 struct bcm2835_spi *bs) in bcm2835_dma_release() argument
866 if (bs->fill_tx_desc) in bcm2835_dma_release()
867 dmaengine_desc_free(bs->fill_tx_desc); in bcm2835_dma_release()
869 if (bs->fill_tx_addr) in bcm2835_dma_release()
871 bs->fill_tx_addr, sizeof(u32), in bcm2835_dma_release()
887 struct bcm2835_spi *bs) in bcm2835_dma_init() argument
931 bs->fill_tx_addr = dma_map_page_attrs(ctlr->dma_tx->device->dev, in bcm2835_dma_init()
935 if (dma_mapping_error(ctlr->dma_tx->device->dev, bs->fill_tx_addr)) { in bcm2835_dma_init()
937 bs->fill_tx_addr = 0; in bcm2835_dma_init()
942 bs->fill_tx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_tx, in bcm2835_dma_init()
943 bs->fill_tx_addr, in bcm2835_dma_init()
946 if (!bs->fill_tx_desc) { in bcm2835_dma_init()
952 ret = dmaengine_desc_set_reuse(bs->fill_tx_desc); in bcm2835_dma_init()
981 bcm2835_dma_release(ctlr, bs); in bcm2835_dma_init()
998 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one_poll() local
1002 bs->count_transfer_polling++; in bcm2835_spi_transfer_one_poll()
1005 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); in bcm2835_spi_transfer_one_poll()
1011 bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_transfer_one_poll()
1017 while (bs->rx_len) { in bcm2835_spi_transfer_one_poll()
1019 bcm2835_wr_fifo(bs); in bcm2835_spi_transfer_one_poll()
1022 bcm2835_rd_fifo(bs); in bcm2835_spi_transfer_one_poll()
1027 if (bs->rx_len && time_after(jiffies, timeout)) { in bcm2835_spi_transfer_one_poll()
1031 bs->tx_len, bs->rx_len); in bcm2835_spi_transfer_one_poll()
1035 bs->count_transfer_irq_after_polling++; in bcm2835_spi_transfer_one_poll()
1043 bcm2835_spi_reset_hw(bs); in bcm2835_spi_transfer_one_poll()
1052 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one() local
1061 if (spi_hz >= bs->clk_hz / 2) { in bcm2835_spi_transfer_one()
1065 cdiv = DIV_ROUND_UP(bs->clk_hz, spi_hz); in bcm2835_spi_transfer_one()
1073 tfr->effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); in bcm2835_spi_transfer_one()
1074 bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); in bcm2835_spi_transfer_one()
1081 bs->tx_buf = tfr->tx_buf; in bcm2835_spi_transfer_one()
1082 bs->rx_buf = tfr->rx_buf; in bcm2835_spi_transfer_one()
1083 bs->tx_len = tfr->len; in bcm2835_spi_transfer_one()
1084 bs->rx_len = tfr->len; in bcm2835_spi_transfer_one()
1114 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_prepare_message() local
1134 bcm2835_wr(bs, BCM2835_SPI_CS, target->prepare_cs); in bcm2835_spi_prepare_message()
1142 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_handle_err() local
1147 bs->tx_dma_active = false; in bcm2835_spi_handle_err()
1151 bs->rx_dma_active = false; in bcm2835_spi_handle_err()
1153 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_handle_err()
1156 bcm2835_spi_reset_hw(bs); in bcm2835_spi_handle_err()
1183 struct bcm2835_spi *bs, in bcm2835_spi_setup_dma() argument
1222 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_setup() local
1236 ret = bcm2835_spi_setup_dma(ctlr, spi, bs, target); in bcm2835_spi_setup()
1328 struct bcm2835_spi *bs; in bcm2835_spi_probe() local
1331 ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*bs)); in bcm2835_spi_probe()
1348 bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_probe()
1349 bs->ctlr = ctlr; in bcm2835_spi_probe()
1351 bs->regs = devm_platform_ioremap_resource(pdev, 0); in bcm2835_spi_probe()
1352 if (IS_ERR(bs->regs)) in bcm2835_spi_probe()
1353 return PTR_ERR(bs->regs); in bcm2835_spi_probe()
1355 bs->clk = devm_clk_get(&pdev->dev, NULL); in bcm2835_spi_probe()
1356 if (IS_ERR(bs->clk)) in bcm2835_spi_probe()
1357 return dev_err_probe(&pdev->dev, PTR_ERR(bs->clk), in bcm2835_spi_probe()
1360 ctlr->max_speed_hz = clk_get_rate(bs->clk) / 2; in bcm2835_spi_probe()
1362 bs->irq = platform_get_irq(pdev, 0); in bcm2835_spi_probe()
1363 if (bs->irq < 0) in bcm2835_spi_probe()
1364 return bs->irq; in bcm2835_spi_probe()
1366 err = clk_prepare_enable(bs->clk); in bcm2835_spi_probe()
1369 bs->clk_hz = clk_get_rate(bs->clk); in bcm2835_spi_probe()
1371 err = bcm2835_dma_init(ctlr, &pdev->dev, bs); in bcm2835_spi_probe()
1376 bcm2835_wr(bs, BCM2835_SPI_CS, in bcm2835_spi_probe()
1379 err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, in bcm2835_spi_probe()
1380 IRQF_SHARED, dev_name(&pdev->dev), bs); in bcm2835_spi_probe()
1393 bcm2835_debugfs_create(bs, dev_name(&pdev->dev)); in bcm2835_spi_probe()
1398 bcm2835_dma_release(ctlr, bs); in bcm2835_spi_probe()
1400 clk_disable_unprepare(bs->clk); in bcm2835_spi_probe()
1407 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_remove() local
1409 bcm2835_debugfs_remove(bs); in bcm2835_spi_remove()
1413 bcm2835_dma_release(ctlr, bs); in bcm2835_spi_remove()
1416 bcm2835_wr(bs, BCM2835_SPI_CS, in bcm2835_spi_remove()
1419 clk_disable_unprepare(bs->clk); in bcm2835_spi_remove()