diff --git a/src/include/stdlib.h b/src/include/stdlib.h index 9bc0ebc97b..2fc6805c73 100644 --- a/src/include/stdlib.h +++ b/src/include/stdlib.h @@ -26,4 +26,12 @@ void *malloc(size_t size); static inline void free(void *ptr) {} #endif +#ifndef __ROMCC__ +static inline unsigned long div_round_up(unsigned int n, unsigned int d) +{ + return (n + d - 1) / d; +} +#endif + + #endif /* STDLIB_H */ diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c index a81cf5f05a..4675b7b124 100644 --- a/src/soc/nvidia/tegra124/clock.c +++ b/src/soc/nvidia/tegra124/clock.c @@ -298,12 +298,12 @@ static void graphics_pll(void) * Will later move it to PLLP in clock_config(). The divisor must be very small * to accomodate 12KHz OSCs, so we override the 16.0 UART divider with the 15.1 * CLK_SOURCE divider to get more precision. (This might still not be enough for - * some OSCs... if you use 13KHz, be prepared to have a bad time.) The 1800 has + * some OSCs... if you use 13KHz, be prepared to have a bad time.) The 1900 has * been determined through trial and error (must lead to div 13 at 24MHz). */ void clock_early_uart(void) { write32(CLK_M << CLK_SOURCE_SHIFT | CLK_UART_DIV_OVERRIDE | - CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1800), &clk_rst->clk_src_uarta); + CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1900), &clk_rst->clk_src_uarta); setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA); udelay(2); clrbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA); diff --git a/src/soc/nvidia/tegra124/include/soc/clock.h b/src/soc/nvidia/tegra124/include/soc/clock.h index ae3e9acfdd..7038b87b7e 100644 --- a/src/soc/nvidia/tegra124/include/soc/clock.h +++ b/src/soc/nvidia/tegra124/include/soc/clock.h @@ -19,6 +19,7 @@ #define __SOC_NVIDIA_TEGRA124_CLOCK_H__ #include +#include enum { CLK_L_CPU = 0x1 << 0, @@ -174,6 +175,7 @@ enum { #define CLOCK_PLL_STABLE_DELAY_US 300 #define IO_STABILIZATION_DELAY (2) + /* Calculate clock fractional divider value from ref and target frequencies. * This is for a U7.1 format. This is not well written up in the book and * there have been some questions about this macro, so here we go. @@ -195,7 +197,7 @@ enum { * and voila, upper 7 bits are (ref/freq-1), and lowest bit is h. Since you * will assign this to a u8, it gets nicely truncated for you. */ -#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / (FREQ)) - 2) +#define CLK_DIVIDER(REF, FREQ) (div_round_up(((REF) * 2), (FREQ)) - 2) /* Calculate clock frequency value from reference and clock divider value * The discussion in the book is pretty lacking. @@ -232,11 +234,14 @@ enum { * We can deal with those here and make it easier to select what the actual * bus frequency will be. The 0x19 value is the default divisor in the * clk_divisor register in the controller, and 8 is just a magic number in the - * documentation. Multiplying by 2 compensates for the different format of the - * divisor. + * documentation. */ #define clock_configure_i2c_scl_freq(device, src, freq) \ - clock_configure_source(device, src, (freq) * (0x19 + 1) * 8 * 2) + clrsetbits_le32(&clk_rst->clk_src_##device, \ + CLK_SOURCE_MASK | CLK_DIVISOR_MASK, \ + src << CLK_SOURCE_SHIFT | \ + (div_round_up((TEGRA_##src##_KHZ), \ + ((freq) * (0x19 + 1) * 8)) - 1)) enum clock_source { /* Careful: Not true for all sources, always check TRM! */ PLLP = 0,