mirror of https://github.com/wolfSSL/wolfBoot.git
110 lines
3.8 KiB
C
110 lines
3.8 KiB
C
/* nxp_ppc.c
|
|
*
|
|
* Copyright (C) 2026 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfBoot.
|
|
*
|
|
* wolfBoot is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfBoot is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
/* This file gets directly included from nxp_ targets.
|
|
* This file contains shared driver code for all NXP QorIQ platforms */
|
|
|
|
/* RAMFUNCTION is defined by image.h (included by targets that need RAM_CODE).
|
|
* Provide an empty fallback for targets that do not use RAM_CODE (e.g. T1024/P1021). */
|
|
#ifndef RAMFUNCTION
|
|
#define RAMFUNCTION
|
|
#endif
|
|
|
|
/* ---- E5500/E6500 clock helpers and udelay ----
|
|
* CLOCKING_PLLCNGSR and CLOCKING_PLLPGSR must be defined by the including
|
|
* target before this file is reached (e.g. via nxp_t2080.h / nxp_t1024.c).
|
|
* SYS_CLK must be the oscillator input frequency (e.g. 100 MHz). */
|
|
#if defined(CORE_E5500) || defined(CORE_E6500)
|
|
#ifdef ENABLE_BUS_CLK_CALC
|
|
static uint32_t hal_get_core_clk(void)
|
|
{
|
|
/* compute core clock: system_input * (CGA_PLL1_RAT / 2) */
|
|
uint32_t core_clk;
|
|
uint32_t core_ratio = get32(CLOCKING_PLLCNGSR(0));
|
|
core_ratio = ((core_ratio >> 1) & 0x3F);
|
|
core_clk = SYS_CLK * core_ratio;
|
|
return core_clk;
|
|
}
|
|
static uint32_t RAMFUNCTION hal_get_plat_clk(void)
|
|
{
|
|
/* compute platform clock: system_input * (SYS_PLL_RAT / 2) */
|
|
uint32_t plat_clk;
|
|
uint32_t plat_ratio = get32(CLOCKING_PLLPGSR);
|
|
plat_ratio = ((plat_ratio >> 1) & 0x1F);
|
|
plat_clk = SYS_CLK * plat_ratio;
|
|
return plat_clk;
|
|
}
|
|
static uint32_t hal_get_bus_clk(void)
|
|
{
|
|
return hal_get_plat_clk() / 2;
|
|
}
|
|
#endif /* ENABLE_BUS_CLK_CALC */
|
|
|
|
#define TIMEBASE_CLK_DIV 16
|
|
#define TIMEBASE_HZ (hal_get_plat_clk() / TIMEBASE_CLK_DIV)
|
|
#define DELAY_US (TIMEBASE_HZ / 1000000)
|
|
static void RAMFUNCTION udelay(uint32_t delay_us)
|
|
{
|
|
wait_ticks((unsigned long long)delay_us * DELAY_US);
|
|
}
|
|
#endif /* CORE_E5500 || CORE_E6500 */
|
|
|
|
/* ---- Shared PC16552D-compatible DUART driver ----
|
|
* Each target must define before including this file:
|
|
* UART_SEL, BAUD_RATE, UART_THR(n), UART_IER(n), UART_FCR(n),
|
|
* UART_LCR(n), UART_DLB(n), UART_DMB(n), UART_LSR(n),
|
|
* UART_FCR_TFR, UART_FCR_RFR, UART_FCR_FEN,
|
|
* UART_LCR_DLAB, UART_LCR_WLS, UART_LSR_TEMT, UART_LSR_THRE */
|
|
#ifdef DEBUG_UART
|
|
void uart_init(void)
|
|
{
|
|
/* baud rate = bus_clk / (16 * div); round up */
|
|
uint32_t div = (hal_get_bus_clk() + (8 * BAUD_RATE)) / (16 * BAUD_RATE);
|
|
|
|
while (!(get8(UART_LSR(UART_SEL)) & UART_LSR_TEMT))
|
|
;
|
|
|
|
set8(UART_IER(UART_SEL), 0);
|
|
set8(UART_FCR(UART_SEL), (UART_FCR_TFR | UART_FCR_RFR | UART_FCR_FEN));
|
|
|
|
/* enable baud rate access (DLAB=1) */
|
|
set8(UART_LCR(UART_SEL), (UART_LCR_DLAB | UART_LCR_WLS));
|
|
set8(UART_DLB(UART_SEL), (div & 0xff));
|
|
set8(UART_DMB(UART_SEL), ((div >> 8) & 0xff));
|
|
/* disable baud rate access (DLAB=0) */
|
|
set8(UART_LCR(UART_SEL), (UART_LCR_WLS));
|
|
}
|
|
|
|
void uart_write(const char* buf, uint32_t sz)
|
|
{
|
|
uint32_t pos = 0;
|
|
while (sz-- > 0) {
|
|
char c = buf[pos++];
|
|
if (c == '\n') { /* handle CRLF */
|
|
while ((get8(UART_LSR(UART_SEL)) & UART_LSR_THRE) == 0);
|
|
set8(UART_THR(UART_SEL), '\r');
|
|
}
|
|
while ((get8(UART_LSR(UART_SEL)) & UART_LSR_THRE) == 0);
|
|
set8(UART_THR(UART_SEL), c);
|
|
}
|
|
}
|
|
#endif /* DEBUG_UART */
|