128
bdk/soc/clock.c
128
bdk/soc/clock.c
@@ -39,9 +39,9 @@ static const clock_osc_t _clock_osc_cnt[] = {
|
||||
{ 48000, 2836, 3023 }
|
||||
};
|
||||
|
||||
/* clock_t: reset, enable, source, index, clk_src, clk_div */
|
||||
/* clk_rst_t: reset, enable, source, index, clk_src, clk_div */
|
||||
|
||||
static const clock_t _clock_uart[] = {
|
||||
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, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_UARTB, CLK_L_UARTB, 0, 2 },
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_UARTC, CLK_H_UARTC, 0, 2 },
|
||||
@@ -50,7 +50,7 @@ static const clock_t _clock_uart[] = {
|
||||
};
|
||||
|
||||
//I2C default parameters - TLOW: 4, THIGH: 2, DEBOUNCE: 0, FM_DIV: 26.
|
||||
static const clock_t _clock_i2c[] = {
|
||||
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, 19 }, //20.4MHz -> 100KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_SOURCE_I2C2, CLK_H_I2C2, 0, 4 }, //81.6MHz -> 400KHz
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_U, CLK_RST_CONTROLLER_CLK_OUT_ENB_U, CLK_RST_CONTROLLER_CLK_SOURCE_I2C3, CLK_U_I2C3, 0, 4 }, //81.6MHz -> 400KHz
|
||||
@@ -59,68 +59,68 @@ static const clock_t _clock_i2c[] = {
|
||||
{ CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_I2C6, CLK_X_I2C6, 0, 19 } //20.4MHz -> 100KHz
|
||||
};
|
||||
|
||||
static clock_t _clock_se = {
|
||||
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, 0 // 408MHz. Default: 408MHz. Max: 627.2 MHz.
|
||||
};
|
||||
static clock_t _clock_tzram = {
|
||||
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, 0
|
||||
};
|
||||
static clock_t _clock_host1x = {
|
||||
static clk_rst_t _clock_host1x = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_L, CLK_RST_CONTROLLER_CLK_OUT_ENB_L, CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X, CLK_L_HOST1X, 4, 3 // 163.2MHz. Max: 408MHz.
|
||||
};
|
||||
static clock_t _clock_tsec = {
|
||||
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, 2 // 204MHz. Max: 408MHz.
|
||||
};
|
||||
static clock_t _clock_nvdec = {
|
||||
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, 0 // 408 MHz. Max: 716.8/979.2MHz.
|
||||
};
|
||||
static clock_t _clock_nvjpg = {
|
||||
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, 0 // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clock_t _clock_vic = {
|
||||
static clk_rst_t _clock_vic = {
|
||||
CLK_RST_CONTROLLER_RST_DEVICES_X, CLK_RST_CONTROLLER_CLK_OUT_ENB_X, CLK_RST_CONTROLLER_CLK_SOURCE_VIC, CLK_X_VIC, 2, 0 // 408 MHz. Max: 627.2/652.8MHz.
|
||||
};
|
||||
static clock_t _clock_sor_safe = {
|
||||
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, 0
|
||||
};
|
||||
static clock_t _clock_sor0 = {
|
||||
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, 0
|
||||
};
|
||||
static clock_t _clock_sor1 = {
|
||||
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, 2 // 204MHz.
|
||||
};
|
||||
static clock_t _clock_kfuse = {
|
||||
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, 0
|
||||
};
|
||||
static clock_t _clock_cl_dvfs = {
|
||||
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, 0
|
||||
};
|
||||
static clock_t _clock_coresight = {
|
||||
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, 4 // 136MHz.
|
||||
};
|
||||
static clock_t _clock_pwm = {
|
||||
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, 4 // Fref: 6.4MHz. HOS: PLLP / 54 = 7.55MHz.
|
||||
};
|
||||
static clock_t _clock_sdmmc_legacy_tm = {
|
||||
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, 66
|
||||
};
|
||||
static clock_t _clock_apbdma = {
|
||||
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, 0 // Max: 204MHz.
|
||||
};
|
||||
static clock_t _clock_ahbdma = {
|
||||
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, 0
|
||||
};
|
||||
static clock_t _clock_actmon = {
|
||||
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, 0 // 19.2MHz.
|
||||
};
|
||||
static clock_t _clock_extperiph1 = {
|
||||
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, 0
|
||||
};
|
||||
static clock_t _clock_extperiph2 = {
|
||||
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, 202 // 4.0MHz
|
||||
};
|
||||
|
||||
void clock_enable(const clock_t *clk)
|
||||
void clock_enable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
@@ -137,7 +137,7 @@ void clock_enable(const clock_t *clk)
|
||||
CLOCK(clk->reset) &= ~BIT(clk->index);
|
||||
}
|
||||
|
||||
void clock_disable(const clock_t *clk)
|
||||
void clock_disable(const clk_rst_t *clk)
|
||||
{
|
||||
// Put clock into reset.
|
||||
CLOCK(clk->reset) = (CLOCK(clk->reset) & ~BIT(clk->index)) | BIT(clk->index);
|
||||
@@ -503,7 +503,7 @@ static void _clock_enable_pllc4(u32 mask)
|
||||
usleep(10);
|
||||
|
||||
// Set PLLC4 dividers.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (104 << 8) | 4; // DIVM: 4, DIVP: 1.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) = (0 << 19) | (104 << 8) | 4; // DIVP: 1, DIVN: 104, DIVM: 4. 998MHz OUT0, 199MHz OUT2.
|
||||
|
||||
// Enable PLLC4 and wait for Phase and Frequency lock.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLC4_BASE) |= PLLCX_BASE_ENABLE;
|
||||
@@ -684,7 +684,7 @@ static void _clock_sdmmc_clear_enable(u32 id)
|
||||
|
||||
static void _clock_sdmmc_config_legacy_tm()
|
||||
{
|
||||
clock_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
clk_rst_t *clk = &_clock_sdmmc_legacy_tm;
|
||||
if (!(CLOCK(clk->enable) & BIT(clk->index)))
|
||||
clock_enable(clk);
|
||||
}
|
||||
@@ -699,6 +699,7 @@ static clock_sdmmc_t _clock_sdmmc_table[4] = { 0 };
|
||||
|
||||
#define SDMMC_CLOCK_SRC_PLLP_OUT0 0x0
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT2 0x3
|
||||
#define SDMMC_CLOCK_SRC_PLLC4_OUT0 0x7
|
||||
#define SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ 0x1
|
||||
|
||||
static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
@@ -716,79 +717,88 @@ static int _clock_sdmmc_config_clock_host(u32 *pclock, u32 id, u32 val)
|
||||
*pclock = 24728;
|
||||
divisor = 31; // 16.5 div.
|
||||
break;
|
||||
|
||||
case 26000:
|
||||
*pclock = 25500;
|
||||
divisor = 30; // 16 div.
|
||||
break;
|
||||
|
||||
case 50000:
|
||||
*pclock = 48000;
|
||||
divisor = 15; // 8.5 div.
|
||||
break;
|
||||
|
||||
case 52000:
|
||||
*pclock = 51000;
|
||||
divisor = 14; // 8 div.
|
||||
break;
|
||||
case 81600: // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 18 (real 10).
|
||||
|
||||
case 82000:
|
||||
*pclock = 81600;
|
||||
divisor = 8; // 5 div.
|
||||
divisor = 8; // 5 div.
|
||||
break;
|
||||
|
||||
case 100000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
*pclock = 99840;
|
||||
divisor = 2; // 2 div.
|
||||
break;
|
||||
|
||||
case 164000:
|
||||
*pclock = 163200;
|
||||
divisor = 3; // 2.5 div.
|
||||
break;
|
||||
case 200000: // 240MHz evo+.
|
||||
|
||||
case 200000:
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT2;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
case SDMMC_4:
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ;
|
||||
source = SDMMC4_CLOCK_SRC_PLLC4_OUT2_LJ; // div is ignored.
|
||||
break;
|
||||
}
|
||||
*pclock = 199680;
|
||||
divisor = 0; // 1 div.
|
||||
break;
|
||||
default:
|
||||
*pclock = 24728;
|
||||
divisor = 31; // 16.5 div.
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case 400000:
|
||||
source = SDMMC_CLOCK_SRC_PLLC4_OUT0;
|
||||
*pclock = 399360;
|
||||
divisor = 3; // 2.5 div
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
_clock_sdmmc_table[id].clock = val;
|
||||
_clock_sdmmc_table[id].real_clock = *pclock;
|
||||
|
||||
// Enable PLLC4 if in use by any SDMMC.
|
||||
if (source)
|
||||
if (source != SDMMC_CLOCK_SRC_PLLP_OUT0)
|
||||
_clock_enable_pllc4(BIT(id));
|
||||
|
||||
// Set SDMMC legacy timeout clock.
|
||||
_clock_sdmmc_config_legacy_tm();
|
||||
|
||||
// Set SDMMC clock.
|
||||
u32 src_div = (source << 29) | divisor;
|
||||
switch (id)
|
||||
{
|
||||
case SDMMC_1:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1) = src_div;
|
||||
break;
|
||||
case SDMMC_2:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2) = src_div;
|
||||
break;
|
||||
case SDMMC_3:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3) = src_div;
|
||||
break;
|
||||
case SDMMC_4:
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = (source << 29) | divisor;
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4) = src_div;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -818,54 +828,71 @@ void clock_sdmmc_get_card_clock_div(u32 *pclock, u16 *pdivisor, u32 type)
|
||||
// Get Card clock divisor.
|
||||
switch (type)
|
||||
{
|
||||
case SDHCI_TIMING_MMC_ID: // Actual IO Freq: 380.59 KHz.
|
||||
case SDHCI_TIMING_MMC_ID: // Actual card clock: 386.36 KHz.
|
||||
*pclock = 26000;
|
||||
*pdivisor = 66;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_LS26:
|
||||
*pclock = 26000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS52:
|
||||
*pclock = 52000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_MMC_HS200:
|
||||
case SDHCI_TIMING_MMC_HS400:
|
||||
case SDHCI_TIMING_UHS_SDR104:
|
||||
*pclock = 200000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_SD_ID: // Actual IO Freq: 380.43 KHz.
|
||||
|
||||
case SDHCI_TIMING_SD_ID: // Actual card clock: 386.38 KHz.
|
||||
*pclock = 25000;
|
||||
*pdivisor = 64;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_SD_DS12:
|
||||
case SDHCI_TIMING_UHS_SDR12:
|
||||
*pclock = 25000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_SD_HS25:
|
||||
case SDHCI_TIMING_UHS_SDR25:
|
||||
*pclock = 50000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR50:
|
||||
*pclock = 100000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
|
||||
case SDHCI_TIMING_UHS_SDR82:
|
||||
*pclock = 164000;
|
||||
*pdivisor = 1;
|
||||
break;
|
||||
case SDHCI_TIMING_UHS_DDR50:
|
||||
*pclock = 81600; // Originally MMC_HS50 for GC FPGA at 40800 KHz, div 1.
|
||||
|
||||
case SDHCI_TIMING_UHS_DDR50: // Actual card clock: 40.80 MHz.
|
||||
*pclock = 82000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
case SDHCI_TIMING_MMC_DDR100: // Actual IO Freq: 99.84 MHz.
|
||||
|
||||
case SDHCI_TIMING_MMC_HS100: // Actual card clock: 99.84 MHz.
|
||||
*pclock = 200000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
|
||||
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
|
||||
case SDHCI_TIMING_UHS_DDR200: // Actual card clock: 199.68 KHz.
|
||||
*pclock = 400000;
|
||||
*pdivisor = 2;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,7 +911,8 @@ void clock_sdmmc_enable(u32 id, u32 val)
|
||||
_clock_sdmmc_config_clock_host(&clock, id, val);
|
||||
_clock_sdmmc_set_enable(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
usleep((100000 + clock - 1) / clock);
|
||||
// Wait 100 cycles for reset and for clocks to stabilize.
|
||||
usleep((100 * 1000 + clock - 1) / clock);
|
||||
_clock_sdmmc_clear_reset(id);
|
||||
_clock_sdmmc_is_reset(id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user