diff options
author | Tom Warren <twarren@nvidia.com> | 2011-11-16 16:38:34 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2011-11-18 00:00:45 -0800 |
commit | 318c9b21768d937e4a8984af86fec6fcd02242f2 (patch) | |
tree | 7f76b9915570a9e1d1c8d3cf16d318676ba2764b | |
parent | e0a72afdcd769abd7ac3465d86e45bc0ccd95833 (diff) |
arm: Tegra3: complete 408MHz PLLP init
Signed-off-by: Tom Warren <twarren@nvidia.com>
BUG=chromium-os:21033
TEST=Built and booted OK on my Waluigi. UART is OK, mmc, spi, i2c OK.
Note that this is only valid with CONFIG_SYS_PLLP_BASE_IS_408MHZ.
No affect on Tegra2. Seaboard builds fine, BTW.
Change-Id: I05a367afd1e78a2170d7308a658ce64017850ca0
Reviewed-on: https://gerrit.chromium.org/gerrit/11811
Tested-by: Tom Warren <twarren@nvidia.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Commit-Ready: Che-Liang Chiou <clchiou@chromium.org>
-rw-r--r-- | arch/arm/cpu/armv7/tegra-common/ap20.c | 35 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra/clk_rst.h | 17 | ||||
-rw-r--r-- | common/fdt_decode.c | 4 |
3 files changed, 52 insertions, 4 deletions
diff --git a/arch/arm/cpu/armv7/tegra-common/ap20.c b/arch/arm/cpu/armv7/tegra-common/ap20.c index fb836963c8..40e8f36cff 100644 --- a/arch/arm/cpu/armv7/tegra-common/ap20.c +++ b/arch/arm/cpu/armv7/tegra-common/ap20.c @@ -65,7 +65,7 @@ static struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_COUNT] { 600, 13, 0, 12}, }, - /* T30: 1.5 GHz with slower PLLP */ + /* T30: 1.5 GHz with slower (216MHz) PLLP */ {{ 0xd8, 13, 1, 8}, { 0xb4, 22, 1, 4}, { 0x1b0, 12, 1, 8}, @@ -119,6 +119,26 @@ int ap20_cpu_is_cortexa9(void) return id == (PG_UP_TAG_0_PID_CPU & 0xff); } +#if defined(CONFIG_SYS_PLLP_BASE_IS_408MHZ) +static void adjust_pllp_out_freqs(void) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH]; + u32 reg; + + /* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ + reg = readl(&pll->pll_out); /* OUTA, contains OUT2 / OUT1 */ + reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR + | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR; + writel(reg, &pll->pll_out); + + reg = readl(&pll->pll_out_b); /* OUTB, contains OUT4 / OUT3 */ + reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR + | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR; + writel(reg, &pll->pll_out_b); +} +#endif + static int pllx_set_rate(struct clk_pll *pll , u32 divn, u32 divm, u32 divp, u32 cpcon) { @@ -168,6 +188,9 @@ void ap20_init_pllx(int slow) /* set pllx */ sel = &tegra_pll_x_table[chip_type][osc]; pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon); +#if defined(CONFIG_SYS_PLLP_BASE_IS_408MHZ) + adjust_pllp_out_freqs(); +#endif } static void enable_cpu_clock(int enable) @@ -340,7 +363,7 @@ void t30_init_clocks(void) clrbits_le32(flow->control, 1 << 0); /* - * Switch system clock to PLLP_out 4 (108 MHz) MHz, AVP will now run + * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run * at 108 MHz. This is glitch free as only the source is changed, no * special precaution needed. */ @@ -399,7 +422,15 @@ static void clock_enable_coresight(int enable) * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) */ +#if defined(CONFIG_SYS_PLLP_BASE_IS_408MHZ) + /* + * Clock divider request for 204MHz would setup CSITE clock as + * 144MHz for PLLP base 216MHz and 204MHz for PLLP base 408MHz + */ + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 204000); +#else src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); +#endif clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); /* Unlock the CPU CoreSight interfaces */ diff --git a/arch/arm/include/asm/arch-tegra/clk_rst.h b/arch/arm/include/asm/arch-tegra/clk_rst.h index 94811679c8..74af2ea8ca 100644 --- a/arch/arm/include/asm/arch-tegra/clk_rst.h +++ b/arch/arm/include/asm/arch-tegra/clk_rst.h @@ -29,7 +29,7 @@ struct clk_pll { uint pll_base; /* the control register */ uint pll_out; /* output control */ - uint reserved; + uint pll_out_b; /* some have output B control */ uint pll_misc; /* other misc things */ }; @@ -128,6 +128,21 @@ struct clk_rst_ctlr { #define PLLU_VCO_FREQ_RANGE 20:20 #define PLL_VCO_FREQ_RANGE 3:0 +#define PLLP_OUT1_OVR (1 << 2) +#define PLLP_OUT2_OVR (1 << 18) +#define PLLP_OUT3_OVR (1 << 2) +#define PLLP_OUT4_OVR (1 << 18) +#define PLLP_OUT1_RATIO 8 +#define PLLP_OUT2_RATIO 24 +#define PLLP_OUT3_RATIO 8 +#define PLLP_OUT4_RATIO 24 +enum { + IN_408_OUT_204_DIVISOR = 2, + IN_408_OUT_102_DIVISOR = 6, + IN_408_OUT_48_DIVISOR = 15, + IN_408_OUT_9_6_DIVISOR = 83, +}; + /* CLK_RST_CONTROLLER_OSC_CTRL_0 */ #define OSC_FREQ_RANGE 31:30 diff --git a/common/fdt_decode.c b/common/fdt_decode.c index 1e32ad9dbf..b6beebda69 100644 --- a/common/fdt_decode.c +++ b/common/fdt_decode.c @@ -307,7 +307,9 @@ int fdt_decode_uart_console(const void *blob, struct fdt_uart *uart, uart->silent = fdt_decode_get_config_int(blob, "silent_console", 0); uart->io_mapped = get_int(blob, node, "io-mapped", 0); uart->compat = fdt_decode_lookup(blob, node); - +#if !defined(CONFIG_SYS_PLLP_BASE_IS_408MHZ) + uart->clock_freq = 216000000; +#endif /* Calculate divisor if required */ if ((uart->divisor == -1) && (uart->clock_freq != -1)) fdt_decode_uart_calc_divisor(uart); |