123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
- *
- * Copyright (C) 2017-2023 Nuvoton Ltd.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <stdbool.h>
- #include <arch.h>
- #include <arch_helpers.h>
- #include <common/debug.h>
- #include <drivers/arm/gicv2.h>
- #include <drivers/delay_timer.h>
- #include <drivers/generic_delay_timer.h>
- #include <lib/mmio.h>
- #include <lib/psci/psci.h>
- #include <npcm845x_clock.h>
- #include <npcm845x_gcr.h>
- #include <npcm845x_lpuart.h>
- #include <plat_npcm845x.h>
- uintptr_t npcm845x_get_base_uart(UART_DEV_T devNum)
- {
- return 0xF0000000 + devNum * 0x1000;
- }
- uintptr_t npcm845x_get_base_clk(void)
- {
- return 0xF0801000;
- }
- uintptr_t npcm845x_get_base_gcr(void)
- {
- return 0xF0800000;
- }
- void npcm845x_wait_for_empty(int uart_n)
- {
- volatile struct npcmX50_uart *uart = (struct npcmX50_uart *)npcm845x_get_base_uart(uart_n);
- while ((*(uint8_t *)(uintptr_t)(&uart->lsr) & 0x40) == 0x00) {
- /*
- * wait for THRE (Transmitter Holding Register Empty)
- * and TSR (Transmitter Shift Register) to be empty.
- * Some delay. notice needed some delay so UartUpdateTool
- * will pass w/o error log
- */
- }
- volatile int delay;
- for (delay = 0; delay < 10000; delay++) {
- ;
- }
- }
- int UART_Init(UART_DEV_T devNum, UART_BAUDRATE_T baudRate)
- {
- uint32_t val = 0;
- uintptr_t clk_base = npcm845x_get_base_clk();
- uintptr_t gcr_base = npcm845x_get_base_gcr();
- uintptr_t uart_base = npcm845x_get_base_uart(devNum);
- volatile struct npcmX50_uart *uart = (struct npcmX50_uart *)uart_base;
- /* Use CLKREF to be independent of CPU frequency */
- volatile struct clk_ctl *clk_ctl_obj = (struct clk_ctl *)clk_base;
- volatile struct npcm845x_gcr *gcr_ctl_obj =
- (struct npcm845x_gcr *)gcr_base;
- clk_ctl_obj->clksel = clk_ctl_obj->clksel & ~(0x3 << 8);
- clk_ctl_obj->clksel = clk_ctl_obj->clksel | (0x2 << 8);
- /* Set devider according to baudrate */
- clk_ctl_obj->clkdiv1 =
- (unsigned int)(clk_ctl_obj->clkdiv1 & ~(0x1F << 16));
- /* clear bits 11-15 - set value 0 */
- if (devNum == UART3_DEV) {
- clk_ctl_obj->clkdiv2 =
- (unsigned int)(clk_ctl_obj->clkdiv2 & ~(0x1F << 11));
- }
- npcm845x_wait_for_empty(devNum);
- val = (uint32_t)LCR_WLS_8bit;
- mmio_write_8((uintptr_t)&uart->lcr, (uint8_t)val);
- /* disable all interrupts */
- mmio_write_8((uintptr_t)&uart->ier, 0);
- /*
- * Set the RX FIFO trigger level, reset RX, TX FIFO
- */
- val = (uint32_t)(FCR_FME | FCR_RFR | FCR_TFR | FCR_RFITL_4B);
- /* reset TX and RX FIFO */
- mmio_write_8((uintptr_t)(&uart->fcr), (uint8_t)val);
- /* Set port for 8 bit, 1 stop, no parity */
- val = (uint32_t)LCR_WLS_8bit;
- /* Set DLAB bit; Accesses the Divisor Latch Registers (DLL, DLM). */
- val |= 0x80;
- mmio_write_8((uintptr_t)(&uart->lcr), (uint8_t)val);
- /* Baud Rate = UART Clock 24MHz / (16 * (11+2)) = 115384 */
- mmio_write_8((uintptr_t)(&uart->dll), 11);
- mmio_write_8((uintptr_t)(&uart->dlm), 0x00);
- val = mmio_read_8((uintptr_t)&uart->lcr);
- /* Clear DLAB bit; Accesses RBR, THR or IER registers. */
- val &= 0x7F;
- mmio_write_8((uintptr_t)(&uart->lcr), (uint8_t)val);
- if (devNum == UART0_DEV) {
- gcr_ctl_obj->mfsel4 &= ~(1 << 1);
- gcr_ctl_obj->mfsel1 |= 1 << 9;
- } else if (devNum == UART3_DEV) {
- /* Pin Mux */
- gcr_ctl_obj->mfsel4 &= ~(1 << 1);
- gcr_ctl_obj->mfsel1 |= 1 << 11;
- gcr_ctl_obj->spswc &= (7 << 0);
- gcr_ctl_obj->spswc |= (2 << 0);
- } else {
- /* halt */
- while (1) {
- ;
- }
- }
- return 0;
- }
|