Lines Matching refs:dws

39 	struct dw_spi *dws = file->private_data;  in dw_spi_show_regs()  local
49 "%s registers:\n", dev_name(&dws->master->dev)); in dw_spi_show_regs()
53 "CTRL0: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL0)); in dw_spi_show_regs()
55 "CTRL1: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL1)); in dw_spi_show_regs()
57 "SSIENR: \t0x%08x\n", dw_readl(dws, DW_SPI_SSIENR)); in dw_spi_show_regs()
59 "SER: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SER)); in dw_spi_show_regs()
61 "BAUDR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_BAUDR)); in dw_spi_show_regs()
63 "TXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_TXFLTR)); in dw_spi_show_regs()
65 "RXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_RXFLTR)); in dw_spi_show_regs()
67 "TXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_TXFLR)); in dw_spi_show_regs()
69 "RXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_RXFLR)); in dw_spi_show_regs()
71 "SR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SR)); in dw_spi_show_regs()
73 "IMR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_IMR)); in dw_spi_show_regs()
75 "ISR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_ISR)); in dw_spi_show_regs()
77 "DMACR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_DMACR)); in dw_spi_show_regs()
79 "DMATDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMATDLR)); in dw_spi_show_regs()
81 "DMARDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMARDLR)); in dw_spi_show_regs()
97 static int dw_spi_debugfs_init(struct dw_spi *dws) in dw_spi_debugfs_init() argument
101 snprintf(name, 32, "dw_spi%d", dws->master->bus_num); in dw_spi_debugfs_init()
102 dws->debugfs = debugfs_create_dir(name, NULL); in dw_spi_debugfs_init()
103 if (!dws->debugfs) in dw_spi_debugfs_init()
107 dws->debugfs, (void *)dws, &dw_spi_regs_ops); in dw_spi_debugfs_init()
111 static void dw_spi_debugfs_remove(struct dw_spi *dws) in dw_spi_debugfs_remove() argument
113 debugfs_remove_recursive(dws->debugfs); in dw_spi_debugfs_remove()
117 static inline int dw_spi_debugfs_init(struct dw_spi *dws) in dw_spi_debugfs_init() argument
122 static inline void dw_spi_debugfs_remove(struct dw_spi *dws) in dw_spi_debugfs_remove() argument
129 struct dw_spi *dws = spi_controller_get_devdata(spi->controller); in dw_spi_set_cs() local
136 dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); in dw_spi_set_cs()
137 else if (dws->cs_override) in dw_spi_set_cs()
138 dw_writel(dws, DW_SPI_SER, 0); in dw_spi_set_cs()
143 static inline u32 tx_max(struct dw_spi *dws) in tx_max() argument
147 tx_left = (dws->tx_end - dws->tx) / dws->n_bytes; in tx_max()
148 tx_room = dws->fifo_len - dw_readl(dws, DW_SPI_TXFLR); in tx_max()
158 rxtx_gap = ((dws->rx_end - dws->rx) - (dws->tx_end - dws->tx)) in tx_max()
159 / dws->n_bytes; in tx_max()
161 return min3(tx_left, tx_room, (u32) (dws->fifo_len - rxtx_gap)); in tx_max()
165 static inline u32 rx_max(struct dw_spi *dws) in rx_max() argument
167 u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; in rx_max()
169 return min_t(u32, rx_left, dw_readl(dws, DW_SPI_RXFLR)); in rx_max()
172 static void dw_writer(struct dw_spi *dws) in dw_writer() argument
174 u32 max = tx_max(dws); in dw_writer()
179 if (dws->tx_end - dws->len) { in dw_writer()
180 if (dws->n_bytes == 1) in dw_writer()
181 txw = *(u8 *)(dws->tx); in dw_writer()
183 txw = *(u16 *)(dws->tx); in dw_writer()
185 dw_write_io_reg(dws, DW_SPI_DR, txw); in dw_writer()
186 dws->tx += dws->n_bytes; in dw_writer()
190 static void dw_reader(struct dw_spi *dws) in dw_reader() argument
192 u32 max = rx_max(dws); in dw_reader()
196 rxw = dw_read_io_reg(dws, DW_SPI_DR); in dw_reader()
198 if (dws->rx_end - dws->len) { in dw_reader()
199 if (dws->n_bytes == 1) in dw_reader()
200 *(u8 *)(dws->rx) = rxw; in dw_reader()
202 *(u16 *)(dws->rx) = rxw; in dw_reader()
204 dws->rx += dws->n_bytes; in dw_reader()
208 static void int_error_stop(struct dw_spi *dws, const char *msg) in int_error_stop() argument
210 spi_reset_chip(dws); in int_error_stop()
212 dev_err(&dws->master->dev, "%s\n", msg); in int_error_stop()
213 dws->master->cur_msg->status = -EIO; in int_error_stop()
214 spi_finalize_current_transfer(dws->master); in int_error_stop()
217 static irqreturn_t interrupt_transfer(struct dw_spi *dws) in interrupt_transfer() argument
219 u16 irq_status = dw_readl(dws, DW_SPI_ISR); in interrupt_transfer()
223 dw_readl(dws, DW_SPI_ICR); in interrupt_transfer()
224 int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun"); in interrupt_transfer()
228 dw_reader(dws); in interrupt_transfer()
229 if (dws->rx_end == dws->rx) { in interrupt_transfer()
230 spi_mask_intr(dws, SPI_INT_TXEI); in interrupt_transfer()
231 spi_finalize_current_transfer(dws->master); in interrupt_transfer()
235 spi_mask_intr(dws, SPI_INT_TXEI); in interrupt_transfer()
236 dw_writer(dws); in interrupt_transfer()
238 spi_umask_intr(dws, SPI_INT_TXEI); in interrupt_transfer()
247 struct dw_spi *dws = spi_controller_get_devdata(master); in dw_spi_irq() local
248 u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f; in dw_spi_irq()
254 spi_mask_intr(dws, SPI_INT_TXEI); in dw_spi_irq()
258 return dws->transfer_handler(dws); in dw_spi_irq()
262 static int poll_transfer(struct dw_spi *dws) in poll_transfer() argument
265 dw_writer(dws); in poll_transfer()
266 dw_reader(dws); in poll_transfer()
268 } while (dws->rx_end > dws->rx); in poll_transfer()
276 struct dw_spi *dws = spi_controller_get_devdata(master); in dw_spi_transfer_one() local
283 dws->dma_mapped = 0; in dw_spi_transfer_one()
285 dws->tx = (void *)transfer->tx_buf; in dw_spi_transfer_one()
286 dws->tx_end = dws->tx + transfer->len; in dw_spi_transfer_one()
287 dws->rx = transfer->rx_buf; in dw_spi_transfer_one()
288 dws->rx_end = dws->rx + transfer->len; in dw_spi_transfer_one()
289 dws->len = transfer->len; in dw_spi_transfer_one()
291 spi_enable_chip(dws, 0); in dw_spi_transfer_one()
294 if (transfer->speed_hz != dws->current_freq) { in dw_spi_transfer_one()
297 chip->clk_div = (DIV_ROUND_UP(dws->max_freq, transfer->speed_hz) + 1) & 0xfffe; in dw_spi_transfer_one()
300 dws->current_freq = transfer->speed_hz; in dw_spi_transfer_one()
301 spi_set_clk(dws, chip->clk_div); in dw_spi_transfer_one()
304 dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE); in dw_spi_transfer_one()
305 dws->dma_width = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE); in dw_spi_transfer_one()
319 if (dws->rx && dws->tx) in dw_spi_transfer_one()
321 else if (dws->rx) in dw_spi_transfer_one()
330 dw_writel(dws, DW_SPI_CTRL0, cr0); in dw_spi_transfer_one()
334 dws->dma_mapped = master->cur_msg_mapped; in dw_spi_transfer_one()
337 spi_mask_intr(dws, 0xff); in dw_spi_transfer_one()
343 if (dws->dma_mapped) { in dw_spi_transfer_one()
344 ret = dws->dma_ops->dma_setup(dws, transfer); in dw_spi_transfer_one()
346 spi_enable_chip(dws, 1); in dw_spi_transfer_one()
350 txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes); in dw_spi_transfer_one()
351 dw_writel(dws, DW_SPI_TXFLTR, txlevel); in dw_spi_transfer_one()
356 spi_umask_intr(dws, imask); in dw_spi_transfer_one()
358 dws->transfer_handler = interrupt_transfer; in dw_spi_transfer_one()
361 spi_enable_chip(dws, 1); in dw_spi_transfer_one()
363 if (dws->dma_mapped) { in dw_spi_transfer_one()
364 ret = dws->dma_ops->dma_transfer(dws, transfer); in dw_spi_transfer_one()
370 return poll_transfer(dws); in dw_spi_transfer_one()
378 struct dw_spi *dws = spi_controller_get_devdata(master); in dw_spi_handle_err() local
380 if (dws->dma_mapped) in dw_spi_handle_err()
381 dws->dma_ops->dma_stop(dws); in dw_spi_handle_err()
383 spi_reset_chip(dws); in dw_spi_handle_err()
430 static void spi_hw_init(struct device *dev, struct dw_spi *dws) in spi_hw_init() argument
432 spi_reset_chip(dws); in spi_hw_init()
438 if (!dws->fifo_len) { in spi_hw_init()
442 dw_writel(dws, DW_SPI_TXFLTR, fifo); in spi_hw_init()
443 if (fifo != dw_readl(dws, DW_SPI_TXFLTR)) in spi_hw_init()
446 dw_writel(dws, DW_SPI_TXFLTR, 0); in spi_hw_init()
448 dws->fifo_len = (fifo == 1) ? 0 : fifo; in spi_hw_init()
449 dev_dbg(dev, "Detected FIFO size: %u bytes\n", dws->fifo_len); in spi_hw_init()
453 if (dws->cs_override) in spi_hw_init()
454 dw_writel(dws, DW_SPI_CS_OVERRIDE, 0xF); in spi_hw_init()
457 int dw_spi_add_host(struct device *dev, struct dw_spi *dws) in dw_spi_add_host() argument
462 BUG_ON(dws == NULL); in dw_spi_add_host()
468 dws->master = master; in dw_spi_add_host()
469 dws->type = SSI_MOTO_SPI; in dw_spi_add_host()
470 dws->dma_inited = 0; in dw_spi_add_host()
471 dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); in dw_spi_add_host()
473 spi_controller_set_devdata(master, dws); in dw_spi_add_host()
475 ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), in dw_spi_add_host()
485 master->bus_num = dws->bus_num; in dw_spi_add_host()
486 master->num_chipselect = dws->num_cs; in dw_spi_add_host()
492 master->max_speed_hz = dws->max_freq; in dw_spi_add_host()
497 if (dws->set_cs) in dw_spi_add_host()
498 master->set_cs = dws->set_cs; in dw_spi_add_host()
501 spi_hw_init(dev, dws); in dw_spi_add_host()
503 if (dws->dma_ops && dws->dma_ops->dma_init) { in dw_spi_add_host()
504 ret = dws->dma_ops->dma_init(dws); in dw_spi_add_host()
507 dws->dma_inited = 0; in dw_spi_add_host()
509 master->can_dma = dws->dma_ops->can_dma; in dw_spi_add_host()
519 dw_spi_debugfs_init(dws); in dw_spi_add_host()
523 if (dws->dma_ops && dws->dma_ops->dma_exit) in dw_spi_add_host()
524 dws->dma_ops->dma_exit(dws); in dw_spi_add_host()
525 spi_enable_chip(dws, 0); in dw_spi_add_host()
526 free_irq(dws->irq, master); in dw_spi_add_host()
533 void dw_spi_remove_host(struct dw_spi *dws) in dw_spi_remove_host() argument
535 dw_spi_debugfs_remove(dws); in dw_spi_remove_host()
537 if (dws->dma_ops && dws->dma_ops->dma_exit) in dw_spi_remove_host()
538 dws->dma_ops->dma_exit(dws); in dw_spi_remove_host()
540 spi_shutdown_chip(dws); in dw_spi_remove_host()
542 free_irq(dws->irq, dws->master); in dw_spi_remove_host()
546 int dw_spi_suspend_host(struct dw_spi *dws) in dw_spi_suspend_host() argument
550 ret = spi_controller_suspend(dws->master); in dw_spi_suspend_host()
554 spi_shutdown_chip(dws); in dw_spi_suspend_host()
559 int dw_spi_resume_host(struct dw_spi *dws) in dw_spi_resume_host() argument
561 spi_hw_init(&dws->master->dev, dws); in dw_spi_resume_host()
562 return spi_controller_resume(dws->master); in dw_spi_resume_host()