mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-09-22 23:52:03 +00:00
Merge commit 'refs/pipelines/15015' of https://source.denx.de/u-boot/custodians/u-boot-tegra
This commit is contained in:
commit
9918b25d21
15 changed files with 281 additions and 85 deletions
|
@ -1286,6 +1286,7 @@ config ARCH_TEGRA
|
|||
select GPIO_EXTRA_HEADER
|
||||
imply DISTRO_DEFAULTS
|
||||
imply FAT_WRITE
|
||||
imply SPL_TIMER if SPL
|
||||
|
||||
config ARCH_VEXPRESS64
|
||||
bool "Support ARMv8 Arm Ltd. VExpress based boards and models"
|
||||
|
|
|
@ -13,12 +13,13 @@ struct udevice;
|
|||
/* Set of oscillator frequencies supported in the internal API. */
|
||||
enum clock_osc_freq {
|
||||
/* All in MHz, so 13_0 is 13.0MHz */
|
||||
CLOCK_OSC_FREQ_13_0,
|
||||
CLOCK_OSC_FREQ_19_2,
|
||||
CLOCK_OSC_FREQ_12_0,
|
||||
CLOCK_OSC_FREQ_26_0,
|
||||
CLOCK_OSC_FREQ_13_0 = 0,
|
||||
CLOCK_OSC_FREQ_16_8,
|
||||
CLOCK_OSC_FREQ_19_2 = 4,
|
||||
CLOCK_OSC_FREQ_38_4,
|
||||
CLOCK_OSC_FREQ_12_0 = 8,
|
||||
CLOCK_OSC_FREQ_48_0,
|
||||
CLOCK_OSC_FREQ_26_0 = 12,
|
||||
|
||||
CLOCK_OSC_FREQ_COUNT,
|
||||
};
|
||||
|
|
|
@ -73,6 +73,7 @@ config TEGRA_ARMV7_COMMON
|
|||
select SPL_BOARD_INIT if SPL
|
||||
select SPL_SKIP_LOWLEVEL_INIT_ONLY if SPL
|
||||
select SUPPORT_SPL
|
||||
select TIMER
|
||||
select TEGRA_CLKRST
|
||||
select TEGRA_COMMON
|
||||
select TEGRA_GPIO
|
||||
|
@ -81,6 +82,7 @@ config TEGRA_ARMV7_COMMON
|
|||
select TEGRA_NO_BPMP
|
||||
select TEGRA_PINCTRL
|
||||
select TEGRA_PMC
|
||||
select TEGRA_TIMER
|
||||
|
||||
config TEGRA_ARMV8_COMMON
|
||||
bool "Tegra 64-bit common options"
|
||||
|
@ -125,6 +127,7 @@ config TEGRA124
|
|||
config TEGRA210
|
||||
bool "Tegra210 family"
|
||||
select GICV2
|
||||
select TIMER
|
||||
select TEGRA_ARMV8_COMMON
|
||||
select TEGRA_CLKRST
|
||||
select TEGRA_GPIO
|
||||
|
@ -134,6 +137,7 @@ config TEGRA210
|
|||
select TEGRA_PINCTRL
|
||||
select TEGRA_PMC
|
||||
select TEGRA_PMC_SECURE
|
||||
select TEGRA_TIMER
|
||||
|
||||
config TEGRA186
|
||||
bool "Tegra186 family"
|
||||
|
|
|
@ -28,16 +28,23 @@
|
|||
static unsigned pll_rate[CLOCK_ID_COUNT];
|
||||
|
||||
/*
|
||||
* The oscillator frequency is fixed to one of four set values. Based on this
|
||||
* The oscillator frequency is fixed to one of seven set values. Based on this
|
||||
* the other clocks are set up appropriately.
|
||||
*/
|
||||
static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
|
||||
13000000,
|
||||
16800000,
|
||||
0,
|
||||
0,
|
||||
19200000,
|
||||
12000000,
|
||||
26000000,
|
||||
38400000,
|
||||
0,
|
||||
0,
|
||||
12000000,
|
||||
48000000,
|
||||
0,
|
||||
0,
|
||||
26000000,
|
||||
};
|
||||
|
||||
/* return 1 if a peripheral ID is in range */
|
||||
|
@ -766,6 +773,7 @@ void tegra30_set_up_pllp(void)
|
|||
*/
|
||||
switch (clock_get_osc_freq()) {
|
||||
case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
|
||||
case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8);
|
||||
break;
|
||||
|
@ -776,10 +784,13 @@ void tegra30_set_up_pllp(void)
|
|||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
|
||||
case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
|
||||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_19_2:
|
||||
case CLOCK_OSC_FREQ_38_4:
|
||||
default:
|
||||
/*
|
||||
* These are not supported. It is too early to print a
|
||||
|
|
|
@ -55,11 +55,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
|
|||
*/
|
||||
{
|
||||
{ .n = 1000, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 625, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 1000, .m = 12, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 1000, .m = 26, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 38.4 MHz (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 48.0 MHz (N/A) */
|
||||
},
|
||||
/*
|
||||
* T25: 1.2 GHz
|
||||
|
@ -73,11 +80,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
|
|||
*/
|
||||
{
|
||||
{ .n = 923, .m = 10, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 750, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 600, .m = 6, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 600, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 38.4 MHz (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 48.0 MHz (N/A) */
|
||||
},
|
||||
/*
|
||||
* T30: 600 MHz
|
||||
|
@ -91,11 +105,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
|
|||
*/
|
||||
{
|
||||
{ .n = 600, .m = 13, .p = 0, .cpcon = 8 }, /* OSC: 13.0 MHz */
|
||||
{ .n = 600, .m = 13, .p = 0, .cpcon = 8 }, /* OSC: 16.8 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 500, .m = 16, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */
|
||||
{ .n = 500, .m = 16, .p = 0, .cpcon = 8 }, /* OSC: 38.4 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 600, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 12.0 MHz */
|
||||
{ .n = 600, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 48.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */
|
||||
{ .n = 600, .m = 26, .p = 0, .cpcon = 8 }, /* OSC: 26.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 38.4 MHz (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 48.0 MHz (N/A) */
|
||||
},
|
||||
/*
|
||||
* T114: 700 MHz
|
||||
|
@ -108,11 +129,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
|
|||
*/
|
||||
{
|
||||
{ .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */
|
||||
{ .n = 108, .m = 1, .p = 1 }, /* OSC: 16.8 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */
|
||||
{ .n = 73, .m = 1, .p = 1 }, /* OSC: 38.4 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */
|
||||
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 48.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* OSC: 38.4 MHz (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* OSC: 48.0 MHz (N/A) */
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -126,11 +154,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
|
|||
*/
|
||||
{
|
||||
{ .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */
|
||||
{ .n = 108, .m = 1, .p = 1 }, /* OSC: 16.8 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */
|
||||
{ .n = 73, .m = 1, .p = 1 }, /* OSC: 38.4 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */
|
||||
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 48.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* OSC: 38.4 MHz (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* OSC: 48.0 MHz (N/A) */
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -143,12 +178,19 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
|
|||
* PLLX_BASE m 7: 0 8
|
||||
*/
|
||||
{
|
||||
{ .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz = 702 MHz*/
|
||||
{ .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz = 700.8 MHz*/
|
||||
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz = 696 MHz*/
|
||||
{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz = 702 MHz*/
|
||||
{ .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz = 702 MHz */
|
||||
{ .n = 108, .m = 1, .p = 1 }, /* OSC: 16.0 MHz = 702 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz = 700.8 MHz */
|
||||
{ .n = 36, .m = 1, .p = 1 }, /* OSC: 38.4 MHz = 691.2 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz = 696 MHz */
|
||||
{ .n = 58, .m = 2, .p = 1 }, /* OSC: 48.0 MHz = 696 MHz */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 0, .m = 0, .p = 0 }, /* (N/A) */
|
||||
{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz = 702 MHz */
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -459,8 +459,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
|
|||
|
||||
/*
|
||||
* Get the oscillator frequency, from the corresponding hardware configuration
|
||||
* field. Note that T30/T114 support 3 new higher freqs, but we map back
|
||||
* to the old T20 freqs. Support for the higher oscillators is TBD.
|
||||
* field. Note that T30+ supports 3 new higher freqs.
|
||||
*/
|
||||
enum clock_osc_freq clock_get_osc_freq(void)
|
||||
{
|
||||
|
@ -469,12 +468,7 @@ enum clock_osc_freq clock_get_osc_freq(void)
|
|||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
|
||||
if (reg & 1) /* one of the newer freqs */
|
||||
printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
|
||||
|
||||
return reg >> 2; /* Map to most common (T20) freqs */
|
||||
return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
|
@ -674,6 +668,7 @@ void clock_early_init(void)
|
|||
*/
|
||||
switch (clock_get_osc_freq()) {
|
||||
case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
|
||||
case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12);
|
||||
break;
|
||||
|
@ -684,10 +679,12 @@ void clock_early_init(void)
|
|||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
|
||||
case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12);
|
||||
break;
|
||||
case CLOCK_OSC_FREQ_19_2:
|
||||
case CLOCK_OSC_FREQ_38_4:
|
||||
default:
|
||||
/*
|
||||
* These are not supported. It is too early to print a
|
||||
|
|
|
@ -601,8 +601,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
|
|||
|
||||
/*
|
||||
* Get the oscillator frequency, from the corresponding hardware configuration
|
||||
* field. Note that Tegra30+ support 3 new higher freqs, but we map back
|
||||
* to the old T20 freqs. Support for the higher oscillators is TBD.
|
||||
* field. Note that T30+ supports 3 new higher freqs.
|
||||
*/
|
||||
enum clock_osc_freq clock_get_osc_freq(void)
|
||||
{
|
||||
|
@ -611,12 +610,7 @@ enum clock_osc_freq clock_get_osc_freq(void)
|
|||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
|
||||
if (reg & 1) /* one of the newer freqs */
|
||||
printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
|
||||
|
||||
return reg >> 2; /* Map to most common (T20) freqs */
|
||||
return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
|
@ -854,6 +848,7 @@ void clock_early_init(void)
|
|||
*/
|
||||
switch (clock_get_osc_freq()) {
|
||||
case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
|
||||
case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12);
|
||||
break;
|
||||
|
@ -864,10 +859,12 @@ void clock_early_init(void)
|
|||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
|
||||
case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12);
|
||||
break;
|
||||
case CLOCK_OSC_FREQ_19_2:
|
||||
case CLOCK_OSC_FREQ_38_4:
|
||||
default:
|
||||
/*
|
||||
* These are not supported. It is too early to print a
|
||||
|
|
|
@ -399,7 +399,9 @@ enum clock_osc_freq clock_get_osc_freq(void)
|
|||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
|
||||
return reg << 2;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
|
|
|
@ -672,8 +672,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
|
|||
|
||||
/*
|
||||
* Get the oscillator frequency, from the corresponding hardware configuration
|
||||
* field. Note that Tegra30+ support 3 new higher freqs, but we map back
|
||||
* to the old T20 freqs. Support for the higher oscillators is TBD.
|
||||
* field. Note that T30+ supports 3 new higher freqs.
|
||||
*/
|
||||
enum clock_osc_freq clock_get_osc_freq(void)
|
||||
{
|
||||
|
@ -682,22 +681,7 @@ enum clock_osc_freq clock_get_osc_freq(void)
|
|||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
/*
|
||||
* 0 = 13MHz, 1 = 16.8MHz, 4 = 19.2MHz, 5 = 38.4MHz,
|
||||
* 8 = 12MHz, 9 = 48MHz, 12 = 26MHz
|
||||
*/
|
||||
if (reg == 5) {
|
||||
debug("OSC_FREQ is 38.4MHz (%d) ...\n", reg);
|
||||
/* Map it to the 5th CLOCK_OSC_ enum, i.e. 4 */
|
||||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map to most common (T20) freqs (except 38.4, handled above):
|
||||
* 13/16.8 = 0, 19.2 = 1, 12/48 = 2, 26 = 3
|
||||
*/
|
||||
return reg >> 2;
|
||||
return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
|
@ -986,6 +970,7 @@ void clock_early_init(void)
|
|||
*/
|
||||
switch (clock_get_osc_freq()) {
|
||||
case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
|
||||
case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12);
|
||||
break;
|
||||
|
@ -996,6 +981,7 @@ void clock_early_init(void)
|
|||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
|
||||
case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12);
|
||||
break;
|
||||
|
|
|
@ -439,8 +439,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
|
|||
|
||||
/*
|
||||
* Get the oscillator frequency, from the corresponding hardware configuration
|
||||
* field. Note that T30 supports 3 new higher freqs, but we map back
|
||||
* to the old T20 freqs. Support for the higher oscillators is TBD.
|
||||
* field. Note that T30+ supports 3 new higher freqs.
|
||||
*/
|
||||
enum clock_osc_freq clock_get_osc_freq(void)
|
||||
{
|
||||
|
@ -449,12 +448,7 @@ enum clock_osc_freq clock_get_osc_freq(void)
|
|||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
|
||||
if (reg & 1) /* one of the newer freqs */
|
||||
printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
|
||||
|
||||
return reg >> 2; /* Map to most common (T20) freqs */
|
||||
return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
|
|
|
@ -252,6 +252,14 @@ config STM32_TIMER
|
|||
Select this to enable support for the timer found on
|
||||
STM32 devices.
|
||||
|
||||
config TEGRA_TIMER
|
||||
bool "Tegra timer support"
|
||||
depends on TIMER
|
||||
select TIMER_EARLY
|
||||
help
|
||||
Select this to enable support for the timer found on
|
||||
Tegra devices.
|
||||
|
||||
config X86_TSC_TIMER
|
||||
bool "x86 Time-Stamp Counter (TSC) timer support"
|
||||
depends on TIMER && X86
|
||||
|
|
|
@ -27,6 +27,7 @@ obj-$(CONFIG_SP804_TIMER) += sp804_timer.o
|
|||
obj-$(CONFIG_$(SPL_)SIFIVE_CLINT) += sifive_clint_timer.o
|
||||
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
|
||||
obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
|
||||
obj-$(CONFIG_TEGRA_TIMER) += tegra-timer.o
|
||||
obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
|
||||
obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
|
||||
obj-$(CONFIG_MCHP_PIT64B_TIMER) += mchp-pit64b-timer.o
|
||||
|
|
130
drivers/timer/tegra-timer.c
Normal file
130
drivers/timer/tegra-timer.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2022 Svyatoslav Ryhel <clamor95@gmail.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <timer.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
|
||||
#define TEGRA_OSC_CLK_ENB_L_SET (NV_PA_CLK_RST_BASE + 0x320)
|
||||
#define TEGRA_OSC_SET_CLK_ENB_TMR BIT(5)
|
||||
|
||||
#define TEGRA_TIMER_USEC_CNTR (NV_PA_TMRUS_BASE + 0)
|
||||
#define TEGRA_TIMER_USEC_CFG (NV_PA_TMRUS_BASE + 4)
|
||||
|
||||
#define TEGRA_TIMER_RATE 1000000 /* 1 MHz */
|
||||
|
||||
/*
|
||||
* On pre-DM stage timer should be left configured by
|
||||
* previous bootloader for correct 1MHz clock.
|
||||
* In the case of reset default value is set to 1/13 of
|
||||
* CLK_M which should be decent enough to safely
|
||||
* get to DM stage.
|
||||
*/
|
||||
u64 notrace timer_early_get_count(void)
|
||||
{
|
||||
/* At this stage raw timer is used */
|
||||
return readl(TEGRA_TIMER_USEC_CNTR);
|
||||
}
|
||||
|
||||
unsigned long notrace timer_early_get_rate(void)
|
||||
{
|
||||
return TEGRA_TIMER_RATE;
|
||||
}
|
||||
|
||||
ulong timer_get_boot_us(void)
|
||||
{
|
||||
return timer_early_get_count();
|
||||
}
|
||||
|
||||
/*
|
||||
* At moment of calling get_count, timer driver is already
|
||||
* probed and is configured to have precise 1MHz clock.
|
||||
* Tegra timer has a step of 1 microsecond which removes
|
||||
* need of using adjusments involving uc_priv->clock_rate.
|
||||
*/
|
||||
static notrace u64 tegra_timer_get_count(struct udevice *dev)
|
||||
{
|
||||
u32 val = timer_early_get_count();
|
||||
return timer_conv_64(val);
|
||||
}
|
||||
|
||||
static int tegra_timer_probe(struct udevice *dev)
|
||||
{
|
||||
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
u32 usec_config, value;
|
||||
|
||||
/* Timer rate has to be set unconditionally */
|
||||
uc_priv->clock_rate = TEGRA_TIMER_RATE;
|
||||
|
||||
/*
|
||||
* Configure microsecond timers to have 1MHz clock
|
||||
* Config register is 0xqqww, where qq is "dividend", ww is "divisor"
|
||||
* Uses n+1 scheme
|
||||
*/
|
||||
switch (clock_get_rate(CLOCK_ID_CLK_M)) {
|
||||
case 12000000:
|
||||
usec_config = 0x000b; /* (11+1)/(0+1) */
|
||||
break;
|
||||
case 12800000:
|
||||
usec_config = 0x043f; /* (63+1)/(4+1) */
|
||||
break;
|
||||
case 13000000:
|
||||
usec_config = 0x000c; /* (12+1)/(0+1) */
|
||||
break;
|
||||
case 16800000:
|
||||
usec_config = 0x0453; /* (83+1)/(4+1) */
|
||||
break;
|
||||
case 19200000:
|
||||
usec_config = 0x045f; /* (95+1)/(4+1) */
|
||||
break;
|
||||
case 26000000:
|
||||
usec_config = 0x0019; /* (25+1)/(0+1) */
|
||||
break;
|
||||
case 38400000:
|
||||
usec_config = 0x04bf; /* (191+1)/(4+1) */
|
||||
break;
|
||||
case 48000000:
|
||||
usec_config = 0x002f; /* (47+1)/(0+1) */
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Enable clock to timer hardware */
|
||||
value = readl_relaxed(TEGRA_OSC_CLK_ENB_L_SET);
|
||||
writel_relaxed(value | TEGRA_OSC_SET_CLK_ENB_TMR,
|
||||
TEGRA_OSC_CLK_ENB_L_SET);
|
||||
|
||||
writel_relaxed(usec_config, TEGRA_TIMER_USEC_CFG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct timer_ops tegra_timer_ops = {
|
||||
.get_count = tegra_timer_get_count,
|
||||
};
|
||||
|
||||
static const struct udevice_id tegra_timer_ids[] = {
|
||||
{ .compatible = "nvidia,tegra20-timer" },
|
||||
{ .compatible = "nvidia,tegra30-timer" },
|
||||
{ .compatible = "nvidia,tegra114-timer" },
|
||||
{ .compatible = "nvidia,tegra124-timer" },
|
||||
{ .compatible = "nvidia,tegra210-timer" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(tegra_timer) = {
|
||||
.name = "tegra_timer",
|
||||
.id = UCLASS_TIMER,
|
||||
.of_match = tegra_timer_ids,
|
||||
.probe = tegra_timer_probe,
|
||||
.ops = &tegra_timer_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
|
@ -127,42 +127,70 @@ struct fdt_usb {
|
|||
static const unsigned T20_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
|
||||
/* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
|
||||
{ 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 },
|
||||
{ 0x3C0, 0x1A, 0x00, 0xC, 0, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 },
|
||||
{ 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x3C0, 0x1A, 0x00, 0xC, 0, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 }
|
||||
};
|
||||
|
||||
static const unsigned T30_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
|
||||
/* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
|
||||
{ 0x3C0, 0x0D, 0x00, 0xC, 1, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 5 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 7 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 1, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
|
||||
{ 0x3C0, 0x1A, 0x00, 0xC, 1, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 },
|
||||
{ 0x3C0, 0x0D, 0x00, 0xC, 1, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 5 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 7 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 7 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 1, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 1, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x3C0, 0x1A, 0x00, 0xC, 1, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 }
|
||||
};
|
||||
|
||||
static const unsigned T114_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
|
||||
/* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
|
||||
{ 0x3C0, 0x0D, 0x00, 0xC, 2, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 6 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 2, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 8 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 2, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
|
||||
{ 0x3C0, 0x1A, 0x00, 0xC, 2, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 11 },
|
||||
{ 0x3C0, 0x0D, 0x00, 0xC, 2, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 6 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 2, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 8 },
|
||||
{ 0x0C8, 0x04, 0x00, 0x3, 2, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 8 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 2, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
|
||||
{ 0x3C0, 0x0C, 0x00, 0xC, 2, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 },
|
||||
{ 0x3C0, 0x1A, 0x00, 0xC, 2, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 11 }
|
||||
};
|
||||
|
||||
/* NOTE: 13/26MHz settings are N/A for T210, so dupe 12MHz settings for now */
|
||||
static const unsigned T210_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
|
||||
/* DivN, DivM, DivP, KCP, KVCO, Delays Debounce, Bias */
|
||||
{ 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 32500, 5 },
|
||||
{ 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 32500, 5 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
|
||||
{ 0x019, 0x01, 0x01, 0x0, 0, 0x03, 0x4B, 0x0C, 0xBB, 48000, 8 },
|
||||
{ 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 },
|
||||
{ 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 65000, 5 },
|
||||
{ 0x019, 0x02, 0x01, 0x0, 0, 0x05, 0x96, 0x18, 0x177, 96000, 15 },
|
||||
{ 0x028, 0x04, 0x01, 0x0, 0, 0x04, 0x66, 0x09, 0xFE, 120000, 20 }
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
|
||||
{ 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 },
|
||||
{ 0x028, 0x04, 0x01, 0x0, 0, 0x04, 0x66, 0x09, 0xFE, 120000, 20 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
|
||||
{ 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 },
|
||||
{ 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 65000, 5 }
|
||||
};
|
||||
|
||||
/* UTMIP Idle Wait Delay */
|
||||
|
|
|
@ -15,12 +15,6 @@
|
|||
|
||||
#include <asm/arch/tegra.h> /* get chip and board defs */
|
||||
|
||||
/* Use the Tegra US timer on ARMv7, but the architected timer on ARMv8. */
|
||||
#ifndef CONFIG_ARM64
|
||||
#define CFG_SYS_TIMER_RATE 1000000
|
||||
#define CFG_SYS_TIMER_COUNTER NV_PA_TMRUS_BASE
|
||||
#endif
|
||||
|
||||
/* Environment */
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue