uplift bdk

Signed-off-by: Damien Zhao <zdm65477730@126.com>
This commit is contained in:
Damien Zhao
2024-10-21 16:21:40 +08:00
parent cd38dbc1ae
commit 22b1fda1d5
64 changed files with 1289 additions and 808 deletions

View File

@@ -1,7 +1,7 @@
/*
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
*
* Copyright (c) 2019-2023 CTCaer
* Copyright (c) 2019-2024 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -118,7 +118,7 @@
#define MMU_EN_READ BIT(2)
#define MMU_EN_WRITE BIT(3)
bpmp_mmu_entry_t mmu_entries[] =
static const bpmp_mmu_entry_t mmu_entries[] =
{
{ DRAM_START, 0xFFFFFFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true },
{ IRAM_BASE, 0x4003FFFF, MMU_EN_READ | MMU_EN_WRITE | MMU_EN_EXEC | MMU_EN_CACHED, true }
@@ -140,7 +140,7 @@ void bpmp_mmu_maintenance(u32 op, bool force)
BPMP_CACHE_CTRL(BPMP_CACHE_INT_CLEAR) = BPMP_CACHE_CTRL(BPMP_CACHE_INT_RAW_EVENT);
}
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply)
void bpmp_mmu_set_entry(int idx, const bpmp_mmu_entry_t *entry, bool apply)
{
if (idx > 31)
return;
@@ -200,10 +200,45 @@ void bpmp_mmu_disable()
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
}
/*
* CLK_RST_CONTROLLER_SCLK_BURST_POLICY:
* 0 = CLKM
* 1 = PLLC_OUT1
* 2 = PLLC4_OUT3
* 3 = PLLP_OUT0
* 4 = PLLP_OUT2
* 5 = PLLC4_OUT1
* 6 = CLK_S
* 7 = PLLC4_OUT2
*/
bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
void bpmp_clk_rate_relaxed(bool enable)
{
// This is a glitch-free way to reduce the SCLK timings.
if (enable)
{
// Restore to PLLP source during PLLC configuration.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT.
usleep(100); // Wait a bit for clock source change.
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
}
else if (bpmp_fid_current)
{
// Restore to PLLC_OUT1.
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 and CLKM for idle.
usleep(100); // Wait a bit for clock source change.
}
}
// APB clock affects RTC, PWM, MEMFETCH, APE, USB, SOR PWM,
// I2C host, DC/DSI/DISP. UART gives extra stress.
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
const u8 pll_divn[] = {
// APB clock max is supposed to be 204 MHz though.
static const u8 pll_divn[] = {
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
@@ -213,8 +248,6 @@ const u8 pll_divn[] = {
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
};
bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
void bpmp_clk_rate_get()
{
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
@@ -237,45 +270,42 @@ void bpmp_clk_rate_get()
}
}
bpmp_freq_t bpmp_clk_rate_set(bpmp_freq_t fid)
void bpmp_clk_rate_set(bpmp_freq_t fid)
{
bpmp_freq_t prev_fid = bpmp_fid_current;
if (fid > (BPMP_CLK_MAX - 1))
fid = BPMP_CLK_MAX - 1;
if (prev_fid == fid)
return prev_fid;
if (bpmp_fid_current == fid)
return;
bpmp_fid_current = fid;
if (fid)
{
if (prev_fid)
{
// Restore to PLLP source during PLLC configuration.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // PLLP_OUT.
msleep(1); // Wait a bit for clock source change.
}
// Use default SCLK / HCLK / PCLK clocks.
bpmp_clk_rate_relaxed(true);
// Configure and enable PLLC.
clock_enable_pllc(pll_divn[fid]);
// Set SCLK / HCLK / PCLK.
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 for active and CLKM for idle.
// Set new source and SCLK / HCLK / PCLK dividers.
bpmp_clk_rate_relaxed(false);
}
else
{
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT for active and CLKM for idle.
msleep(1); // Wait a bit for clock source change.
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
// Use default SCLK / HCLK / PCLK clocks.
bpmp_clk_rate_relaxed(true);
// Disable PLLC to save power.
clock_disable_pllc();
}
bpmp_fid_current = fid;
}
// Return old fid in case of temporary swap.
return prev_fid;
// State is reset to RUN on any clock or source set via SW.
void bpmp_state_set(bpmp_state_t state)
{
u32 cfg = CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) & ~0xF0000000u;
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = cfg | (state << 28u);
}
// The following functions halt BPMP to reduce power while sleeping.