Lines Matching +full:sc9836 +full:- +full:uart
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2012-2015 Spreadtrum Communications Inc.
10 #include <linux/dma-mapping.h>
11 #include <linux/dma/sprd-dma.h>
162 return readl_relaxed(port->membase + offset); in serial_in()
168 writel_relaxed(value, port->membase + offset); in serial_out()
202 if (sp->rx_dma.enable) in sprd_stop_rx()
203 dmaengine_terminate_all(sp->rx_dma.chn); in sprd_stop_rx()
234 dmaengine_pause(sp->tx_dma.chn); in sprd_stop_tx_dma()
236 dmaengine_tx_status(sp->tx_dma.chn, sp->tx_dma.cookie, &state); in sprd_stop_tx_dma()
238 trans_len = state.residue - sp->tx_dma.phys_addr; in sprd_stop_tx_dma()
240 dma_unmap_single(port->dev, sp->tx_dma.phys_addr, in sprd_stop_tx_dma()
241 sp->tx_dma.trans_len, DMA_TO_DEVICE); in sprd_stop_tx_dma()
244 dmaengine_terminate_all(sp->tx_dma.chn); in sprd_stop_tx_dma()
245 sp->tx_dma.trans_len = 0; in sprd_stop_tx_dma()
252 struct tty_port *tport = &port->state->port; in sprd_tx_buf_remap()
255 sp->tx_dma.trans_len = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, in sprd_tx_buf_remap()
258 sp->tx_dma.phys_addr = dma_map_single(port->dev, tail, in sprd_tx_buf_remap()
259 sp->tx_dma.trans_len, in sprd_tx_buf_remap()
261 return dma_mapping_error(port->dev, sp->tx_dma.phys_addr); in sprd_tx_buf_remap()
269 struct tty_port *tport = &port->state->port; in sprd_complete_tx_dma()
273 dma_unmap_single(port->dev, sp->tx_dma.phys_addr, in sprd_complete_tx_dma()
274 sp->tx_dma.trans_len, DMA_TO_DEVICE); in sprd_complete_tx_dma()
276 uart_xmit_advance(port, sp->tx_dma.trans_len); in sprd_complete_tx_dma()
278 if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) in sprd_complete_tx_dma()
281 if (kfifo_is_empty(&tport->xmit_fifo) || sprd_tx_buf_remap(port) || in sprd_complete_tx_dma()
283 sp->tx_dma.trans_len = 0; in sprd_complete_tx_dma()
301 dma_des = dmaengine_prep_slave_single(ud->chn, ud->phys_addr, trans_len, in sprd_uart_dma_submit()
304 return -ENODEV; in sprd_uart_dma_submit()
306 dma_des->callback = callback; in sprd_uart_dma_submit()
307 dma_des->callback_param = port; in sprd_uart_dma_submit()
309 ud->cookie = dmaengine_submit(dma_des); in sprd_uart_dma_submit()
310 if (dma_submit_error(ud->cookie)) in sprd_uart_dma_submit()
311 return dma_submit_error(ud->cookie); in sprd_uart_dma_submit()
313 dma_async_issue_pending(ud->chn); in sprd_uart_dma_submit()
322 u32 burst = sp->tx_dma.trans_len > SPRD_TX_FIFO_FULL ? in sprd_tx_dma_config()
323 SPRD_TX_FIFO_FULL : sp->tx_dma.trans_len; in sprd_tx_dma_config()
326 .dst_addr = port->mapbase + SPRD_TXD, in sprd_tx_dma_config()
332 ret = dmaengine_slave_config(sp->tx_dma.chn, &cfg); in sprd_tx_dma_config()
336 return sprd_uart_dma_submit(port, &sp->tx_dma, sp->tx_dma.trans_len, in sprd_tx_dma_config()
344 struct tty_port *tport = &port->state->port; in sprd_start_tx_dma()
346 if (port->x_char) { in sprd_start_tx_dma()
347 serial_out(port, SPRD_TXD, port->x_char); in sprd_start_tx_dma()
348 port->icount.tx++; in sprd_start_tx_dma()
349 port->x_char = 0; in sprd_start_tx_dma()
353 if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) { in sprd_start_tx_dma()
358 if (sp->tx_dma.trans_len) in sprd_start_tx_dma()
362 sp->tx_dma.trans_len = 0; in sprd_start_tx_dma()
376 sp->rx_dma.virt = dma_alloc_coherent(sp->port.dev, SPRD_UART_RX_SIZE, in sprd_rx_alloc_buf()
377 &sp->rx_dma.phys_addr, GFP_KERNEL); in sprd_rx_alloc_buf()
378 if (!sp->rx_dma.virt) in sprd_rx_alloc_buf()
379 return -ENOMEM; in sprd_rx_alloc_buf()
386 if (sp->rx_dma.virt) in sprd_rx_free_buf()
387 dma_free_coherent(sp->port.dev, SPRD_UART_RX_SIZE, in sprd_rx_free_buf()
388 sp->rx_dma.virt, sp->rx_dma.phys_addr); in sprd_rx_free_buf()
389 sp->rx_dma.virt = NULL; in sprd_rx_free_buf()
397 .src_addr = port->mapbase + SPRD_RXD, in sprd_rx_dma_config()
403 return dmaengine_slave_config(sp->rx_dma.chn, &cfg); in sprd_rx_dma_config()
410 struct tty_port *tty = &port->state->port; in sprd_uart_dma_rx()
412 port->icount.rx += sp->rx_dma.trans_len; in sprd_uart_dma_rx()
413 tty_insert_flip_string(tty, sp->rx_buf_tail, sp->rx_dma.trans_len); in sprd_uart_dma_rx()
424 status = dmaengine_tx_status(sp->rx_dma.chn, in sprd_uart_dma_irq()
425 sp->rx_dma.cookie, &state); in sprd_uart_dma_irq()
429 if (!state.residue && sp->pos == sp->rx_dma.phys_addr) in sprd_uart_dma_irq()
433 sp->rx_dma.trans_len = SPRD_UART_RX_SIZE + in sprd_uart_dma_irq()
434 sp->rx_dma.phys_addr - sp->pos; in sprd_uart_dma_irq()
435 sp->pos = sp->rx_dma.phys_addr; in sprd_uart_dma_irq()
437 sp->rx_dma.trans_len = state.residue - sp->pos; in sprd_uart_dma_irq()
438 sp->pos = state.residue; in sprd_uart_dma_irq()
442 sp->rx_buf_tail += sp->rx_dma.trans_len; in sprd_uart_dma_irq()
456 status = dmaengine_tx_status(sp->rx_dma.chn, in sprd_complete_rx_dma()
457 sp->rx_dma.cookie, &state); in sprd_complete_rx_dma()
464 if (sp->pos != sp->rx_dma.phys_addr) { in sprd_complete_rx_dma()
465 sp->rx_dma.trans_len = SPRD_UART_RX_SIZE + in sprd_complete_rx_dma()
466 sp->rx_dma.phys_addr - sp->pos; in sprd_complete_rx_dma()
468 sp->rx_buf_tail += sp->rx_dma.trans_len; in sprd_complete_rx_dma()
483 if (!sp->rx_dma.enable) in sprd_start_dma_rx()
486 sp->pos = sp->rx_dma.phys_addr; in sprd_start_dma_rx()
487 sp->rx_buf_tail = sp->rx_dma.virt; in sprd_start_dma_rx()
493 return sprd_uart_dma_submit(port, &sp->rx_dma, SPRD_UART_RX_SIZE, in sprd_start_dma_rx()
504 if (sp->rx_dma.enable) in sprd_release_dma()
505 dma_release_channel(sp->rx_dma.chn); in sprd_release_dma()
507 if (sp->tx_dma.enable) in sprd_release_dma()
508 dma_release_channel(sp->tx_dma.chn); in sprd_release_dma()
510 sp->tx_dma.enable = false; in sprd_release_dma()
511 sp->rx_dma.enable = false; in sprd_release_dma()
519 sp->tx_dma.enable = true; in sprd_request_dma()
520 sp->rx_dma.enable = true; in sprd_request_dma()
522 sp->tx_dma.chn = dma_request_chan(port->dev, "tx"); in sprd_request_dma()
523 if (IS_ERR(sp->tx_dma.chn)) { in sprd_request_dma()
524 dev_err(port->dev, "request TX DMA channel failed, ret = %ld\n", in sprd_request_dma()
525 PTR_ERR(sp->tx_dma.chn)); in sprd_request_dma()
526 sp->tx_dma.enable = false; in sprd_request_dma()
529 sp->rx_dma.chn = dma_request_chan(port->dev, "rx"); in sprd_request_dma()
530 if (IS_ERR(sp->rx_dma.chn)) { in sprd_request_dma()
531 dev_err(port->dev, "request RX DMA channel failed, ret = %ld\n", in sprd_request_dma()
532 PTR_ERR(sp->rx_dma.chn)); in sprd_request_dma()
533 sp->rx_dma.enable = false; in sprd_request_dma()
543 if (sp->tx_dma.enable) { in sprd_stop_tx()
564 if (sp->tx_dma.enable) { in sprd_start_tx()
591 port->icount.brk++; in handle_lsr_errors()
596 port->icount.parity++; in handle_lsr_errors()
598 port->icount.frame++; in handle_lsr_errors()
600 port->icount.overrun++; in handle_lsr_errors()
603 *lsr &= port->read_status_mask; in handle_lsr_errors()
618 struct tty_port *tty = &port->state->port; in sprd_rx()
622 if (sp->rx_dma.enable) { in sprd_rx()
628 max_count--) { in sprd_rx()
632 port->icount.rx++; in sprd_rx()
674 if (ims & sp->pdata->timeout_imsr) in sprd_handle_irq()
675 serial_out(port, SPRD_ICLR, sp->pdata->timeout_iclr); in sprd_handle_irq()
681 sp->pdata->timeout_imsr)) in sprd_handle_irq()
698 if (!(sp->rx_dma.enable || sp->tx_dma.enable)) in sprd_uart_dma_startup()
703 sp->rx_dma.enable = false; in sprd_uart_dma_startup()
704 dma_release_channel(sp->rx_dma.chn); in sprd_uart_dma_startup()
705 dev_warn(port->dev, "fail to start RX dma mode\n"); in sprd_uart_dma_startup()
724 while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK) in sprd_startup()
729 while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK) in sprd_startup()
738 snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line); in sprd_startup()
742 ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq, in sprd_startup()
743 IRQF_SHARED, sp->name, port); in sprd_startup()
745 dev_err(port->dev, "fail to request serial irq %d, ret=%d\n", in sprd_startup()
746 port->irq, ret); in sprd_startup()
756 ien |= SPRD_IEN_BREAK_DETECT | sp->pdata->timeout_ien; in sprd_startup()
757 if (!sp->rx_dma.enable) in sprd_startup()
770 devm_free_irq(port->dev, port->irq, port); in sprd_shutdown()
783 quot = port->uartclk / baud; in sprd_set_termios()
786 switch (termios->c_cflag & CSIZE) { in sprd_set_termios()
804 if (termios->c_cflag & CSTOPB) in sprd_set_termios()
811 termios->c_cflag &= ~CMSPAR; /* no support mark/space */ in sprd_set_termios()
812 if (termios->c_cflag & PARENB) { in sprd_set_termios()
814 if (termios->c_cflag & PARODD) in sprd_set_termios()
822 /* update the per-port timeout */ in sprd_set_termios()
823 uart_update_timeout(port, termios->c_cflag, baud); in sprd_set_termios()
825 port->read_status_mask = SPRD_LSR_OE; in sprd_set_termios()
826 if (termios->c_iflag & INPCK) in sprd_set_termios()
827 port->read_status_mask |= SPRD_LSR_FE | SPRD_LSR_PE; in sprd_set_termios()
828 if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) in sprd_set_termios()
829 port->read_status_mask |= SPRD_LSR_BI; in sprd_set_termios()
832 port->ignore_status_mask = 0; in sprd_set_termios()
833 if (termios->c_iflag & IGNPAR) in sprd_set_termios()
834 port->ignore_status_mask |= SPRD_LSR_PE | SPRD_LSR_FE; in sprd_set_termios()
835 if (termios->c_iflag & IGNBRK) { in sprd_set_termios()
836 port->ignore_status_mask |= SPRD_LSR_BI; in sprd_set_termios()
841 if (termios->c_iflag & IGNPAR) in sprd_set_termios()
842 port->ignore_status_mask |= SPRD_LSR_OE; in sprd_set_termios()
848 if (termios->c_cflag & CRTSCTS) { in sprd_set_termios()
889 port->type = PORT_SPRD; in sprd_config_port()
894 if (ser->type != PORT_SPRD) in sprd_verify_port()
895 return -EINVAL; in sprd_verify_port()
896 if (port->irq != ser->irq) in sprd_verify_port()
897 return -EINVAL; in sprd_verify_port()
898 if (port->iotype != ser->io_type) in sprd_verify_port()
899 return -EINVAL; in sprd_verify_port()
911 clk_prepare_enable(sup->clk); in sprd_pm()
914 clk_disable_unprepare(sup->clk); in sprd_pm()
922 if (port->state->pm_state != UART_PM_STATE_ON) { in sprd_poll_init()
924 port->state->pm_state = UART_PM_STATE_ON; in sprd_poll_init()
979 if (--tmout == 0) in wait_for_xmitr()
994 struct uart_port *port = &sprd_port[co->index]->port; in sprd_console_write()
998 if (port->sysrq) in sprd_console_write()
1022 if (co->index >= UART_NR_MAX || co->index < 0) in sprd_console_setup()
1023 co->index = 0; in sprd_console_setup()
1025 sprd_uart_port = sprd_port[co->index]; in sprd_console_setup()
1026 if (!sprd_uart_port || !sprd_uart_port->port.membase) { in sprd_console_setup()
1027 pr_info("serial port %d not yet initialized\n", co->index); in sprd_console_setup()
1028 return -ENODEV; in sprd_console_setup()
1034 return uart_set_options(&sprd_uart_port->port, co, baud, in sprd_console_setup()
1045 .index = -1,
1063 while (timeout-- && in sprd_putc()
1064 !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) in sprd_putc()
1067 writeb(c, port->membase + SPRD_TXD); in sprd_putc()
1072 struct earlycon_device *dev = con->data; in sprd_early_write()
1074 uart_console_write(&dev->port, s, n, sprd_putc); in sprd_early_write()
1080 if (!device->port.membase) in sprd_early_console_setup()
1081 return -ENODEV; in sprd_early_console_setup()
1083 device->con->write = sprd_early_write; in sprd_early_console_setup()
1086 OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart",
1108 uart_remove_one_port(&sprd_uart_driver, &sup->port); in sprd_remove()
1109 sprd_port[sup->port.line] = NULL; in sprd_remove()
1111 sprd_ports_num--; in sprd_remove()
1122 if ((cons && cons->index >= 0 && cons->index == uport->line) || in sprd_uart_is_console()
1123 of_console_check(uport->dev->of_node, SPRD_TTY_NAME, uport->line)) in sprd_uart_is_console()
1134 clk_uart = devm_clk_get(uport->dev, "uart"); in sprd_clk_init()
1136 dev_warn(uport->dev, "uart%d can't get uart clock\n", in sprd_clk_init()
1137 uport->line); in sprd_clk_init()
1141 clk_parent = devm_clk_get(uport->dev, "source"); in sprd_clk_init()
1143 dev_warn(uport->dev, "uart%d can't get source clock\n", in sprd_clk_init()
1144 uport->line); in sprd_clk_init()
1149 uport->uartclk = SPRD_DEFAULT_SOURCE_CLK; in sprd_clk_init()
1151 uport->uartclk = clk_get_rate(clk_uart); in sprd_clk_init()
1153 u->clk = devm_clk_get(uport->dev, "enable"); in sprd_clk_init()
1154 if (IS_ERR(u->clk)) { in sprd_clk_init()
1155 if (PTR_ERR(u->clk) == -EPROBE_DEFER) in sprd_clk_init()
1156 return -EPROBE_DEFER; in sprd_clk_init()
1158 dev_warn(uport->dev, "uart%d can't get enable clock\n", in sprd_clk_init()
1159 uport->line); in sprd_clk_init()
1163 return PTR_ERR(u->clk); in sprd_clk_init()
1165 u->clk = NULL; in sprd_clk_init()
1180 index = of_alias_get_id(pdev->dev.of_node, "serial"); in sprd_probe()
1182 dev_err(&pdev->dev, "got a wrong serial alias id %d\n", index); in sprd_probe()
1183 return -EINVAL; in sprd_probe()
1186 sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); in sprd_probe()
1188 return -ENOMEM; in sprd_probe()
1190 up = &sport->port; in sprd_probe()
1191 up->dev = &pdev->dev; in sprd_probe()
1192 up->line = index; in sprd_probe()
1193 up->type = PORT_SPRD; in sprd_probe()
1194 up->iotype = UPIO_MEM; in sprd_probe()
1195 up->uartclk = SPRD_DEF_RATE; in sprd_probe()
1196 up->fifosize = SPRD_FIFO_SIZE; in sprd_probe()
1197 up->ops = &serial_sprd_ops; in sprd_probe()
1198 up->flags = UPF_BOOT_AUTOCONF; in sprd_probe()
1199 up->has_sysrq = IS_ENABLED(CONFIG_SERIAL_SPRD_CONSOLE); in sprd_probe()
1205 up->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in sprd_probe()
1206 if (IS_ERR(up->membase)) in sprd_probe()
1207 return PTR_ERR(up->membase); in sprd_probe()
1209 up->mapbase = res->start; in sprd_probe()
1211 sport->pdata = of_device_get_match_data(&pdev->dev); in sprd_probe()
1212 if (!sport->pdata) { in sprd_probe()
1213 dev_err(&pdev->dev, "get match data failed!\n"); in sprd_probe()
1214 return -EINVAL; in sprd_probe()
1220 up->irq = irq; in sprd_probe()
1233 pr_err("Failed to register SPRD-UART driver\n"); in sprd_probe()
1251 if (--sprd_ports_num == 0) in sprd_probe()
1263 uart_suspend_port(&sprd_uart_driver, &sup->port); in sprd_suspend()
1272 uart_resume_port(&sprd_uart_driver, &sup->port); in sprd_resume()
1281 {.compatible = "sprd,sc9836-uart", .data = &sc9836_data},
1282 {.compatible = "sprd,sc9632-uart", .data = &sc9632_data},