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 =
|
||||
arch_elf.cpp
|
||||
arch_uart_linflex.cpp
|
||||
arch_uart_samsung.cpp
|
||||
;
|
||||
|
||||
local kernelArchReusableSources =
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#elif defined(__aarch64__)
|
||||
# include <arch/arm/arch_uart_pl011.h>
|
||||
# include <arch/arm64/arch_uart_linflex.h>
|
||||
# include <arch/arm64/arch_uart_samsung.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -83,6 +84,7 @@ const struct supported_uarts {
|
||||
{ "arm,pl011", UART_KIND_PL011, &get_uart<ArchUARTPL011> },
|
||||
{ "fsl,s32-linflexuart", UART_KIND_LINFLEX, &get_uart<ArchUARTlinflex> },
|
||||
{ "brcm,bcm2835-aux-uart", UART_KIND_8250, &get_uart<DebugUART8250> },
|
||||
{ "apple,s5l-uart", UART_KIND_SAMSUNG, &get_uart<ArchUARTSamsung> },
|
||||
#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