diff options
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/clk_rst.h | 112 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/clock.h | 263 |
2 files changed, 326 insertions, 49 deletions
diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h index 36e27b5..a574c53 100644 --- a/arch/arm/include/asm/arch-tegra2/clk_rst.h +++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h @@ -24,15 +24,34 @@ #ifndef _CLK_RST_H_ #define _CLK_RST_H_ +/* PLL registers - there are several PLLs in the clock controller */ +struct clk_pll { + uint pll_base; /* the control register */ + uint pll_out; /* output control */ + uint reserved; + uint pll_misc; /* other misc things */ +}; + +/* PLL registers - there are several PLLs in the clock controller */ +struct clk_pll_simple { + uint pll_base; /* the control register */ + uint pll_misc; /* other misc things */ +}; + +/* + * Most PLLs use the clk_pll structure, but some have a simpler two-member + * structure for which we use clk_pll_simple. The reason for this non- + * othogonal setup is not stated. + */ +#define TEGRA_CLK_PLLS 6 +#define TEGRA_CLK_SIMPLE_PLLS 3 /* Number of simple PLLs */ +#define TEGRA_CLK_REGS 3 /* Number of clock enable registers */ + /* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */ struct clk_rst_ctlr { - uint crc_rst_src; /* _RST_SOURCE_0, 0x00 */ - uint crc_rst_dev_l; /* _RST_DEVICES_L_0, 0x04 */ - uint crc_rst_dev_h; /* _RST_DEVICES_H_0, 0x08 */ - uint crc_rst_dev_u; /* _RST_DEVICES_U_0, 0x0C */ - uint crc_clk_out_enb_l; /* _CLK_OUT_ENB_L_0, 0x10 */ - uint crc_clk_out_enb_h; /* _CLK_OUT_ENB_H_0, 0x14 */ - uint crc_clk_out_enb_u; /* _CLK_OUT_ENB_U_0, 0x18 */ + uint crc_rst_src; /* _RST_SOURCE_0,0x00 */ + uint crc_rst_dev[TEGRA_CLK_REGS]; /* _RST_DEVICES_L/H/U_0 */ + uint crc_clk_out_enb[TEGRA_CLK_REGS]; /* _CLK_OUT_ENB_L/H/U_0 */ uint crc_reserved0; /* reserved_0, 0x1C */ uint crc_cclk_brst_pol; /* _CCLK_BURST_POLICY_0,0x20 */ uint crc_super_cclk_div; /* _SUPER_CCLK_DIVIDER_0,0x24 */ @@ -52,44 +71,11 @@ struct clk_rst_ctlr { uint crc_osc_freq_det_stat; /* _OSC_FREQ_DET_STATUS_0,0x5C */ uint crc_reserved2[8]; /* reserved_2[8], 0x60-7C */ - uint crc_pllc_base; /* _PLLC_BASE_0, 0x80 */ - uint crc_pllc_out; /* _PLLC_OUT_0, 0x84 */ - uint crc_reserved3; /* reserved_3, 0x88 */ - uint crc_pllc_misc; /* _PLLC_MISC_0, 0x8C */ - - uint crc_pllm_base; /* _PLLM_BASE_0, 0x90 */ - uint crc_pllm_out; /* _PLLM_OUT_0, 0x94 */ - uint crc_reserved4; /* reserved_4, 0x98 */ - uint crc_pllm_misc; /* _PLLM_MISC_0, 0x9C */ - - uint crc_pllp_base; /* _PLLP_BASE_0, 0xA0 */ - uint crc_pllp_outa; /* _PLLP_OUTA_0, 0xA4 */ - uint crc_pllp_outb; /* _PLLP_OUTB_0, 0xA8 */ - uint crc_pllp_misc; /* _PLLP_MISC_0, 0xAC */ - - uint crc_plla_base; /* _PLLA_BASE_0, 0xB0 */ - uint crc_plla_out; /* _PLLA_OUT_0, 0xB4 */ - uint crc_reserved5; /* reserved_5, 0xB8 */ - uint crc_plla_misc; /* _PLLA_MISC_0, 0xBC */ - - uint crc_pllu_base; /* _PLLU_BASE_0, 0xC0 */ - uint crc_reserved6; /* _reserved_6, 0xC4 */ - uint crc_reserved7; /* _reserved_7, 0xC8 */ - uint crc_pllu_misc; /* _PLLU_MISC_0, 0xCC */ - - uint crc_plld_base; /* _PLLD_BASE_0, 0xD0 */ - uint crc_reserved8; /* _reserved_8, 0xD4 */ - uint crc_reserved9; /* _reserved_9, 0xD8 */ - uint crc_plld_misc; /* _PLLD_MISC_0, 0xDC */ + struct clk_pll crc_pll[TEGRA_CLK_PLLS]; /* PLLs from 0x80 to 0xdc */ - uint crc_pllx_base; /* _PLLX_BASE_0, 0xE0 */ - uint crc_pllx_misc; /* _PLLX_MISC_0, 0xE4 */ + /* PLLs from 0xe0 to 0xf4 */ + struct clk_pll_simple crc_pll_simple[TEGRA_CLK_SIMPLE_PLLS]; - uint crc_plle_base; /* _PLLE_BASE_0, 0xE8 */ - uint crc_plle_misc; /* _PLLE_MISC_0, 0xEC */ - - uint crc_plls_base; /* _PLLS_BASE_0, 0xF0 */ - uint crc_plls_misc; /* _PLLS_MISC_0, 0xF4 */ uint crc_reserved10; /* _reserved_10, 0xF8 */ uint crc_reserved11; /* _reserved_11, 0xFC */ @@ -157,8 +143,8 @@ struct clk_rst_ctlr { #define PLL_BYPASS (1 << 31) #define PLL_ENABLE (1 << 30) #define PLL_BASE_OVRRIDE (1 << 28) -#define PLL_DIVP (1 << 20) /* post divider, b22:20 */ -#define PLL_DIVM 0x0C /* input divider, b4:0 */ +#define PLL_DIVP_VALUE (1 << 20) /* post divider, b22:20 */ +#define PLL_DIVM_VALUE 0x0C /* input divider, b4:0 */ #define SWR_UARTD_RST (1 << 1) #define CLK_ENB_UARTD (1 << 1) @@ -191,9 +177,37 @@ struct clk_rst_ctlr { #define CPCON (1 << 8) -#define SWR_SDMMC4_RST (1 << 15) -#define CLK_ENB_SDMMC4 (1 << 15) -#define SWR_SDMMC3_RST (1 << 5) -#define CLK_ENB_SDMMC3 (1 << 5) +/* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */ +#define CPU1_CLK_STP_SHIFT 9 + +#define CPU0_CLK_STP_SHIFT 8 +#define CPU0_CLK_STP_MASK (1U << CPU0_CLK_STP_SHIFT) + +/* CLK_RST_CONTROLLER_PLLx_BASE_0 */ +#define PLL_BYPASS_SHIFT 31 +#define PLL_BYPASS_MASK (1U << PLL_BYPASS_SHIFT) + +#define PLL_ENABLE_SHIFT 30 +#define PLL_ENABLE_MASK (1U << PLL_ENABLE_SHIFT) + +#define PLL_BASE_OVRRIDE_MASK (1U << 28) + +#define PLL_DIVP_SHIFT 20 + +#define PLL_DIVN_SHIFT 8 + +#define PLL_DIVM_SHIFT 0 + +/* CLK_RST_CONTROLLER_PLLx_MISC_0 */ +#define PLL_CPCON_SHIFT 8 +#define PLL_CPCON_MASK (15U << PLL_CPCON_SHIFT) + +#define PLL_LFCON_SHIFT 4 + +#define PLLU_VCO_FREQ_SHIFT 20 + +/* CLK_RST_CONTROLLER_OSC_CTRL_0 */ +#define OSC_FREQ_SHIFT 30 +#define OSC_FREQ_MASK (3U << OSC_FREQ_SHIFT) #endif /* CLK_RST_H */ diff --git a/arch/arm/include/asm/arch-tegra2/clock.h b/arch/arm/include/asm/arch-tegra2/clock.h new file mode 100644 index 0000000..d01aec8 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/clock.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Tegra2 clock control functions */ + +#ifndef _CLOCK_H + + +/* 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_COUNT, +}; + +/* The PLLs supported by the hardware */ +enum clock_pll_id { + CLOCK_PLL_ID_FIRST, + CLOCK_PLL_ID_CGENERAL = CLOCK_PLL_ID_FIRST, + CLOCK_PLL_ID_MEMORY, + CLOCK_PLL_ID_PERIPH, + CLOCK_PLL_ID_AUDIO, + CLOCK_PLL_ID_USB, + CLOCK_PLL_ID_DISPLAY, + + /* now the simple ones */ + CLOCK_PLL_ID_FIRST_SIMPLE, + CLOCK_PLL_ID_XCPU = CLOCK_PLL_ID_FIRST_SIMPLE, + CLOCK_PLL_ID_EPCI, + CLOCK_PLL_ID_SFROM32KHZ, + + CLOCK_PLL_ID_COUNT, +}; + +/* The clocks supported by the hardware */ +enum periph_id { + PERIPH_ID_FIRST, + + /* Low word: 31:0 */ + PERIPH_ID_CPU = PERIPH_ID_FIRST, + PERIPH_ID_RESERVED1, + PERIPH_ID_RESERVED2, + PERIPH_ID_AC97, + PERIPH_ID_RTC, + PERIPH_ID_TMR, + PERIPH_ID_UART1, + PERIPH_ID_UART2, + + /* 8 */ + PERIPH_ID_GPIO, + PERIPH_ID_SDMMC2, + PERIPH_ID_SPDIF, + PERIPH_ID_I2S1, + PERIPH_ID_I2C1, + PERIPH_ID_NDFLASH, + PERIPH_ID_SDMMC1, + PERIPH_ID_SDMMC4, + + /* 16 */ + PERIPH_ID_TWC, + PERIPH_ID_PWC, + PERIPH_ID_I2S2, + PERIPH_ID_EPP, + PERIPH_ID_VI, + PERIPH_ID_2D, + PERIPH_ID_USBD, + PERIPH_ID_ISP, + + /* 24 */ + PERIPH_ID_3D, + PERIPH_ID_IDE, + PERIPH_ID_DISP2, + PERIPH_ID_DISP1, + PERIPH_ID_HOST1X, + PERIPH_ID_VCP, + PERIPH_ID_RESERVED30, + PERIPH_ID_CACHE2, + + /* Middle word: 63:32 */ + PERIPH_ID_MEM, + PERIPH_ID_AHBDMA, + PERIPH_ID_APBDMA, + PERIPH_ID_RESERVED35, + PERIPH_ID_KBC, + PERIPH_ID_STAT_MON, + PERIPH_ID_PMC, + PERIPH_ID_FUSE, + + /* 40 */ + PERIPH_ID_KFUSE, + PERIPH_ID_SBC1, + PERIPH_ID_SNOR, + PERIPH_ID_SPI1, + PERIPH_ID_SBC2, + PERIPH_ID_XIO, + PERIPH_ID_SBC3, + PERIPH_ID_DVC_I2C, + + /* 48 */ + PERIPH_ID_DSI, + PERIPH_ID_TVO, + PERIPH_ID_MIPI, + PERIPH_ID_HDMI, + PERIPH_ID_CSI, + PERIPH_ID_TVDAC, + PERIPH_ID_I2C2, + PERIPH_ID_UART3, + + /* 56 */ + PERIPH_ID_RESERVED56, + PERIPH_ID_EMC, + PERIPH_ID_USB2, + PERIPH_ID_USB3, + PERIPH_ID_MPE, + PERIPH_ID_VDE, + PERIPH_ID_BSEA, + PERIPH_ID_BSEV, + + /* Upper word 95:64 */ + PERIPH_ID_SPEEDO, + PERIPH_ID_UART4, + PERIPH_ID_UART5, + PERIPH_ID_I2C3, + PERIPH_ID_SBC4, + PERIPH_ID_SDMMC3, + PERIPH_ID_PCIE, + PERIPH_ID_OWR, + + /* 72 */ + PERIPH_ID_AFI, + PERIPH_ID_CORESIGHT, + PERIPH_ID_RESERVED74, + PERIPH_ID_AVPUCQ, + PERIPH_ID_RESERVED76, + PERIPH_ID_RESERVED77, + PERIPH_ID_RESERVED78, + PERIPH_ID_RESERVED79, + + /* 80 */ + PERIPH_ID_RESERVED80, + PERIPH_ID_RESERVED81, + PERIPH_ID_RESERVED82, + PERIPH_ID_RESERVED83, + PERIPH_ID_IRAMA, + PERIPH_ID_IRAMB, + PERIPH_ID_IRAMC, + PERIPH_ID_IRAMD, + + /* 88 */ + PERIPH_ID_CRAM2, + + PERIPH_ID_COUNT, +}; + +/* Converts a clock number to a clock register: 0=L, 1=H, 2=U */ +#define PERIPH_REG(id) ((id) >> 5) + +/* Mask value for a clock (within PERIPH_REG(id)) */ +#define PERIPH_MASK(id) (1 << ((id) & 0x1f)) + +/* return 1 if a PLL ID is in range */ +#define clock_pll_id_isvalid(id) ((id) >= CLOCK_PLL_ID_FIRST && \ + (id) < CLOCK_PLL_ID_COUNT) + +/* return 1 if a peripheral ID is in range */ +#define clock_periph_id_isvalid(id) ((id) >= PERIPH_ID_FIRST && \ + (id) < PERIPH_ID_COUNT) + +/* PLL stabilization delay in usec */ +#define CLOCK_PLL_STABLE_DELAY_US 300 + +/* return the current oscillator clock frequency */ +enum clock_osc_freq clock_get_osc_freq(void); + +/* + * Start PLL using the provided configuration parameters. + * + * @param id clock id + * @param divm input divider + * @param divn feedback divider + * @param divp post divider 2^n + * @param cpcon charge pump setup control + * @param lfcon loop filter setup control + * + * @returns monotonic time in us that the PLL will be stable + */ +unsigned long clock_start_pll(enum clock_pll_id id, u32 divm, u32 divn, + u32 divp, u32 cpcon, u32 lfcon); + +/* + * Enable a clock + * + * @param id clock id + */ +void clock_enable(enum periph_id clkid); + +/* + * Set whether a clock is enabled or disabled. + * + * @param id clock id + * @param enable 1 to enable, 0 to disable + */ +void clock_set_enable(enum periph_id clkid, int enable); + +/* + * Reset a peripheral. This puts it in reset, waits for a delay, then takes + * it out of reset and waits for th delay again. + * + * @param periph_id peripheral to reset + * @param us_delay time to delay in microseconds + */ +void reset_periph(enum periph_id periph_id, int us_delay); + +/* + * Put a peripheral into or out of reset. + * + * @param periph_id peripheral to reset + * @param enable 1 to put into reset, 0 to take out of reset + */ +void reset_set_enable(enum periph_id periph_id, int enable); + + +/* CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET/CLR_0 */ +enum crc_reset_id { + /* Things we can hold in reset for each CPU */ + crc_rst_cpu = 1, + crc_rst_de = 1 << 2, /* What is de? */ + crc_rst_watchdog = 1 << 3, + crc_rst_debug = 1 << 4, +}; + +/* + * Put parts of the CPU complex into or out of reset.\ + * + * @param cpu cpu number (0 or 1 on Tegra2) + * @param which which parts of the complex to affect (OR of crc_reset_id) + * @param reset 1 to assert reset, 0 to de-assert + */ +void reset_cmplx_set_enable(int cpu, int which, int reset); + +#endif |