Lines Matching +full:meson +full:- +full:gx +full:- +full:uart
1 // SPDX-License-Identifier: GPL-2.0
96 val = readl(port->membase + AML_UART_STATUS); in meson_uart_tx_empty()
105 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_stop_tx()
107 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_stop_tx()
114 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_stop_rx()
116 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_stop_rx()
124 free_irq(port->irq, port); in meson_uart_shutdown()
126 spin_lock_irqsave(&port->lock, flags); in meson_uart_shutdown()
128 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_shutdown()
131 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_shutdown()
133 spin_unlock_irqrestore(&port->lock, flags); in meson_uart_shutdown()
138 struct circ_buf *xmit = &port->state->xmit; in meson_uart_start_tx()
147 while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) { in meson_uart_start_tx()
148 if (port->x_char) { in meson_uart_start_tx()
149 writel(port->x_char, port->membase + AML_UART_WFIFO); in meson_uart_start_tx()
150 port->icount.tx++; in meson_uart_start_tx()
151 port->x_char = 0; in meson_uart_start_tx()
158 ch = xmit->buf[xmit->tail]; in meson_uart_start_tx()
159 writel(ch, port->membase + AML_UART_WFIFO); in meson_uart_start_tx()
160 xmit->tail = (xmit->tail+1) & (SERIAL_XMIT_SIZE - 1); in meson_uart_start_tx()
161 port->icount.tx++; in meson_uart_start_tx()
165 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_start_tx()
167 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_start_tx()
176 struct tty_port *tport = &port->state->port; in meson_receive_chars()
182 port->icount.rx++; in meson_receive_chars()
183 ostatus = status = readl(port->membase + AML_UART_STATUS); in meson_receive_chars()
187 port->icount.overrun++; in meson_receive_chars()
189 port->icount.frame++; in meson_receive_chars()
191 port->icount.frame++; in meson_receive_chars()
193 mode = readl(port->membase + AML_UART_CONTROL); in meson_receive_chars()
195 writel(mode, port->membase + AML_UART_CONTROL); in meson_receive_chars()
199 writel(mode, port->membase + AML_UART_CONTROL); in meson_receive_chars()
201 status &= port->read_status_mask; in meson_receive_chars()
208 ch = readl(port->membase + AML_UART_RFIFO); in meson_receive_chars()
212 port->icount.brk++; in meson_receive_chars()
221 if ((status & port->ignore_status_mask) == 0) in meson_receive_chars()
227 } while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)); in meson_receive_chars()
229 spin_unlock(&port->lock); in meson_receive_chars()
231 spin_lock(&port->lock); in meson_receive_chars()
238 spin_lock(&port->lock); in meson_uart_interrupt()
240 if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)) in meson_uart_interrupt()
243 if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) { in meson_uart_interrupt()
244 if (readl(port->membase + AML_UART_CONTROL) & AML_UART_TX_INT_EN) in meson_uart_interrupt()
248 spin_unlock(&port->lock); in meson_uart_interrupt()
255 return (port->type == PORT_MESON) ? "meson_uart" : NULL; in meson_uart_type()
262 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_reset()
264 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_reset()
267 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_reset()
275 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_startup()
277 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_startup()
279 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_startup()
282 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_startup()
285 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_startup()
287 val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2)); in meson_uart_startup()
288 writel(val, port->membase + AML_UART_MISC); in meson_uart_startup()
290 ret = request_irq(port->irq, meson_uart_interrupt, 0, in meson_uart_startup()
291 port->name, port); in meson_uart_startup()
303 if (port->uartclk == 24000000) { in meson_uart_change_speed()
304 val = ((port->uartclk / 3) / baud) - 1; in meson_uart_change_speed()
307 val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1; in meson_uart_change_speed()
310 writel(val, port->membase + AML_UART_REG5); in meson_uart_change_speed()
321 spin_lock_irqsave(&port->lock, flags); in meson_uart_set_termios()
323 cflags = termios->c_cflag; in meson_uart_set_termios()
324 iflags = termios->c_iflag; in meson_uart_set_termios()
326 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_set_termios()
365 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_set_termios()
370 port->read_status_mask = AML_UART_TX_FIFO_WERR; in meson_uart_set_termios()
372 port->read_status_mask |= AML_UART_PARITY_ERR | in meson_uart_set_termios()
375 port->ignore_status_mask = 0; in meson_uart_set_termios()
377 port->ignore_status_mask |= AML_UART_PARITY_ERR | in meson_uart_set_termios()
380 uart_update_timeout(port, termios->c_cflag, baud); in meson_uart_set_termios()
381 spin_unlock_irqrestore(&port->lock, flags); in meson_uart_set_termios()
389 if (port->type != PORT_MESON) in meson_uart_verify_port()
390 ret = -EINVAL; in meson_uart_verify_port()
391 if (port->irq != ser->irq) in meson_uart_verify_port()
392 ret = -EINVAL; in meson_uart_verify_port()
393 if (ser->baud_base < 9600) in meson_uart_verify_port()
394 ret = -EINVAL; in meson_uart_verify_port()
400 devm_iounmap(port->dev, port->membase); in meson_uart_release_port()
401 port->membase = NULL; in meson_uart_release_port()
402 devm_release_mem_region(port->dev, port->mapbase, port->mapsize); in meson_uart_release_port()
407 if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize, in meson_uart_request_port()
408 dev_name(port->dev))) { in meson_uart_request_port()
409 dev_err(port->dev, "Memory region busy\n"); in meson_uart_request_port()
410 return -EBUSY; in meson_uart_request_port()
413 port->membase = devm_ioremap(port->dev, port->mapbase, in meson_uart_request_port()
414 port->mapsize); in meson_uart_request_port()
415 if (!port->membase) in meson_uart_request_port()
416 return -ENOMEM; in meson_uart_request_port()
424 port->type = PORT_MESON; in meson_uart_config_port()
431 * Console polling routines for writing and reading from the uart while
440 spin_lock_irqsave(&port->lock, flags); in meson_uart_poll_get_char()
442 if (readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY) in meson_uart_poll_get_char()
445 c = readl(port->membase + AML_UART_RFIFO); in meson_uart_poll_get_char()
447 spin_unlock_irqrestore(&port->lock, flags); in meson_uart_poll_get_char()
458 spin_lock_irqsave(&port->lock, flags); in meson_uart_poll_put_char()
461 ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg, in meson_uart_poll_put_char()
465 if (ret == -ETIMEDOUT) { in meson_uart_poll_put_char()
466 dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n"); in meson_uart_poll_put_char()
471 writel(c, port->membase + AML_UART_WFIFO); in meson_uart_poll_put_char()
474 ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg, in meson_uart_poll_put_char()
478 if (ret == -ETIMEDOUT) in meson_uart_poll_put_char()
479 dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n"); in meson_uart_poll_put_char()
482 spin_unlock_irqrestore(&port->lock, flags); in meson_uart_poll_put_char()
513 val = readl(port->membase + AML_UART_CONTROL); in meson_uart_enable_tx_engine()
515 writel(val, port->membase + AML_UART_CONTROL); in meson_uart_enable_tx_engine()
520 if (!port->membase) in meson_console_putchar()
523 while (readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL) in meson_console_putchar()
525 writel(ch, port->membase + AML_UART_WFIFO); in meson_console_putchar()
536 if (port->sysrq) { in meson_serial_port_write()
539 locked = spin_trylock(&port->lock); in meson_serial_port_write()
541 spin_lock(&port->lock); in meson_serial_port_write()
545 val = readl(port->membase + AML_UART_CONTROL); in meson_serial_port_write()
547 writel(tmp, port->membase + AML_UART_CONTROL); in meson_serial_port_write()
550 writel(val, port->membase + AML_UART_CONTROL); in meson_serial_port_write()
553 spin_unlock(&port->lock); in meson_serial_port_write()
562 port = meson_ports[co->index]; in meson_serial_console_write()
577 if (co->index < 0 || co->index >= AML_UART_PORT_NUM) in meson_serial_console_setup()
578 return -EINVAL; in meson_serial_console_setup()
580 port = meson_ports[co->index]; in meson_serial_console_setup()
581 if (!port || !port->membase) in meson_serial_console_setup()
582 return -ENODEV; in meson_serial_console_setup()
598 .index = -1,
613 struct earlycon_device *dev = co->data; in meson_serial_early_console_write()
615 meson_serial_port_write(&dev->port, s, count); in meson_serial_early_console_write()
621 if (!device->port.membase) in meson_serial_early_console_setup()
622 return -ENODEV; in meson_serial_early_console_setup()
624 meson_uart_enable_tx_engine(&device->port); in meson_serial_early_console_setup()
625 device->con->write = meson_serial_early_console_write; in meson_serial_early_console_setup()
629 OF_EARLYCON_DECLARE(meson, "amlogic,meson-uart",
632 OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart",
672 * This function gets clocks in the legacy non-stable DT bindings.
681 clk = meson_uart_probe_clock(&pdev->dev, NULL); in meson_uart_probe_clocks_legacy()
685 port->uartclk = clk_get_rate(clk); in meson_uart_probe_clocks_legacy()
697 clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk"); in meson_uart_probe_clocks()
701 clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal"); in meson_uart_probe_clocks()
705 clk_baud = meson_uart_probe_clock(&pdev->dev, "baud"); in meson_uart_probe_clocks()
709 port->uartclk = clk_get_rate(clk_baud); in meson_uart_probe_clocks()
719 int id = -1; in meson_uart_probe()
721 if (pdev->dev.of_node) in meson_uart_probe()
722 pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); in meson_uart_probe()
724 if (pdev->id < 0) { in meson_uart_probe()
727 pdev->id = id; in meson_uart_probe()
733 if (pdev->id < 0 || pdev->id >= AML_UART_PORT_NUM) in meson_uart_probe()
734 return -EINVAL; in meson_uart_probe()
738 return -ENODEV; in meson_uart_probe()
742 return -ENODEV; in meson_uart_probe()
744 if (meson_ports[pdev->id]) { in meson_uart_probe()
745 dev_err(&pdev->dev, "port %d already allocated\n", pdev->id); in meson_uart_probe()
746 return -EBUSY; in meson_uart_probe()
749 port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL); in meson_uart_probe()
751 return -ENOMEM; in meson_uart_probe()
754 if (of_device_is_compatible(pdev->dev.of_node, "amlogic,meson-uart")) in meson_uart_probe()
762 port->iotype = UPIO_MEM; in meson_uart_probe()
763 port->mapbase = res_mem->start; in meson_uart_probe()
764 port->mapsize = resource_size(res_mem); in meson_uart_probe()
765 port->irq = res_irq->start; in meson_uart_probe()
766 port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY; in meson_uart_probe()
767 port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE); in meson_uart_probe()
768 port->dev = &pdev->dev; in meson_uart_probe()
769 port->line = pdev->id; in meson_uart_probe()
770 port->type = PORT_MESON; in meson_uart_probe()
771 port->x_char = 0; in meson_uart_probe()
772 port->ops = &meson_uart_ops; in meson_uart_probe()
773 port->fifosize = 64; in meson_uart_probe()
775 meson_ports[pdev->id] = port; in meson_uart_probe()
786 meson_ports[pdev->id] = NULL; in meson_uart_probe()
797 meson_ports[pdev->id] = NULL; in meson_uart_remove()
804 { .compatible = "amlogic,meson-uart" },
806 { .compatible = "amlogic,meson6-uart" },
807 { .compatible = "amlogic,meson8-uart" },
808 { .compatible = "amlogic,meson8b-uart" },
809 { .compatible = "amlogic,meson-gx-uart" },
848 MODULE_DESCRIPTION("Amlogic Meson serial port driver");