diff options
Diffstat (limited to 'arch/arm/include/asm/arch-tegra2')
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/clk_rst.h | 84 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/clock.h | 149 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-tegra2/pinmux.h | 444 |
3 files changed, 447 insertions, 230 deletions
diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h index bd9d9ad..0b6e004 100644 --- a/arch/arm/include/asm/arch-tegra2/clk_rst.h +++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h @@ -43,9 +43,12 @@ struct clk_pll_simple { * 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 */ +enum { + TEGRA_CLK_PLLS = 6, /* Number of normal PLLs */ + TEGRA_CLK_SIMPLE_PLLS = 3, /* Number of simple PLLs */ + TEGRA_CLK_REGS = 3, /* Number of clock enable registers */ + TEGRA_CLK_SOURCES = 64, /* Number of peripheral clock sources */ +}; /* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */ struct clk_rst_ctlr { @@ -79,65 +82,10 @@ struct clk_rst_ctlr { uint crc_reserved10; /* _reserved_10, 0xF8 */ uint crc_reserved11; /* _reserved_11, 0xFC */ - uint crc_clk_src_i2s1; /*_I2S1_0, 0x100 */ - uint crc_clk_src_i2s2; /*_I2S2_0, 0x104 */ - uint crc_clk_src_spdif_out; /*_SPDIF_OUT_0, 0x108 */ - uint crc_clk_src_spdif_in; /*_SPDIF_IN_0, 0x10C */ - uint crc_clk_src_pwm; /*_PWM_0, 0x110 */ - uint crc_clk_src_spi1; /*_SPI1_0, 0x114 */ - uint crc_clk_src_sbc2; /*_SBC2_0, 0x118 */ - uint crc_clk_src_sbc3; /*_SBC3_0, 0x11C */ - uint crc_clk_src_xio; /*_XIO_0, 0x120 */ - uint crc_clk_src_i2c1; /*_I2C1_0, 0x124 */ - uint crc_clk_src_dvc_i2c; /*_DVC_I2C_0, 0x128 */ - uint crc_clk_src_twc; /*_TWC_0, 0x12C */ - uint crc_reserved12; /* 0x130 */ - uint crc_clk_src_sbc1; /*_SBC1_0, 0x134 */ - uint crc_clk_src_disp1; /*_DISP1_0, 0x138 */ - uint crc_clk_src_disp2; /*_DISP2_0, 0x13C */ - uint crc_clk_src_cve; /*_CVE_0, 0x140 */ - uint crc_clk_src_ide; /*_IDE_0, 0x144 */ - uint crc_clk_src_vi; /*_VI_0, 0x148 */ - uint crc_reserved13; /* 0x14C */ - uint crc_clk_src_sdmmc1; /*_SDMMC1_0, 0x150 */ - uint crc_clk_src_sdmmc2; /*_SDMMC2_0, 0x154 */ - uint crc_clk_src_g3d; /*_G3D_0, 0x158 */ - uint crc_clk_src_g2d; /*_G2D_0, 0x15C */ - uint crc_clk_src_ndflash; /*_NDFLASH_0, 0x160 */ - uint crc_clk_src_sdmmc4; /*_SDMMC4_0, 0x164 */ - uint crc_clk_src_vfir; /*_VFIR_0, 0x168 */ - uint crc_clk_src_epp; /*_EPP_0, 0x16C */ - uint crc_clk_src_mp3; /*_MPE_0, 0x170 */ - uint crc_clk_src_mipi; /*_MIPI_0, 0x174 */ - uint crc_clk_src_uarta; /*_UARTA_0, 0x178 */ - uint crc_clk_src_uartb; /*_UARTB_0, 0x17C */ - uint crc_clk_src_host1x; /*_HOST1X_0, 0x180 */ - uint crc_reserved14; /* 0x184 */ - uint crc_clk_src_tvo; /*_TVO_0, 0x188 */ - uint crc_clk_src_hdmi; /*_HDMI_0, 0x18C */ - uint crc_reserved15; /* 0x190 */ - uint crc_clk_src_tvdac; /*_TVDAC_0, 0x194 */ - uint crc_clk_src_i2c2; /*_I2C2_0, 0x198 */ - uint crc_clk_src_emc; /*_EMC_0, 0x19C */ - uint crc_clk_src_uartc; /*_UARTC_0, 0x1A0 */ - uint crc_reserved16; /* 0x1A4 */ - uint crc_clk_src_vi_sensor; /*_VI_SENSOR_0, 0x1A8 */ - uint crc_reserved17; /* 0x1AC */ - uint crc_reserved18; /* 0x1B0 */ - uint crc_clk_src_sbc4; /*_SBC4_0, 0x1B4 */ - uint crc_clk_src_i2c3; /*_I2C3_0, 0x1B8 */ - uint crc_clk_src_sdmmc3; /*_SDMMC3_0, 0x1BC */ - uint crc_clk_src_uartd; /*_UARTD_0, 0x1C0 */ - uint crc_clk_src_uarte; /*_UARTE_0, 0x1C4 */ - uint crc_clk_src_vde; /*_VDE_0, 0x1C8 */ - uint crc_clk_src_owr; /*_OWR_0, 0x1CC */ - uint crc_clk_src_nor; /*_NOR_0, 0x1D0 */ - uint crc_clk_src_csite; /*_CSITE_0, 0x1D4 */ - uint crc_reserved19[9]; /* 0x1D8-1F8 */ - uint crc_clk_src_osc; /*_OSC_0, 0x1FC */ + uint crc_clk_src[TEGRA_CLK_SOURCES]; /*_I2S1_0... 0x100-1fc */ uint crc_reserved20[80]; /* 0x200-33C */ - uint crc_cpu_cmplx_set; /* _CPU_CMPLX_SET_0, 0x340 */ - uint crc_cpu_cmplx_clr; /* _CPU_CMPLX_CLR_0, 0x344 */ + uint crc_cpu_cmplx_set; /* _CPU_CMPLX_SET_0, 0x340 */ + uint crc_cpu_cmplx_clr; /* _CPU_CMPLX_CLR_0, 0x344 */ }; /* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */ @@ -156,10 +104,13 @@ struct clk_rst_ctlr { #define PLL_BASE_OVRRIDE_MASK (1U << 28) #define PLL_DIVP_SHIFT 20 +#define PLL_DIVP_MASK (7U << PLL_DIVP_SHIFT) #define PLL_DIVN_SHIFT 8 +#define PLL_DIVN_MASK (0x3ffU << PLL_DIVN_SHIFT) #define PLL_DIVM_SHIFT 0 +#define PLL_DIVM_MASK (0x1f << PLL_DIVM_SHIFT) /* CLK_RST_CONTROLLER_PLLx_MISC_0 */ #define PLL_CPCON_SHIFT 8 @@ -168,9 +119,20 @@ struct clk_rst_ctlr { #define PLL_LFCON_SHIFT 4 #define PLLU_VCO_FREQ_SHIFT 20 +#define PLLU_VCO_FREQ_MASK (1U << PLLU_VCO_FREQ_SHIFT) /* CLK_RST_CONTROLLER_OSC_CTRL_0 */ #define OSC_FREQ_SHIFT 30 #define OSC_FREQ_MASK (3U << OSC_FREQ_SHIFT) +/* CLK_RST_CONTROLLER_CLK_SOURCE_x_OUT_0 */ +#define OUT_CLK_DIVISOR_SHIFT 0 +#define OUT_CLK_DIVISOR_MASK (255 << OUT_CLK_DIVISOR_SHIFT) + +#define OUT_CLK_SOURCE_SHIFT 30 +#define OUT_CLK_SOURCE_MASK (3U << OUT_CLK_SOURCE_SHIFT) + +#define OUT_CLK_SOURCE4_SHIFT 28 +#define OUT_CLK_SOURCE4_MASK (15U << OUT_CLK_SOURCE4_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 index d01aec8..49e9904 100644 --- a/arch/arm/include/asm/arch-tegra2/clock.h +++ b/arch/arm/include/asm/arch-tegra2/clock.h @@ -22,7 +22,7 @@ /* Tegra2 clock control functions */ #ifndef _CLOCK_H - +#define _CLOCK_H /* Set of oscillator frequencies supported in the internal API. */ enum clock_osc_freq { @@ -36,22 +36,27 @@ enum clock_osc_freq { }; /* 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, +enum clock_id { + CLOCK_ID_FIRST, + CLOCK_ID_CGENERAL = CLOCK_ID_FIRST, + CLOCK_ID_MEMORY, + CLOCK_ID_PERIPH, + CLOCK_ID_AUDIO, + CLOCK_ID_USB, + CLOCK_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_ID_FIRST_SIMPLE, + CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE, + CLOCK_ID_EPCI, + CLOCK_ID_SFROM32KHZ, + + /* These are the base clocks (inputs to the Tegra SOC) */ + CLOCK_ID_32KHZ, + CLOCK_ID_OSC, - CLOCK_PLL_ID_COUNT, + CLOCK_ID_COUNT, /* number of clocks */ + CLOCK_ID_NONE = -1, }; /* The clocks supported by the hardware */ @@ -80,7 +85,7 @@ enum periph_id { /* 16 */ PERIPH_ID_TWC, - PERIPH_ID_PWC, + PERIPH_ID_PWM, PERIPH_ID_I2S2, PERIPH_ID_EPP, PERIPH_ID_VI, @@ -181,12 +186,7 @@ enum periph_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) +#define clock_id_isvalid(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_ID_COUNT) /* PLL stabilization delay in usec */ #define CLOCK_PLL_STABLE_DELAY_US 300 @@ -194,7 +194,7 @@ enum periph_id { /* 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 @@ -206,7 +206,7 @@ enum clock_osc_freq clock_get_osc_freq(void); * * @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, +unsigned long clock_start_pll(enum clock_id id, u32 divm, u32 divn, u32 divp, u32 cpcon, u32 lfcon); /* @@ -217,6 +217,13 @@ unsigned long clock_start_pll(enum clock_pll_id id, u32 divm, u32 divn, void clock_enable(enum periph_id clkid); /* + * Disable a clock + * + * @param id clock id + */ +void clock_disable(enum periph_id clkid); + +/* * Set whether a clock is enabled or disabled. * * @param id clock id @@ -224,7 +231,7 @@ void clock_enable(enum periph_id clkid); */ 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. * @@ -233,7 +240,7 @@ void clock_set_enable(enum periph_id clkid, int enable); */ 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 @@ -251,7 +258,7 @@ enum crc_reset_id { 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) @@ -260,4 +267,94 @@ enum crc_reset_id { */ void reset_cmplx_set_enable(int cpu, int which, int reset); +/** + * Set the source for a peripheral clock. This plus the divisor sets the + * clock rate. You need to look up the datasheet to see the meaning of the + * source parameter as it changes for each peripheral. + * + * Warning: This function is only for use pre-relocation. Please use + * clock_start_periph_pll() instead. + * + * @param periph_id peripheral to adjust + * @param source source clock (0, 1, 2 or 3) + */ +void clock_ll_set_source(enum periph_id periph_id, unsigned source); + +/** + * Set the source and divisor for a peripheral clock. This sets the + * clock rate. You need to look up the datasheet to see the meaning of the + * source parameter as it changes for each peripheral. + * + * Warning: This function is only for use pre-relocation. Please use + * clock_start_periph_pll() instead. + * + * @param periph_id peripheral to adjust + * @param source source clock (0, 1, 2 or 3) + * @param divisor divisor value to use + */ +void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source, + unsigned divisor); + +/** + * Start a peripheral PLL clock at the given rate. This also resets the + * peripheral. + * + * @param periph_id peripheral to start + * @param parent PLL id of required parent clock + * @param rate Required clock rate in Hz + * @return rate selected in Hz, or -1U if something went wrong + */ +unsigned clock_start_periph_pll(enum periph_id periph_id, + enum clock_id parent, unsigned rate); + +/** + * Returns the rate of a peripheral clock in Hz. Since the caller almost + * certainly knows the parent clock (having just set it) we require that + * this be passed in so we don't need to work it out. + * + * @param periph_id peripheral to start + * @param parent PLL id of parent clock (used to calculate rate, you + * must know this!) + * @return clock rate of peripheral in Hz + */ +unsigned long clock_get_periph_rate(enum periph_id periph_id, + enum clock_id parent); + +/** + * Adjust peripheral PLL clock to the given rate. This does not reset the + * peripheral. If a second stage divisor is not available, pass NULL for + * extra_div. If it is available, then this parameter will return the + * divisor selected (which will be a power of 2 from 1 to 256). + * + * @param periph_id peripheral to start + * @param parent PLL id of required parent clock + * @param rate Required clock rate in Hz + * @param extra_div value for the second-stage divisor (NULL if one is + not available) + * @return rate selected in Hz, or -1U if something went wrong + */ +unsigned clock_adjust_periph_pll_div(enum periph_id periph_id, + enum clock_id parent, unsigned rate, int *extra_div); + +/** + * Returns the clock rate of a specified clock, in Hz. + * + * @param parent PLL id of clock to check + * @return rate of clock in Hz + */ +unsigned clock_get_rate(enum clock_id clkid); + +/* + * Checks that clocks are valid and prints a warning if not + * + * @return 0 if ok, -1 on error + */ +int clock_verify(void); + +/* Initialize the clocks */ +void clock_init(void); + +/* Initialize the PLLs */ +void clock_early_init(void); + #endif diff --git a/arch/arm/include/asm/arch-tegra2/pinmux.h b/arch/arm/include/asm/arch-tegra2/pinmux.h index b8a4753..469d742 100644 --- a/arch/arm/include/asm/arch-tegra2/pinmux.h +++ b/arch/arm/include/asm/arch-tegra2/pinmux.h @@ -24,173 +24,331 @@ #ifndef _PINMUX_H_ #define _PINMUX_H_ -/* Pins which we can set to tristate or normal */ -enum pmux_pin { +/* + * Pin groups which we adjust. There are three basic attributes of each pin + * group which use this enum: + * + * - function + * - pullup / pulldown + * - tristate or normal + */ +enum pmux_pingrp { /* APB_MISC_PP_TRISTATE_REG_A_0 */ - PIN_ATA, - PIN_ATB, - PIN_ATC, - PIN_ATD, - PIN_CDEV1, - PIN_CDEV2, - PIN_CSUS, - PIN_DAP1, - - PIN_DAP2, - PIN_DAP3, - PIN_DAP4, - PIN_DTA, - PIN_DTB, - PIN_DTC, - PIN_DTD, - PIN_DTE, - - PIN_GPU, - PIN_GPV, - PIN_I2CP, - PIN_IRTX, - PIN_IRRX, - PIN_KBCB, - PIN_KBCA, - PIN_PMC, - - PIN_PTA, - PIN_RM, - PIN_KBCE, - PIN_KBCF, - PIN_GMA, - PIN_GMC, - PIN_SDMMC1, - PIN_OWC, + PINGRP_ATA, + PINGRP_ATB, + PINGRP_ATC, + PINGRP_ATD, + PINGRP_CDEV1, + PINGRP_CDEV2, + PINGRP_CSUS, + PINGRP_DAP1, + + PINGRP_DAP2, + PINGRP_DAP3, + PINGRP_DAP4, + PINGRP_DTA, + PINGRP_DTB, + PINGRP_DTC, + PINGRP_DTD, + PINGRP_DTE, + + PINGRP_GPU, + PINGRP_GPV, + PINGRP_I2CP, + PINGRP_IRTX, + PINGRP_IRRX, + PINGRP_KBCB, + PINGRP_KBCA, + PINGRP_PMC, + + PINGRP_PTA, + PINGRP_RM, + PINGRP_KBCE, + PINGRP_KBCF, + PINGRP_GMA, + PINGRP_GMC, + PINGRP_SDMMC1, + PINGRP_OWC, /* 32: APB_MISC_PP_TRISTATE_REG_B_0 */ - PIN_GME, - PIN_SDC, - PIN_SDD, - PIN_RESERVED0, - PIN_SLXA, - PIN_SLXC, - PIN_SLXD, - PIN_SLXK, - - PIN_SPDI, - PIN_SPDO, - PIN_SPIA, - PIN_SPIB, - PIN_SPIC, - PIN_SPID, - PIN_SPIE, - PIN_SPIF, - - PIN_SPIG, - PIN_SPIH, - PIN_UAA, - PIN_UAB, - PIN_UAC, - PIN_UAD, - PIN_UCA, - PIN_UCB, - - PIN_RESERVED1, - PIN_ATE, - PIN_KBCC, - PIN_RESERVED2, - PIN_RESERVED3, - PIN_GMB, - PIN_GMD, - PIN_DDC, + PINGRP_GME, + PINGRP_SDC, + PINGRP_SDD, + PINGRP_RESERVED0, + PINGRP_SLXA, + PINGRP_SLXC, + PINGRP_SLXD, + PINGRP_SLXK, + + PINGRP_SPDI, + PINGRP_SPDO, + PINGRP_SPIA, + PINGRP_SPIB, + PINGRP_SPIC, + PINGRP_SPID, + PINGRP_SPIE, + PINGRP_SPIF, + + PINGRP_SPIG, + PINGRP_SPIH, + PINGRP_UAA, + PINGRP_UAB, + PINGRP_UAC, + PINGRP_UAD, + PINGRP_UCA, + PINGRP_UCB, + + PINGRP_RESERVED1, + PINGRP_ATE, + PINGRP_KBCC, + PINGRP_RESERVED2, + PINGRP_RESERVED3, + PINGRP_GMB, + PINGRP_GMD, + PINGRP_DDC, /* 64: APB_MISC_PP_TRISTATE_REG_C_0 */ - PIN_LD0, - PIN_LD1, - PIN_LD2, - PIN_LD3, - PIN_LD4, - PIN_LD5, - PIN_LD6, - PIN_LD7, - - PIN_LD8, - PIN_LD9, - PIN_LD10, - PIN_LD11, - PIN_LD12, - PIN_LD13, - PIN_LD14, - PIN_LD15, - - PIN_LD16, - PIN_LD17, - PIN_LHP0, - PIN_LHP1, - PIN_LHP2, - PIN_LVP0, - PIN_LVP1, - PIN_HDINT, - - PIN_LM0, - PIN_LM1, - PIN_LVS, - PIN_LSC0, - PIN_LSC1, - PIN_LSCK, - PIN_LDC, - PIN_LCSN, + PINGRP_LD0, + PINGRP_LD1, + PINGRP_LD2, + PINGRP_LD3, + PINGRP_LD4, + PINGRP_LD5, + PINGRP_LD6, + PINGRP_LD7, + + PINGRP_LD8, + PINGRP_LD9, + PINGRP_LD10, + PINGRP_LD11, + PINGRP_LD12, + PINGRP_LD13, + PINGRP_LD14, + PINGRP_LD15, + + PINGRP_LD16, + PINGRP_LD17, + PINGRP_LHP0, + PINGRP_LHP1, + PINGRP_LHP2, + PINGRP_LVP0, + PINGRP_LVP1, + PINGRP_HDINT, + + PINGRP_LM0, + PINGRP_LM1, + PINGRP_LVS, + PINGRP_LSC0, + PINGRP_LSC1, + PINGRP_LSCK, + PINGRP_LDC, + PINGRP_LCSN, /* 96: APB_MISC_PP_TRISTATE_REG_D_0 */ - PIN_LSPI, - PIN_LSDA, - PIN_LSDI, - PIN_LPW0, - PIN_LPW1, - PIN_LPW2, - PIN_LDI, - PIN_LHS, - - PIN_LPP, - PIN_RESERVED4, - PIN_KBCD, - PIN_GPU7, - PIN_DTF, - PIN_UDA, - PIN_CRTP, - PIN_SDB, + PINGRP_LSPI, + PINGRP_LSDA, + PINGRP_LSDI, + PINGRP_LPW0, + PINGRP_LPW1, + PINGRP_LPW2, + PINGRP_LDI, + PINGRP_LHS, + + PINGRP_LPP, + PINGRP_RESERVED4, + PINGRP_KBCD, + PINGRP_GPU7, + PINGRP_DTF, + PINGRP_UDA, + PINGRP_CRTP, + PINGRP_SDB, + + /* these pin groups only have pullup and pull down control */ + PINGRP_FIRST_NO_MUX, + PINGRP_CK32 = PINGRP_FIRST_NO_MUX, + PINGRP_DDRC, + PINGRP_PMCA, + PINGRP_PMCB, + PINGRP_PMCC, + PINGRP_PMCD, + PINGRP_PMCE, + PINGRP_XM2C, + PINGRP_XM2D, + + PINGRP_COUNT, }; +/* + * Functions which can be assigned to each of the pin groups. The values here + * bear no relation to the values programmed into pinmux registers and are + * purely a convenience. The translation is done through a table search. + */ +enum pmux_func { + PMUX_FUNC_AHB_CLK, + PMUX_FUNC_APB_CLK, + PMUX_FUNC_AUDIO_SYNC, + PMUX_FUNC_CRT, + PMUX_FUNC_DAP1, + PMUX_FUNC_DAP2, + PMUX_FUNC_DAP3, + PMUX_FUNC_DAP4, + PMUX_FUNC_DAP5, + PMUX_FUNC_DISPA, + PMUX_FUNC_DISPB, + PMUX_FUNC_EMC_TEST0_DLL, + PMUX_FUNC_EMC_TEST1_DLL, + PMUX_FUNC_GMI, + PMUX_FUNC_GMI_INT, + PMUX_FUNC_HDMI, + PMUX_FUNC_I2C, + PMUX_FUNC_I2C2, + PMUX_FUNC_I2C3, + PMUX_FUNC_IDE, + PMUX_FUNC_IRDA, + PMUX_FUNC_KBC, + PMUX_FUNC_MIO, + PMUX_FUNC_MIPI_HS, + PMUX_FUNC_NAND, + PMUX_FUNC_OSC, + PMUX_FUNC_OWR, + PMUX_FUNC_PCIE, + PMUX_FUNC_PLLA_OUT, + PMUX_FUNC_PLLC_OUT1, + PMUX_FUNC_PLLM_OUT1, + PMUX_FUNC_PLLP_OUT2, + PMUX_FUNC_PLLP_OUT3, + PMUX_FUNC_PLLP_OUT4, + PMUX_FUNC_PWM, + PMUX_FUNC_PWR_INTR, + PMUX_FUNC_PWR_ON, + PMUX_FUNC_RTCK, + PMUX_FUNC_SDIO1, + PMUX_FUNC_SDIO2, + PMUX_FUNC_SDIO3, + PMUX_FUNC_SDIO4, + PMUX_FUNC_SFLASH, + PMUX_FUNC_SPDIF, + PMUX_FUNC_SPI1, + PMUX_FUNC_SPI2, + PMUX_FUNC_SPI2_ALT, + PMUX_FUNC_SPI3, + PMUX_FUNC_SPI4, + PMUX_FUNC_TRACE, + PMUX_FUNC_TWC, + PMUX_FUNC_UARTA, + PMUX_FUNC_UARTB, + PMUX_FUNC_UARTC, + PMUX_FUNC_UARTD, + PMUX_FUNC_UARTE, + PMUX_FUNC_ULPI, + PMUX_FUNC_VI, + PMUX_FUNC_VI_SENSOR_CLK, + PMUX_FUNC_XIO, + PMUX_FUNC_SAFE, + + /* These don't have a name, but can be used in the table */ + PMUX_FUNC_RSVD1, + PMUX_FUNC_RSVD2, + PMUX_FUNC_RSVD3, + PMUX_FUNC_RSVD4, + PMUX_FUNC_RSVD, /* Not valid and should not be used */ -#define TEGRA_TRISTATE_REGS 4 + PMUX_FUNC_COUNT, + + PMUX_FUNC_NONE = -1, +}; + +/* return 1 if a pmux_func is in range */ +#define pmux_func_isvalid(func) ((func) >= 0 && (func) < PMUX_FUNC_COUNT && \ + (func) != PMUX_FUNC_RSVD) + +/* The pullup/pulldown state of a pin group */ +enum pmux_pull { + PMUX_PULL_NORMAL = 0, + PMUX_PULL_DOWN, + PMUX_PULL_UP, +}; + +/* Defines whether a pin group is tristated or in normal operation */ +enum pmux_tristate { + PMUX_TRI_NORMAL = 0, + PMUX_TRI_TRISTATE = 1, +}; + +/* Available power domains used by pin groups */ +enum pmux_vddio { + PMUX_VDDIO_BB = 0, + PMUX_VDDIO_LCD, + PMUX_VDDIO_VI, + PMUX_VDDIO_UART, + PMUX_VDDIO_DDR, + PMUX_VDDIO_NAND, + PMUX_VDDIO_SYS, + PMUX_VDDIO_AUDIO, + PMUX_VDDIO_SD, + + PMUX_VDDIO_NONE +}; + +enum { + PMUX_TRISTATE_REGS = 4, + PMUX_MUX_REGS = 7, + PMUX_PULL_REGS = 5, +}; /* APB MISC Pin Mux and Tristate (APB_MISC_PP_) registers */ struct pmux_tri_ctlr { uint pmt_reserved0; /* ABP_MISC_PP_ reserved offset 00 */ uint pmt_reserved1; /* ABP_MISC_PP_ reserved offset 04 */ - uint pmt_strap_opt_a; /* _STRAPPING_OPT_A_0, offset 08 */ + uint pmt_strap_opt_a; /* _STRAPPING_OPT_A_0, offset 08 */ uint pmt_reserved2; /* ABP_MISC_PP_ reserved offset 0C */ uint pmt_reserved3; /* ABP_MISC_PP_ reserved offset 10 */ - uint pmt_tri[TEGRA_TRISTATE_REGS]; /* _TRI_STATE_REG_A/B/C/D_0 14-20 */ - uint pmt_cfg_ctl; /* _CONFIG_CTL_0, offset 24 */ + uint pmt_tri[PMUX_TRISTATE_REGS];/* _TRI_STATE_REG_A/B/C/D_0 14-20 */ + uint pmt_cfg_ctl; /* _CONFIG_CTL_0, offset 24 */ uint pmt_reserved[22]; /* ABP_MISC_PP_ reserved offs 28-7C */ - uint pmt_ctl_a; /* _PIN_MUX_CTL_A_0, offset 80 */ - uint pmt_ctl_b; /* _PIN_MUX_CTL_B_0, offset 84 */ - uint pmt_ctl_c; /* _PIN_MUX_CTL_C_0, offset 88 */ - uint pmt_ctl_d; /* _PIN_MUX_CTL_D_0, offset 8C */ - uint pmt_ctl_e; /* _PIN_MUX_CTL_E_0, offset 90 */ - uint pmt_ctl_f; /* _PIN_MUX_CTL_F_0, offset 94 */ - uint pmt_ctl_g; /* _PIN_MUX_CTL_G_0, offset 98 */ + uint pmt_ctl[PMUX_MUX_REGS]; /* _PIN_MUX_CTL_A-G_0, offset 80 */ + uint pmt_reserved4; /* ABP_MISC_PP_ reserved offset 9c */ + uint pmt_pull[PMUX_PULL_REGS]; /* APB_MISC_PP_PULLUPDOWN_REG_A-E */ }; -/* Converts a pin number to a tristate register: 0=A, 1=B, 2=C, 3=D */ -#define TRISTATE_REG(id) ((id) >> 5) +/* + * This defines the configuration for a pin, including the function assigned, + * pull up/down settings and tristate settings. Having set up one of these + * you can call pinmux_config_pingroup() to configure a pin in one step. Also + * available is pinmux_config_table() to configure a list of pins. + */ +struct pingroup_config { + enum pmux_pingrp pingroup; /* pin group PINGRP_... */ + enum pmux_func func; /* function to assign FUNC_... */ + enum pmux_pull pull; /* pull up/down/normal PMUX_PULL_...*/ + enum pmux_tristate tristate; /* tristate or normal PMUX_TRI_... */ +}; + +/* Set a pin group to tristate */ +void pinmux_tristate_enable(enum pmux_pingrp pin); + +/* Set a pin group to normal (non tristate) */ +void pinmux_tristate_disable(enum pmux_pingrp pin); -/* Mask value for a tristate (within TRISTATE_REG(id)) */ -#define TRISTATE_MASK(id) (1 << ((id) & 0x1f)) +/* Set the pull up/down feature for a pin group */ +void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd); -/* Set a pin to tristate */ -void pinmux_tristate_enable(enum pmux_pin pin); +/* Set the mux function for a pin group */ +void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func); -/* Set a pin to normal (non tristate) */ -void pinmux_tristate_disable(enum pmux_pin pin); +/* Set the complete configuration for a pin group */ +void pinmux_config_pingroup(struct pingroup_config *config); + +void pinmux_set_tristate(enum pmux_pingrp pin, int enable); + +/** + * Configuure a list of pin groups + * + * @param config List of config items + * @param len Number of config items in list + */ +void pinmux_config_table(struct pingroup_config *config, int len); #endif /* PINMUX_H */ |