mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
bdk: bpmp: add and use bpmp_clk_rate_relaxed
This commit is contained in:
parent
14706cef4e
commit
7a74761da9
7 changed files with 75 additions and 53 deletions
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* VIC driver for Tegra X1
|
* VIC driver for Tegra X1
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -539,14 +539,8 @@ int vic_compose()
|
||||||
|
|
||||||
int vic_init()
|
int vic_init()
|
||||||
{
|
{
|
||||||
// Ease the stress to APB.
|
|
||||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
|
||||||
|
|
||||||
clock_enable_vic();
|
clock_enable_vic();
|
||||||
|
|
||||||
// Restore sys clock.
|
|
||||||
bpmp_clk_rate_set(prev_fid);
|
|
||||||
|
|
||||||
// Load Fetch Control Engine microcode.
|
// Load Fetch Control Engine microcode.
|
||||||
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
|
for (u32 i = 0; i < sizeof(vic_fce_ucode) / sizeof(u32); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1215,17 +1215,11 @@ void jc_init_hw()
|
||||||
pinmux_config_uart(UART_B);
|
pinmux_config_uart(UART_B);
|
||||||
pinmux_config_uart(UART_C);
|
pinmux_config_uart(UART_C);
|
||||||
|
|
||||||
// Ease the stress to APB.
|
|
||||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
|
||||||
|
|
||||||
// Enable UART B and C clocks.
|
// Enable UART B and C clocks.
|
||||||
if (!jc_gamepad.sio_mode)
|
if (!jc_gamepad.sio_mode)
|
||||||
clock_enable_uart(UART_B);
|
clock_enable_uart(UART_B);
|
||||||
clock_enable_uart(UART_C);
|
clock_enable_uart(UART_C);
|
||||||
|
|
||||||
// Restore OC.
|
|
||||||
bpmp_clk_rate_set(prev_fid);
|
|
||||||
|
|
||||||
jc_init_done = true;
|
jc_init_done = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ int tsec_query(void *tsec_keys, tsec_ctxt_t *tsec_ctxt)
|
||||||
void *ptb;
|
void *ptb;
|
||||||
|
|
||||||
bpmp_mmu_disable();
|
bpmp_mmu_disable();
|
||||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
// Enable clocks.
|
// Enable clocks.
|
||||||
clock_enable_tsec();
|
clock_enable_tsec();
|
||||||
|
@ -305,7 +305,7 @@ out:
|
||||||
clock_disable_sor_safe();
|
clock_disable_sor_safe();
|
||||||
clock_disable_tsec();
|
clock_disable_tsec();
|
||||||
bpmp_mmu_enable();
|
bpmp_mmu_enable();
|
||||||
bpmp_clk_rate_set(prev_fid);
|
bpmp_clk_rate_relaxed(false);
|
||||||
|
|
||||||
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
#ifdef BDK_MC_ENABLE_AHB_REDIRECT
|
||||||
// Re-enable AHB aperture.
|
// Re-enable AHB aperture.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -200,10 +200,44 @@ void bpmp_mmu_disable()
|
||||||
BPMP_CACHE_CTRL(BPMP_CACHE_CONFIG) = 0;
|
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,
|
// APB clock affects RTC, PWM, MEMFETCH, APE, USB, SOR PWM,
|
||||||
// I2C host, DC/DSI/DISP. UART gives extra stress.
|
// I2C host, DC/DSI/DISP. UART gives extra stress.
|
||||||
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
|
// 92: 100% success ratio. 93-94: 595-602MHz has 99% success ratio. 95: 608MHz less.
|
||||||
const u8 pll_divn[] = {
|
static const u8 pll_divn[] = {
|
||||||
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
0, // BPMP_CLK_NORMAL: 408MHz 0% - 136MHz APB.
|
||||||
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
85, // BPMP_CLK_HIGH_BOOST: 544MHz 33% - 136MHz APB.
|
||||||
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
88, // BPMP_CLK_HIGH2_BOOST: 563MHz 38% - 141MHz APB.
|
||||||
|
@ -213,8 +247,6 @@ const u8 pll_divn[] = {
|
||||||
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
//95 // BPMP_CLK_DEV_BOOST: 608MHz 49% - 152MHz APB.
|
||||||
};
|
};
|
||||||
|
|
||||||
bpmp_freq_t bpmp_fid_current = BPMP_CLK_NORMAL;
|
|
||||||
|
|
||||||
void bpmp_clk_rate_get()
|
void bpmp_clk_rate_get()
|
||||||
{
|
{
|
||||||
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
|
bool clk_src_is_pllp = ((CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) >> 4) & 7) == 3;
|
||||||
|
@ -237,45 +269,35 @@ 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))
|
if (fid > (BPMP_CLK_MAX - 1))
|
||||||
fid = BPMP_CLK_MAX - 1;
|
fid = BPMP_CLK_MAX - 1;
|
||||||
|
|
||||||
if (prev_fid == fid)
|
if (bpmp_fid_current == fid)
|
||||||
return prev_fid;
|
return;
|
||||||
|
|
||||||
|
bpmp_fid_current = fid;
|
||||||
|
|
||||||
if (fid)
|
if (fid)
|
||||||
{
|
{
|
||||||
if (prev_fid)
|
// Use default SCLK / HCLK / PCLK clocks.
|
||||||
{
|
bpmp_clk_rate_relaxed(true);
|
||||||
// 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.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure and enable PLLC.
|
// Configure and enable PLLC.
|
||||||
clock_enable_pllc(pll_divn[fid]);
|
clock_enable_pllc(pll_divn[fid]);
|
||||||
|
|
||||||
// Set SCLK / HCLK / PCLK.
|
// Set new source and SCLK / HCLK / PCLK dividers.
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 3; // PCLK = HCLK / (3 + 1). HCLK == SCLK.
|
bpmp_clk_rate_relaxed(false);
|
||||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003310; // PLLC_OUT1 for active and CLKM for idle.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003330; // PLLP_OUT for active and CLKM for idle.
|
// Use default SCLK / HCLK / PCLK clocks.
|
||||||
msleep(1); // Wait a bit for clock source change.
|
bpmp_clk_rate_relaxed(true);
|
||||||
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // PCLK = HCLK / (2 + 1). HCLK == SCLK.
|
|
||||||
|
|
||||||
// Disable PLLC to save power.
|
// Disable PLLC to save power.
|
||||||
clock_disable_pllc();
|
clock_disable_pllc();
|
||||||
}
|
}
|
||||||
bpmp_fid_current = fid;
|
|
||||||
|
|
||||||
// Return old fid in case of temporary swap.
|
|
||||||
return prev_fid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following functions halt BPMP to reduce power while sleeping.
|
// The following functions halt BPMP to reduce power while sleeping.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* BPMP-Lite Cache/MMU and Frequency driver for Tegra X1
|
* 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
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -62,8 +62,9 @@ void bpmp_mmu_maintenance(u32 op, bool force);
|
||||||
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
|
void bpmp_mmu_set_entry(int idx, bpmp_mmu_entry_t *entry, bool apply);
|
||||||
void bpmp_mmu_enable();
|
void bpmp_mmu_enable();
|
||||||
void bpmp_mmu_disable();
|
void bpmp_mmu_disable();
|
||||||
|
void bpmp_clk_rate_relaxed(bool enable);
|
||||||
void bpmp_clk_rate_get();
|
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);
|
||||||
void bpmp_usleep(u32 us);
|
void bpmp_usleep(u32 us);
|
||||||
void bpmp_msleep(u32 ms);
|
void bpmp_msleep(u32 ms);
|
||||||
void bpmp_halt();
|
void bpmp_halt();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <soc/bpmp.h>
|
||||||
#include <soc/clock.h>
|
#include <soc/clock.h>
|
||||||
#include <soc/hw_init.h>
|
#include <soc/hw_init.h>
|
||||||
#include <soc/pmc.h>
|
#include <soc/pmc.h>
|
||||||
|
@ -153,7 +154,13 @@ void clock_enable_fuse(bool enable)
|
||||||
|
|
||||||
void clock_enable_uart(u32 idx)
|
void clock_enable_uart(u32 idx)
|
||||||
{
|
{
|
||||||
|
// Ease the stress to APB.
|
||||||
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
clock_enable(&_clock_uart[idx]);
|
clock_enable(&_clock_uart[idx]);
|
||||||
|
|
||||||
|
// Restore OC.
|
||||||
|
bpmp_clk_rate_relaxed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable_uart(u32 idx)
|
void clock_disable_uart(u32 idx)
|
||||||
|
@ -247,7 +254,13 @@ void clock_disable_nvjpg()
|
||||||
|
|
||||||
void clock_enable_vic()
|
void clock_enable_vic()
|
||||||
{
|
{
|
||||||
|
// Ease the stress to APB.
|
||||||
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
clock_enable(&_clock_vic);
|
clock_enable(&_clock_vic);
|
||||||
|
|
||||||
|
// Restore sys clock.
|
||||||
|
bpmp_clk_rate_relaxed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable_vic()
|
void clock_disable_vic()
|
||||||
|
@ -323,7 +336,13 @@ void clock_disable_coresight()
|
||||||
|
|
||||||
void clock_enable_pwm()
|
void clock_enable_pwm()
|
||||||
{
|
{
|
||||||
|
// Ease the stress to APB.
|
||||||
|
bpmp_clk_rate_relaxed(true);
|
||||||
|
|
||||||
clock_enable(&_clock_pwm);
|
clock_enable(&_clock_pwm);
|
||||||
|
|
||||||
|
// Restore OC.
|
||||||
|
bpmp_clk_rate_relaxed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_disable_pwm()
|
void clock_disable_pwm()
|
||||||
|
@ -464,10 +483,10 @@ void clock_enable_pllc(u32 divn)
|
||||||
;
|
;
|
||||||
|
|
||||||
// Disable PLLC_OUT1, enable reset and set div to 1.5.
|
// Disable PLLC_OUT1, enable reset and set div to 1.5.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = BIT(8);
|
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) = 1 << 8;
|
||||||
|
|
||||||
// Enable PLLC_OUT1 and bring it out of reset.
|
// Enable PLLC_OUT1 and bring it out of reset.
|
||||||
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= (PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR);
|
CLOCK(CLK_RST_CONTROLLER_PLLC_OUT) |= PLLC_OUT1_CLKEN | PLLC_OUT1_RSTN_CLR;
|
||||||
msleep(1); // Wait a bit for PLL to stabilize.
|
msleep(1); // Wait a bit for PLL to stabilize.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Fan driver for Nintendo Switch
|
* Fan driver for Nintendo Switch
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2023 CTCaer
|
* Copyright (c) 2018-2024 CTCaer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
@ -49,16 +49,8 @@ void set_fan_duty(u32 duty)
|
||||||
|
|
||||||
// Enable PWM if disabled.
|
// Enable PWM if disabled.
|
||||||
if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA)
|
if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA)
|
||||||
{
|
|
||||||
// Ease the stress to APB.
|
|
||||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
|
||||||
|
|
||||||
clock_enable_pwm();
|
clock_enable_pwm();
|
||||||
|
|
||||||
// Restore OC.
|
|
||||||
bpmp_clk_rate_set(prev_fid);
|
|
||||||
}
|
|
||||||
|
|
||||||
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Max PWM to disable fan.
|
PWM(PWM_CONTROLLER_PWM_CSR_1) = PWM_CSR_EN | (0x100 << 16); // Max PWM to disable fan.
|
||||||
|
|
||||||
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1.
|
PINMUX_AUX(PINMUX_AUX_LCD_GPIO2) = 1; // Set source to PWM1.
|
||||||
|
|
Loading…
Reference in a new issue