Lines Matching refs:dws

62 static void dw_spi_debugfs_init(struct dw_spi *dws)  in dw_spi_debugfs_init()  argument
66 snprintf(name, 32, "dw_spi%d", dws->host->bus_num); in dw_spi_debugfs_init()
67 dws->debugfs = debugfs_create_dir(name, NULL); in dw_spi_debugfs_init()
69 dws->regset.regs = dw_spi_dbgfs_regs; in dw_spi_debugfs_init()
70 dws->regset.nregs = ARRAY_SIZE(dw_spi_dbgfs_regs); in dw_spi_debugfs_init()
71 dws->regset.base = dws->regs; in dw_spi_debugfs_init()
72 debugfs_create_regset32("registers", 0400, dws->debugfs, &dws->regset); in dw_spi_debugfs_init()
75 static void dw_spi_debugfs_remove(struct dw_spi *dws) in dw_spi_debugfs_remove() argument
77 debugfs_remove_recursive(dws->debugfs); in dw_spi_debugfs_remove()
81 static inline void dw_spi_debugfs_init(struct dw_spi *dws) in dw_spi_debugfs_init() argument
85 static inline void dw_spi_debugfs_remove(struct dw_spi *dws) in dw_spi_debugfs_remove() argument
92 struct dw_spi *dws = spi_controller_get_devdata(spi->controller); in dw_spi_set_cs() local
103 dw_writel(dws, DW_SPI_SER, BIT(spi_get_chipselect(spi, 0))); in dw_spi_set_cs()
105 dw_writel(dws, DW_SPI_SER, 0); in dw_spi_set_cs()
110 static inline u32 dw_spi_tx_max(struct dw_spi *dws) in dw_spi_tx_max() argument
114 tx_room = dws->fifo_len - dw_readl(dws, DW_SPI_TXFLR); in dw_spi_tx_max()
124 rxtx_gap = dws->fifo_len - (dws->rx_len - dws->tx_len); in dw_spi_tx_max()
126 return min3((u32)dws->tx_len, tx_room, rxtx_gap); in dw_spi_tx_max()
130 static inline u32 dw_spi_rx_max(struct dw_spi *dws) in dw_spi_rx_max() argument
132 return min_t(u32, dws->rx_len, dw_readl(dws, DW_SPI_RXFLR)); in dw_spi_rx_max()
135 static void dw_writer(struct dw_spi *dws) in dw_writer() argument
137 u32 max = dw_spi_tx_max(dws); in dw_writer()
141 if (dws->tx) { in dw_writer()
142 if (dws->n_bytes == 1) in dw_writer()
143 txw = *(u8 *)(dws->tx); in dw_writer()
144 else if (dws->n_bytes == 2) in dw_writer()
145 txw = *(u16 *)(dws->tx); in dw_writer()
147 txw = *(u32 *)(dws->tx); in dw_writer()
149 dws->tx += dws->n_bytes; in dw_writer()
151 dw_write_io_reg(dws, DW_SPI_DR, txw); in dw_writer()
152 --dws->tx_len; in dw_writer()
156 static void dw_reader(struct dw_spi *dws) in dw_reader() argument
158 u32 max = dw_spi_rx_max(dws); in dw_reader()
162 rxw = dw_read_io_reg(dws, DW_SPI_DR); in dw_reader()
163 if (dws->rx) { in dw_reader()
164 if (dws->n_bytes == 1) in dw_reader()
165 *(u8 *)(dws->rx) = rxw; in dw_reader()
166 else if (dws->n_bytes == 2) in dw_reader()
167 *(u16 *)(dws->rx) = rxw; in dw_reader()
169 *(u32 *)(dws->rx) = rxw; in dw_reader()
171 dws->rx += dws->n_bytes; in dw_reader()
173 --dws->rx_len; in dw_reader()
177 int dw_spi_check_status(struct dw_spi *dws, bool raw) in dw_spi_check_status() argument
183 irq_status = dw_readl(dws, DW_SPI_RISR); in dw_spi_check_status()
185 irq_status = dw_readl(dws, DW_SPI_ISR); in dw_spi_check_status()
188 dev_err(&dws->host->dev, "RX FIFO overflow detected\n"); in dw_spi_check_status()
193 dev_err(&dws->host->dev, "RX FIFO underflow detected\n"); in dw_spi_check_status()
198 dev_err(&dws->host->dev, "TX FIFO overflow detected\n"); in dw_spi_check_status()
204 dw_spi_reset_chip(dws); in dw_spi_check_status()
205 if (dws->host->cur_msg) in dw_spi_check_status()
206 dws->host->cur_msg->status = ret; in dw_spi_check_status()
213 static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) in dw_spi_transfer_handler() argument
215 u16 irq_status = dw_readl(dws, DW_SPI_ISR); in dw_spi_transfer_handler()
217 if (dw_spi_check_status(dws, false)) { in dw_spi_transfer_handler()
218 spi_finalize_current_transfer(dws->host); in dw_spi_transfer_handler()
229 dw_reader(dws); in dw_spi_transfer_handler()
230 if (!dws->rx_len) { in dw_spi_transfer_handler()
231 dw_spi_mask_intr(dws, 0xff); in dw_spi_transfer_handler()
232 spi_finalize_current_transfer(dws->host); in dw_spi_transfer_handler()
233 } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) { in dw_spi_transfer_handler()
234 dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1); in dw_spi_transfer_handler()
243 dw_writer(dws); in dw_spi_transfer_handler()
244 if (!dws->tx_len) in dw_spi_transfer_handler()
245 dw_spi_mask_intr(dws, DW_SPI_INT_TXEI); in dw_spi_transfer_handler()
254 struct dw_spi *dws = spi_controller_get_devdata(host); in dw_spi_irq() local
255 u16 irq_status = dw_readl(dws, DW_SPI_ISR) & DW_SPI_INT_MASK; in dw_spi_irq()
261 dw_spi_mask_intr(dws, 0xff); in dw_spi_irq()
265 return dws->transfer_handler(dws); in dw_spi_irq()
268 static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) in dw_spi_prepare_cr0() argument
272 if (dw_spi_ip_is(dws, PSSI)) { in dw_spi_prepare_cr0()
308 if (dw_spi_ver_is_ge(dws, HSSI, 102A)) in dw_spi_prepare_cr0()
315 void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, in dw_spi_update_config() argument
324 cr0 |= (cfg->dfs - 1) << dws->dfs_offset; in dw_spi_update_config()
326 if (dw_spi_ip_is(dws, PSSI)) in dw_spi_update_config()
333 dw_writel(dws, DW_SPI_CTRLR0, cr0); in dw_spi_update_config()
337 dw_writel(dws, DW_SPI_CTRLR1, cfg->ndf ? cfg->ndf - 1 : 0); in dw_spi_update_config()
340 clk_div = (DIV_ROUND_UP(dws->max_freq, cfg->freq) + 1) & 0xfffe; in dw_spi_update_config()
341 speed_hz = dws->max_freq / clk_div; in dw_spi_update_config()
343 if (dws->current_freq != speed_hz) { in dw_spi_update_config()
344 dw_spi_set_clk(dws, clk_div); in dw_spi_update_config()
345 dws->current_freq = speed_hz; in dw_spi_update_config()
349 if (dws->cur_rx_sample_dly != chip->rx_sample_dly) { in dw_spi_update_config()
350 dw_writel(dws, DW_SPI_RX_SAMPLE_DLY, chip->rx_sample_dly); in dw_spi_update_config()
351 dws->cur_rx_sample_dly = chip->rx_sample_dly; in dw_spi_update_config()
356 static void dw_spi_irq_setup(struct dw_spi *dws) in dw_spi_irq_setup() argument
366 level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len); in dw_spi_irq_setup()
367 dw_writel(dws, DW_SPI_TXFTLR, level); in dw_spi_irq_setup()
368 dw_writel(dws, DW_SPI_RXFTLR, level - 1); in dw_spi_irq_setup()
370 dws->transfer_handler = dw_spi_transfer_handler; in dw_spi_irq_setup()
374 dw_spi_umask_intr(dws, imask); in dw_spi_irq_setup()
387 static int dw_spi_poll_transfer(struct dw_spi *dws, in dw_spi_poll_transfer() argument
395 nbits = dws->n_bytes * BITS_PER_BYTE; in dw_spi_poll_transfer()
398 dw_writer(dws); in dw_spi_poll_transfer()
400 delay.value = nbits * (dws->rx_len - dws->tx_len); in dw_spi_poll_transfer()
403 dw_reader(dws); in dw_spi_poll_transfer()
405 ret = dw_spi_check_status(dws, true); in dw_spi_poll_transfer()
408 } while (dws->rx_len); in dw_spi_poll_transfer()
417 struct dw_spi *dws = spi_controller_get_devdata(host); in dw_spi_transfer_one() local
425 dws->dma_mapped = 0; in dw_spi_transfer_one()
426 dws->n_bytes = roundup_pow_of_two(BITS_TO_BYTES(transfer->bits_per_word)); in dw_spi_transfer_one()
427 dws->tx = (void *)transfer->tx_buf; in dw_spi_transfer_one()
428 dws->tx_len = transfer->len / dws->n_bytes; in dw_spi_transfer_one()
429 dws->rx = transfer->rx_buf; in dw_spi_transfer_one()
430 dws->rx_len = dws->tx_len; in dw_spi_transfer_one()
435 dw_spi_enable_chip(dws, 0); in dw_spi_transfer_one()
437 dw_spi_update_config(dws, spi, &cfg); in dw_spi_transfer_one()
439 transfer->effective_speed_hz = dws->current_freq; in dw_spi_transfer_one()
442 dws->dma_mapped = spi_xfer_is_dma_mapped(host, spi, transfer); in dw_spi_transfer_one()
445 dw_spi_mask_intr(dws, 0xff); in dw_spi_transfer_one()
447 if (dws->dma_mapped) { in dw_spi_transfer_one()
448 ret = dws->dma_ops->dma_setup(dws, transfer); in dw_spi_transfer_one()
453 dw_spi_enable_chip(dws, 1); in dw_spi_transfer_one()
455 if (dws->dma_mapped) in dw_spi_transfer_one()
456 return dws->dma_ops->dma_transfer(dws, transfer); in dw_spi_transfer_one()
457 else if (dws->irq == IRQ_NOTCONNECTED) in dw_spi_transfer_one()
458 return dw_spi_poll_transfer(dws, transfer); in dw_spi_transfer_one()
460 dw_spi_irq_setup(dws); in dw_spi_transfer_one()
468 struct dw_spi *dws = spi_controller_get_devdata(host); in dw_spi_handle_err() local
470 if (dws->dma_mapped) in dw_spi_handle_err()
471 dws->dma_ops->dma_stop(dws); in dw_spi_handle_err()
473 dw_spi_reset_chip(dws); in dw_spi_handle_err()
494 static int dw_spi_init_mem_buf(struct dw_spi *dws, const struct spi_mem_op *op) in dw_spi_init_mem_buf() argument
508 out = dws->buf; in dw_spi_init_mem_buf()
530 dws->n_bytes = 1; in dw_spi_init_mem_buf()
531 dws->tx = out; in dw_spi_init_mem_buf()
532 dws->tx_len = len; in dw_spi_init_mem_buf()
534 dws->rx = op->data.buf.in; in dw_spi_init_mem_buf()
535 dws->rx_len = op->data.nbytes; in dw_spi_init_mem_buf()
537 dws->rx = NULL; in dw_spi_init_mem_buf()
538 dws->rx_len = 0; in dw_spi_init_mem_buf()
544 static void dw_spi_free_mem_buf(struct dw_spi *dws) in dw_spi_free_mem_buf() argument
546 if (dws->tx != dws->buf) in dw_spi_free_mem_buf()
547 kfree(dws->tx); in dw_spi_free_mem_buf()
550 static int dw_spi_write_then_read(struct dw_spi *dws, struct spi_device *spi) in dw_spi_write_then_read() argument
561 len = min(dws->fifo_len, dws->tx_len); in dw_spi_write_then_read()
562 buf = dws->tx; in dw_spi_write_then_read()
564 dw_write_io_reg(dws, DW_SPI_DR, *buf++); in dw_spi_write_then_read()
572 len = dws->tx_len - ((void *)buf - dws->tx); in dw_spi_write_then_read()
575 entries = readl_relaxed(dws->regs + DW_SPI_TXFLR); in dw_spi_write_then_read()
577 dev_err(&dws->host->dev, "CS de-assertion on Tx\n"); in dw_spi_write_then_read()
580 room = min(dws->fifo_len - entries, len); in dw_spi_write_then_read()
582 dw_write_io_reg(dws, DW_SPI_DR, *buf++); in dw_spi_write_then_read()
590 len = dws->rx_len; in dw_spi_write_then_read()
591 buf = dws->rx; in dw_spi_write_then_read()
593 entries = readl_relaxed(dws->regs + DW_SPI_RXFLR); in dw_spi_write_then_read()
595 sts = readl_relaxed(dws->regs + DW_SPI_RISR); in dw_spi_write_then_read()
597 dev_err(&dws->host->dev, "FIFO overflow on Rx\n"); in dw_spi_write_then_read()
604 *buf++ = dw_read_io_reg(dws, DW_SPI_DR); in dw_spi_write_then_read()
610 static inline bool dw_spi_ctlr_busy(struct dw_spi *dws) in dw_spi_ctlr_busy() argument
612 return dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_BUSY; in dw_spi_ctlr_busy()
615 static int dw_spi_wait_mem_op_done(struct dw_spi *dws) in dw_spi_wait_mem_op_done() argument
622 nents = dw_readl(dws, DW_SPI_TXFLR); in dw_spi_wait_mem_op_done()
623 ns = NSEC_PER_SEC / dws->current_freq * nents; in dw_spi_wait_mem_op_done()
624 ns *= dws->n_bytes * BITS_PER_BYTE; in dw_spi_wait_mem_op_done()
634 while (dw_spi_ctlr_busy(dws) && retry--) in dw_spi_wait_mem_op_done()
638 dev_err(&dws->host->dev, "Mem op hanged up\n"); in dw_spi_wait_mem_op_done()
645 static void dw_spi_stop_mem_op(struct dw_spi *dws, struct spi_device *spi) in dw_spi_stop_mem_op() argument
647 dw_spi_enable_chip(dws, 0); in dw_spi_stop_mem_op()
649 dw_spi_enable_chip(dws, 1); in dw_spi_stop_mem_op()
662 struct dw_spi *dws = spi_controller_get_devdata(mem->spi->controller); in dw_spi_exec_mem_op() local
671 ret = dw_spi_init_mem_buf(dws, op); in dw_spi_exec_mem_op()
680 cfg.freq = clamp(op->max_freq, 0U, dws->max_mem_freq); in dw_spi_exec_mem_op()
688 dw_spi_enable_chip(dws, 0); in dw_spi_exec_mem_op()
690 dw_spi_update_config(dws, mem->spi, &cfg); in dw_spi_exec_mem_op()
692 dw_spi_mask_intr(dws, 0xff); in dw_spi_exec_mem_op()
694 dw_spi_enable_chip(dws, 1); in dw_spi_exec_mem_op()
727 ret = dw_spi_write_then_read(dws, mem->spi); in dw_spi_exec_mem_op()
740 ret = dw_spi_wait_mem_op_done(dws); in dw_spi_exec_mem_op()
742 ret = dw_spi_check_status(dws, true); in dw_spi_exec_mem_op()
745 dw_spi_stop_mem_op(dws, mem->spi); in dw_spi_exec_mem_op()
747 dw_spi_free_mem_buf(dws); in dw_spi_exec_mem_op()
761 static void dw_spi_init_mem_ops(struct dw_spi *dws) in dw_spi_init_mem_ops() argument
763 if (!dws->mem_ops.exec_op && !(dws->caps & DW_SPI_CAP_CS_OVERRIDE) && in dw_spi_init_mem_ops()
764 !dws->set_cs) { in dw_spi_init_mem_ops()
765 dws->mem_ops.adjust_op_size = dw_spi_adjust_mem_op_size; in dw_spi_init_mem_ops()
766 dws->mem_ops.supports_op = dw_spi_supports_mem_op; in dw_spi_init_mem_ops()
767 dws->mem_ops.exec_op = dw_spi_exec_mem_op; in dw_spi_init_mem_ops()
768 if (!dws->max_mem_freq) in dw_spi_init_mem_ops()
769 dws->max_mem_freq = dws->max_freq; in dw_spi_init_mem_ops()
776 struct dw_spi *dws = spi_controller_get_devdata(spi->controller); in dw_spi_setup() local
782 struct dw_spi *dws = spi_controller_get_devdata(spi->controller); in dw_spi_setup() local
794 rx_sample_dly_ns = dws->def_rx_sample_dly_ns; in dw_spi_setup()
797 dws->max_freq); in dw_spi_setup()
805 chip->cr0 = dw_spi_prepare_cr0(dws, spi); in dw_spi_setup()
819 static void dw_spi_hw_init(struct device *dev, struct dw_spi *dws) in dw_spi_hw_init() argument
821 dw_spi_reset_chip(dws); in dw_spi_hw_init()
828 if (!dws->ver) { in dw_spi_hw_init()
829 dws->ver = dw_readl(dws, DW_SPI_VERSION); in dw_spi_hw_init()
832 dw_spi_ip_is(dws, PSSI) ? " APB " : " ", in dw_spi_hw_init()
833 DW_SPI_GET_BYTE(dws->ver, 3), DW_SPI_GET_BYTE(dws->ver, 2), in dw_spi_hw_init()
834 DW_SPI_GET_BYTE(dws->ver, 1)); in dw_spi_hw_init()
841 if (!dws->num_cs) { in dw_spi_hw_init()
844 dw_writel(dws, DW_SPI_SER, 0xffff); in dw_spi_hw_init()
845 ser = dw_readl(dws, DW_SPI_SER); in dw_spi_hw_init()
846 dw_writel(dws, DW_SPI_SER, 0); in dw_spi_hw_init()
848 dws->num_cs = hweight16(ser); in dw_spi_hw_init()
855 if (!dws->fifo_len) { in dw_spi_hw_init()
859 dw_writel(dws, DW_SPI_TXFTLR, fifo); in dw_spi_hw_init()
860 if (fifo != dw_readl(dws, DW_SPI_TXFTLR)) in dw_spi_hw_init()
863 dw_writel(dws, DW_SPI_TXFTLR, 0); in dw_spi_hw_init()
865 dws->fifo_len = (fifo == 1) ? 0 : fifo; in dw_spi_hw_init()
866 dev_dbg(dev, "Detected FIFO size: %u bytes\n", dws->fifo_len); in dw_spi_hw_init()
874 if (dw_spi_ip_is(dws, PSSI)) { in dw_spi_hw_init()
875 u32 cr0, tmp = dw_readl(dws, DW_SPI_CTRLR0); in dw_spi_hw_init()
877 dw_spi_enable_chip(dws, 0); in dw_spi_hw_init()
878 dw_writel(dws, DW_SPI_CTRLR0, 0xffffffff); in dw_spi_hw_init()
879 cr0 = dw_readl(dws, DW_SPI_CTRLR0); in dw_spi_hw_init()
880 dw_writel(dws, DW_SPI_CTRLR0, tmp); in dw_spi_hw_init()
881 dw_spi_enable_chip(dws, 1); in dw_spi_hw_init()
884 dws->caps |= DW_SPI_CAP_DFS32; in dw_spi_hw_init()
885 dws->dfs_offset = __bf_shf(DW_PSSI_CTRLR0_DFS32_MASK); in dw_spi_hw_init()
889 dws->caps |= DW_SPI_CAP_DFS32; in dw_spi_hw_init()
893 if (dws->caps & DW_SPI_CAP_CS_OVERRIDE) in dw_spi_hw_init()
894 dw_writel(dws, DW_SPI_CS_OVERRIDE, 0xF); in dw_spi_hw_init()
901 int dw_spi_add_host(struct device *dev, struct dw_spi *dws) in dw_spi_add_host() argument
906 if (!dws) in dw_spi_add_host()
915 dws->host = host; in dw_spi_add_host()
916 dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); in dw_spi_add_host()
918 spi_controller_set_devdata(host, dws); in dw_spi_add_host()
921 dw_spi_hw_init(dev, dws); in dw_spi_add_host()
923 ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), in dw_spi_add_host()
930 dw_spi_init_mem_ops(dws); in dw_spi_add_host()
934 if (dws->caps & DW_SPI_CAP_DFS32) in dw_spi_add_host()
938 host->bus_num = dws->bus_num; in dw_spi_add_host()
939 host->num_chipselect = dws->num_cs; in dw_spi_add_host()
942 if (dws->set_cs) in dw_spi_add_host()
943 host->set_cs = dws->set_cs; in dw_spi_add_host()
948 if (dws->mem_ops.exec_op) { in dw_spi_add_host()
949 host->mem_ops = &dws->mem_ops; in dw_spi_add_host()
952 host->max_speed_hz = dws->max_freq; in dw_spi_add_host()
958 &dws->def_rx_sample_dly_ns); in dw_spi_add_host()
960 if (dws->dma_ops && dws->dma_ops->dma_init) { in dw_spi_add_host()
961 ret = dws->dma_ops->dma_init(dev, dws); in dw_spi_add_host()
967 host->can_dma = dws->dma_ops->can_dma; in dw_spi_add_host()
978 dw_spi_debugfs_init(dws); in dw_spi_add_host()
982 if (dws->dma_ops && dws->dma_ops->dma_exit) in dw_spi_add_host()
983 dws->dma_ops->dma_exit(dws); in dw_spi_add_host()
984 dw_spi_enable_chip(dws, 0); in dw_spi_add_host()
986 free_irq(dws->irq, host); in dw_spi_add_host()
993 void dw_spi_remove_host(struct dw_spi *dws) in dw_spi_remove_host() argument
995 dw_spi_debugfs_remove(dws); in dw_spi_remove_host()
997 spi_unregister_controller(dws->host); in dw_spi_remove_host()
999 if (dws->dma_ops && dws->dma_ops->dma_exit) in dw_spi_remove_host()
1000 dws->dma_ops->dma_exit(dws); in dw_spi_remove_host()
1002 dw_spi_shutdown_chip(dws); in dw_spi_remove_host()
1004 free_irq(dws->irq, dws->host); in dw_spi_remove_host()
1008 int dw_spi_suspend_host(struct dw_spi *dws) in dw_spi_suspend_host() argument
1012 ret = spi_controller_suspend(dws->host); in dw_spi_suspend_host()
1016 dw_spi_shutdown_chip(dws); in dw_spi_suspend_host()
1021 int dw_spi_resume_host(struct dw_spi *dws) in dw_spi_resume_host() argument
1023 dw_spi_hw_init(&dws->host->dev, dws); in dw_spi_resume_host()
1024 return spi_controller_resume(dws->host); in dw_spi_resume_host()