Lines Matching refs:as

301 static bool atmel_spi_is_v2(struct atmel_spi *as)
303 return as->caps.is_spi2;
310 * transmitted") Not so! Workaround uses nCSx pins as GPIOs; or newer
313 * Even controller newer than ar91rm9200, using GPIOs can make sens as
324 static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
331 chip_select = as->native_cs_for_gpio;
335 if (atmel_spi_is_v2(as)) {
336 spi_writel(as, CSR0 + 4 * chip_select, asd->csr);
338 * on CS1,2,3 needs SPI_CSR0.BITS config as SPI_CSR1,2,3.BITS
340 spi_writel(as, CSR0, asd->csr);
341 if (as->caps.has_wdrbt) {
342 spi_writel(as, MR,
348 spi_writel(as, MR,
354 mr = spi_readl(as, MR);
362 csr = spi_readl(as, CSR0 + 4 * i);
364 spi_writel(as, CSR0 + 4 * i,
368 mr = spi_readl(as, MR);
370 spi_writel(as, MR, mr);
376 static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
382 chip_select = as->native_cs_for_gpio;
389 mr = spi_readl(as, MR);
392 spi_writel(as, MR, mr);
398 spi_writel(as, CR, SPI_BIT(LASTXFER));
401 static void atmel_spi_lock(struct atmel_spi *as) __acquires(&as->lock)
403 spin_lock_irqsave(&as->lock, as->flags);
406 static void atmel_spi_unlock(struct atmel_spi *as) __releases(&as->lock)
408 spin_unlock_irqrestore(&as->lock, as->flags);
416 static inline bool atmel_spi_use_dma(struct atmel_spi *as,
419 return as->use_dma && xfer->len >= DMA_MIN_BYTES;
426 struct atmel_spi *as = spi_master_get_devdata(master);
429 return atmel_spi_use_dma(as, xfer) &&
432 return atmel_spi_use_dma(as, xfer);
436 static int atmel_spi_dma_slave_config(struct atmel_spi *as,
440 struct spi_master *master = platform_get_drvdata(as->pdev);
451 slave_config->dst_addr = (dma_addr_t)as->phybase + SPI_TDR;
452 slave_config->src_addr = (dma_addr_t)as->phybase + SPI_RDR;
473 dev_err(&as->pdev->dev,
488 dev_err(&as->pdev->dev,
497 struct atmel_spi *as)
500 struct device *dev = &as->pdev->dev;
525 err = atmel_spi_dma_slave_config(as, &slave_config, 8);
529 dev_info(&as->pdev->dev,
569 struct atmel_spi *as = spi_master_get_devdata(master);
571 if (is_vmalloc_addr(as->current_transfer->rx_buf) &&
573 memcpy(as->current_transfer->rx_buf, as->addr_rx_bbuf,
574 as->current_transfer->len);
576 complete(&as->xfer_completion);
585 struct atmel_spi *as = spi_master_get_devdata(master);
586 unsigned long xfer_pos = xfer->len - as->current_remaining_bytes;
591 spi_readl(as, RDR);
592 while (spi_readl(as, SR) & SPI_BIT(RDRF)) {
593 spi_readl(as, RDR);
598 spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos));
600 spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos));
608 spi_writel(as, IER, SPI_BIT(RDRF) | SPI_BIT(OVRES));
617 struct atmel_spi *as = spi_master_get_devdata(master);
619 u32 offset = xfer->len - as->current_remaining_bytes;
629 ((u32)as->current_remaining_bytes >> 1) :
630 (u32)as->current_remaining_bytes);
631 num_data = min(current_remaining_data, as->fifo_size);
634 spi_writel(as, CR, SPI_BIT(RXFCLR) | SPI_BIT(TXFCLR));
635 while (spi_readl(as, FLR))
639 fifomr = spi_readl(as, FMR);
640 spi_writel(as, FMR, SPI_BFINS(RXFTHRES, num_data, fifomr));
643 (void)spi_readl(as, SR);
655 spi_writel(as, TDR, (td1 << 16) | td0);
665 spi_writew(as, TDR, td0);
678 spi_writel(as, IER, SPI_BIT(RXFTHF) | SPI_BIT(OVRES));
687 struct atmel_spi *as = spi_master_get_devdata(master);
689 if (as->fifo_size)
701 __must_hold(&as->lock)
703 struct atmel_spi *as = spi_master_get_devdata(master);
718 atmel_spi_unlock(as);
722 if (atmel_spi_dma_slave_config(as, &slave_config,
730 as->dma_addr_rx_bbuf,
748 memcpy(as->addr_tx_bbuf, xfer->tx_buf, xfer->len);
750 as->dma_addr_tx_bbuf,
771 spi_writel(as, IER, SPI_BIT(OVRES));
788 atmel_spi_lock(as);
792 spi_writel(as, IDR, SPI_BIT(OVRES));
795 atmel_spi_lock(as);
811 static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
820 chip_select = as->native_cs_for_gpio;
825 bus_hz = as->spi_clk;
826 if (!atmel_spi_is_v2(as))
851 csr = spi_readl(as, CSR0 + 4 * chip_select);
853 spi_writel(as, CSR0 + 4 * chip_select, csr);
866 struct atmel_spi *as = spi_master_get_devdata(master);
870 spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
872 len = as->current_remaining_bytes;
874 as->current_remaining_bytes -= len;
876 spi_writel(as, RPR, rx_dma);
877 spi_writel(as, TPR, tx_dma);
881 spi_writel(as, RCR, len);
882 spi_writel(as, TCR, len);
890 if (as->current_remaining_bytes) {
891 len = as->current_remaining_bytes;
893 as->current_remaining_bytes -= len;
895 spi_writel(as, RNPR, rx_dma);
896 spi_writel(as, TNPR, tx_dma);
900 spi_writel(as, RNCR, len);
901 spi_writel(as, TNCR, len);
920 spi_writel(as, IER, SPI_BIT(RXBUFF) | SPI_BIT(OVRES));
921 spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));
925 * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma:
932 atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer)
934 struct device *dev = &as->pdev->dev;
974 static void atmel_spi_disable_pdc_transfer(struct atmel_spi *as)
976 spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
980 atmel_spi_pump_single_data(struct atmel_spi *as, struct spi_transfer *xfer)
984 unsigned long xfer_pos = xfer->len - as->current_remaining_bytes;
988 *rxp16 = spi_readl(as, RDR);
991 *rxp = spi_readl(as, RDR);
994 if (as->current_remaining_bytes > 2)
995 as->current_remaining_bytes -= 2;
997 as->current_remaining_bytes = 0;
999 as->current_remaining_bytes--;
1004 atmel_spi_pump_fifo_data(struct atmel_spi *as, struct spi_transfer *xfer)
1006 u32 fifolr = spi_readl(as, FLR);
1008 u32 offset = xfer->len - as->current_remaining_bytes;
1018 if (as->current_remaining_bytes > num_bytes)
1019 as->current_remaining_bytes -= num_bytes;
1021 as->current_remaining_bytes = 0;
1025 as->current_remaining_bytes &= ~0x1;
1029 rd = spi_readl(as, RDR);
1044 atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer)
1046 if (as->fifo_size)
1047 atmel_spi_pump_fifo_data(as, xfer);
1049 atmel_spi_pump_single_data(as, xfer);
1061 struct atmel_spi *as = spi_master_get_devdata(master);
1066 imr = spi_readl(as, IMR);
1067 status = spi_readl(as, SR);
1072 spi_writel(as, IDR, SPI_BIT(OVRES));
1084 as->done_status = -EIO;
1088 spi_readl(as, SR);
1090 complete(&as->xfer_completion);
1093 atmel_spi_lock(as);
1095 if (as->current_remaining_bytes) {
1097 xfer = as->current_transfer;
1098 atmel_spi_pump_pio_data(as, xfer);
1099 if (!as->current_remaining_bytes)
1100 spi_writel(as, IDR, pending);
1102 complete(&as->xfer_completion);
1105 atmel_spi_unlock(as);
1109 spi_writel(as, IDR, pending);
1119 struct atmel_spi *as = spi_master_get_devdata(master);
1123 imr = spi_readl(as, IMR);
1124 status = spi_readl(as, SR);
1131 spi_writel(as, IDR, (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX)
1135 spi_readl(as, SR);
1137 as->done_status = -EIO;
1139 complete(&as->xfer_completion);
1144 spi_writel(as, IDR, pending);
1146 complete(&as->xfer_completion);
1152 static int atmel_word_delay_csr(struct spi_device *spi, struct atmel_spi *as)
1167 return (as->spi_clk / 1000000 * value) >> 5;
1170 static void initialize_native_cs_for_gpio(struct atmel_spi *as)
1173 struct spi_master *master = platform_get_drvdata(as->pdev);
1175 if (!as->native_cs_free)
1185 if (atmel_spi_is_v2(as))
1192 as->native_cs_free |= BIT(i);
1194 if (as->native_cs_free)
1195 as->native_cs_for_gpio = ffs(as->native_cs_free);
1200 struct atmel_spi *as;
1207 as = spi_master_get_devdata(spi->master);
1220 initialize_native_cs_for_gpio(as);
1222 if (spi->cs_gpiod && as->native_cs_free) {
1229 chip_select = as->native_cs_for_gpio;
1243 word_delay_csr = atmel_word_delay_csr(spi, as);
1267 if (!atmel_spi_is_v2(as))
1268 spi_writel(as, CSR0 + 4 * chip_select, csr);
1275 struct atmel_spi *as = spi_master_get_devdata(spi->master);
1283 cs_activate(as, spi);
1285 cs_deactivate(as, spi);
1294 struct atmel_spi *as;
1302 as = spi_master_get_devdata(master);
1304 atmel_spi_lock(as);
1319 && as->use_pdc) {
1320 if (atmel_spi_dma_map_xfer(as, xfer) < 0)
1324 atmel_spi_set_xfer_speed(as, spi, xfer);
1326 as->done_status = 0;
1327 as->current_transfer = xfer;
1328 as->current_remaining_bytes = xfer->len;
1329 while (as->current_remaining_bytes) {
1330 reinit_completion(&as->xfer_completion);
1332 if (as->use_pdc) {
1334 } else if (atmel_spi_use_dma(as, xfer)) {
1335 len = as->current_remaining_bytes;
1341 as->done_status = ret;
1344 as->current_remaining_bytes -= len;
1345 if (as->current_remaining_bytes < 0)
1346 as->current_remaining_bytes = 0;
1353 atmel_spi_unlock(as);
1354 dma_timeout = wait_for_completion_timeout(&as->xfer_completion,
1356 atmel_spi_lock(as);
1359 as->done_status = -EIO;
1362 if (as->done_status)
1366 if (as->done_status) {
1367 if (as->use_pdc) {
1370 spi_readl(as, TCR), spi_readl(as, RCR));
1376 spi_writel(as, RNCR, 0);
1377 spi_writel(as, TNCR, 0);
1378 spi_writel(as, RCR, 0);
1379 spi_writel(as, TCR, 0);
1381 if (spi_readl(as, SR) & SPI_BIT(TXEMPTY))
1386 while (spi_readl(as, SR) & SPI_BIT(RDRF))
1387 spi_readl(as, RDR);
1390 spi_readl(as, SR);
1392 } else if (atmel_spi_use_dma(as, xfer)) {
1398 && as->use_pdc)
1401 if (as->use_pdc)
1402 atmel_spi_disable_pdc_transfer(as);
1404 atmel_spi_unlock(as);
1406 return as->done_status;
1420 static inline unsigned int atmel_get_version(struct atmel_spi *as)
1422 return spi_readl(as, VERSION) & 0x00000fff;
1425 static void atmel_get_caps(struct atmel_spi *as)
1429 version = atmel_get_version(as);
1431 as->caps.is_spi2 = version > 0x121;
1432 as->caps.has_wdrbt = version >= 0x210;
1433 as->caps.has_dma_support = version >= 0x212;
1434 as->caps.has_pdc_support = version < 0x212;
1437 static void atmel_spi_init(struct atmel_spi *as)
1439 spi_writel(as, CR, SPI_BIT(SWRST));
1440 spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
1443 if (as->fifo_size)
1444 spi_writel(as, CR, SPI_BIT(FIFOEN));
1446 if (as->caps.has_wdrbt) {
1447 spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS)
1450 spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS));
1453 if (as->use_pdc)
1454 spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
1455 spi_writel(as, CR, SPI_BIT(SPIEN));
1465 struct atmel_spi *as;
1483 master = spi_alloc_master(&pdev->dev, sizeof(*as));
1505 as = spi_master_get_devdata(master);
1507 spin_lock_init(&as->lock);
1509 as->pdev = pdev;
1510 as->regs = devm_ioremap_resource(&pdev->dev, regs);
1511 if (IS_ERR(as->regs)) {
1512 ret = PTR_ERR(as->regs);
1515 as->phybase = regs->start;
1516 as->irq = irq;
1517 as->clk = clk;
1519 init_completion(&as->xfer_completion);
1521 atmel_get_caps(as);
1523 as->use_dma = false;
1524 as->use_pdc = false;
1525 if (as->caps.has_dma_support) {
1526 ret = atmel_spi_configure_dma(master, as);
1528 as->use_dma = true;
1532 } else if (as->caps.has_pdc_support) {
1533 as->use_pdc = true;
1537 as->addr_rx_bbuf = dma_alloc_coherent(&pdev->dev,
1539 &as->dma_addr_rx_bbuf,
1541 if (!as->addr_rx_bbuf) {
1542 as->use_dma = false;
1544 as->addr_tx_bbuf = dma_alloc_coherent(&pdev->dev,
1546 &as->dma_addr_tx_bbuf,
1548 if (!as->addr_tx_bbuf) {
1549 as->use_dma = false;
1551 as->addr_rx_bbuf,
1552 as->dma_addr_rx_bbuf);
1555 if (!as->use_dma)
1560 if (as->caps.has_dma_support && !as->use_dma)
1563 if (as->use_pdc) {
1578 as->spi_clk = clk_get_rate(clk);
1580 as->fifo_size = 0;
1582 &as->fifo_size)) {
1583 dev_info(&pdev->dev, "Using FIFO (%u data)\n", as->fifo_size);
1586 atmel_spi_init(as);
1599 atmel_get_version(as), (unsigned long)regs->start,
1608 if (as->use_dma)
1611 spi_writel(as, CR, SPI_BIT(SWRST));
1612 spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
1623 struct atmel_spi *as = spi_master_get_devdata(master);
1628 if (as->use_dma) {
1633 as->addr_tx_bbuf,
1634 as->dma_addr_tx_bbuf);
1636 as->addr_rx_bbuf,
1637 as->dma_addr_rx_bbuf);
1641 spin_lock_irq(&as->lock);
1642 spi_writel(as, CR, SPI_BIT(SWRST));
1643 spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
1644 spi_readl(as, SR);
1645 spin_unlock_irq(&as->lock);
1647 clk_disable_unprepare(as->clk);
1659 struct atmel_spi *as = spi_master_get_devdata(master);
1661 clk_disable_unprepare(as->clk);
1670 struct atmel_spi *as = spi_master_get_devdata(master);
1674 return clk_prepare_enable(as->clk);
1697 struct atmel_spi *as = spi_master_get_devdata(master);
1700 ret = clk_prepare_enable(as->clk);
1704 atmel_spi_init(as);
1706 clk_disable_unprepare(as->clk);