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()
380 bcm2835_rd_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_interrupt()
382 bcm2835_rd_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE_3_4); in bcm2835_spi_interrupt()
384 if (bs->tx_len && cs & BCM2835_SPI_CS_DONE) in bcm2835_spi_interrupt()
385 bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_interrupt()
388 bcm2835_rd_fifo(bs); in bcm2835_spi_interrupt()
390 bcm2835_wr_fifo(bs); in bcm2835_spi_interrupt()
392 if (!bs->rx_len) { in bcm2835_spi_interrupt()
394 bcm2835_spi_reset_hw(bs); in bcm2835_spi_interrupt()
396 spi_finalize_current_transfer(bs->ctlr); in bcm2835_spi_interrupt()
407 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one_irq() local
410 bs->count_transfer_irq++; in bcm2835_spi_transfer_one_irq()
416 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); in bcm2835_spi_transfer_one_irq()
420 bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_transfer_one_irq()
421 bcm2835_wr_fifo(bs); in bcm2835_spi_transfer_one_irq()
425 bcm2835_wr(bs, BCM2835_SPI_CS, cs); in bcm2835_spi_transfer_one_irq()
479 struct bcm2835_spi *bs, in bcm2835_spi_transfer_prologue() argument
484 bs->tfr = tfr; in bcm2835_spi_transfer_prologue()
485 bs->tx_prologue = 0; in bcm2835_spi_transfer_prologue()
486 bs->rx_prologue = 0; in bcm2835_spi_transfer_prologue()
487 bs->tx_spillover = false; in bcm2835_spi_transfer_prologue()
489 if (bs->tx_buf && !sg_is_last(&tfr->tx_sg.sgl[0])) in bcm2835_spi_transfer_prologue()
490 bs->tx_prologue = sg_dma_len(&tfr->tx_sg.sgl[0]) & 3; in bcm2835_spi_transfer_prologue()
492 if (bs->rx_buf && !sg_is_last(&tfr->rx_sg.sgl[0])) { in bcm2835_spi_transfer_prologue()
493 bs->rx_prologue = sg_dma_len(&tfr->rx_sg.sgl[0]) & 3; in bcm2835_spi_transfer_prologue()
495 if (bs->rx_prologue > bs->tx_prologue) { in bcm2835_spi_transfer_prologue()
496 if (!bs->tx_buf || sg_is_last(&tfr->tx_sg.sgl[0])) { in bcm2835_spi_transfer_prologue()
497 bs->tx_prologue = bs->rx_prologue; in bcm2835_spi_transfer_prologue()
499 bs->tx_prologue += 4; in bcm2835_spi_transfer_prologue()
500 bs->tx_spillover = in bcm2835_spi_transfer_prologue()
507 if (!bs->tx_prologue) in bcm2835_spi_transfer_prologue()
511 if (bs->rx_prologue) { in bcm2835_spi_transfer_prologue()
512 bcm2835_wr(bs, BCM2835_SPI_DLEN, bs->rx_prologue); in bcm2835_spi_transfer_prologue()
513 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA in bcm2835_spi_transfer_prologue()
515 bcm2835_wr_fifo_count(bs, bs->rx_prologue); in bcm2835_spi_transfer_prologue()
516 bcm2835_wait_tx_fifo_empty(bs); in bcm2835_spi_transfer_prologue()
517 bcm2835_rd_fifo_count(bs, bs->rx_prologue); in bcm2835_spi_transfer_prologue()
518 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_RX in bcm2835_spi_transfer_prologue()
524 bs->rx_prologue, DMA_FROM_DEVICE); in bcm2835_spi_transfer_prologue()
526 sg_dma_address(&tfr->rx_sg.sgl[0]) += bs->rx_prologue; in bcm2835_spi_transfer_prologue()
527 sg_dma_len(&tfr->rx_sg.sgl[0]) -= bs->rx_prologue; in bcm2835_spi_transfer_prologue()
530 if (!bs->tx_buf) in bcm2835_spi_transfer_prologue()
537 tx_remaining = bs->tx_prologue - bs->rx_prologue; in bcm2835_spi_transfer_prologue()
539 bcm2835_wr(bs, BCM2835_SPI_DLEN, tx_remaining); in bcm2835_spi_transfer_prologue()
540 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA in bcm2835_spi_transfer_prologue()
542 bcm2835_wr_fifo_count(bs, tx_remaining); in bcm2835_spi_transfer_prologue()
543 bcm2835_wait_tx_fifo_empty(bs); in bcm2835_spi_transfer_prologue()
544 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_TX in bcm2835_spi_transfer_prologue()
548 if (likely(!bs->tx_spillover)) { in bcm2835_spi_transfer_prologue()
549 sg_dma_address(&tfr->tx_sg.sgl[0]) += bs->tx_prologue; in bcm2835_spi_transfer_prologue()
550 sg_dma_len(&tfr->tx_sg.sgl[0]) -= bs->tx_prologue; in bcm2835_spi_transfer_prologue()
566 static void bcm2835_spi_undo_prologue(struct bcm2835_spi *bs) in bcm2835_spi_undo_prologue() argument
568 struct spi_transfer *tfr = bs->tfr; in bcm2835_spi_undo_prologue()
570 if (!bs->tx_prologue) in bcm2835_spi_undo_prologue()
573 if (bs->rx_prologue) { in bcm2835_spi_undo_prologue()
574 sg_dma_address(&tfr->rx_sg.sgl[0]) -= bs->rx_prologue; in bcm2835_spi_undo_prologue()
575 sg_dma_len(&tfr->rx_sg.sgl[0]) += bs->rx_prologue; in bcm2835_spi_undo_prologue()
578 if (!bs->tx_buf) in bcm2835_spi_undo_prologue()
581 if (likely(!bs->tx_spillover)) { in bcm2835_spi_undo_prologue()
582 sg_dma_address(&tfr->tx_sg.sgl[0]) -= bs->tx_prologue; in bcm2835_spi_undo_prologue()
583 sg_dma_len(&tfr->tx_sg.sgl[0]) += bs->tx_prologue; in bcm2835_spi_undo_prologue()
585 sg_dma_len(&tfr->tx_sg.sgl[0]) = bs->tx_prologue - 4; in bcm2835_spi_undo_prologue()
590 bs->tx_prologue = 0; in bcm2835_spi_undo_prologue()
602 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_dma_rx_done() local
610 bs->tx_dma_active = false; in bcm2835_spi_dma_rx_done()
611 bs->rx_dma_active = false; in bcm2835_spi_dma_rx_done()
612 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_dma_rx_done()
615 bcm2835_spi_reset_hw(bs); in bcm2835_spi_dma_rx_done()
630 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_dma_tx_done() local
633 while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE)) in bcm2835_spi_dma_tx_done()
634 bcm2835_wr(bs, BCM2835_SPI_CS, bs->slv->clear_rx_cs); in bcm2835_spi_dma_tx_done()
636 bs->tx_dma_active = false; in bcm2835_spi_dma_tx_done()
644 if (cmpxchg(&bs->rx_dma_active, true, false)) in bcm2835_spi_dma_tx_done()
647 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_dma_tx_done()
648 bcm2835_spi_reset_hw(bs); in bcm2835_spi_dma_tx_done()
665 struct bcm2835_spi *bs, in bcm2835_spi_prepare_sg() argument
706 bs->slv = slv; in bcm2835_spi_prepare_sg()
767 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one_dma() local
772 bs->count_transfer_dma++; in bcm2835_spi_transfer_one_dma()
778 bcm2835_spi_transfer_prologue(ctlr, tfr, bs, cs); in bcm2835_spi_transfer_one_dma()
781 if (bs->tx_buf) { in bcm2835_spi_transfer_one_dma()
782 ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, slv, true); in bcm2835_spi_transfer_one_dma()
784 cookie = dmaengine_submit(bs->fill_tx_desc); in bcm2835_spi_transfer_one_dma()
791 bcm2835_wr(bs, BCM2835_SPI_DLEN, bs->tx_len); in bcm2835_spi_transfer_one_dma()
794 bcm2835_wr(bs, BCM2835_SPI_CS, in bcm2835_spi_transfer_one_dma()
797 bs->tx_dma_active = true; in bcm2835_spi_transfer_one_dma()
807 if (bs->rx_buf) { in bcm2835_spi_transfer_one_dma()
808 ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, slv, false); in bcm2835_spi_transfer_one_dma()
816 bs->tx_dma_active = false; in bcm2835_spi_transfer_one_dma()
822 bs->rx_dma_active = true; in bcm2835_spi_transfer_one_dma()
829 if (!bs->rx_buf && !bs->tx_dma_active && in bcm2835_spi_transfer_one_dma()
830 cmpxchg(&bs->rx_dma_active, true, false)) { in bcm2835_spi_transfer_one_dma()
832 bcm2835_spi_reset_hw(bs); in bcm2835_spi_transfer_one_dma()
839 bcm2835_spi_reset_hw(bs); in bcm2835_spi_transfer_one_dma()
840 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_transfer_one_dma()
857 struct bcm2835_spi *bs) in bcm2835_dma_release() argument
862 if (bs->fill_tx_desc) in bcm2835_dma_release()
863 dmaengine_desc_free(bs->fill_tx_desc); in bcm2835_dma_release()
865 if (bs->fill_tx_addr) in bcm2835_dma_release()
867 bs->fill_tx_addr, sizeof(u32), in bcm2835_dma_release()
883 struct bcm2835_spi *bs) in bcm2835_dma_init() argument
927 bs->fill_tx_addr = dma_map_page_attrs(ctlr->dma_tx->device->dev, in bcm2835_dma_init()
931 if (dma_mapping_error(ctlr->dma_tx->device->dev, bs->fill_tx_addr)) { in bcm2835_dma_init()
933 bs->fill_tx_addr = 0; in bcm2835_dma_init()
938 bs->fill_tx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_tx, in bcm2835_dma_init()
939 bs->fill_tx_addr, in bcm2835_dma_init()
942 if (!bs->fill_tx_desc) { in bcm2835_dma_init()
948 ret = dmaengine_desc_set_reuse(bs->fill_tx_desc); in bcm2835_dma_init()
977 bcm2835_dma_release(ctlr, bs); in bcm2835_dma_init()
994 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one_poll() local
998 bs->count_transfer_polling++; in bcm2835_spi_transfer_one_poll()
1001 bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); in bcm2835_spi_transfer_one_poll()
1007 bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); in bcm2835_spi_transfer_one_poll()
1013 while (bs->rx_len) { in bcm2835_spi_transfer_one_poll()
1015 bcm2835_wr_fifo(bs); in bcm2835_spi_transfer_one_poll()
1018 bcm2835_rd_fifo(bs); in bcm2835_spi_transfer_one_poll()
1023 if (bs->rx_len && time_after(jiffies, timeout)) { in bcm2835_spi_transfer_one_poll()
1027 bs->tx_len, bs->rx_len); in bcm2835_spi_transfer_one_poll()
1031 bs->count_transfer_irq_after_polling++; in bcm2835_spi_transfer_one_poll()
1039 bcm2835_spi_reset_hw(bs); in bcm2835_spi_transfer_one_poll()
1048 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_transfer_one() local
1057 if (spi_hz >= bs->clk_hz / 2) { in bcm2835_spi_transfer_one()
1061 cdiv = DIV_ROUND_UP(bs->clk_hz, spi_hz); in bcm2835_spi_transfer_one()
1069 tfr->effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); in bcm2835_spi_transfer_one()
1070 bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); in bcm2835_spi_transfer_one()
1077 bs->tx_buf = tfr->tx_buf; in bcm2835_spi_transfer_one()
1078 bs->rx_buf = tfr->rx_buf; in bcm2835_spi_transfer_one()
1079 bs->tx_len = tfr->len; in bcm2835_spi_transfer_one()
1080 bs->rx_len = tfr->len; in bcm2835_spi_transfer_one()
1110 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_prepare_message() local
1130 bcm2835_wr(bs, BCM2835_SPI_CS, slv->prepare_cs); in bcm2835_spi_prepare_message()
1138 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_handle_err() local
1142 bs->tx_dma_active = false; in bcm2835_spi_handle_err()
1144 bs->rx_dma_active = false; in bcm2835_spi_handle_err()
1145 bcm2835_spi_undo_prologue(bs); in bcm2835_spi_handle_err()
1148 bcm2835_spi_reset_hw(bs); in bcm2835_spi_handle_err()
1175 struct bcm2835_spi *bs, in bcm2835_spi_setup_dma() argument
1214 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_setup() local
1228 ret = bcm2835_spi_setup_dma(ctlr, spi, bs, slv); in bcm2835_spi_setup()
1319 struct bcm2835_spi *bs; in bcm2835_spi_probe() local
1322 ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*bs)); in bcm2835_spi_probe()
1339 bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_probe()
1340 bs->ctlr = ctlr; in bcm2835_spi_probe()
1342 bs->regs = devm_platform_ioremap_resource(pdev, 0); in bcm2835_spi_probe()
1343 if (IS_ERR(bs->regs)) in bcm2835_spi_probe()
1344 return PTR_ERR(bs->regs); in bcm2835_spi_probe()
1346 bs->clk = devm_clk_get(&pdev->dev, NULL); in bcm2835_spi_probe()
1347 if (IS_ERR(bs->clk)) in bcm2835_spi_probe()
1348 return dev_err_probe(&pdev->dev, PTR_ERR(bs->clk), in bcm2835_spi_probe()
1351 ctlr->max_speed_hz = clk_get_rate(bs->clk) / 2; in bcm2835_spi_probe()
1353 bs->irq = platform_get_irq(pdev, 0); in bcm2835_spi_probe()
1354 if (bs->irq <= 0) in bcm2835_spi_probe()
1355 return bs->irq ? bs->irq : -ENODEV; in bcm2835_spi_probe()
1357 clk_prepare_enable(bs->clk); in bcm2835_spi_probe()
1358 bs->clk_hz = clk_get_rate(bs->clk); in bcm2835_spi_probe()
1360 err = bcm2835_dma_init(ctlr, &pdev->dev, bs); in bcm2835_spi_probe()
1365 bcm2835_wr(bs, BCM2835_SPI_CS, in bcm2835_spi_probe()
1368 err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, in bcm2835_spi_probe()
1369 dev_name(&pdev->dev), bs); in bcm2835_spi_probe()
1382 bcm2835_debugfs_create(bs, dev_name(&pdev->dev)); in bcm2835_spi_probe()
1387 bcm2835_dma_release(ctlr, bs); in bcm2835_spi_probe()
1389 clk_disable_unprepare(bs->clk); in bcm2835_spi_probe()
1396 struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); in bcm2835_spi_remove() local
1398 bcm2835_debugfs_remove(bs); in bcm2835_spi_remove()
1402 bcm2835_dma_release(ctlr, bs); in bcm2835_spi_remove()
1405 bcm2835_wr(bs, BCM2835_SPI_CS, in bcm2835_spi_remove()
1408 clk_disable_unprepare(bs->clk); in bcm2835_spi_remove()