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 xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); 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 tcu->rx = mbox_request_channel_byname(&tcu->rx_client, "rx"); 199 if (IS_ERR(tcu->rx)) { 200 err = PTR_ERR(tcu->rx); 201 dev_err(&pdev->dev, "failed to get rx mailbox: %d\n", err); 202 goto free_tx; 203 } 204 205 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 206 /* setup the console */ 207 strcpy(tcu->console.name, "ttyTCU"); 208 tcu->console.device = uart_console_device; 209 tcu->console.flags = CON_PRINTBUFFER | CON_ANYTIME; 210 tcu->console.index = -1; 211 tcu->console.write = tegra_tcu_console_write; 212 tcu->console.setup = tegra_tcu_console_setup; 213 tcu->console.data = &tcu->driver; 214 #endif 215 216 /* setup the driver */ 217 tcu->driver.owner = THIS_MODULE; 218 tcu->driver.driver_name = "tegra-tcu"; 219 tcu->driver.dev_name = "ttyTCU"; 220 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 221 tcu->driver.cons = &tcu->console; 222 #endif 223 tcu->driver.nr = 1; 224 225 err = uart_register_driver(&tcu->driver); 226 if (err) { 227 dev_err(&pdev->dev, "failed to register UART driver: %d\n", 228 err); 229 goto free_rx; 230 } 231 232 /* setup the port */ 233 port = &tcu->port; 234 spin_lock_init(&port->lock); 235 port->dev = &pdev->dev; 236 port->type = PORT_TEGRA_TCU; 237 port->ops = &tegra_tcu_uart_ops; 238 port->fifosize = 1; 239 port->iotype = UPIO_MEM; 240 port->flags = UPF_BOOT_AUTOCONF; 241 port->private_data = tcu; 242 243 err = uart_add_one_port(&tcu->driver, port); 244 if (err) { 245 dev_err(&pdev->dev, "failed to add UART port: %d\n", err); 246 goto unregister_uart; 247 } 248 249 platform_set_drvdata(pdev, tcu); 250 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 251 register_console(&tcu->console); 252 #endif 253 254 return 0; 255 256 unregister_uart: 257 uart_unregister_driver(&tcu->driver); 258 free_rx: 259 mbox_free_channel(tcu->rx); 260 free_tx: 261 mbox_free_channel(tcu->tx); 262 263 return err; 264 } 265 266 static int tegra_tcu_remove(struct platform_device *pdev) 267 { 268 struct tegra_tcu *tcu = platform_get_drvdata(pdev); 269 270 #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) 271 unregister_console(&tcu->console); 272 #endif 273 uart_remove_one_port(&tcu->driver, &tcu->port); 274 uart_unregister_driver(&tcu->driver); 275 mbox_free_channel(tcu->rx); 276 mbox_free_channel(tcu->tx); 277 278 return 0; 279 } 280 281 static const struct of_device_id tegra_tcu_match[] = { 282 { .compatible = "nvidia,tegra194-tcu" }, 283 { } 284 }; 285 286 static struct platform_driver tegra_tcu_driver = { 287 .driver = { 288 .name = "tegra-tcu", 289 .of_match_table = tegra_tcu_match, 290 }, 291 .probe = tegra_tcu_probe, 292 .remove = tegra_tcu_remove, 293 }; 294 module_platform_driver(tegra_tcu_driver); 295 296 MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>"); 297 MODULE_LICENSE("GPL v2"); 298 MODULE_DESCRIPTION("NVIDIA Tegra Combined UART driver"); 299