<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23779">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/cavium: Move UART<br><br>Move UART code to common folder.<br>Use addressmap.h instead of hardcoding registers.<br>Implement a function to wait # HCLKs and get rid of long delays.<br>Fix coding style.<br>Add comments.<br><br>Change-Id: I33a043b753651b0aa8cf8b31bd0ecde836859c64<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>---<br>M src/mainboard/cavium/cn8100_sff_evb/bootblock.c<br>M src/soc/cavium/cn81xx/Makefile.inc<br>D src/soc/cavium/cn81xx/include/soc/uart.h<br>D src/soc/cavium/cn81xx/uart.c<br>M src/soc/cavium/common/Makefile.inc<br>A src/soc/cavium/common/include/soc/uart.h<br>A src/soc/cavium/common/uart.c<br>7 files changed, 296 insertions(+), 177 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/79/23779/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/mainboard/cavium/cn8100_sff_evb/bootblock.c b/src/mainboard/cavium/cn8100_sff_evb/bootblock.c</span><br><span>index 977a295..8cf2307 100644</span><br><span>--- a/src/mainboard/cavium/cn8100_sff_evb/bootblock.c</span><br><span>+++ b/src/mainboard/cavium/cn8100_sff_evb/bootblock.c</span><br><span>@@ -26,18 +26,12 @@</span><br><span> </span><br><span> void bootblock_mainboard_early_init(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct cn81xx_uart *uart0 = (struct cn81xx_uart *)UAA0_PF_BAR0;</span><br><span style="color: hsl(0, 100%, 40%);">- struct cn81xx_uart *uart1 = (struct cn81xx_uart *)UAA1_PF_BAR0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#if IS_ENABLED(CONFIG_DRIVERS_UART)</span><br><span style="color: hsl(0, 100%, 40%);">-      _Static_assert(CONFIG_CONSOLE_SERIAL_UART_ADDRESS == UAA0_PF_BAR0,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "CONSOLE_SERIAL_UART should be UART0");</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!(uart0->uctl_ctl & UART_UCTL_CTL_H_CLK_EN))</span><br><span style="color: hsl(0, 100%, 40%);">-         cavium_uart_setup(uart0, CONFIG_TTYS0_BAUD);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!(uart1->uctl_ctl & UART_UCTL_CTL_H_CLK_EN))</span><br><span style="color: hsl(0, 100%, 40%);">-         cavium_uart_setup(uart1, CONFIG_TTYS0_BAUD);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!uart_is_enabled(0))</span><br><span style="color: hsl(120, 100%, 40%);">+                      uart_setup(0, CONFIG_TTYS0_BAUD);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!uart_is_enabled(1))</span><br><span style="color: hsl(120, 100%, 40%);">+                      uart_setup(0, CONFIG_TTYS0_BAUD);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span> }</span><br><span> </span><br><span> static void configure_spi_flash(void)</span><br><span>diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>index 1ac9f69..f835b09 100644</span><br><span>--- a/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>+++ b/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>@@ -19,9 +19,6 @@</span><br><span> bootblock-$(CONFIG_BOOTBLOCK_CUSTOM) += bootblock_custom.S</span><br><span> </span><br><span> #bootblock-y += ../common/i2c.c</span><br><span style="color: hsl(0, 100%, 40%);">-ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)</span><br><span style="color: hsl(0, 100%, 40%);">-bootblock-$(CONFIG_DRIVERS_UART) += uart.c</span><br><span style="color: hsl(0, 100%, 40%);">-endif</span><br><span> #bootblock-y += ../common/gpio.c</span><br><span> #bootblock-y += ../common/pwm.c</span><br><span> bootblock-y += bootblock.c</span><br><span>@@ -69,13 +66,11 @@</span><br><span> #verstage-y += gpio.c</span><br><span> #verstage-y += sdram.c</span><br><span> #verstage-y += ../common/i2c.c</span><br><span style="color: hsl(0, 100%, 40%);">-#verstage-$(CONFIG_DRIVERS_UART) += uart.c</span><br><span> </span><br><span> </span><br><span> ################################################################################</span><br><span> </span><br><span> romstage-y += ../common/cbmem.c</span><br><span style="color: hsl(0, 100%, 40%);">-romstage-$(CONFIG_DRIVERS_UART) += uart.c</span><br><span> romstage-y += mmu_operations.c</span><br><span> #romstage-y += ../common/pwm.c</span><br><span> #romstage-y += gpio.c</span><br><span>@@ -85,7 +80,6 @@</span><br><span> </span><br><span> ramstage-y += ../common/cbmem.c</span><br><span> ramstage-y += sdram.c</span><br><span style="color: hsl(0, 100%, 40%);">-ramstage-$(CONFIG_DRIVERS_UART) += uart.c</span><br><span> #ramstage-y += ../common/gpio.c</span><br><span> #ramstage-y += gpio.c</span><br><span> #ramstage-y += ../common/i2c.c</span><br><span>diff --git a/src/soc/cavium/cn81xx/include/soc/uart.h b/src/soc/cavium/cn81xx/include/soc/uart.h</span><br><span>deleted file mode 100644</span><br><span>index f45dbe1..0000000</span><br><span>--- a/src/soc/cavium/cn81xx/include/soc/uart.h</span><br><span>+++ /dev/null</span><br><span>@@ -1,51 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * This file is part of the coreboot project.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright 2017-present Facebook, Inc.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#ifndef __SOC_CAVIUM_COMMON_INCLUDE_SOC_UART_H</span><br><span style="color: hsl(0, 100%, 40%);">-#define __SOC_CAVIUM_COMMON_INCLUDE_SOC_UART_H</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <drivers/uart/pl011.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <inttypes.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <types.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct cn81xx_uart {</span><br><span style="color: hsl(0, 100%, 40%);">- struct pl011_uart pl011;</span><br><span style="color: hsl(0, 100%, 40%);">-        u64 uctl_ctl;</span><br><span style="color: hsl(0, 100%, 40%);">-   u8 rsvd4[0x8];</span><br><span style="color: hsl(0, 100%, 40%);">-  u64 uctl_spare0;</span><br><span style="color: hsl(0, 100%, 40%);">-        u8 rsvd5[0xe0];</span><br><span style="color: hsl(0, 100%, 40%);">- u64 uctl_spare1;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-check_member(cn81xx_uart, uctl_ctl, 0x1000);</span><br><span style="color: hsl(0, 100%, 40%);">-check_member(cn81xx_uart, uctl_spare1, 0x10f8);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_IBRD_BAUD_DIVINT_SHIFT                0</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_IBRD_BAUD_DIVINT_MASK             0xffff</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_FBRD_BAUD_DIVFRAC_SHIFT              0</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_FBRD_BAUD_DIVFRAC_MASK            0x3f</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_UCTL_RST                      (1 << 0)</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_UAA_RST                     (1 << 1)</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_CSCLK_EN                    (1 << 4)</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT  24</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_H_CLKDIV_MASK           0x7</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_H_CLKDIV_RST           (1 << 28)</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_H_CLK_BYP_SEL              (1 << 29)</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_UCTL_CTL_H_CLK_EN                   (1 << 30)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int cavium_uart_setup(struct cn81xx_uart *uart, int baudrate);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#endif     /* __SOC_CAVIUM_COMMON_INCLUDE_SOC_UART_H */</span><br><span>diff --git a/src/soc/cavium/cn81xx/uart.c b/src/soc/cavium/cn81xx/uart.c</span><br><span>deleted file mode 100644</span><br><span>index aacca82..0000000</span><br><span>--- a/src/soc/cavium/cn81xx/uart.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,105 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * This file is part of the coreboot project.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright (c) 2003-2017  Cavium Inc. (support@cavium.com). All rights</span><br><span style="color: hsl(0, 100%, 40%);">- * reserved.</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright 2017-present Facebook, Inc.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * SPDX-License-Identifier: BSD-3-Clause</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <arch/io.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <console/uart.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <delay.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <endian.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <soc/clock.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <soc/uart.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <assert.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define UART_SCLK_DIV 3</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static size_t uart_sclk_divisor(size_t reg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    static const u8 div[] = {1, 2, 4, 6, 8, 16, 24, 32};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    assert(reg < ARRAY_SIZE(div));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return div[reg];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-unsigned int uart_platform_refclk(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return thunderx_get_io_clock() / uart_sclk_divisor(UART_SCLK_DIV);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-uintptr_t uart_platform_base(int idx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return CONFIG_CONSOLE_SERIAL_UART_ADDRESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int cavium_uart_setup(struct cn81xx_uart *uart, int baudrate)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       /* 1.2.1 Initialization Sequence (Power-On/Hard/Cold Reset) */</span><br><span style="color: hsl(0, 100%, 40%);">-  /* 1. Wait for IOI reset (srst_n) to deassert. */</span><br><span style="color: hsl(0, 100%, 40%);">-       /* 2. Assert all resets:</span><br><span style="color: hsl(0, 100%, 40%);">-           a. UAA reset: UCTL_CTL[UAA_RST] = 1</span><br><span style="color: hsl(0, 100%, 40%);">-     b. UCTL reset: UCTL_CTL[UCTL_RST] = 1  */</span><br><span style="color: hsl(0, 100%, 40%);">-    setbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_UCTL_RST | UART_UCTL_CTL_UAA_RST);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* 3. Configure the HCLK:</span><br><span style="color: hsl(0, 100%, 40%);">-          a. Reset the clock dividers: UCTL_CTL[H_CLKDIV_RST] = 1.</span><br><span style="color: hsl(0, 100%, 40%);">-        b. Select the HCLK frequency</span><br><span style="color: hsl(0, 100%, 40%);">-    i. UCTL_CTL[H_CLKDIV] = desired value,</span><br><span style="color: hsl(0, 100%, 40%);">-          ii. UCTL_CTL[H_CLKDIV_EN] = 1 to enable the HCLK.</span><br><span style="color: hsl(0, 100%, 40%);">-       iii. Readback UCTL_CTL to ensure the values take effect.</span><br><span style="color: hsl(0, 100%, 40%);">-        c. Deassert the HCLK clock divider reset: UCTL_CTL[H_CLKDIV_RST] = 0. */</span><br><span style="color: hsl(0, 100%, 40%);">-     clrsetbits_le64(&uart->uctl_ctl,</span><br><span style="color: hsl(0, 100%, 40%);">-                 UART_UCTL_CTL_H_CLKDIV_MASK << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">-                  UART_SCLK_DIV << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT);</span><br><span style="color: hsl(0, 100%, 40%);">-       clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLK_BYP_SEL);</span><br><span style="color: hsl(0, 100%, 40%);">-      setbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLK_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-   clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLKDIV_RST);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* 4. Wait 20 HCLK cycles from step 3 for HCLK to start and async fifo</span><br><span style="color: hsl(0, 100%, 40%);">-     to properly reset. */</span><br><span style="color: hsl(0, 100%, 40%);">-        mdelay(200);            /* Overkill */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* 5. Deassert UCTL and UAHC resets:</span><br><span style="color: hsl(0, 100%, 40%);">-       a. UCTL_CTL[UCTL_RST] = 0</span><br><span style="color: hsl(0, 100%, 40%);">-       b. Wait 10 HCLK cycles.</span><br><span style="color: hsl(0, 100%, 40%);">-         c. UCTL_CTL[UAHC_RST] = 0</span><br><span style="color: hsl(0, 100%, 40%);">-       d. You will have to wait 10 HCLK cycles before accessing any</span><br><span style="color: hsl(0, 100%, 40%);">-    HCLK-only registers. */</span><br><span style="color: hsl(0, 100%, 40%);">-      clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_UCTL_RST);</span><br><span style="color: hsl(0, 100%, 40%);">-   mdelay(100);            /* Overkill */</span><br><span style="color: hsl(0, 100%, 40%);">-  clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_UAA_RST);</span><br><span style="color: hsl(0, 100%, 40%);">-    mdelay(100);            /* Overkill */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* 6. Enable conditional SCLK of UCTL by writing UCTL_CTL[CSCLK_EN] = 1. */</span><br><span style="color: hsl(0, 100%, 40%);">-     setbits_le32(&uart->uctl_ctl, UART_UCTL_CTL_CSCLK_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* 7. Initialize the integer and fractional baud rate divider registers</span><br><span style="color: hsl(0, 100%, 40%);">-    UARTIBRD and UARTFBRD as follows:</span><br><span style="color: hsl(0, 100%, 40%);">-       a. Baud Rate Divisor = UARTCLK/(16xBaud Rate) = BRDI + BRDF</span><br><span style="color: hsl(0, 100%, 40%);">-     b. The fractional register BRDF, m is calculated as integer(BRDF x 64 + 0.5)</span><br><span style="color: hsl(0, 100%, 40%);">-    Example calculation:</span><br><span style="color: hsl(0, 100%, 40%);">-    If the required baud rate is 230400 and hclk = 4MHz then:</span><br><span style="color: hsl(0, 100%, 40%);">-       Baud Rate Divisor = (4x10^6)/(16x230400) = 1.085</span><br><span style="color: hsl(0, 100%, 40%);">-        This means BRDI = 1 and BRDF = 0.085.</span><br><span style="color: hsl(0, 100%, 40%);">-           Therefore, fractional part, BRDF = integer((0.085x64)+0.5) = 5</span><br><span style="color: hsl(0, 100%, 40%);">-          Generated baud rate divider = 1+5/64 = 1.078 */</span><br><span style="color: hsl(0, 100%, 40%);">-      u64 divisor = thunderx_get_io_clock() /</span><br><span style="color: hsl(0, 100%, 40%);">-         (baudrate * 16 * uart_sclk_divisor(UART_SCLK_DIV) / 64);</span><br><span style="color: hsl(0, 100%, 40%);">-        write32(&uart->pl011.ibrd, divisor >> 6);</span><br><span style="color: hsl(0, 100%, 40%);">-  write32(&uart->pl011.fbrd, divisor & UART_FBRD_BAUD_DIVFRAC_MASK);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* 8. Program the line control register UAA(0..1)_LCR_H and the control</span><br><span style="color: hsl(0, 100%, 40%);">-    register UAA(0..1)_CR */</span><br><span style="color: hsl(0, 100%, 40%);">-     /* 8-bits, FIFO enable */</span><br><span style="color: hsl(0, 100%, 40%);">-       write32(&uart->pl011.lcr_h, PL011_UARTLCR_H_WLEN_8 | PL011_UARTLCR_H_FEN);</span><br><span style="color: hsl(0, 100%, 40%);">-       /* RX/TX enable, UART enable */</span><br><span style="color: hsl(0, 100%, 40%);">- write32(&uart->pl011.cr, PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/soc/cavium/common/Makefile.inc b/src/soc/cavium/common/Makefile.inc</span><br><span>index fce377c..feeeb6e 100644</span><br><span>--- a/src/soc/cavium/common/Makefile.inc</span><br><span>+++ b/src/soc/cavium/common/Makefile.inc</span><br><span>@@ -21,7 +21,10 @@</span><br><span> bootblock-y += gpio.c</span><br><span> bootblock-y += timer.c</span><br><span> bootblock-y += spi.c</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-y += uart.c</span><br><span style="color: hsl(120, 100%, 40%);">+ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-$(CONFIG_DRIVERS_UART) += uart.c</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span> </span><br><span> </span><br><span> romstage-y += twsi.c</span><br><span>@@ -29,14 +32,16 @@</span><br><span> romstage-y += gpio.c</span><br><span> romstage-y += timer.c</span><br><span> romstage-y += spi.c</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-y += uart.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-$(CONFIG_DRIVERS_UART) += uart.c</span><br><span> </span><br><span> ramstage-y += twsi.c</span><br><span> ramstage-y += clock.c</span><br><span> ramstage-y += gpio.c</span><br><span> ramstage-y += timer.c</span><br><span> ramstage-y += spi.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += uart.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-$(CONFIG_DRIVERS_UART) += uart.c</span><br><span> </span><br><span> CPPFLAGS_common += -Isrc/soc/cavium/common/include</span><br><span> </span><br><span>diff --git a/src/soc/cavium/common/include/soc/uart.h b/src/soc/cavium/common/include/soc/uart.h</span><br><span>new file mode 100644</span><br><span>index 0000000..e402206</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/cavium/common/include/soc/uart.h</span><br><span>@@ -0,0 +1,25 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2017-present Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __SOC_CAVIUM_COMMON_INCLUDE_SOC_UART_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define __SOC_CAVIUM_COMMON_INCLUDE_SOC_UART_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int uart_is_enabled(const size_t bus);</span><br><span style="color: hsl(120, 100%, 40%);">+int uart_setup(const size_t bus, int baudrate);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* __SOC_CAVIUM_COMMON_INCLUDE_SOC_UART_H */</span><br><span>diff --git a/src/soc/cavium/common/uart.c b/src/soc/cavium/common/uart.c</span><br><span>new file mode 100644</span><br><span>index 0000000..b3cce8e</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/cavium/common/uart.c</span><br><span>@@ -0,0 +1,257 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2017  Cavium Inc. (support@cavium.com). All rights</span><br><span style="color: hsl(120, 100%, 40%);">+ * reserved.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2017-present Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: BSD-3-Clause</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/uart.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <delay.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <endian.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/clock.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/uart.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/addressmap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <drivers/uart/pl011.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+union cn81xx_uart_ctl {</span><br><span style="color: hsl(120, 100%, 40%);">+        u64 u;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              u64 uctl_rst            : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64 uaa_rst             : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64                     : 2;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64 csclk_en            : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64                     : 19;</span><br><span style="color: hsl(120, 100%, 40%);">+         u64 h_clkdiv_sel        : 3;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64                     : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64 h_clkdiv_rst        : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64 h_clk_byp_sel       : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64 h_clk_en            : 1;</span><br><span style="color: hsl(120, 100%, 40%);">+          u64                     : 33;</span><br><span style="color: hsl(120, 100%, 40%);">+ } s;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct cn81xx_uart {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct pl011_uart pl011;</span><br><span style="color: hsl(120, 100%, 40%);">+      union cn81xx_uart_ctl uctl_ctl;</span><br><span style="color: hsl(120, 100%, 40%);">+       u8 rsvd4[0x8];</span><br><span style="color: hsl(120, 100%, 40%);">+        u64 uctl_spare0;</span><br><span style="color: hsl(120, 100%, 40%);">+      u8 rsvd5[0xe0];</span><br><span style="color: hsl(120, 100%, 40%);">+       u64 uctl_spare1;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define UART_IBRD_BAUD_DIVINT_SHIFT             0</span><br><span style="color: hsl(120, 100%, 40%);">+#define UART_IBRD_BAUD_DIVINT_MASK           0xffff</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define UART_FBRD_BAUD_DIVFRAC_SHIFT          0</span><br><span style="color: hsl(120, 100%, 40%);">+#define UART_FBRD_BAUD_DIVFRAC_MASK          0x3f</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+check_member(cn81xx_uart, uctl_ctl, 0x1000);</span><br><span style="color: hsl(120, 100%, 40%);">+check_member(cn81xx_uart, uctl_spare1, 0x10f8);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define UART_SCLK_DIV 3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns the current UART HCLK divider</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param reg      The H_CLKDIV_SEL value</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return         The HCLK divider</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t uart_sclk_divisor(const size_t reg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    static const u8 div[] = {1, 2, 4, 6, 8, 16, 24, 32};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        assert(reg < ARRAY_SIZE(div));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return div[reg];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns the current UART HCLK</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param uart     The UART to operate on</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return         The HCLK in Hz</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t uart_hclk(struct cn81xx_uart *uart)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     union cn81xx_uart_ctl ctl;</span><br><span style="color: hsl(120, 100%, 40%);">+    const uint64_t sclk = thunderx_get_io_clock();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       return sclk / uart_sclk_divisor(ctl.s.h_clkdiv_sel);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned int uart_platform_refclk(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct cn81xx_uart *uart =</span><br><span style="color: hsl(120, 100%, 40%);">+        (struct cn81xx_uart *)CONFIG_CONSOLE_SERIAL_UART_ADDRESS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!uart)</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return uart_hclk(uart);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uintptr_t uart_platform_base(int idx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        return CONFIG_CONSOLE_SERIAL_UART_ADDRESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Waits given count if HCLK cycles</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param uart     The UART to operate on</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param hclks    The number of HCLK cycles to wait</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void uart_wait_hclk(struct cn81xx_uart *uart, const size_t hclks)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      const size_t hclk = uart_hclk(uart);</span><br><span style="color: hsl(120, 100%, 40%);">+  const size_t delay = (hclks * 1000000ULL) / hclk;</span><br><span style="color: hsl(120, 100%, 40%);">+     udelay(MAX(delay, 1));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns the UART state.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param bus     The UART to operate on</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return        Boolean: True if UART is enabled</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int uart_is_enabled(const size_t bus)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct cn81xx_uart *uart = (struct cn81xx_uart *)UAAx_PF_BAR0(bus);</span><br><span style="color: hsl(120, 100%, 40%);">+   union cn81xx_uart_ctl ctl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  assert(uart);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!uart)</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       return !!ctl.s.csclk_en;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Setup UART with desired BAUD rate in 8N1, no parity mode.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param bus          The UART to operate on</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param baudrate     baudrate to set up</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return             Boolean: True on error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int uart_setup(const size_t bus, int baudrate)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     union cn81xx_uart_ctl ctl;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct cn81xx_uart *uart = (struct cn81xx_uart *)UAAx_PF_BAR0(bus);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ assert(uart);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!uart)</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* 1.2.1 Initialization Sequence (Power-On/Hard/Cold Reset) */</span><br><span style="color: hsl(120, 100%, 40%);">+        /* 1. Wait for IOI reset (srst_n) to deassert. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 2. Assert all resets:</span><br><span style="color: hsl(120, 100%, 40%);">+       * a. UAA reset: UCTL_CTL[UAA_RST] = 1</span><br><span style="color: hsl(120, 100%, 40%);">+         * b. UCTL reset: UCTL_CTL[UCTL_RST] = 1</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.uctl_rst = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   ctl.s.uaa_rst = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+    write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 3. Configure the HCLK:</span><br><span style="color: hsl(120, 100%, 40%);">+      * a. Reset the clock dividers: UCTL_CTL[H_CLKDIV_RST] = 1.</span><br><span style="color: hsl(120, 100%, 40%);">+    * b. Select the HCLK frequency</span><br><span style="color: hsl(120, 100%, 40%);">+        * i. UCTL_CTL[H_CLKDIV] = desired value,</span><br><span style="color: hsl(120, 100%, 40%);">+      * ii. UCTL_CTL[H_CLKDIV_EN] = 1 to enable the HCLK.</span><br><span style="color: hsl(120, 100%, 40%);">+   * iii. Readback UCTL_CTL to ensure the values take effect.</span><br><span style="color: hsl(120, 100%, 40%);">+    * c. Deassert the HCLK clock divider reset: UCTL_CTL[H_CLKDIV_RST] = 0.</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.h_clkdiv_sel = UART_SCLK_DIV;</span><br><span style="color: hsl(120, 100%, 40%);">+   write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.h_clk_byp_sel = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.h_clk_en = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.h_clkdiv_rst = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 4. Wait 20 HCLK cycles from step 3 for HCLK to start and async fifo</span><br><span style="color: hsl(120, 100%, 40%);">+         * to properly reset.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   uart_wait_hclk(uart, 20 + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 5. Deassert UCTL and UAHC resets:</span><br><span style="color: hsl(120, 100%, 40%);">+   *  a. UCTL_CTL[UCTL_RST] = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  * b. Wait 10 HCLK cycles.</span><br><span style="color: hsl(120, 100%, 40%);">+     * c. UCTL_CTL[UAHC_RST] = 0</span><br><span style="color: hsl(120, 100%, 40%);">+   * d. You will have to wait 10 HCLK cycles before accessing any</span><br><span style="color: hsl(120, 100%, 40%);">+        * HCLK-only registers.</span><br><span style="color: hsl(120, 100%, 40%);">+        */</span><br><span style="color: hsl(120, 100%, 40%);">+   ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.uctl_rst = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     uart_wait_hclk(uart, 10 + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.uaa_rst = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     uart_wait_hclk(uart, 10 + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 6. Enable conditional SCLK of UCTL by writing</span><br><span style="color: hsl(120, 100%, 40%);">+       * UCTL_CTL[CSCLK_EN] = 1.</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+   ctl.u = read64(&uart->uctl_ctl);</span><br><span style="color: hsl(120, 100%, 40%);">+       ctl.s.csclk_en = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   write64(&uart->uctl_ctl, ctl.u);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 7. Initialize the integer and fractional baud rate divider registers</span><br><span style="color: hsl(120, 100%, 40%);">+        * UARTIBRD and UARTFBRD as follows:</span><br><span style="color: hsl(120, 100%, 40%);">+   * a. Baud Rate Divisor = UARTCLK/(16xBaud Rate) = BRDI + BRDF</span><br><span style="color: hsl(120, 100%, 40%);">+         * b. The fractional register BRDF, m is calculated as</span><br><span style="color: hsl(120, 100%, 40%);">+         * integer(BRDF x 64 + 0.5)</span><br><span style="color: hsl(120, 100%, 40%);">+    * Example calculation:</span><br><span style="color: hsl(120, 100%, 40%);">+        * If the required baud rate is 230400 and hclk = 4MHz then:</span><br><span style="color: hsl(120, 100%, 40%);">+   * Baud Rate Divisor = (4x10^6)/(16x230400) = 1.085</span><br><span style="color: hsl(120, 100%, 40%);">+    * This means BRDI = 1 and BRDF = 0.085.</span><br><span style="color: hsl(120, 100%, 40%);">+       * Therefore, fractional part, BRDF = integer((0.085x64)+0.5) = 5</span><br><span style="color: hsl(120, 100%, 40%);">+      * Generated baud rate divider = 1+5/64 = 1.078</span><br><span style="color: hsl(120, 100%, 40%);">+        */</span><br><span style="color: hsl(120, 100%, 40%);">+   u64 divisor = thunderx_get_io_clock() /</span><br><span style="color: hsl(120, 100%, 40%);">+               (baudrate * 16 * uart_sclk_divisor(UART_SCLK_DIV) / 64);</span><br><span style="color: hsl(120, 100%, 40%);">+      write32(&uart->pl011.ibrd, divisor >> 6);</span><br><span style="color: hsl(120, 100%, 40%);">+        write32(&uart->pl011.fbrd, divisor & UART_FBRD_BAUD_DIVFRAC_MASK);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /**</span><br><span style="color: hsl(120, 100%, 40%);">+    * 8. Program the line control register UAA(0..1)_LCR_H and the control</span><br><span style="color: hsl(120, 100%, 40%);">+        * register UAA(0..1)_CR</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* 8-bits, FIFO enable */</span><br><span style="color: hsl(120, 100%, 40%);">+     write32(&uart->pl011.lcr_h, PL011_UARTLCR_H_WLEN_8 |</span><br><span style="color: hsl(120, 100%, 40%);">+                               PL011_UARTLCR_H_FEN);</span><br><span style="color: hsl(120, 100%, 40%);">+     /* RX/TX enable, UART enable */</span><br><span style="color: hsl(120, 100%, 40%);">+       write32(&uart->pl011.cr, PL011_UARTCR_RXE | PL011_UARTCR_TXE |</span><br><span style="color: hsl(120, 100%, 40%);">+                          PL011_UARTCR_UARTEN);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23779">change 23779</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/23779"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I33a043b753651b0aa8cf8b31bd0ecde836859c64 </div>
<div style="display:none"> Gerrit-Change-Number: 23779 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>