bdk: clock: use SET/CLR registers for all modules

This is not mandatory but removes unnecessary load-mask/or-stores.

On the other hand, due to an undocumented T210 silicon errata,
these are mandatory for SDMMC modules.
This is because a fraction of T210 chips can glitch out and cause SoC hang.
T210B01 is not affected.
This commit is contained in:
CTCaer
2025-11-26 14:33:56 +02:00
parent 50ac32fd40
commit a2ea3fb08e
2 changed files with 106 additions and 71 deletions

View File

@@ -23,10 +23,29 @@
#include <soc/t210.h>
#include <storage/sdmmc.h>
#define RST_DEV_L_SET CLK_RST_CONTROLLER_RST_DEV_L_SET
#define RST_DEV_H_SET CLK_RST_CONTROLLER_RST_DEV_H_SET
#define RST_DEV_U_SET CLK_RST_CONTROLLER_RST_DEV_U_SET
#define RST_DEV_V_SET CLK_RST_CONTROLLER_RST_DEV_V_SET
#define RST_DEV_W_SET CLK_RST_CONTROLLER_RST_DEV_W_SET
#define RST_DEV_X_SET CLK_RST_CONTROLLER_RST_DEV_X_SET
#define RST_DEV_Y_SET CLK_RST_CONTROLLER_RST_DEV_Y_SET
#define CLK_ENB_L_SET CLK_RST_CONTROLLER_CLK_ENB_L_SET
#define CLK_ENB_H_SET CLK_RST_CONTROLLER_CLK_ENB_H_SET
#define CLK_ENB_U_SET CLK_RST_CONTROLLER_CLK_ENB_U_SET
#define CLK_ENB_V_SET CLK_RST_CONTROLLER_CLK_ENB_V_SET
#define CLK_ENB_W_SET CLK_RST_CONTROLLER_CLK_ENB_W_SET
#define CLK_ENB_X_SET CLK_RST_CONTROLLER_CLK_ENB_X_SET
#define CLK_ENB_Y_SET CLK_RST_CONTROLLER_CLK_ENB_Y_SET
#define RST_DEV_H_CLR CLK_RST_CONTROLLER_RST_DEV_H_CLR
#define CLK_ENB_H_CLR CLK_RST_CONTROLLER_CLK_ENB_H_CLR
typedef struct _clk_rst_mgd_t
{
u16 reset;
u16 enable;
u16 reset; // Reset SET.
u16 enable; // Enable SET.
u16 source;
u8 index;
} clk_rst_mgd_t;
@@ -39,8 +58,8 @@ typedef struct _clock_osc_t
} clock_osc_t;
static const clock_osc_t _clock_osc_cnt[] = {
{ 12000, 706, 757 },
{ 13000, 766, 820 },
{ 12000, 706, 757 },
{ 13000, 766, 820 },
{ 16800, 991, 1059 },
{ 19200, 1133, 1210 },
{ 26000, 1535, 1638 },
@@ -48,119 +67,133 @@ static const clock_osc_t _clock_osc_cnt[] = {
{ 48000, 2836, 3023 }
};
/* clk_rst_mgd_t: reset, enable, source, index */
/*
* T210 rare HW Errata
* A fraction of T210 silicon has an undocumented HW Errata on SDMMC clock state machine.
* Specifically on enable when using the combo registers. Using SET/CLR variants is mandatory.
*/
static const clk_rst_mgd_t _clock_sdmmc[] = {
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1, CLK_L_SDMMC1 },
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2, CLK_L_SDMMC2 },
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3, CLK_U_SDMMC3 },
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4, CLK_L_SDMMC4 },
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1, CLK_L_SDMMC1 },
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2, CLK_L_SDMMC2 },
{ RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3, CLK_U_SDMMC3 },
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4, CLK_L_SDMMC4 },
};
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
static const clk_rst_t _clock_uart[] = {
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
{ CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTA, CLK_L_UARTA, 0, CLK_SRC_DIV(2) },
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, CLK_SRC_DIV(2) },
{ RST_DEV_H_SET, CLK_ENB_H_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, CLK_SRC_DIV(2) },
{ RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTD, CLK_U_UARTD, 0, CLK_SRC_DIV(2) },
{ RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_UARTAPE, CLK_Y_UARTAPE, 0, CLK_SRC_DIV(2) }
};
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
static const clk_rst_t _clock_i2c[] = {
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, // 20.4 MHz -> 100 KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, // 20.4 MHz -> 100 KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } // 20.4 MHz -> 100 KHz
{ RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C1, CLK_L_I2C1, 0, CLK_SRC_DIV(10.5) }, // 20.4 MHz -> 100 KHz
{ RST_DEV_H_SET, CLK_ENB_H_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
{ RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
{ RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C4, CLK_V_I2C4, 0, CLK_SRC_DIV(10.5) }, // 20.4 MHz -> 100 KHz
{ RST_DEV_H_SET, CLK_ENB_H_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C5, CLK_H_I2C5, 0, CLK_SRC_DIV(3) }, // 81.6 MHz -> 400 KHz
{ RST_DEV_X_SET, CLK_ENB_X_SET, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, CLK_SRC_DIV(10.5) } // 20.4 MHz -> 100 KHz
};
static clk_rst_t _clock_se = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2 MHz.
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SE, CLK_V_SE, 0, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2 MHz.
};
static clk_rst_t _clock_tzram = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_NO_SOURCE, CLK_V_TZRAM, 0, CLK_SRC_DIV(1)
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_NO_SOURCE, CLK_V_TZRAM, 0, 0
};
static clk_rst_t _clock_host1x = { // Has idle divisor.
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408 MHz.
RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, CLK_SRC_DIV(2.5) // 163.2MHz. Max: 408 MHz.
};
static clk_rst_t _clock_tsec = {
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204 MHz. Max: 408 MHz.
RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_TSEC, CLK_U_TSEC, 0, CLK_SRC_DIV(2) // 204 MHz. Max: 408 MHz.
};
static clk_rst_t _clock_nvdec = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2 MHz.
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_NVDEC, CLK_Y_NVDEC, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 716.8/979.2 MHz.
};
static clk_rst_t _clock_nvjpg = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_NVJPG, CLK_Y_NVJPG, 4, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
};
static clk_rst_t _clock_vic = { // Has idle divisor.
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
RST_DEV_X_SET, CLK_ENB_X_SET, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, CLK_SRC_DIV(1) // 408 MHz. Max: 627.2/652.8 MHz.
};
static clk_rst_t _clock_sor_safe = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, CLK_SRC_DIV(1) // 24 MHz.
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_NO_SOURCE, CLK_Y_SOR_SAFE, 0, 0 // 24 MHz.
};
static clk_rst_t _clock_sor0 = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_NOT_USED, CLK_X_SOR0, 0, CLK_SRC_DIV(1)
RST_DEV_X_SET, CLK_ENB_X_SET, CLK_NOT_USED, CLK_X_SOR0, 0, 0 // 24 MHz (safe).
};
static clk_rst_t _clock_sor1 = {
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204 MHz.
RST_DEV_X_SET, CLK_ENB_X_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SOR1, CLK_X_SOR1, 0, CLK_SRC_DIV(2) // 204 MHz.
};
static clk_rst_t _clock_kfuse = {
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_KFUSE, 0, CLK_SRC_DIV(1)
RST_DEV_H_SET, CLK_ENB_H_SET, CLK_NO_SOURCE, CLK_H_KFUSE, 0, 0
};
static clk_rst_t _clock_cl_dvfs = {
CLK_RST_CONTROLLER_RST_DEVICES_W, CLK_RST_CONTROLLER_CLK_OUT_ENB_W, CLK_NO_SOURCE, CLK_W_DVFS, 0, CLK_SRC_DIV(1)
RST_DEV_W_SET, CLK_ENB_W_SET, CLK_NO_SOURCE, CLK_W_DVFS, 0, 0
};
static clk_rst_t _clock_coresight = {
CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136 MHz.
RST_DEV_U_SET, CLK_ENB_U_SET, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE, CLK_U_CSITE, 0, CLK_SRC_DIV(3) // 136 MHz.
};
static clk_rst_t _clock_pwm = {
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
RST_DEV_L_SET, CLK_ENB_L_SET, CLK_RST_CONTROLLER_CLK_SOURCE_PWM, CLK_L_PWM, 6, CLK_SRC_DIV(3) // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
};
static clk_rst_t _clock_sdmmc_legacy_tm = {
CLK_RST_CONTROLLER_RST_DEVICES_Y, CLK_RST_CONTROLLER_CLK_OUT_ENB_Y, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
RST_DEV_Y_SET, CLK_ENB_Y_SET, CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC_LEGACY_TM, CLK_Y_SDMMC_LEGACY_TM, 4, CLK_SRC_DIV(34) // 12MHz.
};
static clk_rst_t _clock_apbdma = {
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_APBDMA, 0, CLK_SRC_DIV(1) // Max: 204 MHz.
RST_DEV_H_SET, CLK_ENB_H_SET, CLK_NO_SOURCE, CLK_H_APBDMA, 0, 0 // Max: 204 MHz.
};
static clk_rst_t _clock_ahbdma = {
CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, CLK_SRC_DIV(1)
RST_DEV_H_SET, CLK_ENB_H_SET, CLK_NO_SOURCE, CLK_H_AHBDMA, 0, 0 // Max: 408 MHz.
};
static clk_rst_t _clock_actmon = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2 MHz.
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON, CLK_V_ACTMON, 6, CLK_SRC_DIV(1) // 19.2 MHz.
};
static clk_rst_t _clock_extperiph1 = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1, CLK_V_EXTPERIPH1, 0, CLK_SRC_DIV(1)
};
static clk_rst_t _clock_extperiph2 = {
CLK_RST_CONTROLLER_RST_DEVICES_V, CLK_RST_CONTROLLER_CLK_OUT_ENB_V, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0 MHz
RST_DEV_V_SET, CLK_ENB_V_SET, CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2, CLK_V_EXTPERIPH2, 2, CLK_SRC_DIV(102) // 4.0 MHz
};
void clock_enable(const clk_rst_t *clk)
{
const u32 module = BIT(clk->index);
// Put clock into reset.
CLOCK(clk->reset) |= BIT(clk->index);
CLOCK(clk->reset) = module;
// Disable.
CLOCK(clk->enable) &= ~BIT(clk->index);
CLOCK(clk->enable + CLK_CLR_OFFSET) = module;
// Configure clock source if required.
if (clk->source)
CLOCK(clk->source) = (clk->clk_src << 29u) | clk->clk_div;
// Enable.
CLOCK(clk->enable) |= BIT(clk->index);
CLOCK(clk->enable) = module;
usleep(2);
// Take clock off reset.
CLOCK(clk->reset) &= ~BIT(clk->index);
CLOCK(clk->reset + CLK_CLR_OFFSET) = module;
// Commit changes.
(void)CLOCK(clk->reset);
}
void clock_disable(const clk_rst_t *clk)
{
const u32 module = BIT(clk->index);
// Put clock into reset.
CLOCK(clk->reset) |= BIT(clk->index);
CLOCK(clk->reset) = module;
// Disable.
CLOCK(clk->enable) &= ~BIT(clk->index);
CLOCK(clk->enable + CLK_CLR_OFFSET) = module;
}
void clock_enable_fuse(bool enable)
@@ -176,7 +209,7 @@ void clock_enable_uart(u32 idx)
clock_enable(&_clock_uart[idx]);
// Restore OC.
// Restore sys clock.
bpmp_clk_rate_relaxed(false);
}
@@ -189,15 +222,15 @@ void clock_disable_uart(u32 idx)
int clock_uart_use_src_div(u32 idx, u32 baud)
{
u32 clk_src_div = CLOCK(_clock_uart[idx].source) & 0xE0000000;
u32 clk_src = CLOCK(_clock_uart[idx].source) & 0xE0000000;
if (baud == 3000000)
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
CLOCK(_clock_uart[idx].source) = clk_src | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(8.5);
else if (baud == 1000000)
CLOCK(_clock_uart[idx].source) = clk_src_div | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
CLOCK(_clock_uart[idx].source) = clk_src | UART_SRC_CLK_DIV_EN | CLK_SRC_DIV(25.5);
else
{
CLOCK(_clock_uart[idx].source) = clk_src_div | CLK_SRC_DIV(2);
CLOCK(_clock_uart[idx].source) = clk_src | CLK_SRC_DIV(2);
return 1;
}
@@ -221,7 +254,7 @@ void clock_enable_se()
// Lock clock to always enabled if T210B01.
if (hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01)
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SE) |= 0x100;
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SE) |= BIT(8);
}
void clock_enable_tzram()
@@ -323,13 +356,13 @@ void clock_disable_sor1()
void clock_enable_kfuse()
{
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_KFUSE);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_KFUSE);
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_KFUSE);
usleep(10); // Wait 10s to prevent glitching.
CLOCK(RST_DEV_H_SET) = BIT(CLK_H_KFUSE);
CLOCK(CLK_ENB_H_CLR) = BIT(CLK_H_KFUSE);
CLOCK(CLK_ENB_H_SET) = BIT(CLK_H_KFUSE);
usleep(10); // Wait 10us to prevent glitching.
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_KFUSE);
usleep(20); // Wait 20s fo kfuse hw to init.
CLOCK(RST_DEV_H_CLR) = BIT(CLK_H_KFUSE);
usleep(20); // Wait 20us for KFUSE HW to init.
}
void clock_disable_kfuse()
@@ -364,7 +397,7 @@ void clock_enable_pwm()
clock_enable(&_clock_pwm);
// Restore OC.
// Restore sys clock.
bpmp_clk_rate_relaxed(false);
}
@@ -436,9 +469,9 @@ void clock_enable_plld(u32 divp, u32 divn, bool lowpower, bool tegra_t210)
u32 plld_div = (divp << 20) | (divn << 11) | 1;
// N divider is fractional, so N = DIVN + 1/2 + PLLD_SDM_DIN/8192.
u32 misc = 0x2D0000 | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
u32 misc = BIT(21) | BIT(19) | BIT(18) | BIT(16) | 0xFC00; // Clock enable and PLLD_SDM_DIN: -1024 -> DIVN + 0.375.
if (lowpower && tegra_t210)
misc = 0x2D0000 | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
misc = BIT(21) | BIT(19) | BIT(18) | BIT(16) | 0x0AAA; // Clock enable and PLLD_SDM_DIN: 2730 -> DIVN + 0.833.
// Set DISP1 clock source.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 2 << 29u; // PLLD_OUT0.
@@ -633,14 +666,14 @@ static void _clock_sdmmc_set_reset(u32 id)
{
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
CLOCK(clk->reset) |= BIT(clk->index);
CLOCK(clk->reset) = BIT(clk->index);
}
static void _clock_sdmmc_clear_reset(u32 id)
{
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
CLOCK(clk->reset) &= ~BIT(clk->index);
CLOCK(clk->reset + CLK_CLR_OFFSET) = BIT(clk->index);
}
static int _clock_sdmmc_is_enabled(u32 id)
@@ -654,14 +687,14 @@ static void _clock_sdmmc_set_enable(u32 id)
{
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
CLOCK(clk->enable) |= BIT(clk->index);
CLOCK(clk->enable) = BIT(clk->index);
}
static void _clock_sdmmc_clear_enable(u32 id)
{
const clk_rst_mgd_t *clk = &_clock_sdmmc[id];
CLOCK(clk->enable) &= ~BIT(clk->index);
CLOCK(clk->enable + CLK_CLR_OFFSET) = BIT(clk->index);
}
static void _clock_sdmmc_config_legacy_tm()

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2024 CTCaer
* Copyright (c) 2018-2025 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,
@@ -171,6 +171,8 @@
#define CLK_NO_SOURCE 0x0
#define CLK_NOT_USED 0x0
#define CLK_CLR_OFFSET 0x4
/*! PLL control and status bits */
#define PLL_BASE_LOCK BIT(27)
#define PLL_BASE_REF_DIS BIT(29)
@@ -674,11 +676,11 @@ enum CLK_Y_DEV
/*! Generic clock descriptor. */
typedef struct _clk_rst_t
{
u16 reset;
u16 enable;
u16 reset; // Reset SET.
u16 enable; // Enable SET.
u16 source;
u8 index;
u8 clk_src;
u8 index:5;
u8 clk_src:3;
u8 clk_div;
} clk_rst_t;