mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-09-21 07:38:59 +00:00
![Tomasz Moń](/assets/img/avatar_default.png)
Use 204 MHz as host clock in SDR104 mode instead of 136 MHz. Due to this, also change the frequency init divider so the initialization frequency is below 400 kHz. This makes the clocks for SDMMC1 in all modes to match the TRM table. Make it clear in the code that HS200/HS400 modes in fact use PLLP_OUT0 and not PLLC4_OUT2_LJ like the comment suggest. In fact selecting the PLLC4_OUT2_LJ as clock source results in freeze after switching to HS200/HS400 mode. This is most likely related to the PLLC4 not being enabled, but it should be checked later. Set the HS200/HS400 divider to 3, as this is what the code really did set prior to this change - so this commit does not change that. Configure Legacy 12 MHz clock to run at 12 MHz using the SW default configuration (as per TRM) for the SDMMC legacy timer. Introduce initial version of sdmmc_host_clock_delay() in order to use it in places where the wait is host clock dependent. The way it is implemented now does not change the sleep that was used instead.
299 lines
12 KiB
C
299 lines
12 KiB
C
|
|
#ifndef __FUSEE_CLOCK_H__
|
|
#define __FUSEE_CLOCK_H__
|
|
|
|
#include "utils.h"
|
|
|
|
/**
|
|
* Struct definition yanked from u-boot.
|
|
*/
|
|
|
|
/* PLL registers - there are several PLLs in the clock controller */
|
|
struct clk_pll {
|
|
uint32_t pll_base; /* the control register */
|
|
/* pll_out[0] is output A control, pll_out[1] is output B control */
|
|
uint32_t pll_out[2];
|
|
uint32_t pll_misc; /* other misc things */
|
|
};
|
|
|
|
/* PLL registers - there are several PLLs in the clock controller */
|
|
struct clk_pll_simple {
|
|
uint32_t pll_base; /* the control register */
|
|
uint32_t pll_misc; /* other misc things */
|
|
};
|
|
|
|
struct clk_pllm {
|
|
uint32_t pllm_base; /* the control register */
|
|
uint32_t pllm_out; /* output control */
|
|
uint32_t pllm_misc1; /* misc1 */
|
|
uint32_t pllm_misc2; /* misc2 */
|
|
};
|
|
|
|
|
|
/*
|
|
* Most PLLs use the clk_pll structure, but some have a simpler two-member
|
|
* structure for which we use clk_pll_simple. The reason for this non-
|
|
* othogonal setup is not stated.
|
|
*/
|
|
enum {
|
|
TEGRA_CLK_PLLS = 6, /* Number of normal PLLs */
|
|
TEGRA_CLK_SIMPLE_PLLS = 3, /* Number of simple PLLs */
|
|
TEGRA_CLK_SOURCES = 64, /* Number of ppl clock sources L/H/U */
|
|
TEGRA_CLK_SOURCES_VW = 32, /* Number of ppl clock sources V/W */
|
|
TEGRA_CLK_SOURCES_X = 32, /* Number of ppl clock sources X */
|
|
TEGRA_CLK_SOURCES_Y = 18, /* Number of ppl clock sources Y */
|
|
};
|
|
|
|
/*
|
|
* Masks for TEGRA_CLK_SOURCE elements.
|
|
*/
|
|
enum {
|
|
CLK_SOURCE_MASK = (0b111 << 29),
|
|
CLK_SOURCE_SDMMC1_PLLP_OUT0 = (0b000 << 29), /* Fixed 408 MHz */
|
|
CLK_SOURCE_SDMMC4_PLLP_OUT0 = (0b000 << 29), /* Fixed 408 MHz */
|
|
CLK_SOURCE_SDMMC4_PLLC4_OUT2_LJ = (0b001 << 29), /* 199.68 MHz */
|
|
CLK_SOURCE_SDMMC_LEGACY_PLLP_OUT0 = (0b100 << 29), /* Fixed 408 MHz */
|
|
|
|
CLK_DIVIDER_MASK = (0xff << 0),
|
|
CLK_DIVIDER_UNITY = (0x00 << 0),
|
|
};
|
|
|
|
|
|
/**
|
|
* Reset bits for relevant registers.
|
|
*/
|
|
enum {
|
|
CAR_CONTROL_SDMMC1 = (1 << 14),
|
|
CAR_CONTROL_SDMMC4 = (1 << 15),
|
|
CAR_CONTROL_SDMMC_LEGACY = (1 << 1),
|
|
};
|
|
|
|
|
|
enum {
|
|
CLK_SOURCE_SDMMC1 = 20,
|
|
CLK_SOURCE_SDMMC4 = 25, /* 0x54 into the the main source block */
|
|
|
|
CLK_SOURCE_SDMMC_LEGACY = 0, /* first in block Y */
|
|
};
|
|
|
|
|
|
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
|
|
struct tegra_car {
|
|
uint32_t rst_src; /* _RST_SOURCE_0,0x00 */
|
|
|
|
uint32_t rst_dev_l;
|
|
uint32_t rst_dev_h;
|
|
uint32_t rst_dev_u;
|
|
|
|
uint32_t clk_out_dev_l;
|
|
uint32_t clk_out_dev_h;
|
|
uint32_t clk_out_dev_u;
|
|
|
|
uint32_t reserved0; /* reserved_0, 0x1C */
|
|
uint32_t cclk_brst_pol; /* _CCLK_BURST_POLICY_0, 0x20 */
|
|
uint32_t super_cclk_div; /* _SUPER_CCLK_DIVIDER_0,0x24 */
|
|
uint32_t sclk_brst_pol; /* _SCLK_BURST_POLICY_0, 0x28 */
|
|
uint32_t super_sclk_div; /* _SUPER_SCLK_DIVIDER_0,0x2C */
|
|
uint32_t clk_sys_rate; /* _CLK_SYSTEM_RATE_0, 0x30 */
|
|
uint32_t prog_dly_clk; /* _PROG_DLY_CLK_0, 0x34 */
|
|
uint32_t aud_sync_clk_rate; /* _AUDIO_SYNC_CLK_RATE_0,0x38 */
|
|
uint32_t reserved1; /* reserved_1, 0x3C */
|
|
uint32_t cop_clk_skip_plcy; /* _COP_CLK_SKIP_POLICY_0,0x40 */
|
|
uint32_t clk_mask_arm; /* _CLK_MASK_ARM_0, 0x44 */
|
|
uint32_t misc_clk_enb; /* _MISC_CLK_ENB_0, 0x48 */
|
|
uint32_t clk_cpu_cmplx; /* _CLK_CPU_CMPLX_0, 0x4C */
|
|
uint32_t osc_ctrl; /* _OSC_CTRL_0, 0x50 */
|
|
uint32_t pll_lfsr; /* _PLL_LFSR_0, 0x54 */
|
|
uint32_t osc_freq_det; /* _OSC_FREQ_DET_0, 0x58 */
|
|
uint32_t osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0,0x5C */
|
|
uint32_t reserved2[8]; /* reserved_2[8], 0x60-7C */
|
|
|
|
struct clk_pll pll[TEGRA_CLK_PLLS]; /* PLLs from 0x80 to 0xdc */
|
|
|
|
/* PLLs from 0xe0 to 0xf4 */
|
|
struct clk_pll_simple pll_simple[TEGRA_CLK_SIMPLE_PLLS];
|
|
|
|
uint32_t reserved10; /* _reserved_10, 0xF8 */
|
|
uint32_t reserved11; /* _reserved_11, 0xFC */
|
|
|
|
uint32_t clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0... 0x100-1fc */
|
|
|
|
uint32_t reserved20[32]; /* _reserved_20, 0x200-27c */
|
|
|
|
uint32_t clk_out_enb_x; /* _CLK_OUT_ENB_X_0, 0x280 */
|
|
uint32_t clk_enb_x_set; /* _CLK_ENB_X_SET_0, 0x284 */
|
|
uint32_t clk_enb_x_clr; /* _CLK_ENB_X_CLR_0, 0x288 */
|
|
|
|
uint32_t rst_devices_x; /* _RST_DEVICES_X_0, 0x28c */
|
|
uint32_t rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
|
|
uint32_t rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
|
|
|
|
uint32_t clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
|
|
uint32_t clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
|
|
uint32_t clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
|
|
|
|
uint32_t rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
|
|
uint32_t rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
|
|
uint32_t rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
|
|
|
|
uint32_t reserved21[17]; /* _reserved_21, 0x2b0-2f0 */
|
|
|
|
uint32_t dfll_base; /* _DFLL_BASE_0, 0x2f4 */
|
|
|
|
uint32_t reserved22[2]; /* _reserved_22, 0x2f8-2fc */
|
|
|
|
/* _RST_DEV_L/H/U_SET_0 0x300 ~ 0x314 */
|
|
uint32_t rst_dev_l_set;
|
|
uint32_t rst_dev_l_clr;
|
|
uint32_t rst_dev_h_set;
|
|
uint32_t rst_dev_h_clr;
|
|
uint32_t rst_dev_u_set;
|
|
uint32_t rst_dev_u_clr;
|
|
|
|
uint32_t reserved30[2]; /* _reserved_30, 0x318, 0x31c */
|
|
|
|
/* _CLK_ENB_L/H/U_CLR_0 0x320 ~ 0x334 */
|
|
uint32_t clk_enb_l_set;
|
|
uint32_t clk_enb_l_clr;
|
|
uint32_t clk_enb_h_set;
|
|
uint32_t clk_enb_h_clr;
|
|
uint32_t clk_enb_u_set;
|
|
uint32_t clk_enb_u_clr;
|
|
|
|
uint32_t reserved31[2]; /* _reserved_31, 0x338, 0x33c */
|
|
|
|
uint32_t cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
|
|
uint32_t cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
|
|
|
|
/* Additional (T30) registers */
|
|
uint32_t clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
|
|
uint32_t clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
|
|
|
|
uint32_t reserved32[2]; /* _reserved_32, 0x350,0x354 */
|
|
|
|
uint32_t rst_dev_v; /* _RST_DEVICES_V/W_0 */
|
|
uint32_t rst_dev_w; /* _RST_DEVICES_V/W_0 */
|
|
|
|
uint32_t clk_out_enb_v; /* _CLK_OUT_ENB_V/W_0 */
|
|
uint32_t clk_out_enb_w; /* _CLK_OUT_ENB_V/W_0 */
|
|
uint32_t cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
|
|
uint32_t super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36C */
|
|
uint32_t cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
|
|
uint32_t super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
|
|
uint32_t clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
|
|
uint32_t clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37C */
|
|
uint32_t cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
|
|
uint32_t cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTRL1_0, 0x384 */
|
|
uint32_t cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
|
|
uint32_t reserved33[9]; /* _reserved_33, 0x38c-3ac */
|
|
uint32_t clk_src_v; /* 0x3B0-0x42C */
|
|
uint32_t clk_src_w; /* 0x3B0-0x42C */
|
|
|
|
/* _RST_DEV_V/W_SET_0 0x430 ~ 0x43c */
|
|
uint32_t rst_dev_v_set;
|
|
uint32_t rst_dev_v_clr;
|
|
uint32_t rst_dev_w_set;
|
|
uint32_t rst_dev_w_clr;
|
|
|
|
/* _CLK_ENB_V/W_CLR_0 0x440 ~ 0x44c */
|
|
uint32_t rst_clk_v_set;
|
|
uint32_t rst_clk_v_clr;
|
|
uint32_t rst_clk_w_set;
|
|
uint32_t rst_clk_w_clr;
|
|
|
|
/* Additional (T114+) registers */
|
|
uint32_t rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
|
|
uint32_t rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
|
|
uint32_t rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
|
|
uint32_t rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45C */
|
|
uint32_t clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
|
|
uint32_t clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
|
|
uint32_t clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
|
|
uint32_t clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46C */
|
|
uint32_t cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
|
|
uint32_t reserved40[1]; /* _reserved_40, 0x474 */
|
|
uint32_t intstatus; /* __INTSTATUS_0, 0x478 */
|
|
uint32_t intmask; /* __INTMASK_0, 0x47C */
|
|
uint32_t utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
|
|
uint32_t utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
|
|
uint32_t utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
|
|
|
|
uint32_t plle_aux; /* _PLLE_AUX_0, 0x48C */
|
|
uint32_t sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
|
|
uint32_t sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
|
|
uint32_t pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
|
|
|
|
uint32_t prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49C */
|
|
uint32_t audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4A0 */
|
|
uint32_t audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4A4 */
|
|
uint32_t audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4A8 */
|
|
uint32_t audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4AC */
|
|
uint32_t audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4B0 */
|
|
uint32_t audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4B4 */
|
|
|
|
uint32_t plld2_base; /* _PLLD2_BASE_0, 0x4B8 */
|
|
uint32_t plld2_misc; /* _PLLD2_MISC_0, 0x4BC */
|
|
uint32_t utmip_pll_cfg3; /* _UTMIP_PLL_CFG3_0, 0x4C0 */
|
|
uint32_t pllrefe_base; /* _PLLREFE_BASE_0, 0x4C4 */
|
|
uint32_t pllrefe_misc; /* _PLLREFE_MISC_0, 0x4C8 */
|
|
uint32_t crs_reserved_50[7]; /* _reserved_50, 0x4CC-0x4E4 */
|
|
uint32_t pllc2_base; /* _PLLC2_BASE_0, 0x4E8 */
|
|
uint32_t pllc2_misc0; /* _PLLC2_MISC_0_0, 0x4EC */
|
|
uint32_t pllc2_misc1; /* _PLLC2_MISC_1_0, 0x4F0 */
|
|
uint32_t pllc2_misc2; /* _PLLC2_MISC_2_0, 0x4F4 */
|
|
uint32_t pllc2_misc3; /* _PLLC2_MISC_3_0, 0x4F8 */
|
|
uint32_t pllc3_base; /* _PLLC3_BASE_0, 0x4FC */
|
|
uint32_t pllc3_misc0; /* _PLLC3_MISC_0_0, 0x500 */
|
|
uint32_t pllc3_misc1; /* _PLLC3_MISC_1_0, 0x504 */
|
|
uint32_t pllc3_misc2; /* _PLLC3_MISC_2_0, 0x508 */
|
|
uint32_t pllc3_misc3; /* _PLLC3_MISC_3_0, 0x50C */
|
|
uint32_t pllx_misc1; /* _PLLX_MISC_1_0, 0x510 */
|
|
uint32_t pllx_misc2; /* _PLLX_MISC_2_0, 0x514 */
|
|
uint32_t pllx_misc3; /* _PLLX_MISC_3_0, 0x518 */
|
|
uint32_t xusbio_pll_cfg0; /* _XUSBIO_PLL_CFG0_0, 0x51C */
|
|
uint32_t xusbio_pll_cfg1; /* _XUSBIO_PLL_CFG0_1, 0x520 */
|
|
uint32_t plle_aux1; /* _PLLE_AUX1_0, 0x524 */
|
|
uint32_t pllp_reshift; /* _PLLP_RESHIFT_0, 0x528 */
|
|
uint32_t utmipll_hw_pwrdn_cfg0; /* _UTMIPLL_HW_PWRDN_CFG0_0, 0x52C */
|
|
uint32_t pllu_hw_pwrdn_cfg0; /* _PLLU_HW_PWRDN_CFG0_0, 0x530 */
|
|
uint32_t xusb_pll_cfg0; /* _XUSB_PLL_CFG0_0, 0x534 */
|
|
uint32_t reserved51[1]; /* _reserved_51, 0x538 */
|
|
uint32_t clk_cpu_misc; /* _CLK_CPU_MISC_0, 0x53C */
|
|
uint32_t clk_cpug_misc; /* _CLK_CPUG_MISC_0, 0x540 */
|
|
uint32_t clk_cpulp_misc; /* _CLK_CPULP_MISC_0, 0x544 */
|
|
uint32_t pllx_hw_ctrl_cfg; /* _PLLX_HW_CTRL_CFG_0, 0x548 */
|
|
uint32_t pllx_sw_ramp_cfg; /* _PLLX_SW_RAMP_CFG_0, 0x54C */
|
|
uint32_t pllx_hw_ctrl_status; /* _PLLX_HW_CTRL_STATUS_0, 0x550 */
|
|
uint32_t reserved52[1]; /* _reserved_52, 0x554 */
|
|
uint32_t super_gr3d_clk_div; /* _SUPER_GR3D_CLK_DIVIDER_0, 0x558 */
|
|
uint32_t spare_reg0; /* _SPARE_REG0_0, 0x55C */
|
|
uint32_t _rsv32[4]; /* 0x560-0x56c */
|
|
uint32_t plld2_ss_cfg; /* _PLLD2_SS_CFG 0x570 */
|
|
uint32_t _rsv32_1[7]; /* 0x574-58c */
|
|
struct clk_pll_simple plldp; /* _PLLDP_BASE, 0x590 _PLLDP_MISC */
|
|
uint32_t plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
|
|
|
|
/* Tegra124+ - skip to 0x600 here for new CLK_SOURCE_ regs */
|
|
uint32_t _rsrv32_2[25]; /* _0x59C - 0x5FC */
|
|
uint32_t clk_src_x[TEGRA_CLK_SOURCES_X]; /* XUSB, etc, 0x600-0x67C */
|
|
|
|
/* Tegra210 - skip to 0x694 here for new CLK_SOURCE_ regs */
|
|
uint32_t reserved61[5]; /* _reserved_61, 0x680 - 0x690 */
|
|
/*
|
|
* NOTE: PLLA1 regs are in the middle of this Y region. Break this in
|
|
* two later if PLLA1 is needed, but for now this is cleaner.
|
|
*/
|
|
uint32_t clk_src_y[TEGRA_CLK_SOURCES_Y]; /* SPARE1, etc, 0x694-0x6D8 */
|
|
};
|
|
|
|
|
|
/**
|
|
* Utility function that grabs the Tegra CAR registers.
|
|
*/
|
|
static inline struct tegra_car *car_get_regs(void)
|
|
{
|
|
return (struct tegra_car *)0x60006000UL;
|
|
}
|
|
|
|
#endif
|