tegra124: Increase SCLK (AVP) to 300MHz
This patch changes some of the early clock initialization code to max out the AVP clock rate at 300MHz as soon as possible (which will hopefully speed up boot time). Instead of temporarily switching it to CLK_M (from PLLP at 1MHz), we just set up PLLC (600MHz) extra early and move it straight to there with a divisor of 2. This also inadvertently affects the AHB and APB bus clocks (HCLK and PCLK), so we do what we can with the tiny 2-bit divisors we have to turn that down a little (leading to HCLK = 75MHz and PCLK = 18.75MHz). This is still way higher than the 6MHz our former code would put them to, and thus conveniently solves our USB FIFO underrun problems. BUG=None TEST=None Change-Id: I1e68359a6f69370ddfcf1a634da043d6676b9d7f Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/175489
This commit is contained in:
parent
2173edacc6
commit
7e082f2c2f
2 changed files with 68 additions and 128 deletions
|
|
@ -362,17 +362,15 @@ struct __attribute__ ((__packed__)) clk_rst_ctlr {
|
|||
/* CLK_RST_CONTROLLER_PLL*_OUT*_0 */
|
||||
#define PLL_OUT_RSTN (1 << 0)
|
||||
#define PLL_OUT_CLKEN (1 << 1)
|
||||
#define PLL_OUT_OVRRIDE (1 << 2)
|
||||
#define PLL_OUT_OVR (1 << 2)
|
||||
|
||||
#define PLL_OUT_RATIO_SHIFT 8
|
||||
#define PLL_OUT_RATIO_MASK (0xffU << PLL_OUT_RATIO_SHIFT)
|
||||
|
||||
#define PLL_OUT2_RSTN (1 << 16)
|
||||
#define PLL_OUT2_CLKEN (1 << 17)
|
||||
#define PLL_OUT2_OVRRIDE (1 << 18)
|
||||
|
||||
#define PLL_OUT2_RATIO_SHIFT 24
|
||||
#define PLL_OUT2_RATIO_MASK (0xffU << PLL_OUT2_RATIO_SHIFT)
|
||||
#define PLL_OUT1_SHIFT 0
|
||||
#define PLL_OUT2_SHIFT 16
|
||||
#define PLL_OUT3_SHIFT 0
|
||||
#define PLL_OUT4_SHIFT 16
|
||||
|
||||
/* CLK_RST_CONTROLLER_PLL*_MISC_0 */
|
||||
#define PLL_MISC_DCCON (1 << 20)
|
||||
|
|
@ -391,31 +389,6 @@ struct __attribute__ ((__packed__)) clk_rst_ctlr {
|
|||
|
||||
#define PLLU_MISC_VCO_FREQ (1 << 20)
|
||||
|
||||
#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
|
||||
|
||||
#define PLLP_OUT3_RSTN_DIS (1 << 0)
|
||||
#define PLLP_OUT3_RSTN_EN (0 << 0)
|
||||
#define PLLP_OUT3_CLKEN (1 << 1)
|
||||
#define PLLP_OUT3_OVRRIDE (1 << 2)
|
||||
#define PLLP_OUT4_RSTN_DIS (1 << 16)
|
||||
#define PLLP_OUT4_RSTN_EN (0 << 16)
|
||||
#define PLLP_OUT4_CLKEN (1 << 17)
|
||||
#define PLLP_OUT4_OVRRIDE (1 << 18)
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
/* PLLX_BASE_0 0xe0 */
|
||||
#define PLLX_BASE_PLLX_ENABLE (1 << 30)
|
||||
|
||||
|
|
@ -455,56 +428,39 @@ enum {
|
|||
#define SCLK_COP_IRQ_MASK (1 << 25)
|
||||
#define SCLK_CPU_IRQ_MASK (1 << 24)
|
||||
|
||||
#define SCLK_SWAKEUP_FIQ_SOURCE_SHIFT 12
|
||||
#define SCLK_SWAKEUP_FIQ_SOURCE_MASK \
|
||||
(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
|
||||
#define SCLK_SWAKEUP_IRQ_SOURCE_SHIFT 8
|
||||
#define SCLK_SWAKEUP_IRQ_SOURCE_MASK \
|
||||
(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
|
||||
#define SCLK_SWAKEUP_RUN_SOURCE_SHIFT 4
|
||||
#define SCLK_SWAKEUP_RUN_SOURCE_MASK \
|
||||
(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
|
||||
#define SCLK_SWAKEUP_IDLE_SOURCE_SHIFT 0
|
||||
|
||||
#define SCLK_SWAKEUP_IDLE_SOURCE_MASK \
|
||||
(7 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT)
|
||||
#define SCLK_FIQ_SHIFT 12
|
||||
#define SCLK_FIQ_MASK (7 << SCLK_FIQ_SHIFT)
|
||||
#define SCLK_IRQ_SHIFT 8
|
||||
#define SCLK_IRQ_MASK (7 << SCLK_FIQ_SHIFT)
|
||||
#define SCLK_RUN_SHIFT 4
|
||||
#define SCLK_RUN_MASK (7 << SCLK_FIQ_SHIFT)
|
||||
#define SCLK_IDLE_SHIFT 0
|
||||
#define SCLK_IDLE_MASK (7 << SCLK_FIQ_SHIFT)
|
||||
enum {
|
||||
SCLK_SOURCE_CLKM,
|
||||
SCLK_SOURCE_PLLC_OUT1,
|
||||
SCLK_SOURCE_PLLP_OUT4,
|
||||
SCLK_SOURCE_PLLP_OUT3,
|
||||
SCLK_SOURCE_PLLP_OUT2,
|
||||
SCLK_SOURCE_CLKD,
|
||||
SCLK_SOURCE_PLLC_OUT0,
|
||||
SCLK_SOURCE_CLKS,
|
||||
SCLK_SOURCE_PLLM_OUT1,
|
||||
};
|
||||
|
||||
#define SCLK_SWAKE_FIQ_SRC_CLKM (0 << 12)
|
||||
#define SCLK_SWAKE_IRQ_SRC_CLKM (0 << 8)
|
||||
#define SCLK_SWAKE_RUN_SRC_CLKM (0 << 4)
|
||||
#define SCLK_SWAKE_IDLE_SRC_CLKM (0 << 0)
|
||||
#define SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 (7 << 12)
|
||||
#define SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 (7 << 8)
|
||||
#define SCLK_SWAKE_RUN_SRC_PLLM_OUT1 (7 << 4)
|
||||
#define SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 (7 << 0)
|
||||
|
||||
/* CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER 0x2c */
|
||||
#define SUPER_SCLK_ENB_SHIFT 31U
|
||||
#define SUPER_SCLK_ENB_MASK (1U << 31)
|
||||
#define SUPER_SCLK_DIVIDEND_SHIFT 8
|
||||
#define SUPER_SCLK_DIVIDEND_MASK (0xff << SUPER_SCLK_DIVIDEND_SHIFT)
|
||||
#define SUPER_SCLK_DIVISOR_SHIFT 0
|
||||
#define SUPER_SCLK_DIVISOR_MASK (0xff << SUPER_SCLK_DIVISOR_SHIFT)
|
||||
#define SCLK_DIV_ENB (1 << 31)
|
||||
#define SCLK_DIVIDEND_SHIFT 8
|
||||
#define SCLK_DIVIDEND_MASK (0xff << SCLK_DIVIDEND_SHIFT)
|
||||
#define SCLK_DIVISOR_SHIFT 0
|
||||
#define SCLK_DIVISOR_MASK (0xff << SCLK_DIVISOR_SHIFT)
|
||||
|
||||
/* CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30 */
|
||||
#define CLK_SYS_RATE_HCLK_DISABLE_SHIFT 7
|
||||
#define CLK_SYS_RATE_HCLK_DISABLE_MASK (1 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT)
|
||||
#define CLK_SYS_RATE_AHB_RATE_SHIFT 4
|
||||
#define CLK_SYS_RATE_AHB_RATE_MASK (3 << CLK_SYS_RATE_AHB_RATE_SHIFT)
|
||||
#define CLK_SYS_RATE_PCLK_DISABLE_SHIFT 3
|
||||
#define CLK_SYS_RATE_PCLK_DISABLE_MASK (1 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT)
|
||||
#define CLK_SYS_RATE_APB_RATE_SHIFT 0
|
||||
#define CLK_SYS_RATE_APB_RATE_MASK (3 << CLK_SYS_RATE_AHB_RATE_SHIFT)
|
||||
#define HCLK_DISABLE (1 << 7)
|
||||
#define HCLK_DIVISOR_SHIFT 4
|
||||
#define HCLK_DIVISOR_MASK (3 << AHB_RATE_SHIFT)
|
||||
#define PCLK_DISABLE (1 << 3)
|
||||
#define PCLK_DIVISOR_SHIFT 0
|
||||
#define PCLK_DIVISOR_MASK (3 << AHB_RATE_SHIFT)
|
||||
|
||||
/* CRC_CLK_SOURCE_MSELECT_0 0x3b4 */
|
||||
#define MSELECT_CLK_SRC_PLLP_OUT0 (0 << 29)
|
||||
|
|
|
|||
|
|
@ -191,21 +191,6 @@ void clock_init_arm_generic_timer(void)
|
|||
write32(cntcr, &sysctr->cntcr);
|
||||
}
|
||||
|
||||
static void adjust_pllp_out_freqs(void)
|
||||
{
|
||||
u32 reg;
|
||||
/* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
|
||||
reg = readl(&clk_rst->pllp_outa); // 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, &clk_rst->pllp_outa);
|
||||
|
||||
reg = readl(&clk_rst->pllp_outb); // 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, &clk_rst->pllp_outb);
|
||||
}
|
||||
|
||||
#define SOR0_CLK_SEL0 (1 << 14)
|
||||
#define SOR0_CLK_SEL1 (1 << 15)
|
||||
|
||||
|
|
@ -328,6 +313,9 @@ void clock_cpu0_config_and_reset(void *entry)
|
|||
write32((uintptr_t)entry, &cpug_entry_point);
|
||||
write32((uintptr_t)&cpug_setup, evp_cpu_reset);
|
||||
|
||||
/* Set active CPU cluster to G */
|
||||
clrbits_le32(&flow->cluster_control, 1);
|
||||
|
||||
// Set up cclk_brst and divider.
|
||||
write32((CRC_CCLK_BRST_POL_PLLX_OUT0 << 0) |
|
||||
(CRC_CCLK_BRST_POL_PLLX_OUT0 << 4) |
|
||||
|
|
@ -364,67 +352,63 @@ void clock_cpu0_config_and_reset(void *entry)
|
|||
&clk_rst->rst_cpug_cmplx_clr);
|
||||
}
|
||||
|
||||
/**
|
||||
* The T124 requires some special clock initialization, including setting up
|
||||
* the DVC I2C, turning on MSELECT and selecting the G CPU cluster
|
||||
*/
|
||||
void clock_init(void)
|
||||
{
|
||||
u32 val;
|
||||
u32 osc = clock_get_osc_bits();
|
||||
|
||||
/*
|
||||
* On poweron, AVP clock source (also called system clock) is set to
|
||||
* PLLP_out0 with frequency set at 1MHz. Before initializing PLLP, we
|
||||
* need to move the system clock's source to CLK_M temporarily. And
|
||||
* then switch it to PLLP_out4 (204MHz) at a later time.
|
||||
*/
|
||||
val = (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_CLKM << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
|
||||
(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
|
||||
writel(val, &clk_rst->sclk_brst_pol);
|
||||
udelay(2);
|
||||
|
||||
/* Set active CPU cluster to G */
|
||||
clrbits_le32(&flow->cluster_control, 1);
|
||||
|
||||
/* Change the oscillator drive strength */
|
||||
val = readl(&clk_rst->osc_ctrl);
|
||||
val &= ~OSC_XOFS_MASK;
|
||||
val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
|
||||
writel(val, &clk_rst->osc_ctrl);
|
||||
|
||||
/* Ambiguous quote from u-boot. TODO: what's this mean?
|
||||
* "should update same value in PMC_OSC_EDPD_OVER XOFS
|
||||
field for warmboot "*/
|
||||
val = readl(&pmc->osc_edpd_over);
|
||||
val &= ~PMC_OSC_EDPD_OVER_XOFS_MASK;
|
||||
val |= (OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
|
||||
writel(val, &pmc->osc_edpd_over);
|
||||
|
||||
/* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
|
||||
val = readl(&clk_rst->pllx_misc3);
|
||||
val &= ~PLLX_IDDQ_MASK;
|
||||
writel(val, &clk_rst->pllx_misc3);
|
||||
udelay(2);
|
||||
|
||||
/* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
|
||||
writel(0x2b << 17 | 0xb << 9, &clk_rst->pllc_misc2);
|
||||
|
||||
adjust_pllp_out_freqs();
|
||||
/* Max out the AVP clock before everything else (need PLLC for that). */
|
||||
init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc, osc_table[osc].pllc);
|
||||
|
||||
/* Be more careful with processor clock, wait for the lock. (~10us) */
|
||||
setbits_le32(&clk_rst->pllc_misc, PLLC_MISC_LOCK_ENABLE);
|
||||
while (!(read32(&clk_rst->pllc_base) & PLL_BASE_LOCK)) /* wait */;
|
||||
|
||||
/* APB pclk and AHB hclk derive from sclk, let's not overkill them */
|
||||
write32(3 << HCLK_DIVISOR_SHIFT | 3 << PCLK_DIVISOR_SHIFT,
|
||||
&clk_rst->clk_sys_rate); /* pclk = hclk/4 = sclk/16 */
|
||||
write32(0 << SCLK_DIVIDEND_SHIFT |
|
||||
(div_round_up(TEGRA_PLLC_KHZ, 300000) - 1) << SCLK_DIVISOR_SHIFT
|
||||
| SCLK_DIV_ENB, &clk_rst->super_sclk_div);
|
||||
write32(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT |
|
||||
SCLK_SOURCE_PLLC_OUT0 << SCLK_RUN_SHIFT,
|
||||
&clk_rst->sclk_brst_pol); /* sclk = 300 MHz */
|
||||
|
||||
/* Change the oscillator drive strength (from U-Boot -- why?) */
|
||||
clrsetbits_le32(&clk_rst->osc_ctrl, OSC_XOFS_MASK,
|
||||
OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
|
||||
|
||||
/*
|
||||
* Ambiguous quote from u-boot. TODO: what's this mean?
|
||||
* "should update same value in PMC_OSC_EDPD_OVER XOFS
|
||||
* field for warmboot "
|
||||
*/
|
||||
clrsetbits_le32(&pmc->osc_edpd_over, PMC_OSC_EDPD_OVER_XOFS_MASK,
|
||||
OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
|
||||
|
||||
/* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
|
||||
clrbits_le32(&clk_rst->pllx_misc3, PLLX_IDDQ_MASK);
|
||||
|
||||
/* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
|
||||
write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << PLL_OUT_RATIO_SHIFT |
|
||||
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT1_SHIFT |
|
||||
(CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << PLL_OUT_RATIO_SHIFT |
|
||||
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT2_SHIFT,
|
||||
&clk_rst->pllp_outa);
|
||||
write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << PLL_OUT_RATIO_SHIFT |
|
||||
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT3_SHIFT |
|
||||
(CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << PLL_OUT_RATIO_SHIFT |
|
||||
PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT4_SHIFT,
|
||||
&clk_rst->pllp_outb);
|
||||
|
||||
init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc, osc_table[osc].pllx);
|
||||
init_pll(&clk_rst->pllp_base, &clk_rst->pllp_misc, osc_table[osc].pllp);
|
||||
init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc, osc_table[osc].pllc);
|
||||
init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, osc_table[osc].plld);
|
||||
init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc, osc_table[osc].pllu);
|
||||
init_utmip_pll();
|
||||
graphics_pll();
|
||||
|
||||
val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT);
|
||||
writel(val, &clk_rst->clk_sys_rate);
|
||||
}
|
||||
|
||||
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue