tegra124: nyan: Move mainboard level clock stuff into the mainboard source.
The decision about what clocks and units to enable and what sources and divisors to use had been configured in the tegra124 source, but really those decisions need to be made on a mainboard to mainboard basis. This code keeps some generic mechanism in the tegra124 directory but moves most of the rest of it to the nyan directory. It would be good to abstract the source and divisor setting functions a bit more since that code is still pretty big, and requires knowledge of the clock and reset controller and its constants and bitfields. Also we should move code related to function units which aren't actually used in the bootblock into later stages so they can be updated. BUG=None TEST=Built and booted on nyan. BRANCH=None Change-Id: Ied7ecceced3016f1fcb32101d780b7c235b881db Signed-off-by: Gabe Black <gabeblack@google.com> Reviewed-on: https://chromium-review.googlesource.com/174843 Reviewed-by: Gabe Black <gabeblack@chromium.org> Commit-Queue: Gabe Black <gabeblack@chromium.org> Tested-by: Gabe Black <gabeblack@chromium.org>
This commit is contained in:
parent
581f592c12
commit
5ab100b0ba
3 changed files with 73 additions and 66 deletions
|
|
@ -17,19 +17,71 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <bootblock_common.h>
|
||||
#include <console/console.h>
|
||||
#include <device/i2c.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/nvidia/tegra/i2c.h>
|
||||
#include <soc/nvidia/tegra124/clk_rst.h>
|
||||
#include <soc/nvidia/tegra124/pinmux.h>
|
||||
#include <soc/nvidia/tegra124/spi.h> /* FIXME: move back to soc code? */
|
||||
|
||||
#include "pmic.h"
|
||||
|
||||
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
||||
|
||||
static void set_clock_sources(void)
|
||||
{
|
||||
clock_configure_source(mselect, PLLP, 102000);
|
||||
|
||||
/* TODO: is the 1.333MHz correct? This may have always been bogus... */
|
||||
clock_configure_source(i2c1, CLK_M, 1333);
|
||||
clock_configure_source(i2c2, CLK_M, 1333);
|
||||
clock_configure_source(i2c3, CLK_M, 1333);
|
||||
clock_configure_source(i2c4, CLK_M, 1333);
|
||||
clock_configure_source(i2c5, CLK_M, 1333);
|
||||
|
||||
/* UARTA gets PLLP, deactivate CLK_UART_DIV_OVERRIDE */
|
||||
writel(PLLP << CLK_SOURCE_SHIFT, &clk_rst->clk_src_uarta);
|
||||
|
||||
/*
|
||||
* MMC3 and MMC4: Set base clock frequency for SD Clock to Tegra MMC's
|
||||
* maximum speed (48MHz) so we can change SDCLK by second stage divisor
|
||||
* in payloads, without touching base clock.
|
||||
*/
|
||||
clock_configure_source(sdmmc3, PLLP, 48000);
|
||||
clock_configure_source(sdmmc4, PLLP, 48000);
|
||||
|
||||
/* PLLP and PLLM are switched for HOST1x for no apparent reason. */
|
||||
write32(4 /* PLLP! */ << CLK_SOURCE_SHIFT |
|
||||
/* TODO(rminnich): The divisor isn't accurate enough to get to
|
||||
* 144MHz (it goes to 163 instead). What should we do here? */
|
||||
CLK_DIVIDER(TEGRA_PLLP_KHZ, 144000),
|
||||
&clk_rst->clk_src_host1x);
|
||||
|
||||
/* DISP1 doesn't support a divisor. Use PLLC which runs at 600MHz. */
|
||||
clock_configure_source(disp1, PLLC, 600000);
|
||||
}
|
||||
|
||||
void bootblock_mainboard_init(void)
|
||||
{
|
||||
clock_config();
|
||||
set_clock_sources();
|
||||
|
||||
clock_enable_clear_reset(
|
||||
// l clocks.
|
||||
CLK_L_CACHE2 | CLK_L_GPIO | CLK_L_TMR | CLK_L_I2C1 |
|
||||
CLK_L_SDMMC4,
|
||||
// h clocks.
|
||||
CLK_H_EMC | CLK_H_I2C2 | CLK_H_I2C5 | CLK_H_SBC1 | CLK_H_PMC |
|
||||
CLK_H_APBDMA | CLK_H_MEM,
|
||||
// u clocks.
|
||||
CLK_U_I2C3 | CLK_U_CSITE | CLK_U_SDMMC3,
|
||||
// v clocks.
|
||||
CLK_V_MSELECT | CLK_V_I2C4,
|
||||
// w clocks.
|
||||
CLK_W_DVFS);
|
||||
|
||||
// I2C1 clock.
|
||||
pinmux_set_config(PINMUX_GEN1_I2C_SCL_INDEX,
|
||||
|
|
|
|||
|
|
@ -24,13 +24,6 @@
|
|||
#include "pmc.h"
|
||||
#include "sysctr.h"
|
||||
|
||||
/* Warning: Some devices just use different bits for the same sources for no
|
||||
* apparent reason. *Always* double-check the TRM before trusting this macro. */
|
||||
#define clock_configure_source(device, src, freq) \
|
||||
clrsetbits_le32(&clk_rst->clk_src_##device, \
|
||||
CLK_SOURCE_MASK | CLK_DIVISOR_MASK, \
|
||||
src << CLK_SOURCE_SHIFT | CLK_DIVIDER(TEGRA_##src##_KHZ, freq));
|
||||
|
||||
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
|
||||
static struct flow_ctlr *flow = (void *)TEGRA_FLOW_BASE;
|
||||
static struct tegra_pmc_regs *pmc = (void *)TEGRA_PMC_BASE;
|
||||
|
|
@ -332,66 +325,21 @@ void clock_init(void)
|
|||
writel(val, &clk_rst->clk_sys_rate);
|
||||
}
|
||||
|
||||
void clock_config(void)
|
||||
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w)
|
||||
{
|
||||
/* Enable clocks for the required peripherals. */
|
||||
/* TODO: can (should?) we use the _SET and _CLR registers here? */
|
||||
setbits_le32(&clk_rst->clk_out_enb_l,
|
||||
CLK_L_CACHE2 | CLK_L_GPIO | CLK_L_TMR | CLK_L_I2C1 |
|
||||
CLK_L_SDMMC4 | CLK_L_DISP1 | CLK_L_HOST1X);
|
||||
setbits_le32(&clk_rst->clk_out_enb_h,
|
||||
CLK_H_EMC | CLK_H_I2C2 | CLK_H_I2C5 | CLK_H_SBC1 |
|
||||
CLK_H_PMC | CLK_H_APBDMA | CLK_H_MEM);
|
||||
setbits_le32(&clk_rst->clk_out_enb_u,
|
||||
CLK_U_I2C3 | CLK_U_CSITE | CLK_U_SDMMC3);
|
||||
setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_MSELECT | CLK_V_I2C4);
|
||||
setbits_le32(&clk_rst->clk_out_enb_w, CLK_W_DVFS);
|
||||
setbits_le32(&clk_rst->clk_out_enb_l, l);
|
||||
setbits_le32(&clk_rst->clk_out_enb_h, h);
|
||||
setbits_le32(&clk_rst->clk_out_enb_u, u);
|
||||
setbits_le32(&clk_rst->clk_out_enb_v, v);
|
||||
setbits_le32(&clk_rst->clk_out_enb_w, w);
|
||||
|
||||
/* Give clock time to stabilize */
|
||||
/* Give clocks time to stabilize. */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
|
||||
clock_configure_source(mselect, PLLP, 102000);
|
||||
|
||||
/* TODO: is the 1.333MHz correct? This may have always been bogus... */
|
||||
clock_configure_source(i2c1, CLK_M, 1333);
|
||||
clock_configure_source(i2c2, CLK_M, 1333);
|
||||
clock_configure_source(i2c3, CLK_M, 1333);
|
||||
clock_configure_source(i2c4, CLK_M, 1333);
|
||||
clock_configure_source(i2c5, CLK_M, 1333);
|
||||
|
||||
/* Move UARTA to PLLP and remove the CLK_UART_DIV_OVERRIDE */
|
||||
write32(PLLP << CLK_SOURCE_SHIFT, &clk_rst->clk_src_uarta);
|
||||
|
||||
/* MMC3 and MMC4: Set base clock frequency for SD Clock to Tegra MMC's
|
||||
* maximum speed (48MHz) so we can change SDCLK by second stage divisor
|
||||
* in payloads, without touching base clock.
|
||||
*/
|
||||
clock_configure_source(sdmmc3, PLLP, 48000);
|
||||
clock_configure_source(sdmmc4, PLLP, 48000);
|
||||
|
||||
/* PLLP and PLLM are switched for HOST1x for no apparent reason. */
|
||||
write32(4 /* PLLP! */ << CLK_SOURCE_SHIFT |
|
||||
/* TODO(rminnich): The divisor isn't accurate enough to get to
|
||||
* 144MHz (it goes to 163 instead). What should we do here? */
|
||||
CLK_DIVIDER(TEGRA_PLLP_KHZ, 144000),
|
||||
&clk_rst->clk_src_host1x);
|
||||
|
||||
/* DISP1 doesn't support a divisor. Use PLLC which runs at 600MHz. */
|
||||
clock_configure_source(disp1, PLLC, 600000);
|
||||
|
||||
/* Give clock time to stabilize. */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
|
||||
/* Take required peripherals out of reset. */
|
||||
|
||||
clrbits_le32(&clk_rst->rst_dev_l,
|
||||
CLK_L_CACHE2 | CLK_L_GPIO | CLK_L_TMR | CLK_L_I2C1 |
|
||||
CLK_L_SDMMC4 | CLK_L_DISP1 | CLK_L_HOST1X);
|
||||
clrbits_le32(&clk_rst->rst_dev_h,
|
||||
CLK_H_EMC | CLK_H_I2C2 | CLK_H_I2C5 | CLK_H_SBC1 |
|
||||
CLK_H_PMC | CLK_H_APBDMA | CLK_H_MEM);
|
||||
clrbits_le32(&clk_rst->rst_dev_u,
|
||||
CLK_U_I2C3 | CLK_U_CSITE | CLK_U_SDMMC3);
|
||||
clrbits_le32(&clk_rst->rst_dev_v, CLK_V_MSELECT | CLK_V_I2C4);
|
||||
clrbits_le32(&clk_rst->rst_dev_w, CLK_W_DVFS);
|
||||
clrbits_le32(&clk_rst->rst_dev_l, l);
|
||||
clrbits_le32(&clk_rst->rst_dev_h, h);
|
||||
clrbits_le32(&clk_rst->rst_dev_u, u);
|
||||
clrbits_le32(&clk_rst->rst_dev_v, v);
|
||||
clrbits_le32(&clk_rst->rst_dev_w, w);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,6 +155,13 @@ enum {
|
|||
/* Calculate clock frequency value from reference and clock divider value */
|
||||
#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2))
|
||||
|
||||
/* Warning: Some devices just use different bits for the same sources for no
|
||||
* apparent reason. *Always* double-check the TRM before trusting this macro. */
|
||||
#define clock_configure_source(device, src, freq) \
|
||||
clrsetbits_le32(&clk_rst->clk_src_##device, \
|
||||
CLK_SOURCE_MASK | CLK_DIVISOR_MASK, \
|
||||
src << CLK_SOURCE_SHIFT | CLK_DIVIDER(TEGRA_##src##_KHZ, freq));
|
||||
|
||||
enum clock_source { /* Careful: Not true for all sources, always check TRM! */
|
||||
PLLP = 0,
|
||||
PLLC2 = 1,
|
||||
|
|
@ -178,7 +185,7 @@ enum clock_source { /* Careful: Not true for all sources, always check TRM! */
|
|||
int clock_get_osc_khz(void);
|
||||
void clock_early_uart(void);
|
||||
void clock_cpu0_config_and_reset(void * entry);
|
||||
void clock_config(void);
|
||||
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w);
|
||||
void clock_init(void);
|
||||
void clock_init_arm_generic_timer(void);
|
||||
#endif /* __SOC_NVIDIA_TEGRA124_CLOCK_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue