forked from torvalds/linux
Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
early_tcu
- Loading branch information
Thierry Reding
committed
Mar 19, 2021
1 parent
b740f32
commit f3d8000cf65d974c4b59bdb20f72a7b2af0260de
Showing
3 changed files
with
85 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| // SPDX-License-Identifier: GPL-2.0 | ||
| /* | ||
| * Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved. | ||
| */ | ||
|
|
||
| #include <linux/console.h> | ||
| #include <linux/io.h> | ||
| #include <linux/serial_core.h> | ||
|
|
||
| #define NUM_BYTES_FIELD_BIT 24 | ||
| #define FLUSH_BIT 26 | ||
| #define INTR_TRIGGER_BIT 31 | ||
|
|
||
| static u32 update_and_send_mbox(u8 __iomem *addr, u32 mbox_val, char c) | ||
| { | ||
| int bytes = bytes = (mbox_val >> NUM_BYTES_FIELD_BIT) & 0x3; | ||
|
|
||
| mbox_val |= BIT(INTR_TRIGGER_BIT); | ||
| mbox_val |= c << (bytes * 8); | ||
| bytes++; | ||
| mbox_val = (mbox_val & ~(3 << NUM_BYTES_FIELD_BIT)) | | ||
| (bytes << NUM_BYTES_FIELD_BIT); | ||
|
|
||
| if (bytes == 3) { | ||
| /* Send current packet to SPE */ | ||
| while (readl(addr) & BIT(INTR_TRIGGER_BIT)) | ||
| cpu_relax(); | ||
| writel(mbox_val, addr); | ||
| mbox_val = BIT(INTR_TRIGGER_BIT); | ||
| } | ||
|
|
||
| return mbox_val; | ||
| } | ||
|
|
||
| /* | ||
| * This function splits the string to be printed (const char *s) into multiple | ||
| * packets. Each packet contains a max of 3 characters. Packets are sent to the | ||
| * SPE-based combined UART server for printing. Communication with SPE is done | ||
| * through mailbox registers which can generate interrupts for SPE. | ||
| */ | ||
| static void early_tcu_write(struct console *console, const char *s, unsigned int count) | ||
| { | ||
| struct earlycon_device *device = console->data; | ||
| u8 __iomem *addr = device->port.membase; | ||
| u32 mbox_val = BIT(INTR_TRIGGER_BIT); | ||
| unsigned int i; | ||
|
|
||
| /* Loop for processing each 3 char packet */ | ||
| for (i = 0; i < count; i++) { | ||
| if (s[i] == '\n') | ||
| mbox_val = update_and_send_mbox(addr, mbox_val, '\r'); | ||
| mbox_val = update_and_send_mbox(addr, mbox_val, s[i]); | ||
| } | ||
|
|
||
| if ((mbox_val >> NUM_BYTES_FIELD_BIT) & 0x3) { | ||
| while (readl(addr) & BIT(INTR_TRIGGER_BIT)) | ||
| cpu_relax(); | ||
| writel(mbox_val, addr); | ||
| } | ||
| } | ||
|
|
||
| int __init early_tegra_combined_uart_setup(struct earlycon_device *device, const char *options) | ||
| { | ||
| if (!(device->port.membase)) | ||
| return -ENODEV; | ||
|
|
||
| device->con->write = early_tcu_write; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| EARLYCON_DECLARE(tegra_comb_uart, early_tegra_combined_uart_setup); |