arm64: Add apple,s5l UART driver
This is the debug UART found in Apple SoCs. Tested on M1 MacBook Air. Registers definitions were taken from: - https://github.com/AsahiLinux/m1n1/blob/18eb02fa92789dfcdab8e00e8b1cace7ab002718/src/uart_regs.h - https://www.sistemasorp.es/blog/S3C2410%20-%20datasheet.pdf Change-Id: I2e4c8b7927fc823cedca421e1a2623b91f5ef112 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10480 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
5bb69a0f33
commit
d2819f9e83
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2026 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Sam Roberts, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef __DEV_UART_SAMSUNG_H
|
||||||
|
#define __DEV_UART_SAMSUNG_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <arch/generic/debug_uart.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define UART_KIND_SAMSUNG "samsung"
|
||||||
|
|
||||||
|
|
||||||
|
class ArchUARTSamsung : public DebugUART {
|
||||||
|
public:
|
||||||
|
ArchUARTSamsung(addr_t base, int64 clock);
|
||||||
|
~ArchUARTSamsung();
|
||||||
|
|
||||||
|
|
||||||
|
void InitPort(uint32 baud);
|
||||||
|
|
||||||
|
void Enable();
|
||||||
|
void Disable();
|
||||||
|
|
||||||
|
int PutChar(char c);
|
||||||
|
int GetChar(bool wait);
|
||||||
|
|
||||||
|
void FlushTx();
|
||||||
|
void FlushRx();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Out32(int reg, uint32 data);
|
||||||
|
uint32 In32(int reg);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,6 +5,7 @@ local platform ;
|
|||||||
local kernelArchSources =
|
local kernelArchSources =
|
||||||
arch_elf.cpp
|
arch_elf.cpp
|
||||||
arch_uart_linflex.cpp
|
arch_uart_linflex.cpp
|
||||||
|
arch_uart_samsung.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
local kernelArchReusableSources =
|
local kernelArchReusableSources =
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
# include <arch/arm/arch_uart_pl011.h>
|
# include <arch/arm/arch_uart_pl011.h>
|
||||||
# include <arch/arm64/arch_uart_linflex.h>
|
# include <arch/arm64/arch_uart_linflex.h>
|
||||||
|
# include <arch/arm64/arch_uart_samsung.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -83,6 +84,7 @@ const struct supported_uarts {
|
|||||||
{ "arm,pl011", UART_KIND_PL011, &get_uart<ArchUARTPL011> },
|
{ "arm,pl011", UART_KIND_PL011, &get_uart<ArchUARTPL011> },
|
||||||
{ "fsl,s32-linflexuart", UART_KIND_LINFLEX, &get_uart<ArchUARTlinflex> },
|
{ "fsl,s32-linflexuart", UART_KIND_LINFLEX, &get_uart<ArchUARTlinflex> },
|
||||||
{ "brcm,bcm2835-aux-uart", UART_KIND_8250, &get_uart<DebugUART8250> },
|
{ "brcm,bcm2835-aux-uart", UART_KIND_8250, &get_uart<DebugUART8250> },
|
||||||
|
{ "apple,s5l-uart", UART_KIND_SAMSUNG, &get_uart<ArchUARTSamsung> },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2026 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Sam Roberts, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch/generic/debug_uart.h>
|
||||||
|
#include <arch/arm64/arch_uart_samsung.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define ULCON 0x00 // Line control
|
||||||
|
#define UCON 0x04 // Control
|
||||||
|
#define UFCON 0x08 // FIFO control
|
||||||
|
#define UTRSTAT 0x10 // Transmit status
|
||||||
|
#define UFSTAT 0x18 // FIFO status
|
||||||
|
#define UTXH 0x20 // Transmit holding
|
||||||
|
#define URXH 0x24 // Receive holding
|
||||||
|
#define UBRDIV 0x28 // Baud rate divider
|
||||||
|
|
||||||
|
#define UCON_TXTHRESH_ENA (1 << 13) // Transmit threshold enable
|
||||||
|
#define UCON_RXTHRESH_ENA (1 << 12) // Receive threshold enable
|
||||||
|
#define UCON_RXTO_ENA (1 << 9) // Receive timeout enable
|
||||||
|
#define UCON_TXMODE (3 << 2) // Transmit mode
|
||||||
|
#define UCON_RXMODE (3 << 0) // Receive mode
|
||||||
|
|
||||||
|
#define UCON_MODE_OFF 0
|
||||||
|
#define UCON_MODE_IRQ 1
|
||||||
|
|
||||||
|
#define UTRSTAT_RXTO (1 << 9) // Receive timeout status
|
||||||
|
#define UTRSTAT_TXTHRESH (1 << 5) // Transmit threshold status
|
||||||
|
#define UTRSTAT_RXTHRESH (1 << 4) // Receive threshold status
|
||||||
|
#define UTRSTAT_TXE (1 << 2) // Transmit empty status
|
||||||
|
#define UTRSTAT_TXBE (1 << 1) // Transmit buffer empty status
|
||||||
|
#define UTRSTAT_RXD (1 << 0) // Receive data status
|
||||||
|
|
||||||
|
#define UFSTAT_TXFULL (1 << 9) // Transmit FIFO full status
|
||||||
|
#define UFSTAT_RXFULL (1 << 8) // Receive FIFO full status
|
||||||
|
#define UFSTAT_TXCNT (15 << 4) // Transmit FIFO count
|
||||||
|
#define UFSTAT_RXCNT (15 << 0) // Receive FIFO count
|
||||||
|
|
||||||
|
|
||||||
|
ArchUARTSamsung::ArchUARTSamsung(addr_t base, int64 clock)
|
||||||
|
:
|
||||||
|
DebugUART(base, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ArchUARTSamsung::~ArchUARTSamsung()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ArchUARTSamsung::Out32(int reg, uint32 data)
|
||||||
|
{
|
||||||
|
*(volatile uint32*)(Base() + reg) = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
ArchUARTSamsung::In32(int reg)
|
||||||
|
{
|
||||||
|
return *(volatile uint32*)(Base() + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ArchUARTSamsung::InitPort(uint32 baud)
|
||||||
|
{
|
||||||
|
uint32 ucon = In32(UCON);
|
||||||
|
// Disable TX and RX IRQ
|
||||||
|
Out32(UCON, ucon & !(UCON_RXMODE | UCON_TXMODE));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ArchUARTSamsung::Enable()
|
||||||
|
{
|
||||||
|
DebugUART::Enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ArchUARTSamsung::Disable()
|
||||||
|
{
|
||||||
|
DebugUART::Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
ArchUARTSamsung::PutChar(char c)
|
||||||
|
{
|
||||||
|
if (Enabled()) {
|
||||||
|
while ((In32(UFSTAT) & UFSTAT_TXFULL) != 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
Out32(UTXH, c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
ArchUARTSamsung::GetChar(bool wait)
|
||||||
|
{
|
||||||
|
if (Enabled()) {
|
||||||
|
while (wait && ((In32(UFSTAT) & UFSTAT_RXCNT) == 0))
|
||||||
|
;
|
||||||
|
|
||||||
|
if ((In32(UFSTAT) & UFSTAT_RXCNT) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return In32(URXH);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ArchUARTSamsung::FlushTx()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ArchUARTSamsung::FlushRx()
|
||||||
|
{
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user