1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. 4 */ 5 6 #include <linux/console.h> 7 #include <linux/mailbox_client.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/of_device.h> 11 #include <linux/platform_device.h> 12 #include <linux/serial.h> 13 #include <linux/serial_core.h> 14 #include <linux/slab.h> 15 #include <linux/tty.h> 16 #include <linux/tty_flip.h> 17 18 #define TCU_MBOX_BYTE(i, x) ((x) << (i * 8)) 19 #define TCU_MBOX_BYTE_V(x, i) (((x) >> (i * 8)) & 0xff) 20 #define TCU_MBOX_NUM_BYTES(x) ((x) << 24) 21 #define TCU_MBOX_NUM_BYTES_V(x) (((x) >> 24) & 0x3) 22 23 struct tegra_tcu { 24 struct uart_driver driver; 25 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 26 struct console console; 27 #endif 28 struct uart_port port; 29 30 struct mbox_client tx_client, rx_client; 31 struct mbox_chan *tx, *rx; 32 }; 33 34 static unsigned int tegra_tcu_uart_tx_empty(struct uart_port *port) 35 { 36 return TIOCSER_TEMT; 37 } 38 39 static void tegra_tcu_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 40 { 41 } 42 43 static unsigned int tegra_tcu_uart_get_mctrl(struct uart_port *port) 44 { 45 return 0; 46 } 47 48 static void tegra_tcu_uart_stop_tx(struct uart_port *port) 49 { 50 } 51 52 static void tegra_tcu_write_one(struct tegra_tcu *tcu, u32 value, 53 unsigned int count) 54 { 55 void *msg; 56 57 value |= TCU_MBOX_NUM_BYTES(count); 58 msg = (void *)(unsigned long)value; 59 mbox_send_message(tcu->tx, msg); 60 mbox_flush(tcu->tx, 1000); 61 } 62 63 static void tegra_tcu_write(struct tegra_tcu *tcu, const char *s, 64 unsigned int count) 65 { 66 unsigned int written = 0, i = 0; 67 bool insert_nl = false; 68 u32 value = 0; 69 70 while (i < count) { 71 if (insert_nl) { 72 value |= TCU_MBOX_BYTE(written++, '\n'); 73 insert_nl = false; 74 i++; 75 } else if (s[i] == '\n') { 76 value |= TCU_MBOX_BYTE(written++, '\r'); 77 insert_nl = true; 78 } else { 79 value |= TCU_MBOX_BYTE(written++, s[i++]); 80 } 81 82 if (written == 3) { 83 tegra_tcu_write_one(tcu, value, 3); 84 value = written = 0; 85 } 86 } 87 88 if (written) 89 tegra_tcu_write_one(tcu, value, written); 90 } 91 92 static void tegra_tcu_uart_start_tx(struct uart_port *port) 93 { 94 struct tegra_tcu *tcu = port->private_data; 95 struct circ_buf *xmit = &port->state->xmit; 96 unsigned long count; 97 98 for (;;) { 99 count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); 100 if (!count) 101 break; 102 103 tegra_tcu_write(tcu, &xmit->buf[xmit->tail], count); 104 uart_xmit_advance(port, count); 105 } 106 107 uart_write_wakeup(port); 108 } 109 110 static void tegra_tcu_uart_stop_rx(struct uart_port *port) 111 { 112 } 113 114 static void tegra_tcu_uart_break_ctl(struct uart_port *port, int ctl) 115 { 116 } 117 118 static int tegra_tcu_uart_startup(struct uart_port *port) 119 { 120 return 0; 121 } 122 123 static void tegra_tcu_uart_shutdown(struct uart_port *port) 124 { 125 } 126 127 static void tegra_tcu_uart_set_termios(struct uart_port *port, 128 struct ktermios *new, 129 struct ktermios *old) 130 { 131 } 132 133 static const struct uart_ops tegra_tcu_uart_ops = { 134 .tx_empty = tegra_tcu_uart_tx_empty, 135 .set_mctrl = tegra_tcu_uart_set_mctrl, 136 .get_mctrl = tegra_tcu_uart_get_mctrl, 137 .stop_tx = tegra_tcu_uart_stop_tx, 138 .start_tx = tegra_tcu_uart_start_tx, 139 .stop_rx = tegra_tcu_uart_stop_rx, 140 .break_ctl = tegra_tcu_uart_break_ctl, 141 .startup = tegra_tcu_uart_startup, 142 .shutdown = tegra_tcu_uart_shutdown, 143 .set_termios = tegra_tcu_uart_set_termios, 144 }; 145 146 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 147 static void tegra_tcu_console_write(struct console *cons, const char *s, 148 unsigned int count) 149 { 150 struct tegra_tcu *tcu = container_of(cons, struct tegra_tcu, console); 151 152 tegra_tcu_write(tcu, s, count); 153 } 154 155 static int tegra_tcu_console_setup(struct console *cons, char *options) 156 { 157 return 0; 158 } 159 #endif 160 161 static void tegra_tcu_receive(struct mbox_client *cl, void *msg) 162 { 163 struct tegra_tcu *tcu = container_of(cl, struct tegra_tcu, rx_client); 164 struct tty_port *port = &tcu->port.state->port; 165 u32 value = (u32)(unsigned long)msg; 166 unsigned int num_bytes, i; 167 168 num_bytes = TCU_MBOX_NUM_BYTES_V(value); 169 170 for (i = 0; i < num_bytes; i++) 171 tty_insert_flip_char(port, TCU_MBOX_BYTE_V(value, i), 172 TTY_NORMAL); 173 174 tty_flip_buffer_push(port); 175 } 176 177 static int tegra_tcu_probe(struct platform_device *pdev) 178 { 179 struct uart_port *port; 180 struct tegra_tcu *tcu; 181 int err; 182 183 tcu = devm_kzalloc(&pdev->dev, sizeof(*tcu), GFP_KERNEL); 184 if (!tcu) 185 return -ENOMEM; 186 187 tcu->tx_client.dev = &pdev->dev; 188 tcu->rx_client.dev = &pdev->dev; 189 tcu->rx_client.rx_callback = tegra_tcu_receive; 190 191 tcu->tx = mbox_request_channel_byname(&tcu->tx_client, "tx"); 192 if (IS_ERR(tcu->tx)) { 193 err = PTR_ERR(tcu->tx); 194 dev_err(&pdev->dev, "failed to get tx mailbox: %d\n", err); 195 return err; 196 } 197 198 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 199 /* setup the console */ 200 strcpy(tcu->console.name, "ttyTCU"); 201 tcu->console.device = uart_console_device; 202 tcu->console.flags = CON_PRINTBUFFER | CON_ANYTIME; 203 tcu->console.index = -1; 204 tcu->console.write = tegra_tcu_console_write; 205 tcu->console.setup = tegra_tcu_console_setup; 206 tcu->console.data = &tcu->driver; 207 #endif 208 209 /* setup the driver */ 210 tcu->driver.owner = THIS_MODULE; 211 tcu->driver.driver_name = "tegra-tcu"; 212 tcu->driver.dev_name = "ttyTCU"; 213 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 214 tcu->driver.cons = &tcu->console; 215 #endif 216 tcu->driver.nr = 1; 217 218 err = uart_register_driver(&tcu->driver); 219 if (err) { 220 dev_err(&pdev->dev, "failed to register UART driver: %d\n", 221 err); 222 goto free_tx; 223 } 224 225 /* setup the port */ 226 port = &tcu->port; 227 spin_lock_init(&port->lock); 228 port->dev = &pdev->dev; 229 port->type = PORT_TEGRA_TCU; 230 port->ops = &tegra_tcu_uart_ops; 231 port->fifosize = 1; 232 port->iotype = UPIO_MEM; 233 port->flags = UPF_BOOT_AUTOCONF; 234 port->private_data = tcu; 235 236 err = uart_add_one_port(&tcu->driver, port); 237 if (err) { 238 dev_err(&pdev->dev, "failed to add UART port: %d\n", err); 239 goto unregister_uart; 240 } 241 242 /* 243 * Request RX channel after creating port to ensure tcu->port 244 * is ready for any immediate incoming bytes. 245 */ 246 tcu->rx = mbox_request_channel_byname(&tcu->rx_client, "rx"); 247 if (IS_ERR(tcu->rx)) { 248 err = PTR_ERR(tcu->rx); 249 dev_err(&pdev->dev, "failed to get rx mailbox: %d\n", err); 250 goto remove_uart_port; 251 } 252 253 platform_set_drvdata(pdev, tcu); 254 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 255 register_console(&tcu->console); 256 #endif 257 258 return 0; 259 260 remove_uart_port: 261 uart_remove_one_port(&tcu->driver, &tcu->port); 262 unregister_uart: 263 uart_unregister_driver(&tcu->driver); 264 free_tx: 265 mbox_free_channel(tcu->tx); 266 267 return err; 268 } 269 270 static int tegra_tcu_remove(struct platform_device *pdev) 271 { 272 struct tegra_tcu *tcu = platform_get_drvdata(pdev); 273 274 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 275 unregister_console(&tcu->console); 276 #endif 277 mbox_free_channel(tcu->rx); 278 uart_remove_one_port(&tcu->driver, &tcu->port); 279 uart_unregister_driver(&tcu->driver); 280 mbox_free_channel(tcu->tx); 281 282 return 0; 283 } 284 285 static const struct of_device_id tegra_tcu_match[] = { 286 { .compatible = "nvidia,tegra194-tcu" }, 287 { } 288 }; 289 MODULE_DEVICE_TABLE(of, tegra_tcu_match); 290 291 static struct platform_driver tegra_tcu_driver = { 292 .driver = { 293 .name = "tegra-tcu", 294 .of_match_table = tegra_tcu_match, 295 }, 296 .probe = tegra_tcu_probe, 297 .remove = tegra_tcu_remove, 298 }; 299 module_platform_driver(tegra_tcu_driver); 300 301 MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>"); 302 MODULE_LICENSE("GPL v2"); 303 MODULE_DESCRIPTION("NVIDIA Tegra Combined UART driver"); 304