mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-arm
This commit is contained in:
commit
9cd9b34dc7
488 changed files with 18843 additions and 15350 deletions
|
@ -27,6 +27,10 @@ Poonam Aggrwal <poonam.aggrwal@freescale.com>
|
|||
|
||||
BSC9131RDB BSC9131
|
||||
|
||||
Naveen Burmi <NaveenBurmi@freescale.com>
|
||||
|
||||
BSC9132QDS BSC9132
|
||||
|
||||
Greg Allen <gallen@arlut.utexas.edu>
|
||||
|
||||
UTX8245 MPC8245
|
||||
|
@ -603,6 +607,7 @@ Enric Balletbo i Serra <eballetbo@iseebcn.com>
|
|||
|
||||
igep0020 ARM ARMV7 (OMAP3xx SoC)
|
||||
igep0030 ARM ARMV7 (OMAP3xx SoC)
|
||||
igep0032 ARM ARMV7 (OMAP3xx SoC)
|
||||
|
||||
Eric Benard <eric@eukrea.com>
|
||||
|
||||
|
@ -815,6 +820,9 @@ Dave Peverley <dpeverley@mpc-data.co.uk>
|
|||
|
||||
omap730p2 ARM926EJS
|
||||
|
||||
Lars Poeschel <poeschel@lemonage.de>
|
||||
pcm051 ARM ARMV7 (AM33xx Soc)
|
||||
|
||||
Mathieu Poirier <mathieu.poirier@linaro.org>
|
||||
|
||||
snowball ARM ARMV7 (u8500 SoC)
|
||||
|
|
18
Makefile
18
Makefile
|
@ -230,10 +230,6 @@ endif
|
|||
# U-Boot objects....order is important (i.e. start must be first)
|
||||
|
||||
OBJS = $(CPUDIR)/start.o
|
||||
ifeq ($(CPU),x86)
|
||||
RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/start16.o
|
||||
RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/resetvec.o
|
||||
endif
|
||||
ifeq ($(CPU),ppc4xx)
|
||||
OBJS += $(CPUDIR)/resetvec.o
|
||||
endif
|
||||
|
@ -241,7 +237,7 @@ ifeq ($(CPU),mpc85xx)
|
|||
OBJS += $(CPUDIR)/resetvec.o
|
||||
endif
|
||||
|
||||
OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))
|
||||
OBJS := $(addprefix $(obj),$(OBJS))
|
||||
|
||||
HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n)
|
||||
|
||||
|
@ -348,7 +344,7 @@ endif
|
|||
ifeq ($(SOC),exynos)
|
||||
LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o
|
||||
endif
|
||||
ifeq ($(SOC),tegra20)
|
||||
ifneq ($(CONFIG_TEGRA),)
|
||||
LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o
|
||||
LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o
|
||||
LIBS-y += $(CPUDIR)/tegra-common/libtegra-common.o
|
||||
|
@ -413,7 +409,7 @@ ALL-$(CONFIG_SPL) += $(obj)$(subst ",,$(CONFIG_SPL_TARGET))
|
|||
ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
|
||||
|
||||
# enable combined SPL/u-boot/dtb rules for tegra
|
||||
ifeq ($(SOC),tegra20)
|
||||
ifneq ($(CONFIG_TEGRA),)
|
||||
ifeq ($(CONFIG_OF_SEPARATE),y)
|
||||
ALL-y += $(obj)u-boot-dtb-tegra.bin
|
||||
else
|
||||
|
@ -485,8 +481,12 @@ $(obj)u-boot.sha1: $(obj)u-boot.bin
|
|||
$(obj)u-boot.dis: $(obj)u-boot
|
||||
$(OBJDUMP) -d $< > $@
|
||||
|
||||
|
||||
|
||||
$(obj)u-boot-with-spl.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
|
||||
$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
|
||||
$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(or $(CONFIG_SPL_PAD_TO),0) \
|
||||
-O binary $(obj)spl/u-boot-spl \
|
||||
$(obj)spl/u-boot-spl-pad.bin
|
||||
cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@
|
||||
rm $(obj)spl/u-boot-spl-pad.bin
|
||||
|
||||
|
@ -530,7 +530,7 @@ $(obj)u-boot.spr: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
|
|||
conv=notrunc 2>/dev/null
|
||||
cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
|
||||
|
||||
ifeq ($(SOC),tegra20)
|
||||
ifneq ($(CONFIG_TEGRA),)
|
||||
ifeq ($(CONFIG_OF_SEPARATE),y)
|
||||
nodtb=dtb
|
||||
dtbfile=$(obj)u-boot.dtb
|
||||
|
|
21
README
21
README
|
@ -2819,6 +2819,12 @@ FIT uImage format:
|
|||
CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
|
||||
Filename to read to load U-Boot when reading from FAT
|
||||
|
||||
CONFIG_SPL_MPC83XX_WAIT_FOR_NAND
|
||||
Set this for NAND SPL on PPC mpc83xx targets, so that
|
||||
start.S waits for the rest of the SPL to load before
|
||||
continuing (the hardware starts execution after just
|
||||
loading the first page rather than the full 4K).
|
||||
|
||||
CONFIG_SPL_NAND_BASE
|
||||
Include nand_base.c in the SPL. Requires
|
||||
CONFIG_SPL_NAND_DRIVERS.
|
||||
|
@ -2876,6 +2882,10 @@ FIT uImage format:
|
|||
CONFIG_SPL_LIBGENERIC_SUPPORT
|
||||
Support for lib/libgeneric.o in SPL binary
|
||||
|
||||
CONFIG_SPL_PAD_TO
|
||||
Linker address to which the SPL should be padded before
|
||||
appending the SPL payload.
|
||||
|
||||
CONFIG_SPL_TARGET
|
||||
Final target image containing SPL and payload. Some SPLs
|
||||
use an arch-specific makefile fragment instead, for
|
||||
|
@ -3806,14 +3816,9 @@ Low Level (hardware related) configuration options:
|
|||
be used if available. These functions may be faster under some
|
||||
conditions but may increase the binary size.
|
||||
|
||||
- CONFIG_X86_NO_RESET_VECTOR
|
||||
If defined, the x86 reset vector code is excluded. You will need
|
||||
to do this when U-Boot is running from Coreboot.
|
||||
|
||||
- CONFIG_X86_NO_REAL_MODE
|
||||
If defined, x86 real mode code is omitted. This assumes a
|
||||
32-bit environment where such code is not needed. You will
|
||||
need to do this when U-Boot is running from Coreboot.
|
||||
- CONFIG_X86_RESET_VECTOR
|
||||
If defined, the x86 reset vector code is included. This is not
|
||||
needed when U-Boot is running from Coreboot.
|
||||
|
||||
|
||||
Freescale QE/FMAN Firmware Support:
|
||||
|
|
|
@ -115,13 +115,13 @@ unsigned long long get_ticks(void)
|
|||
{
|
||||
ulong now = GPTCNT; /* current tick value */
|
||||
|
||||
if (now >= gd->lastinc) /* normal mode (non roll) */
|
||||
if (now >= gd->arch.lastinc) /* normal mode (non roll) */
|
||||
/* move stamp forward with absolut diff ticks */
|
||||
gd->tbl += (now - gd->lastinc);
|
||||
gd->arch.tbl += (now - gd->arch.lastinc);
|
||||
else /* we have rollover of incrementer */
|
||||
gd->tbl += (0xFFFFFFFF - gd->lastinc) + now;
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now;
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
|
|
|
@ -478,11 +478,11 @@ int get_clocks(void)
|
|||
{
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
#elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
||||
#else
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp (gd->tbl)
|
||||
#define lastinc (gd->lastinc)
|
||||
#define timestamp (gd->arch.tbl)
|
||||
#define lastinc (gd->arch.lastinc)
|
||||
|
||||
/* General purpose timers bitfields */
|
||||
#define GPTCR_SWR (1<<15) /* Software reset */
|
||||
|
|
|
@ -51,8 +51,8 @@ int timer_init (void)
|
|||
*((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val; /* start timer */
|
||||
|
||||
/* reset time */
|
||||
gd->lastinc = READ_TIMER; /* capture current incrementer value */
|
||||
gd->tbl = 0; /* start "advancing" time stamp */
|
||||
gd->arch.lastinc = READ_TIMER; /* capture current incrementer value */
|
||||
gd->arch.tbl = 0; /* start "advancing" time stamp */
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -81,8 +81,8 @@ void __udelay (unsigned long usec)
|
|||
tmp = get_timer (0); /* get current timestamp */
|
||||
if ((tmo + tmp + 1) < tmp) { /* if setting this forward will roll */
|
||||
/* time stamp, then reset time */
|
||||
gd->lastinc = READ_TIMER; /* capture incrementer value */
|
||||
gd->tbl = 0; /* start time stamp */
|
||||
gd->arch.lastinc = READ_TIMER; /* capture incrementer value */
|
||||
gd->arch.tbl = 0; /* start time stamp */
|
||||
} else {
|
||||
tmo += tmp; /* else, set advancing stamp wake up time */
|
||||
}
|
||||
|
@ -94,12 +94,15 @@ ulong get_timer_masked (void)
|
|||
{
|
||||
ulong now = READ_TIMER; /* current tick value */
|
||||
|
||||
if (now >= gd->lastinc) /* normal mode (non roll) */
|
||||
gd->tbl += (now - gd->lastinc); /* move stamp fordward with absoulte diff ticks */
|
||||
else /* we have rollover of incrementer */
|
||||
gd->tbl += (0xFFFFFFFF - gd->lastinc) + now;
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
if (now >= gd->arch.lastinc) { /* normal mode (non roll) */
|
||||
/* move stamp fordward with absoulte diff ticks */
|
||||
gd->arch.tbl += (now - gd->arch.lastinc);
|
||||
} else {
|
||||
/* we have rollover of incrementer */
|
||||
gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now;
|
||||
}
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/* waits specified delay value and resets timestamp */
|
||||
|
|
|
@ -28,6 +28,7 @@ include $(TOPDIR)/config.mk
|
|||
LIB = $(obj)libtegra-common.o
|
||||
|
||||
COBJS-$(CONFIG_SPL_BUILD) += spl.o
|
||||
COBJS-y += cpu.o
|
||||
|
||||
SRCS := $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS-y))
|
||||
|
|
333
arch/arm/cpu/arm720t/tegra-common/cpu.c
Normal file
333
arch/arm/cpu/arm720t/tegra-common/cpu.c
Normal file
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/gp_padctrl.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/clk_rst.h>
|
||||
#include <asm/arch-tegra/pmc.h>
|
||||
#include <asm/arch-tegra/scu.h>
|
||||
#include "cpu.h"
|
||||
|
||||
int get_num_cpus(void)
|
||||
{
|
||||
struct apb_misc_gp_ctlr *gp;
|
||||
uint rev;
|
||||
|
||||
gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
|
||||
rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
|
||||
|
||||
switch (rev) {
|
||||
case CHIPID_TEGRA20:
|
||||
return 2;
|
||||
break;
|
||||
case CHIPID_TEGRA30:
|
||||
case CHIPID_TEGRA114:
|
||||
default:
|
||||
return 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Timing tables for each SOC for all four oscillator options.
|
||||
*/
|
||||
struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
|
||||
/* T20: 1 GHz */
|
||||
/* n, m, p, cpcon */
|
||||
{{ 1000, 13, 0, 12}, /* OSC 13M */
|
||||
{ 625, 12, 0, 8}, /* OSC 19.2M */
|
||||
{ 1000, 12, 0, 12}, /* OSC 12M */
|
||||
{ 1000, 26, 0, 12}, /* OSC 26M */
|
||||
},
|
||||
|
||||
/* T25: 1.2 GHz */
|
||||
{{ 923, 10, 0, 12},
|
||||
{ 750, 12, 0, 8},
|
||||
{ 600, 6, 0, 12},
|
||||
{ 600, 13, 0, 12},
|
||||
},
|
||||
|
||||
/* T30: 1.4 GHz */
|
||||
{{ 862, 8, 0, 8},
|
||||
{ 583, 8, 0, 4},
|
||||
{ 700, 6, 0, 8},
|
||||
{ 700, 13, 0, 8},
|
||||
},
|
||||
|
||||
/* T114: 1.4 GHz */
|
||||
{{ 862, 8, 0, 8},
|
||||
{ 583, 8, 0, 4},
|
||||
{ 696, 12, 0, 8},
|
||||
{ 700, 13, 0, 8},
|
||||
},
|
||||
};
|
||||
|
||||
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[0]); /* 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[0]);
|
||||
|
||||
reg = readl(&pll->pll_out[1]); /* 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[1]);
|
||||
}
|
||||
|
||||
int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm,
|
||||
u32 divp, u32 cpcon)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
/* If PLLX is already enabled, just return */
|
||||
if (readl(&pll->pll_base) & PLL_ENABLE_MASK) {
|
||||
debug("pllx_set_rate: PLLX already enabled, returning\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug(" pllx_set_rate entry\n");
|
||||
|
||||
/* Set BYPASS, m, n and p to PLLX_BASE */
|
||||
reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT);
|
||||
reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT));
|
||||
writel(reg, &pll->pll_base);
|
||||
|
||||
/* Set cpcon to PLLX_MISC */
|
||||
reg = (cpcon << PLL_CPCON_SHIFT);
|
||||
|
||||
/* Set dccon to PLLX_MISC if freq > 600MHz */
|
||||
if (divn > 600)
|
||||
reg |= (1 << PLL_DCCON_SHIFT);
|
||||
writel(reg, &pll->pll_misc);
|
||||
|
||||
/* Enable PLLX */
|
||||
reg = readl(&pll->pll_base);
|
||||
reg |= PLL_ENABLE_MASK;
|
||||
|
||||
/* Disable BYPASS */
|
||||
reg &= ~PLL_BYPASS_MASK;
|
||||
writel(reg, &pll->pll_base);
|
||||
|
||||
/* Set lock_enable to PLLX_MISC */
|
||||
reg = readl(&pll->pll_misc);
|
||||
reg |= PLL_LOCK_ENABLE_MASK;
|
||||
writel(reg, &pll->pll_misc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_pllx(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX];
|
||||
int chip_type;
|
||||
enum clock_osc_freq osc;
|
||||
struct clk_pll_table *sel;
|
||||
|
||||
debug("init_pllx entry\n");
|
||||
|
||||
/* get chip type */
|
||||
chip_type = tegra_get_chip_type();
|
||||
debug(" init_pllx: chip_type = %d\n", chip_type);
|
||||
|
||||
/* get osc freq */
|
||||
osc = clock_get_osc_freq();
|
||||
debug(" init_pllx: osc = %d\n", osc);
|
||||
|
||||
/* set pllx */
|
||||
sel = &tegra_pll_x_table[chip_type][osc];
|
||||
pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon);
|
||||
|
||||
/* adjust PLLP_out1-4 on T30/T114 */
|
||||
if (chip_type == TEGRA_SOC_T30 || chip_type == TEGRA_SOC_T114) {
|
||||
debug(" init_pllx: adjusting PLLP out freqs\n");
|
||||
adjust_pllp_out_freqs();
|
||||
}
|
||||
}
|
||||
|
||||
void enable_cpu_clock(int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 clk;
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* Regardless of whether the request is to enable or disable the CPU
|
||||
* clock, every processor in the CPU complex except the master (CPU 0)
|
||||
* will have it's clock stopped because the AVP only talks to the
|
||||
* master.
|
||||
*/
|
||||
|
||||
if (enable) {
|
||||
/* Initialize PLLX */
|
||||
init_pllx();
|
||||
|
||||
/* Wait until all clocks are stable */
|
||||
udelay(PLL_STABILIZATION_DELAY);
|
||||
|
||||
writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
|
||||
writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the register containing the individual CPU clock enables and
|
||||
* always stop the clocks to CPUs > 0.
|
||||
*/
|
||||
clk = readl(&clkrst->crc_clk_cpu_cmplx);
|
||||
clk |= 1 << CPU1_CLK_STP_SHIFT;
|
||||
if (get_num_cpus() == 4)
|
||||
clk |= (1 << CPU2_CLK_STP_SHIFT) + (1 << CPU3_CLK_STP_SHIFT);
|
||||
|
||||
/* Stop/Unstop the CPU clock */
|
||||
clk &= ~CPU0_CLK_STP_MASK;
|
||||
clk |= !enable << CPU0_CLK_STP_SHIFT;
|
||||
writel(clk, &clkrst->crc_clk_cpu_cmplx);
|
||||
|
||||
clock_enable(PERIPH_ID_CPU);
|
||||
}
|
||||
|
||||
static int is_cpu_powered(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
|
||||
return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void remove_cpu_io_clamps(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
u32 reg;
|
||||
|
||||
/* Remove the clamps on the CPU I/O signals */
|
||||
reg = readl(&pmc->pmc_remove_clamping);
|
||||
reg |= CPU_CLMP;
|
||||
writel(reg, &pmc->pmc_remove_clamping);
|
||||
|
||||
/* Give I/O signals time to stabilize */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
}
|
||||
|
||||
void powerup_cpu(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
u32 reg;
|
||||
int timeout = IO_STABILIZATION_DELAY;
|
||||
|
||||
if (!is_cpu_powered()) {
|
||||
/* Toggle the CPU power state (OFF -> ON) */
|
||||
reg = readl(&pmc->pmc_pwrgate_toggle);
|
||||
reg &= PARTID_CP;
|
||||
reg |= START_CP;
|
||||
writel(reg, &pmc->pmc_pwrgate_toggle);
|
||||
|
||||
/* Wait for the power to come up */
|
||||
while (!is_cpu_powered()) {
|
||||
if (timeout-- == 0)
|
||||
printf("CPU failed to power up!\n");
|
||||
else
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the I/O clamps from CPU power partition.
|
||||
* Recommended only on a Warm boot, if the CPU partition gets
|
||||
* power gated. Shouldn't cause any harm when called after a
|
||||
* cold boot according to HW, probably just redundant.
|
||||
*/
|
||||
remove_cpu_io_clamps();
|
||||
}
|
||||
}
|
||||
|
||||
void reset_A9_cpu(int reset)
|
||||
{
|
||||
/*
|
||||
* NOTE: Regardless of whether the request is to hold the CPU in reset
|
||||
* or take it out of reset, every processor in the CPU complex
|
||||
* except the master (CPU 0) will be held in reset because the
|
||||
* AVP only talks to the master. The AVP does not know that there
|
||||
* are multiple processors in the CPU complex.
|
||||
*/
|
||||
int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug;
|
||||
int num_cpus = get_num_cpus();
|
||||
int cpu;
|
||||
|
||||
debug("reset_a9_cpu entry\n");
|
||||
/* Hold CPUs 1 onwards in reset, and CPU 0 if asked */
|
||||
for (cpu = 1; cpu < num_cpus; cpu++)
|
||||
reset_cmplx_set_enable(cpu, mask, 1);
|
||||
reset_cmplx_set_enable(0, mask, reset);
|
||||
|
||||
/* Enable/Disable master CPU reset */
|
||||
reset_set_enable(PERIPH_ID_CPU, reset);
|
||||
}
|
||||
|
||||
void clock_enable_coresight(int enable)
|
||||
{
|
||||
u32 rst, src = 2;
|
||||
int chip;
|
||||
|
||||
debug("clock_enable_coresight entry\n");
|
||||
clock_set_enable(PERIPH_ID_CORESIGHT, enable);
|
||||
reset_set_enable(PERIPH_ID_CORESIGHT, !enable);
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
* Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by
|
||||
* 1.5, giving an effective frequency of 144MHz.
|
||||
* Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor
|
||||
* (bits 7:0), so 00000001b == 1.5 (n+1 + .5)
|
||||
*
|
||||
* Clock divider request for 204MHz would setup CSITE clock as
|
||||
* 144MHz for PLLP base 216MHz and 204MHz for PLLP base 408MHz
|
||||
*/
|
||||
chip = tegra_get_chip_type();
|
||||
if (chip == TEGRA_SOC_T30 || chip == TEGRA_SOC_T114)
|
||||
src = CLK_DIVIDER(NVBL_PLLP_KHZ, 204000);
|
||||
else if (chip == TEGRA_SOC_T20 || chip == TEGRA_SOC_T25)
|
||||
src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000);
|
||||
else
|
||||
printf("%s: Unknown chip type %X!\n", __func__, chip);
|
||||
clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src);
|
||||
|
||||
/* Unlock the CPU CoreSight interfaces */
|
||||
rst = CORESIGHT_UNLOCK;
|
||||
writel(rst, CSITE_CPU_DBG0_LAR);
|
||||
writel(rst, CSITE_CPU_DBG1_LAR);
|
||||
if (get_num_cpus() == 4) {
|
||||
writel(rst, CSITE_CPU_DBG2_LAR);
|
||||
writel(rst, CSITE_CPU_DBG3_LAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void halt_avp(void)
|
||||
{
|
||||
for (;;) {
|
||||
writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \
|
||||
| HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)),
|
||||
FLOW_CTLR_HALT_COP_EVENTS);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,13 @@
|
|||
#define PLL_STABILIZATION_DELAY (300)
|
||||
#define IO_STABILIZATION_DELAY (1000)
|
||||
|
||||
#if defined(CONFIG_TEGRA20)
|
||||
#define NVBL_PLLP_KHZ (216000)
|
||||
#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114)
|
||||
#define NVBL_PLLP_KHZ (408000)
|
||||
#else
|
||||
#error "Unknown Tegra chip!"
|
||||
#endif
|
||||
|
||||
#define PLLX_ENABLED (1 << 30)
|
||||
#define CCLK_BURST_POLICY 0x20008888
|
||||
|
@ -44,50 +50,11 @@
|
|||
|
||||
#define CORESIGHT_UNLOCK 0xC5ACCE55;
|
||||
|
||||
/* AP20-Specific Base Addresses */
|
||||
|
||||
/* AP20 Base physical address of SDRAM. */
|
||||
#define AP20_BASE_PA_SDRAM 0x00000000
|
||||
/* AP20 Base physical address of internal SRAM. */
|
||||
#define AP20_BASE_PA_SRAM 0x40000000
|
||||
/* AP20 Size of internal SRAM (256KB). */
|
||||
#define AP20_BASE_PA_SRAM_SIZE 0x00040000
|
||||
/* AP20 Base physical address of flash. */
|
||||
#define AP20_BASE_PA_NOR_FLASH 0xD0000000
|
||||
/* AP20 Base physical address of boot information table. */
|
||||
#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM
|
||||
|
||||
/*
|
||||
* Super-temporary stacks for EXTREMELY early startup. The values chosen for
|
||||
* these addresses must be valid on ALL SOCs because this value is used before
|
||||
* we are able to differentiate between the SOC types.
|
||||
*
|
||||
* NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its
|
||||
* stack is placed below the AVP stack. Once the CPU stack has been moved,
|
||||
* the AVP is free to use the IRAM the CPU stack previously occupied if
|
||||
* it should need to do so.
|
||||
*
|
||||
* NOTE: In multi-processor CPU complex configurations, each processor will have
|
||||
* its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a
|
||||
* limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a
|
||||
* stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous
|
||||
* CPU.
|
||||
*/
|
||||
|
||||
/* Common AVP early boot stack limit */
|
||||
#define AVP_EARLY_BOOT_STACK_LIMIT \
|
||||
(AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2))
|
||||
/* Common AVP early boot stack size */
|
||||
#define AVP_EARLY_BOOT_STACK_SIZE 0x1000
|
||||
/* Common CPU early boot stack limit */
|
||||
#define CPU_EARLY_BOOT_STACK_LIMIT \
|
||||
(AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE)
|
||||
/* Common CPU early boot stack size */
|
||||
#define CPU_EARLY_BOOT_STACK_SIZE 0x1000
|
||||
|
||||
#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100)
|
||||
#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0)
|
||||
#define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0)
|
||||
#define CSITE_CPU_DBG2_LAR (NV_PA_CSITE_BASE + 0x14FB0)
|
||||
#define CSITE_CPU_DBG3_LAR (NV_PA_CSITE_BASE + 0x16FB0)
|
||||
|
||||
#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4)
|
||||
#define FLOW_MODE_STOP 2
|
||||
|
@ -95,6 +62,23 @@
|
|||
#define HALT_COP_EVENT_IRQ_1 (1 << 11)
|
||||
#define HALT_COP_EVENT_FIQ_1 (1 << 9)
|
||||
|
||||
void start_cpu(u32 reset_vector);
|
||||
int ap20_cpu_is_cortexa9(void);
|
||||
#define FLOW_MODE_NONE 0
|
||||
|
||||
#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE)
|
||||
|
||||
struct clk_pll_table {
|
||||
u16 n;
|
||||
u16 m;
|
||||
u8 p;
|
||||
u8 cpcon;
|
||||
};
|
||||
|
||||
void clock_enable_coresight(int enable);
|
||||
void enable_cpu_clock(int enable);
|
||||
void halt_avp(void) __attribute__ ((noreturn));
|
||||
void init_pllx(void);
|
||||
void powerup_cpu(void);
|
||||
void reset_A9_cpu(int reset);
|
||||
void start_cpu(u32 reset_vector);
|
||||
int tegra_get_chip_type(void);
|
||||
void adjust_pllp_out_freqs(void);
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
#include "cpu.h"
|
||||
#include <spl.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
@ -32,7 +31,7 @@
|
|||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/board.h>
|
||||
#include <asm/arch/spl.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
|
|
42
arch/arm/cpu/arm720t/tegra114/Makefile
Normal file
42
arch/arm/cpu/arm720t/tegra114/Makefile
Normal file
|
@ -0,0 +1,42 @@
|
|||
#
|
||||
# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2000-2008
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
#COBJS-y += cpu.o t11x.o
|
||||
COBJS-y += cpu.o
|
||||
|
||||
SRCS := $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
19
arch/arm/cpu/arm720t/tegra114/config.mk
Normal file
19
arch/arm/cpu/arm720t/tegra114/config.mk
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
USE_PRIVATE_LIBGCC = yes
|
297
arch/arm/cpu/arm720t/tegra114/cpu.c
Normal file
297
arch/arm/cpu/arm720t/tegra114/cpu.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/flow.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/clk_rst.h>
|
||||
#include <asm/arch-tegra/pmc.h>
|
||||
#include "../tegra-common/cpu.h"
|
||||
|
||||
/* Tegra114-specific CPU init code */
|
||||
static void enable_cpu_power_rail(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 reg;
|
||||
|
||||
debug("enable_cpu_power_rail entry\n");
|
||||
|
||||
/* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */
|
||||
pinmux_tristate_disable(PINGRP_PWR_I2C_SCL);
|
||||
pinmux_tristate_disable(PINGRP_PWR_I2C_SDA);
|
||||
|
||||
/*
|
||||
* Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz),
|
||||
* set it for 25ms (102MHz * .025)
|
||||
*/
|
||||
reg = 0x26E8F0;
|
||||
writel(reg, &pmc->pmc_cpupwrgood_timer);
|
||||
|
||||
/* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */
|
||||
clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL);
|
||||
setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE);
|
||||
|
||||
/*
|
||||
* Set CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0_CAR2PMC_CPU_ACK_WIDTH
|
||||
* to 408 to satisfy the requirement of having at least 16 CPU clock
|
||||
* cycles before clamp removal.
|
||||
*/
|
||||
|
||||
clrbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 0xFFF);
|
||||
setbits_le32(&clkrst->crc_cpu_softrst_ctrl2, 408);
|
||||
}
|
||||
|
||||
static void enable_cpu_clocks(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 reg;
|
||||
|
||||
debug("enable_cpu_clocks entry\n");
|
||||
|
||||
/* Wait for PLL-X to lock */
|
||||
do {
|
||||
reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
|
||||
} while ((reg & (1 << 27)) == 0);
|
||||
|
||||
/* Wait until all clocks are stable */
|
||||
udelay(PLL_STABILIZATION_DELAY);
|
||||
|
||||
writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
|
||||
writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
|
||||
|
||||
/* Always enable the main CPU complex clocks */
|
||||
clock_enable(PERIPH_ID_CPU);
|
||||
clock_enable(PERIPH_ID_CPULP);
|
||||
clock_enable(PERIPH_ID_CPUG);
|
||||
}
|
||||
|
||||
static void remove_cpu_resets(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 reg;
|
||||
|
||||
debug("remove_cpu_resets entry\n");
|
||||
/* Take the slow non-CPU partition out of reset */
|
||||
reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr);
|
||||
writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpulp_cmplx_clr);
|
||||
|
||||
/* Take the fast non-CPU partition out of reset */
|
||||
reg = readl(&clkrst->crc_rst_cpug_cmplx_clr);
|
||||
writel((reg | CLR_NONCPURESET), &clkrst->crc_rst_cpug_cmplx_clr);
|
||||
|
||||
/* Clear the SW-controlled reset of the slow cluster */
|
||||
reg = readl(&clkrst->crc_rst_cpulp_cmplx_clr);
|
||||
reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0);
|
||||
writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr);
|
||||
|
||||
/* Clear the SW-controlled reset of the fast cluster */
|
||||
reg = readl(&clkrst->crc_rst_cpug_cmplx_clr);
|
||||
reg |= (CLR_CPURESET0+CLR_DBGRESET0+CLR_CORERESET0+CLR_CXRESET0);
|
||||
reg |= (CLR_CPURESET1+CLR_DBGRESET1+CLR_CORERESET1+CLR_CXRESET1);
|
||||
reg |= (CLR_CPURESET2+CLR_DBGRESET2+CLR_CORERESET2+CLR_CXRESET2);
|
||||
reg |= (CLR_CPURESET3+CLR_DBGRESET3+CLR_CORERESET3+CLR_CXRESET3);
|
||||
writel(reg, &clkrst->crc_rst_cpug_cmplx_clr);
|
||||
}
|
||||
|
||||
/**
|
||||
* The T114 requires some special clock initialization, including setting up
|
||||
* the DVC I2C, turning on MSELECT and selecting the G CPU cluster
|
||||
*/
|
||||
void t114_init_clocks(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
|
||||
u32 val;
|
||||
|
||||
debug("t114_init_clocks entry\n");
|
||||
|
||||
/* Set active CPU cluster to G */
|
||||
clrbits_le32(&flow->cluster_control, 1);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
|
||||
(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
|
||||
writel(val, &clkrst->crc_sclk_brst_pol);
|
||||
|
||||
writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
|
||||
|
||||
debug("Setting up PLLX\n");
|
||||
init_pllx();
|
||||
|
||||
val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT);
|
||||
writel(val, &clkrst->crc_clk_sys_rate);
|
||||
|
||||
/* Enable clocks to required peripherals. TBD - minimize this list */
|
||||
debug("Enabling clocks\n");
|
||||
|
||||
clock_set_enable(PERIPH_ID_CACHE2, 1);
|
||||
clock_set_enable(PERIPH_ID_GPIO, 1);
|
||||
clock_set_enable(PERIPH_ID_TMR, 1);
|
||||
clock_set_enable(PERIPH_ID_RTC, 1);
|
||||
clock_set_enable(PERIPH_ID_CPU, 1);
|
||||
clock_set_enable(PERIPH_ID_EMC, 1);
|
||||
clock_set_enable(PERIPH_ID_I2C5, 1);
|
||||
clock_set_enable(PERIPH_ID_FUSE, 1);
|
||||
clock_set_enable(PERIPH_ID_PMC, 1);
|
||||
clock_set_enable(PERIPH_ID_APBDMA, 1);
|
||||
clock_set_enable(PERIPH_ID_MEM, 1);
|
||||
clock_set_enable(PERIPH_ID_IRAMA, 1);
|
||||
clock_set_enable(PERIPH_ID_IRAMB, 1);
|
||||
clock_set_enable(PERIPH_ID_IRAMC, 1);
|
||||
clock_set_enable(PERIPH_ID_IRAMD, 1);
|
||||
clock_set_enable(PERIPH_ID_CORESIGHT, 1);
|
||||
clock_set_enable(PERIPH_ID_MSELECT, 1);
|
||||
clock_set_enable(PERIPH_ID_EMC1, 1);
|
||||
clock_set_enable(PERIPH_ID_MC1, 1);
|
||||
clock_set_enable(PERIPH_ID_DVFS, 1);
|
||||
|
||||
/* Switch MSELECT clock to PLLP (00) */
|
||||
clock_ll_set_source(PERIPH_ID_MSELECT, 0);
|
||||
|
||||
/*
|
||||
* Clock divider request for 102MHz would setup MSELECT clock as
|
||||
* 102MHz for PLLP base 408MHz
|
||||
*/
|
||||
clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0,
|
||||
(NVBL_PLLP_KHZ/102000));
|
||||
|
||||
/* I2C5 (DVC) gets CLK_M and a divisor of 17 */
|
||||
clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16);
|
||||
|
||||
/* Give clocks time to stabilize */
|
||||
udelay(1000);
|
||||
|
||||
/* Take required peripherals out of reset */
|
||||
debug("Taking periphs out of reset\n");
|
||||
reset_set_enable(PERIPH_ID_CACHE2, 0);
|
||||
reset_set_enable(PERIPH_ID_GPIO, 0);
|
||||
reset_set_enable(PERIPH_ID_TMR, 0);
|
||||
reset_set_enable(PERIPH_ID_COP, 0);
|
||||
reset_set_enable(PERIPH_ID_EMC, 0);
|
||||
reset_set_enable(PERIPH_ID_I2C5, 0);
|
||||
reset_set_enable(PERIPH_ID_FUSE, 0);
|
||||
reset_set_enable(PERIPH_ID_APBDMA, 0);
|
||||
reset_set_enable(PERIPH_ID_MEM, 0);
|
||||
reset_set_enable(PERIPH_ID_CORESIGHT, 0);
|
||||
reset_set_enable(PERIPH_ID_MSELECT, 0);
|
||||
reset_set_enable(PERIPH_ID_EMC1, 0);
|
||||
reset_set_enable(PERIPH_ID_MC1, 0);
|
||||
|
||||
debug("t114_init_clocks exit\n");
|
||||
}
|
||||
|
||||
static int is_partition_powered(u32 mask)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
u32 reg;
|
||||
|
||||
/* Get power gate status */
|
||||
reg = readl(&pmc->pmc_pwrgate_status);
|
||||
return (reg & mask) == mask;
|
||||
}
|
||||
|
||||
static int is_clamp_enabled(u32 mask)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
u32 reg;
|
||||
|
||||
/* Get clamp status. TODO: Add pmc_clamp_status alias to pmc.h */
|
||||
reg = readl(&pmc->pmc_pwrgate_timer_on);
|
||||
return (reg & mask) == mask;
|
||||
}
|
||||
|
||||
static void power_partition(u32 status, u32 partid)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
|
||||
debug("%s: status = %08X, part ID = %08X\n", __func__, status, partid);
|
||||
/* Is the partition already on? */
|
||||
if (!is_partition_powered(status)) {
|
||||
/* No, toggle the partition power state (OFF -> ON) */
|
||||
debug("power_partition, toggling state\n");
|
||||
clrbits_le32(&pmc->pmc_pwrgate_toggle, 0x1F);
|
||||
setbits_le32(&pmc->pmc_pwrgate_toggle, partid);
|
||||
setbits_le32(&pmc->pmc_pwrgate_toggle, START_CP);
|
||||
|
||||
/* Wait for the power to come up */
|
||||
while (!is_partition_powered(status))
|
||||
;
|
||||
|
||||
/* Wait for the clamp status to be cleared */
|
||||
while (is_clamp_enabled(status))
|
||||
;
|
||||
|
||||
/* Give I/O signals time to stabilize */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void powerup_cpus(void)
|
||||
{
|
||||
debug("powerup_cpus entry\n");
|
||||
|
||||
/* We boot to the fast cluster */
|
||||
debug("powerup_cpus entry: G cluster\n");
|
||||
/* Power up the fast cluster rail partition */
|
||||
power_partition(CRAIL, CRAILID);
|
||||
|
||||
/* Power up the fast cluster non-CPU partition */
|
||||
power_partition(C0NC, C0NCID);
|
||||
|
||||
/* Power up the fast cluster CPU0 partition */
|
||||
power_partition(CE0, CE0ID);
|
||||
}
|
||||
|
||||
void start_cpu(u32 reset_vector)
|
||||
{
|
||||
debug("start_cpu entry, reset_vector = %x\n", reset_vector);
|
||||
|
||||
t114_init_clocks();
|
||||
|
||||
/* Enable VDD_CPU */
|
||||
enable_cpu_power_rail();
|
||||
|
||||
/* Get the CPU(s) running */
|
||||
enable_cpu_clocks();
|
||||
|
||||
/* Enable CoreSight */
|
||||
clock_enable_coresight(1);
|
||||
|
||||
/* Take CPU(s) out of reset */
|
||||
remove_cpu_resets();
|
||||
|
||||
/*
|
||||
* Set the entry point for CPU execution from reset,
|
||||
* if it's a non-zero value.
|
||||
*/
|
||||
if (reset_vector)
|
||||
writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
|
||||
|
||||
/* If the CPU(s) don't already have power, power 'em up */
|
||||
powerup_cpus();
|
||||
}
|
|
@ -1,160 +1,25 @@
|
|||
/*
|
||||
* (C) Copyright 2010-2011
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
* Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/clk_rst.h>
|
||||
#include <asm/arch-tegra/pmc.h>
|
||||
#include <asm/arch-tegra/scu.h>
|
||||
#include "../tegra-common/cpu.h"
|
||||
|
||||
/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */
|
||||
int ap20_cpu_is_cortexa9(void)
|
||||
{
|
||||
u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0);
|
||||
return id == (PG_UP_TAG_0_PID_CPU & 0xff);
|
||||
}
|
||||
|
||||
void init_pllx(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU];
|
||||
u32 reg;
|
||||
|
||||
/* If PLLX is already enabled, just return */
|
||||
if (readl(&pll->pll_base) & PLL_ENABLE_MASK)
|
||||
return;
|
||||
|
||||
/* Set PLLX_MISC */
|
||||
writel(1 << PLL_CPCON_SHIFT, &pll->pll_misc);
|
||||
|
||||
/* Use 12MHz clock here */
|
||||
reg = PLL_BYPASS_MASK | (12 << PLL_DIVM_SHIFT);
|
||||
reg |= 1000 << PLL_DIVN_SHIFT;
|
||||
writel(reg, &pll->pll_base);
|
||||
|
||||
reg |= PLL_ENABLE_MASK;
|
||||
writel(reg, &pll->pll_base);
|
||||
|
||||
reg &= ~PLL_BYPASS_MASK;
|
||||
writel(reg, &pll->pll_base);
|
||||
}
|
||||
|
||||
static void enable_cpu_clock(int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 clk;
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* Regardless of whether the request is to enable or disable the CPU
|
||||
* clock, every processor in the CPU complex except the master (CPU 0)
|
||||
* will have it's clock stopped because the AVP only talks to the
|
||||
* master. The AVP does not know (nor does it need to know) that there
|
||||
* are multiple processors in the CPU complex.
|
||||
*/
|
||||
|
||||
if (enable) {
|
||||
/* Initialize PLLX */
|
||||
init_pllx();
|
||||
|
||||
/* Wait until all clocks are stable */
|
||||
udelay(PLL_STABILIZATION_DELAY);
|
||||
|
||||
writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
|
||||
writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the register containing the individual CPU clock enables and
|
||||
* always stop the clock to CPU 1.
|
||||
*/
|
||||
clk = readl(&clkrst->crc_clk_cpu_cmplx);
|
||||
clk |= 1 << CPU1_CLK_STP_SHIFT;
|
||||
|
||||
/* Stop/Unstop the CPU clock */
|
||||
clk &= ~CPU0_CLK_STP_MASK;
|
||||
clk |= !enable << CPU0_CLK_STP_SHIFT;
|
||||
writel(clk, &clkrst->crc_clk_cpu_cmplx);
|
||||
|
||||
clock_enable(PERIPH_ID_CPU);
|
||||
}
|
||||
|
||||
static int is_cpu_powered(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
|
||||
return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void remove_cpu_io_clamps(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
u32 reg;
|
||||
|
||||
/* Remove the clamps on the CPU I/O signals */
|
||||
reg = readl(&pmc->pmc_remove_clamping);
|
||||
reg |= CPU_CLMP;
|
||||
writel(reg, &pmc->pmc_remove_clamping);
|
||||
|
||||
/* Give I/O signals time to stabilize */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
}
|
||||
|
||||
static void powerup_cpu(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
u32 reg;
|
||||
int timeout = IO_STABILIZATION_DELAY;
|
||||
|
||||
if (!is_cpu_powered()) {
|
||||
/* Toggle the CPU power state (OFF -> ON) */
|
||||
reg = readl(&pmc->pmc_pwrgate_toggle);
|
||||
reg &= PARTID_CP;
|
||||
reg |= START_CP;
|
||||
writel(reg, &pmc->pmc_pwrgate_toggle);
|
||||
|
||||
/* Wait for the power to come up */
|
||||
while (!is_cpu_powered()) {
|
||||
if (timeout-- == 0)
|
||||
printf("CPU failed to power up!\n");
|
||||
else
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the I/O clamps from CPU power partition.
|
||||
* Recommended only on a Warm boot, if the CPU partition gets
|
||||
* power gated. Shouldn't cause any harm when called after a
|
||||
* cold boot according to HW, probably just redundant.
|
||||
*/
|
||||
remove_cpu_io_clamps();
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_cpu_power_rail(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
|
@ -173,49 +38,6 @@ static void enable_cpu_power_rail(void)
|
|||
udelay(3750);
|
||||
}
|
||||
|
||||
static void reset_A9_cpu(int reset)
|
||||
{
|
||||
/*
|
||||
* NOTE: Regardless of whether the request is to hold the CPU in reset
|
||||
* or take it out of reset, every processor in the CPU complex
|
||||
* except the master (CPU 0) will be held in reset because the
|
||||
* AVP only talks to the master. The AVP does not know that there
|
||||
* are multiple processors in the CPU complex.
|
||||
*/
|
||||
|
||||
/* Hold CPU 1 in reset, and CPU 0 if asked */
|
||||
reset_cmplx_set_enable(1, crc_rst_cpu | crc_rst_de | crc_rst_debug, 1);
|
||||
reset_cmplx_set_enable(0, crc_rst_cpu | crc_rst_de | crc_rst_debug,
|
||||
reset);
|
||||
|
||||
/* Enable/Disable master CPU reset */
|
||||
reset_set_enable(PERIPH_ID_CPU, reset);
|
||||
}
|
||||
|
||||
static void clock_enable_coresight(int enable)
|
||||
{
|
||||
u32 rst, src;
|
||||
|
||||
clock_set_enable(PERIPH_ID_CORESIGHT, enable);
|
||||
reset_set_enable(PERIPH_ID_CORESIGHT, !enable);
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
* Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by
|
||||
* 1.5, giving an effective frequency of 144MHz.
|
||||
* Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor
|
||||
* (bits 7:0), so 00000001b == 1.5 (n+1 + .5)
|
||||
*/
|
||||
src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000);
|
||||
clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src);
|
||||
|
||||
/* Unlock the CPU CoreSight interfaces */
|
||||
rst = 0xC5ACCE55;
|
||||
writel(rst, CSITE_CPU_DBG0_LAR);
|
||||
writel(rst, CSITE_CPU_DBG1_LAR);
|
||||
}
|
||||
}
|
||||
|
||||
void start_cpu(u32 reset_vector)
|
||||
{
|
||||
/* Enable VDD_CPU */
|
||||
|
@ -246,13 +68,3 @@ void start_cpu(u32 reset_vector)
|
|||
/* Take the CPU out of reset */
|
||||
reset_A9_cpu(0);
|
||||
}
|
||||
|
||||
|
||||
void halt_avp(void)
|
||||
{
|
||||
for (;;) {
|
||||
writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \
|
||||
| HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)),
|
||||
FLOW_CTLR_HALT_COP_EVENTS);
|
||||
}
|
||||
}
|
||||
|
|
41
arch/arm/cpu/arm720t/tegra30/Makefile
Normal file
41
arch/arm/cpu/arm720t/tegra30/Makefile
Normal file
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2000-2008
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
COBJS-y += cpu.o
|
||||
|
||||
SRCS := $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
19
arch/arm/cpu/arm720t/tegra30/config.mk
Normal file
19
arch/arm/cpu/arm720t/tegra30/config.mk
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
USE_PRIVATE_LIBGCC = yes
|
176
arch/arm/cpu/arm720t/tegra30/cpu.c
Normal file
176
arch/arm/cpu/arm720t/tegra30/cpu.c
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/flow.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/clk_rst.h>
|
||||
#include <asm/arch-tegra/pmc.h>
|
||||
#include <asm/arch-tegra/tegra_i2c.h>
|
||||
#include "../tegra-common/cpu.h"
|
||||
|
||||
/* Tegra30-specific CPU init code */
|
||||
void tegra_i2c_ll_write_addr(uint addr, uint config)
|
||||
{
|
||||
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
|
||||
|
||||
writel(addr, ®->cmd_addr0);
|
||||
writel(config, ®->cnfg);
|
||||
}
|
||||
|
||||
void tegra_i2c_ll_write_data(uint data, uint config)
|
||||
{
|
||||
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
|
||||
|
||||
writel(data, ®->cmd_data1);
|
||||
writel(config, ®->cnfg);
|
||||
}
|
||||
|
||||
#define TPS65911_I2C_ADDR 0x5A
|
||||
#define TPS65911_VDDCTRL_OP_REG 0x28
|
||||
#define TPS65911_VDDCTRL_SR_REG 0x27
|
||||
#define TPS65911_VDDCTRL_OP_DATA (0x2300 | TPS65911_VDDCTRL_OP_REG)
|
||||
#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG)
|
||||
#define I2C_SEND_2_BYTES 0x0A02
|
||||
|
||||
static void enable_cpu_power_rail(void)
|
||||
{
|
||||
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
|
||||
u32 reg;
|
||||
|
||||
debug("enable_cpu_power_rail entry\n");
|
||||
reg = readl(&pmc->pmc_cntrl);
|
||||
reg |= CPUPWRREQ_OE;
|
||||
writel(reg, &pmc->pmc_cntrl);
|
||||
|
||||
/*
|
||||
* Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus.
|
||||
* First set VDD to 1.4V, then enable the VDD regulator.
|
||||
*/
|
||||
tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2);
|
||||
tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES);
|
||||
udelay(1000);
|
||||
tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES);
|
||||
udelay(10 * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* The T30 requires some special clock initialization, including setting up
|
||||
* the dvc i2c, turning on mselect and selecting the G CPU cluster
|
||||
*/
|
||||
void t30_init_clocks(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
|
||||
u32 val;
|
||||
|
||||
debug("t30_init_clocks entry\n");
|
||||
/* Set active CPU cluster to G */
|
||||
clrbits_le32(flow->cluster_control, 1 << 0);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
|
||||
(SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
|
||||
(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
|
||||
writel(val, &clkrst->crc_sclk_brst_pol);
|
||||
|
||||
writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
|
||||
|
||||
val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) |
|
||||
(1 << CLK_SYS_RATE_AHB_RATE_SHIFT) |
|
||||
(0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) |
|
||||
(0 << CLK_SYS_RATE_APB_RATE_SHIFT);
|
||||
writel(val, &clkrst->crc_clk_sys_rate);
|
||||
|
||||
/* Put i2c, mselect in reset and enable clocks */
|
||||
reset_set_enable(PERIPH_ID_DVC_I2C, 1);
|
||||
clock_set_enable(PERIPH_ID_DVC_I2C, 1);
|
||||
reset_set_enable(PERIPH_ID_MSELECT, 1);
|
||||
clock_set_enable(PERIPH_ID_MSELECT, 1);
|
||||
|
||||
/* Switch MSELECT clock to PLLP (00) */
|
||||
clock_ll_set_source(PERIPH_ID_MSELECT, 0);
|
||||
|
||||
/*
|
||||
* Our high-level clock routines are not available prior to
|
||||
* relocation. We use the low-level functions which require a
|
||||
* hard-coded divisor. Use CLK_M with divide by (n + 1 = 17)
|
||||
*/
|
||||
clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16);
|
||||
|
||||
/*
|
||||
* Give clocks time to stabilize, then take i2c and mselect out of
|
||||
* reset
|
||||
*/
|
||||
udelay(1000);
|
||||
reset_set_enable(PERIPH_ID_DVC_I2C, 0);
|
||||
reset_set_enable(PERIPH_ID_MSELECT, 0);
|
||||
}
|
||||
|
||||
static void set_cpu_running(int run)
|
||||
{
|
||||
struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
|
||||
|
||||
debug("set_cpu_running entry, run = %d\n", run);
|
||||
writel(run ? FLOW_MODE_NONE : FLOW_MODE_STOP, &flow->halt_cpu_events);
|
||||
}
|
||||
|
||||
void start_cpu(u32 reset_vector)
|
||||
{
|
||||
debug("start_cpu entry, reset_vector = %x\n", reset_vector);
|
||||
t30_init_clocks();
|
||||
|
||||
/* Enable VDD_CPU */
|
||||
enable_cpu_power_rail();
|
||||
|
||||
set_cpu_running(0);
|
||||
|
||||
/* Hold the CPUs in reset */
|
||||
reset_A9_cpu(1);
|
||||
|
||||
/* Disable the CPU clock */
|
||||
enable_cpu_clock(0);
|
||||
|
||||
/* Enable CoreSight */
|
||||
clock_enable_coresight(1);
|
||||
|
||||
/*
|
||||
* Set the entry point for CPU execution from reset,
|
||||
* if it's a non-zero value.
|
||||
*/
|
||||
if (reset_vector)
|
||||
writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
|
||||
|
||||
/* Enable the CPU clock */
|
||||
enable_cpu_clock(1);
|
||||
|
||||
/* If the CPU doesn't already have power, power it up */
|
||||
powerup_cpu();
|
||||
|
||||
/* Take the CPU out of reset */
|
||||
reset_A9_cpu(0);
|
||||
|
||||
set_cpu_running(1);
|
||||
}
|
|
@ -31,14 +31,14 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
tick *= CONFIG_SYS_HZ;
|
||||
do_div(tick, gd->timer_rate_hz);
|
||||
do_div(tick, gd->arch.timer_rate_hz);
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long usec_to_tick(unsigned long long usec)
|
||||
{
|
||||
usec *= gd->timer_rate_hz;
|
||||
usec *= gd->arch.timer_rate_hz;
|
||||
do_div(usec, 1000000);
|
||||
|
||||
return usec;
|
||||
|
@ -74,8 +74,8 @@ int timer_init(void)
|
|||
cr |= FTTMR010_TM3_ENABLE;
|
||||
writel(cr, &tmr->cr);
|
||||
|
||||
gd->timer_rate_hz = TIMER_CLOCK;
|
||||
gd->tbu = gd->tbl = 0;
|
||||
gd->arch.timer_rate_hz = TIMER_CLOCK;
|
||||
gd->arch.tbu = gd->arch.tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -89,10 +89,10 @@ unsigned long long get_ticks(void)
|
|||
ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
|
||||
|
||||
/* increment tbu if tbl has rolled over */
|
||||
if (now < gd->tbl)
|
||||
gd->tbu++;
|
||||
gd->tbl = now;
|
||||
return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
|
||||
if (now < gd->arch.tbl)
|
||||
gd->arch.tbu++;
|
||||
gd->arch.tbl = now;
|
||||
return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
|
@ -126,5 +126,5 @@ ulong get_timer(ulong base)
|
|||
*/
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return gd->timer_rate_hz;
|
||||
return gd->arch.timer_rate_hz;
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@ static unsigned long at91_css_to_rate(unsigned long css)
|
|||
case AT91_PMC_MCKR_CSS_SLOW:
|
||||
return CONFIG_SYS_AT91_SLOW_CLOCK;
|
||||
case AT91_PMC_MCKR_CSS_MAIN:
|
||||
return gd->main_clk_rate_hz;
|
||||
return gd->arch.main_clk_rate_hz;
|
||||
case AT91_PMC_MCKR_CSS_PLLA:
|
||||
return gd->plla_rate_hz;
|
||||
return gd->arch.plla_rate_hz;
|
||||
case AT91_PMC_MCKR_CSS_PLLB:
|
||||
return gd->pllb_rate_hz;
|
||||
return gd->arch.pllb_rate_hz;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -124,10 +124,10 @@ int at91_clock_init(unsigned long main_clock)
|
|||
main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
|
||||
}
|
||||
#endif
|
||||
gd->main_clk_rate_hz = main_clock;
|
||||
gd->arch.main_clk_rate_hz = main_clock;
|
||||
|
||||
/* report if PLLA is more than mildly overclocked */
|
||||
gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
|
||||
gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
|
||||
|
||||
#ifdef CONFIG_USB_ATMEL
|
||||
/*
|
||||
|
@ -136,9 +136,10 @@ int at91_clock_init(unsigned long main_clock)
|
|||
*
|
||||
* REVISIT: assumes MCK doesn't derive from PLLB!
|
||||
*/
|
||||
gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
|
||||
gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
|
||||
AT91_PMC_PLLBR_USBDIV_2;
|
||||
gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init);
|
||||
gd->arch.pllb_rate_hz = at91_pll_rate(main_clock,
|
||||
gd->arch.at91_pllb_usb_init);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -146,13 +147,14 @@ int at91_clock_init(unsigned long main_clock)
|
|||
* For now, assume this parentage won't change.
|
||||
*/
|
||||
mckr = readl(&pmc->mckr);
|
||||
gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
|
||||
freq = gd->mck_rate_hz;
|
||||
gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
|
||||
freq = gd->arch.mck_rate_hz;
|
||||
|
||||
freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */
|
||||
/* mdiv */
|
||||
gd->mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
|
||||
gd->cpu_clk_rate_hz = freq;
|
||||
gd->arch.mck_rate_hz = freq /
|
||||
(1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
|
||||
gd->arch.cpu_clk_rate_hz = freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ int timer_init(void)
|
|||
writel(TIMER_LOAD_VAL, &tc->tc[0].rc);
|
||||
|
||||
writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr);
|
||||
gd->lastinc = 0;
|
||||
gd->tbl = 0;
|
||||
gd->arch.lastinc = 0;
|
||||
gd->arch.tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -89,16 +89,16 @@ ulong get_timer_raw(void)
|
|||
|
||||
now = readl(&tc->tc[0].cv) & 0x0000ffff;
|
||||
|
||||
if (now >= gd->lastinc) {
|
||||
if (now >= gd->arch.lastinc) {
|
||||
/* normal mode */
|
||||
gd->tbl += now - gd->lastinc;
|
||||
gd->arch.tbl += now - gd->arch.lastinc;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
gd->tbl += now + TIMER_LOAD_VAL - gd->lastinc;
|
||||
gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc;
|
||||
}
|
||||
gd->lastinc = now;
|
||||
gd->arch.lastinc = now;
|
||||
|
||||
return gd->tbl;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
|
|
|
@ -45,25 +45,25 @@ int timer_init(void)
|
|||
/* use PWM Timer 4 because it has no output */
|
||||
/* prescaler for Timer 4 is 16 */
|
||||
writel(0x0f00, &timers->tcfg0);
|
||||
if (gd->tbu == 0) {
|
||||
if (gd->arch.tbu == 0) {
|
||||
/*
|
||||
* for 10 ms clock period @ PCLK with 4 bit divider = 1/2
|
||||
* (default) and prescaler = 16. Should be 10390
|
||||
* @33.25MHz and 15625 @ 50 MHz
|
||||
*/
|
||||
gd->tbu = get_PCLK() / (2 * 16 * 100);
|
||||
gd->timer_rate_hz = get_PCLK() / (2 * 16);
|
||||
gd->arch.tbu = get_PCLK() / (2 * 16 * 100);
|
||||
gd->arch.timer_rate_hz = get_PCLK() / (2 * 16);
|
||||
}
|
||||
/* load value for 10 ms timeout */
|
||||
writel(gd->tbu, &timers->tcntb4);
|
||||
writel(gd->arch.tbu, &timers->tcntb4);
|
||||
/* auto load, manual update of timer 4 */
|
||||
tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000;
|
||||
writel(tmr, &timers->tcon);
|
||||
/* auto load, start timer 4 */
|
||||
tmr = (tmr & ~0x0700000) | 0x0500000;
|
||||
writel(tmr, &timers->tcon);
|
||||
gd->lastinc = 0;
|
||||
gd->tbl = 0;
|
||||
gd->arch.lastinc = 0;
|
||||
gd->arch.tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void __udelay (unsigned long usec)
|
|||
ulong start = get_ticks();
|
||||
|
||||
tmo = usec / 1000;
|
||||
tmo *= (gd->tbu * 100);
|
||||
tmo *= (gd->arch.tbu * 100);
|
||||
tmo /= 1000;
|
||||
|
||||
while ((ulong) (get_ticks() - start) < tmo)
|
||||
|
@ -93,7 +93,7 @@ ulong get_timer_masked(void)
|
|||
{
|
||||
ulong tmr = get_ticks();
|
||||
|
||||
return tmr / (gd->timer_rate_hz / CONFIG_SYS_HZ);
|
||||
return tmr / (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
|
||||
}
|
||||
|
||||
void udelay_masked(unsigned long usec)
|
||||
|
@ -104,10 +104,10 @@ void udelay_masked(unsigned long usec)
|
|||
|
||||
if (usec >= 1000) {
|
||||
tmo = usec / 1000;
|
||||
tmo *= (gd->tbu * 100);
|
||||
tmo *= (gd->arch.tbu * 100);
|
||||
tmo /= 1000;
|
||||
} else {
|
||||
tmo = usec * (gd->tbu * 100);
|
||||
tmo = usec * (gd->arch.tbu * 100);
|
||||
tmo /= (1000 * 1000);
|
||||
}
|
||||
|
||||
|
@ -128,16 +128,16 @@ unsigned long long get_ticks(void)
|
|||
struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
|
||||
ulong now = readl(&timers->tcnto4) & 0xffff;
|
||||
|
||||
if (gd->lastinc >= now) {
|
||||
if (gd->arch.lastinc >= now) {
|
||||
/* normal mode */
|
||||
gd->tbl += gd->lastinc - now;
|
||||
gd->arch.tbl += gd->arch.lastinc - now;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
gd->tbl += gd->lastinc + gd->tbu - now;
|
||||
gd->arch.tbl += gd->arch.lastinc + gd->arch.tbu - now;
|
||||
}
|
||||
gd->lastinc = now;
|
||||
gd->arch.lastinc = now;
|
||||
|
||||
return gd->tbl;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -61,7 +61,7 @@ struct armd1tmr_registers {
|
|||
#define COUNT_RD_REQ 0x1
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
/* Using gd->tbu from timestamp and gd->tbl for lastdec */
|
||||
/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */
|
||||
|
||||
/* For preventing risk of instability in reading counter value,
|
||||
* first set read request to register cvwr and then read same
|
||||
|
@ -82,16 +82,16 @@ ulong get_timer_masked(void)
|
|||
{
|
||||
ulong now = read_timer();
|
||||
|
||||
if (now >= gd->tbl) {
|
||||
if (now >= gd->arch.tbl) {
|
||||
/* normal mode */
|
||||
gd->tbu += now - gd->tbl;
|
||||
gd->arch.tbu += now - gd->arch.tbl;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
gd->tbu += now + TIMER_LOAD_VAL - gd->tbl;
|
||||
gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl;
|
||||
}
|
||||
gd->tbl = now;
|
||||
gd->arch.tbl = now;
|
||||
|
||||
return gd->tbu;
|
||||
return gd->arch.tbu;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
|
@ -135,9 +135,9 @@ int timer_init(void)
|
|||
|
||||
/* Enable timer 0 */
|
||||
writel(0x1, &armd1timers->cer);
|
||||
/* init the gd->tbu and gd->tbl value */
|
||||
gd->tbl = read_timer();
|
||||
gd->tbu = 0;
|
||||
/* init the gd->arch.tbu and gd->arch.tbl value */
|
||||
gd->arch.tbl = read_timer();
|
||||
gd->arch.tbu = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@ static unsigned long at91_css_to_rate(unsigned long css)
|
|||
case AT91_PMC_MCKR_CSS_SLOW:
|
||||
return CONFIG_SYS_AT91_SLOW_CLOCK;
|
||||
case AT91_PMC_MCKR_CSS_MAIN:
|
||||
return gd->main_clk_rate_hz;
|
||||
return gd->arch.main_clk_rate_hz;
|
||||
case AT91_PMC_MCKR_CSS_PLLA:
|
||||
return gd->plla_rate_hz;
|
||||
return gd->arch.plla_rate_hz;
|
||||
case AT91_PMC_MCKR_CSS_PLLB:
|
||||
return gd->pllb_rate_hz;
|
||||
return gd->arch.pllb_rate_hz;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -132,10 +132,10 @@ int at91_clock_init(unsigned long main_clock)
|
|||
main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
|
||||
}
|
||||
#endif
|
||||
gd->main_clk_rate_hz = main_clock;
|
||||
gd->arch.main_clk_rate_hz = main_clock;
|
||||
|
||||
/* report if PLLA is more than mildly overclocked */
|
||||
gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
|
||||
gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
|
||||
|
||||
#ifdef CONFIG_USB_ATMEL
|
||||
/*
|
||||
|
@ -144,9 +144,10 @@ int at91_clock_init(unsigned long main_clock)
|
|||
*
|
||||
* REVISIT: assumes MCK doesn't derive from PLLB!
|
||||
*/
|
||||
gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
|
||||
gd->arch.at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
|
||||
AT91_PMC_PLLBR_USBDIV_2;
|
||||
gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init);
|
||||
gd->arch.pllb_rate_hz = at91_pll_rate(main_clock,
|
||||
gd->arch.at91_pllb_usb_init);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -157,15 +158,15 @@ int at91_clock_init(unsigned long main_clock)
|
|||
#if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) \
|
||||
|| defined(CONFIG_AT91SAM9X5)
|
||||
/* plla divisor by 2 */
|
||||
gd->plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12));
|
||||
gd->arch.plla_rate_hz /= (1 << ((mckr & 1 << 12) >> 12));
|
||||
#endif
|
||||
gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
|
||||
freq = gd->mck_rate_hz;
|
||||
gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
|
||||
freq = gd->arch.mck_rate_hz;
|
||||
|
||||
freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */
|
||||
#if defined(CONFIG_AT91SAM9G20)
|
||||
/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
|
||||
gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
|
||||
gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
|
||||
freq / ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 7) : freq;
|
||||
if (mckr & AT91_PMC_MCKR_MDIV_MASK)
|
||||
freq /= 2; /* processor clock division */
|
||||
|
@ -177,14 +178,15 @@ int at91_clock_init(unsigned long main_clock)
|
|||
* 2 <==> 4
|
||||
* 3 <==> 3
|
||||
*/
|
||||
gd->mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ==
|
||||
gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ==
|
||||
(AT91_PMC_MCKR_MDIV_2 | AT91_PMC_MCKR_MDIV_4)
|
||||
? freq / 3
|
||||
: freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
|
||||
#else
|
||||
gd->mck_rate_hz = freq / (1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
|
||||
gd->arch.mck_rate_hz = freq /
|
||||
(1 << ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
|
||||
#endif
|
||||
gd->cpu_clk_rate_hz = freq;
|
||||
gd->arch.cpu_clk_rate_hz = freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -52,14 +52,14 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
tick *= CONFIG_SYS_HZ;
|
||||
do_div(tick, gd->timer_rate_hz);
|
||||
do_div(tick, gd->arch.timer_rate_hz);
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long usec_to_tick(unsigned long long usec)
|
||||
{
|
||||
usec *= gd->timer_rate_hz;
|
||||
usec *= gd->arch.timer_rate_hz;
|
||||
do_div(usec, 1000000);
|
||||
|
||||
return usec;
|
||||
|
@ -79,8 +79,8 @@ int timer_init(void)
|
|||
/* Enable PITC */
|
||||
writel(TIMER_LOAD_VAL | AT91_PIT_MR_EN , &pit->mr);
|
||||
|
||||
gd->timer_rate_hz = gd->mck_rate_hz / 16;
|
||||
gd->tbu = gd->tbl = 0;
|
||||
gd->arch.timer_rate_hz = gd->arch.mck_rate_hz / 16;
|
||||
gd->arch.tbu = gd->arch.tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -95,10 +95,10 @@ unsigned long long get_ticks(void)
|
|||
ulong now = readl(&pit->piir);
|
||||
|
||||
/* increment tbu if tbl has rolled over */
|
||||
if (now < gd->tbl)
|
||||
gd->tbu++;
|
||||
gd->tbl = now;
|
||||
return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
|
||||
if (now < gd->arch.tbl)
|
||||
gd->arch.tbu++;
|
||||
gd->arch.tbl = now;
|
||||
return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
|
@ -132,5 +132,5 @@ ulong get_timer(ulong base)
|
|||
*/
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return gd->timer_rate_hz;
|
||||
return gd->arch.timer_rate_hz;
|
||||
}
|
||||
|
|
|
@ -60,8 +60,8 @@ int timer_init(void)
|
|||
writel(0x0, &timer->tim34);
|
||||
writel(TIMER_LOAD_VAL, &timer->prd34);
|
||||
writel(2 << 22, &timer->tcr);
|
||||
gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV;
|
||||
gd->timer_reset_value = 0;
|
||||
gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV;
|
||||
gd->arch.timer_reset_value = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -74,27 +74,28 @@ unsigned long long get_ticks(void)
|
|||
unsigned long now = readl(&timer->tim34);
|
||||
|
||||
/* increment tbu if tbl has rolled over */
|
||||
if (now < gd->tbl)
|
||||
gd->tbu++;
|
||||
gd->tbl = now;
|
||||
if (now < gd->arch.tbl)
|
||||
gd->arch.tbu++;
|
||||
gd->arch.tbl = now;
|
||||
|
||||
return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
|
||||
return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
unsigned long long timer_diff;
|
||||
|
||||
timer_diff = get_ticks() - gd->timer_reset_value;
|
||||
timer_diff = get_ticks() - gd->arch.timer_reset_value;
|
||||
|
||||
return lldiv(timer_diff, (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base;
|
||||
return lldiv(timer_diff,
|
||||
(gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) - base;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
unsigned long long endtime;
|
||||
|
||||
endtime = lldiv((unsigned long long)usec * gd->timer_rate_hz,
|
||||
endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz,
|
||||
1000000UL);
|
||||
endtime += get_ticks();
|
||||
|
||||
|
@ -108,7 +109,7 @@ void __udelay(unsigned long usec)
|
|||
*/
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return gd->timer_rate_hz;
|
||||
return gd->arch.timer_rate_hz;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HW_WATCHDOG
|
||||
|
|
|
@ -86,8 +86,8 @@ struct kwtmr_registers *kwtmr_regs = (struct kwtmr_registers *)KW_TIMER_BASE;
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp gd->tbl
|
||||
#define lastdec gd->lastinc
|
||||
#define timestamp gd->arch.tbl
|
||||
#define lastdec gd->arch.lastinc
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp gd->tbl
|
||||
#define lastdec gd->lastinc
|
||||
#define timestamp gd->arch.tbl
|
||||
#define lastdec gd->arch.lastinc
|
||||
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
|
|
|
@ -229,9 +229,9 @@ int get_clocks(void)
|
|||
{
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#if CONFIG_SYS_FSL_ESDHC_ADDR == IMX_MMC_SDHC2_BASE
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
#else
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK);
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp (gd->tbl)
|
||||
#define lastinc (gd->lastinc)
|
||||
#define timestamp (gd->arch.tbl)
|
||||
#define lastinc (gd->arch.lastinc)
|
||||
|
||||
/*
|
||||
* "time" is measured in 1 / CONFIG_SYS_HZ seconds,
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp (gd->tbl)
|
||||
#define lastinc (gd->lastinc)
|
||||
#define timestamp (gd->arch.tbl)
|
||||
#define lastinc (gd->arch.lastinc)
|
||||
|
||||
/*
|
||||
* "time" is measured in 1 / CONFIG_SYS_HZ seconds,
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp (gd->tbl)
|
||||
#define lastdec (gd->lastinc)
|
||||
#define timestamp (gd->arch.tbl)
|
||||
#define lastdec (gd->arch.lastinc)
|
||||
|
||||
/*
|
||||
* This driver uses 1kHz clock source.
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp gd->tbl
|
||||
#define lastdec gd->lastinc
|
||||
#define timestamp gd->arch.tbl
|
||||
#define lastdec gd->arch.lastinc
|
||||
|
||||
int timer_init (void)
|
||||
{
|
||||
|
|
|
@ -92,8 +92,8 @@ static inline ulong read_timer(void)
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp gd->tbl
|
||||
#define lastdec gd->lastinc
|
||||
#define timestamp gd->arch.tbl
|
||||
#define lastdec gd->arch.lastinc
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
|
|
|
@ -60,7 +60,7 @@ struct panthtmr_registers {
|
|||
#define COUNT_RD_REQ 0x1
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
/* Using gd->tbu from timestamp and gd->tbl for lastdec */
|
||||
/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */
|
||||
|
||||
/*
|
||||
* For preventing risk of instability in reading counter value,
|
||||
|
@ -90,16 +90,16 @@ ulong get_timer_masked(void)
|
|||
{
|
||||
ulong now = read_timer();
|
||||
|
||||
if (now >= gd->tbl) {
|
||||
if (now >= gd->arch.tbl) {
|
||||
/* normal mode */
|
||||
gd->tbu += now - gd->tbl;
|
||||
gd->arch.tbu += now - gd->arch.tbl;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
gd->tbu += now + TIMER_LOAD_VAL - gd->tbl;
|
||||
gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl;
|
||||
}
|
||||
gd->tbl = now;
|
||||
gd->arch.tbl = now;
|
||||
|
||||
return gd->tbu;
|
||||
return gd->arch.tbu;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
|
@ -144,9 +144,9 @@ int timer_init(void)
|
|||
|
||||
/* Enable timer 0 */
|
||||
writel(0x1, &panthtimers->cer);
|
||||
/* init the gd->tbu and gd->tbl value */
|
||||
gd->tbl = read_timer();
|
||||
gd->tbu = 0;
|
||||
/* init the gd->arch.tbu and gd->arch.tbl value */
|
||||
gd->arch.tbl = read_timer();
|
||||
gd->arch.tbu = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ static struct misc_regs *const misc_regs_p =
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp gd->tbl
|
||||
#define lastdec gd->lastinc
|
||||
#define timestamp gd->arch.tbl
|
||||
#define lastdec gd->arch.lastinc
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp gd->tbl
|
||||
#define lastdec gd->lastinc
|
||||
#define timestamp gd->arch.tbl
|
||||
#define lastdec gd->arch.lastinc
|
||||
|
||||
#define TIMER_ENABLE (1 << 7)
|
||||
#define TIMER_MODE_MSK (1 << 6)
|
||||
|
|
|
@ -32,7 +32,7 @@ COBJS += cache_v7.o
|
|||
COBJS += cpu.o
|
||||
COBJS += syslib.o
|
||||
|
||||
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),)
|
||||
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA),)
|
||||
SOBJS += lowlevel_init.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -55,6 +55,9 @@ void spl_board_init(void)
|
|||
#ifdef CONFIG_SPL_NAND_SUPPORT
|
||||
gpmc_init();
|
||||
#endif
|
||||
#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
|
||||
arch_misc_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
int board_mmc_init(bd_t *bis)
|
||||
|
|
|
@ -56,8 +56,9 @@ int timer_init(void)
|
|||
&timer_base->tclr);
|
||||
|
||||
/* reset time, capture current incrementer value time */
|
||||
gd->lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
|
||||
gd->tbl = 0; /* start "advancing" time stamp from 0 */
|
||||
gd->arch.lastinc = readl(&timer_base->tcrr) /
|
||||
(TIMER_CLOCK / CONFIG_SYS_HZ);
|
||||
gd->arch.tbl = 0; /* start "advancing" time stamp from 0 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -91,14 +92,15 @@ ulong get_timer_masked(void)
|
|||
/* current tick value */
|
||||
ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
|
||||
|
||||
if (now >= gd->lastinc) /* normal mode (non roll) */
|
||||
if (now >= gd->arch.lastinc) { /* normal mode (non roll) */
|
||||
/* move stamp fordward with absoulte diff ticks */
|
||||
gd->tbl += (now - gd->lastinc);
|
||||
else /* we have rollover of incrementer */
|
||||
gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ))
|
||||
- gd->lastinc) + now;
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
gd->arch.tbl += (now - gd->arch.lastinc);
|
||||
} else { /* we have rollover of incrementer */
|
||||
gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK /
|
||||
CONFIG_SYS_HZ)) - gd->arch.lastinc) + now;
|
||||
}
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -105,8 +105,8 @@ void reset_timer_masked(void)
|
|||
struct s5p_timer *const timer = s5p_get_base_timer();
|
||||
|
||||
/* reset time */
|
||||
gd->lastinc = readl(&timer->tcnto4);
|
||||
gd->tbl = 0;
|
||||
gd->arch.lastinc = readl(&timer->tcnto4);
|
||||
gd->arch.tbl = 0;
|
||||
}
|
||||
|
||||
unsigned long get_timer_masked(void)
|
||||
|
@ -123,14 +123,14 @@ unsigned long get_current_tick(void)
|
|||
unsigned long now = readl(&timer->tcnto4);
|
||||
unsigned long count_value = readl(&timer->tcntb4);
|
||||
|
||||
if (gd->lastinc >= now)
|
||||
gd->tbl += gd->lastinc - now;
|
||||
if (gd->arch.lastinc >= now)
|
||||
gd->arch.tbl += gd->arch.lastinc - now;
|
||||
else
|
||||
gd->tbl += gd->lastinc + count_value - now;
|
||||
gd->arch.tbl += gd->arch.lastinc + count_value - now;
|
||||
|
||||
gd->lastinc = now;
|
||||
gd->arch.lastinc = now;
|
||||
|
||||
return gd->tbl;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -80,16 +80,16 @@ ulong get_timer_masked(void)
|
|||
{
|
||||
/* current tick value */
|
||||
ulong now = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ);
|
||||
if (gd->lastinc >= now) {
|
||||
if (gd->arch.lastinc >= now) {
|
||||
/* normal mode (non roll) */
|
||||
/* move stamp forward with absolute diff ticks */
|
||||
gd->tbl += gd->lastinc - now;
|
||||
gd->arch.tbl += gd->arch.lastinc - now;
|
||||
} else {
|
||||
/* we have overflow of the count down timer */
|
||||
gd->tbl += TIMER_LOAD_VAL - gd->lastinc + now;
|
||||
gd->arch.tbl += TIMER_LOAD_VAL - gd->arch.lastinc + now;
|
||||
}
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -98,7 +98,8 @@ ulong get_timer_masked(void)
|
|||
void reset_timer(void)
|
||||
{
|
||||
/* capture current decrementer value time */
|
||||
gd->lastinc = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ);
|
||||
gd->arch.lastinc = read_timer() /
|
||||
(CONFIG_TIMER_CLOCK_KHZ / CONFIG_SYS_HZ);
|
||||
/* start "advancing" time stamp from 0 */
|
||||
gd->tbl = 0;
|
||||
gd->arch.tbl = 0;
|
||||
}
|
||||
|
|
|
@ -251,12 +251,12 @@ ENTRY(c_runtime_cpu_setup)
|
|||
/*
|
||||
* Move vector table
|
||||
*/
|
||||
#if !defined(CONFIG_TEGRA20)
|
||||
#if !defined(CONFIG_TEGRA)
|
||||
/* Set vector address in CP15 VBAR register */
|
||||
ldr r0, =_start
|
||||
add r0, r0, r9
|
||||
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
|
||||
#endif /* !Tegra20 */
|
||||
#endif /* !Tegra */
|
||||
|
||||
bx lr
|
||||
|
||||
|
|
40
arch/arm/cpu/armv7/tegra114/Makefile
Normal file
40
arch/arm/cpu/armv7/tegra114/Makefile
Normal file
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
19
arch/arm/cpu/armv7/tegra114/config.mk
Normal file
19
arch/arm/cpu/armv7/tegra114/config.mk
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
CONFIG_ARCH_DEVICE_TREE := tegra114
|
40
arch/arm/cpu/armv7/tegra30/Makefile
Normal file
40
arch/arm/cpu/armv7/tegra30/Makefile
Normal file
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2000-2003
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
19
arch/arm/cpu/armv7/tegra30/config.mk
Normal file
19
arch/arm/cpu/armv7/tegra30/config.mk
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
CONFIG_ARCH_DEVICE_TREE := tegra30
|
|
@ -100,12 +100,14 @@ ulong get_timer_masked(void)
|
|||
/* current tick value */
|
||||
ulong now = TICKS_TO_HZ(READ_TIMER());
|
||||
|
||||
if (now >= gd->lastinc) /* normal (non rollover) */
|
||||
gd->tbl += (now - gd->lastinc);
|
||||
else /* rollover */
|
||||
gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
if (now >= gd->arch.lastinc) { /* normal (non rollover) */
|
||||
gd->arch.tbl += (now - gd->arch.lastinc);
|
||||
} else { /* rollover */
|
||||
gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) -
|
||||
gd->arch.lastinc) + now;
|
||||
}
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/* Delay x useconds */
|
||||
|
@ -132,7 +134,7 @@ ulong get_timer(ulong base)
|
|||
/*
|
||||
* Emulation of Power architecture long long timebase.
|
||||
*
|
||||
* TODO: Support gd->tbu for real long long timebase.
|
||||
* TODO: Support gd->arch.tbu for real long long timebase.
|
||||
*/
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ LIB = $(obj)lib$(SOC).o
|
|||
|
||||
COBJS-y := timer.o
|
||||
COBJS-y += cpu.o
|
||||
COBJS-y += slcr.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
|
||||
|
|
|
@ -21,11 +21,37 @@
|
|||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
inline void lowlevel_init(void) {}
|
||||
void lowlevel_init(void)
|
||||
{
|
||||
zynq_slcr_unlock();
|
||||
/* remap DDR to zero, FILTERSTART */
|
||||
writel(0, &scu_base->filter_start);
|
||||
|
||||
/* Device config APB, unlock the PCAP */
|
||||
writel(0x757BDF0D, &devcfg_base->unlock);
|
||||
writel(0xFFFFFFFF, &devcfg_base->rom_shadow);
|
||||
|
||||
/* OCM_CFG, Mask out the ROM, map ram into upper addresses */
|
||||
writel(0x1F, &slcr_base->ocm_cfg);
|
||||
/* FPGA_RST_CTRL, clear resets on AXI fabric ports */
|
||||
writel(0x0, &slcr_base->fpga_rst_ctrl);
|
||||
/* TZ_DDR_RAM, Set DDR trust zone non-secure */
|
||||
writel(0xFFFFFFFF, &slcr_base->trust_zone);
|
||||
/* Set urgent bits with register */
|
||||
writel(0x0, &slcr_base->ddr_urgent_sel);
|
||||
/* Urgent write, ports S2/S3 */
|
||||
writel(0xC, &slcr_base->ddr_urgent);
|
||||
|
||||
zynq_slcr_lock();
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
zynq_slcr_cpu_reset();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
|
63
arch/arm/cpu/armv7/zynq/slcr.c
Normal file
63
arch/arm/cpu/armv7/zynq/slcr.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Xilinx Inc.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
#define SLCR_LOCK_MAGIC 0x767B
|
||||
#define SLCR_UNLOCK_MAGIC 0xDF0D
|
||||
|
||||
static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */
|
||||
|
||||
void zynq_slcr_lock(void)
|
||||
{
|
||||
if (!slcr_lock)
|
||||
writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock);
|
||||
}
|
||||
|
||||
void zynq_slcr_unlock(void)
|
||||
{
|
||||
if (slcr_lock)
|
||||
writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock);
|
||||
}
|
||||
|
||||
/* Reset the entire system */
|
||||
void zynq_slcr_cpu_reset(void)
|
||||
{
|
||||
/*
|
||||
* Unlock the SLCR then reset the system.
|
||||
* Note that this seems to require raw i/o
|
||||
* functions or there's a lockup?
|
||||
*/
|
||||
zynq_slcr_unlock();
|
||||
|
||||
/*
|
||||
* Clear 0x0F000000 bits of reboot status register to workaround
|
||||
* the FSBL not loading the bitstream after soft-reboot
|
||||
* This is a temporary solution until we know more.
|
||||
*/
|
||||
clrbits_le32(&slcr_base->reboot_status, 0xF000000);
|
||||
|
||||
writel(1, &slcr_base->pss_rst_ctrl);
|
||||
}
|
|
@ -83,9 +83,9 @@ int timer_init(void)
|
|||
emask);
|
||||
|
||||
/* Reset time */
|
||||
gd->lastinc = readl(&timer_base->counter) /
|
||||
gd->arch.lastinc = readl(&timer_base->counter) /
|
||||
(TIMER_TICK_HZ / CONFIG_SYS_HZ);
|
||||
gd->tbl = 0;
|
||||
gd->arch.tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,16 +100,16 @@ ulong get_timer_masked(void)
|
|||
|
||||
now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ);
|
||||
|
||||
if (gd->lastinc >= now) {
|
||||
if (gd->arch.lastinc >= now) {
|
||||
/* Normal mode */
|
||||
gd->tbl += gd->lastinc - now;
|
||||
gd->arch.tbl += gd->arch.lastinc - now;
|
||||
} else {
|
||||
/* We have an overflow ... */
|
||||
gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now;
|
||||
gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now;
|
||||
}
|
||||
gd->lastinc = now;
|
||||
gd->arch.lastinc = now;
|
||||
|
||||
return gd->tbl;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
|
|
|
@ -70,23 +70,23 @@ unsigned long long get_ticks(void)
|
|||
|
||||
if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
|
||||
/* rollover of timestamp timer register */
|
||||
gd->timestamp += (0xFFFFFFFF - gd->lastinc) + now + 1;
|
||||
gd->arch.timestamp += (0xFFFFFFFF - gd->arch.lastinc) + now + 1;
|
||||
writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
|
||||
} else {
|
||||
/* move stamp forward with absolut diff ticks */
|
||||
gd->timestamp += (now - gd->lastinc);
|
||||
gd->arch.timestamp += (now - gd->arch.lastinc);
|
||||
}
|
||||
gd->lastinc = now;
|
||||
return gd->timestamp;
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.timestamp;
|
||||
}
|
||||
|
||||
|
||||
void reset_timer_masked(void)
|
||||
{
|
||||
/* capture current timestamp counter */
|
||||
gd->lastinc = readl(IXP425_OSTS_B);
|
||||
gd->arch.lastinc = readl(IXP425_OSTS_B);
|
||||
/* start "advancing" time stamp from 0 */
|
||||
gd->timestamp = 0;
|
||||
gd->arch.timestamp = 0;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
|
|
|
@ -31,8 +31,8 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
#define TIMER_LOAD_VAL 0xffffffff
|
||||
|
||||
#define timestamp (gd->tbl)
|
||||
#define lastinc (gd->lastinc)
|
||||
#define timestamp (gd->arch.tbl)
|
||||
#define lastinc (gd->arch.lastinc)
|
||||
|
||||
#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS)
|
||||
#define TIMER_FREQ_HZ 3250000
|
||||
|
|
|
@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk
|
|||
LIB = $(obj)libcputegra-common.o
|
||||
|
||||
SOBJS += lowlevel_init.o
|
||||
COBJS-y += ap.o board.o sys_info.o timer.o
|
||||
COBJS-y += ap.o board.o sys_info.o timer.o clock.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
|
||||
|
|
|
@ -20,13 +20,18 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Tegra AP (Application Processor) code */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/gp_padctrl.h>
|
||||
#include <asm/arch-tegra/ap.h>
|
||||
#include <asm/arch-tegra/clock.h>
|
||||
#include <asm/arch-tegra/fuse.h>
|
||||
#include <asm/arch-tegra/pmc.h>
|
||||
#include <asm/arch-tegra/scu.h>
|
||||
#include <asm/arch-tegra/tegra.h>
|
||||
#include <asm/arch-tegra/warmboot.h>
|
||||
|
||||
int tegra_get_chip_type(void)
|
||||
|
@ -38,7 +43,7 @@ int tegra_get_chip_type(void)
|
|||
/*
|
||||
* This is undocumented, Chip ID is bits 15:8 of the register
|
||||
* APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
|
||||
* Tegra30
|
||||
* Tegra30, and 0x35 for T114.
|
||||
*/
|
||||
gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
|
||||
rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
|
||||
|
@ -58,6 +63,18 @@ int tegra_get_chip_type(void)
|
|||
return TEGRA_SOC_T25;
|
||||
}
|
||||
break;
|
||||
case CHIPID_TEGRA30:
|
||||
switch (tegra_sku_id) {
|
||||
case SKU_ID_T30:
|
||||
return TEGRA_SOC_T30;
|
||||
}
|
||||
break;
|
||||
case CHIPID_TEGRA114:
|
||||
switch (tegra_sku_id) {
|
||||
case SKU_ID_T114_ENG:
|
||||
return TEGRA_SOC_T114;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* unknown sku id */
|
||||
return TEGRA_SOC_UNKNOWN;
|
||||
|
@ -93,7 +110,7 @@ static u32 get_odmdata(void)
|
|||
|
||||
u32 bct_start, odmdata;
|
||||
|
||||
bct_start = readl(AP20_BASE_PA_SRAM + NVBOOTINFOTABLE_BCTPTR);
|
||||
bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR);
|
||||
odmdata = readl(bct_start + BCT_ODMDATA_OFFSET);
|
||||
|
||||
return odmdata;
|
||||
|
@ -127,5 +144,5 @@ void s_init(void)
|
|||
"orr r0, r0, #0x41\n"
|
||||
"mcr p15, 0, r0, c1, c0, 1\n");
|
||||
|
||||
/* FIXME: should have ap20's L2 disabled too? */
|
||||
/* FIXME: should have SoC's L2 disabled too? */
|
||||
}
|
||||
|
|
|
@ -37,8 +37,10 @@ enum {
|
|||
/* UARTs which we can enable */
|
||||
UARTA = 1 << 0,
|
||||
UARTB = 1 << 1,
|
||||
UARTC = 1 << 2,
|
||||
UARTD = 1 << 3,
|
||||
UART_COUNT = 4,
|
||||
UARTE = 1 << 4,
|
||||
UART_COUNT = 5,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -54,16 +56,37 @@ unsigned int query_sdram_size(void)
|
|||
reg = readl(&pmc->pmc_scratch20);
|
||||
debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
|
||||
|
||||
/* bits 31:28 in OdmData are used for RAM size */
|
||||
#if defined(CONFIG_TEGRA20)
|
||||
/* bits 30:28 in OdmData are used for RAM size on T20 */
|
||||
reg &= 0x70000000;
|
||||
|
||||
switch ((reg) >> 28) {
|
||||
case 1:
|
||||
return 0x10000000; /* 256 MB */
|
||||
case 0:
|
||||
case 2:
|
||||
default:
|
||||
return 0x20000000; /* 512 MB */
|
||||
case 3:
|
||||
return 0x40000000; /* 1GB */
|
||||
}
|
||||
#else /* Tegra30/Tegra114 */
|
||||
/* bits 31:28 in OdmData are used for RAM size on T30 */
|
||||
switch ((reg) >> 28) {
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
return 0x10000000; /* 256 MB */
|
||||
case 2:
|
||||
return 0x20000000; /* 512 MB */
|
||||
case 3:
|
||||
return 0x30000000; /* 768 MB */
|
||||
case 4:
|
||||
return 0x40000000; /* 1GB */
|
||||
case 8:
|
||||
return 0x7ff00000; /* 2GB - 1MB */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
|
@ -82,19 +105,33 @@ int checkboard(void)
|
|||
#endif /* CONFIG_DISPLAY_BOARDINFO */
|
||||
|
||||
static int uart_configs[] = {
|
||||
#if defined(CONFIG_TEGRA_UARTA_UAA_UAB)
|
||||
#if defined(CONFIG_TEGRA20)
|
||||
#if defined(CONFIG_TEGRA_UARTA_UAA_UAB)
|
||||
FUNCMUX_UART1_UAA_UAB,
|
||||
#elif defined(CONFIG_TEGRA_UARTA_GPU)
|
||||
#elif defined(CONFIG_TEGRA_UARTA_GPU)
|
||||
FUNCMUX_UART1_GPU,
|
||||
#elif defined(CONFIG_TEGRA_UARTA_SDIO1)
|
||||
#elif defined(CONFIG_TEGRA_UARTA_SDIO1)
|
||||
FUNCMUX_UART1_SDIO1,
|
||||
#else
|
||||
#else
|
||||
FUNCMUX_UART1_IRRX_IRTX,
|
||||
#endif
|
||||
FUNCMUX_UART2_IRDA,
|
||||
FUNCMUX_UART2_UAD,
|
||||
-1,
|
||||
FUNCMUX_UART4_GMC,
|
||||
-1,
|
||||
#elif defined(CONFIG_TEGRA30)
|
||||
FUNCMUX_UART1_ULPI, /* UARTA */
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
#else /* Tegra114 */
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
FUNCMUX_UART4_GMI, /* UARTD */
|
||||
-1,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -109,6 +146,7 @@ static void setup_uarts(int uart_ids)
|
|||
PERIPH_ID_UART2,
|
||||
PERIPH_ID_UART3,
|
||||
PERIPH_ID_UART4,
|
||||
PERIPH_ID_UART5,
|
||||
};
|
||||
size_t i;
|
||||
|
||||
|
@ -132,8 +170,14 @@ void board_init_uart_f(void)
|
|||
#ifdef CONFIG_TEGRA_ENABLE_UARTB
|
||||
uart_ids |= UARTB;
|
||||
#endif
|
||||
#ifdef CONFIG_TEGRA_ENABLE_UARTC
|
||||
uart_ids |= UARTC;
|
||||
#endif
|
||||
#ifdef CONFIG_TEGRA_ENABLE_UARTD
|
||||
uart_ids |= UARTD;
|
||||
#endif
|
||||
#ifdef CONFIG_TEGRA_ENABLE_UARTE
|
||||
uart_ids |= UARTE;
|
||||
#endif
|
||||
setup_uarts(uart_ids);
|
||||
}
|
||||
|
|
560
arch/arm/cpu/tegra-common/clock.c
Normal file
560
arch/arm/cpu/tegra-common/clock.c
Normal file
|
@ -0,0 +1,560 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra SoC common clock control functions */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/clk_rst.h>
|
||||
#include <asm/arch-tegra/timer.h>
|
||||
#include <div64.h>
|
||||
#include <fdtdec.h>
|
||||
|
||||
/*
|
||||
* This is our record of the current clock rate of each clock. We don't
|
||||
* fill all of these in since we are only really interested in clocks which
|
||||
* we use as parents.
|
||||
*/
|
||||
static unsigned pll_rate[CLOCK_ID_COUNT];
|
||||
|
||||
/*
|
||||
* The oscillator frequency is fixed to one of four set values. Based on this
|
||||
* the other clocks are set up appropriately.
|
||||
*/
|
||||
static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
|
||||
13000000,
|
||||
19200000,
|
||||
12000000,
|
||||
26000000,
|
||||
};
|
||||
|
||||
/* return 1 if a peripheral ID is in range */
|
||||
#define clock_type_id_isvalid(id) ((id) >= 0 && \
|
||||
(id) < CLOCK_TYPE_COUNT)
|
||||
|
||||
char pllp_valid = 1; /* PLLP is set up correctly */
|
||||
|
||||
/* return 1 if a periphc_internal_id is in range */
|
||||
#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
|
||||
(id) < PERIPHC_COUNT)
|
||||
|
||||
/* number of clock outputs of a PLL */
|
||||
static const u8 pll_num_clkouts[] = {
|
||||
1, /* PLLC */
|
||||
1, /* PLLM */
|
||||
4, /* PLLP */
|
||||
1, /* PLLA */
|
||||
0, /* PLLU */
|
||||
0, /* PLLD */
|
||||
};
|
||||
|
||||
int clock_get_osc_bypass(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the registers of the given pll */
|
||||
static struct clk_pll *get_pll(enum clock_id clkid)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
|
||||
assert(clock_id_is_pll(clkid));
|
||||
return &clkrst->crc_pll[clkid];
|
||||
}
|
||||
|
||||
int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
|
||||
u32 *divp, u32 *cpcon, u32 *lfcon)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(clkid);
|
||||
u32 data;
|
||||
|
||||
assert(clkid != CLOCK_ID_USB);
|
||||
|
||||
/* Safety check, adds to code size but is small */
|
||||
if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB)
|
||||
return -1;
|
||||
data = readl(&pll->pll_base);
|
||||
*divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
|
||||
*divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT;
|
||||
*divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
|
||||
data = readl(&pll->pll_misc);
|
||||
*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT;
|
||||
*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
|
||||
u32 divp, u32 cpcon, u32 lfcon)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(clkid);
|
||||
u32 data;
|
||||
|
||||
/*
|
||||
* We cheat by treating all PLL (except PLLU) in the same fashion.
|
||||
* This works only because:
|
||||
* - same fields are always mapped at same offsets, except DCCON
|
||||
* - DCCON is always 0, doesn't conflict
|
||||
* - M,N, P of PLLP values are ignored for PLLP
|
||||
*/
|
||||
data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
|
||||
writel(data, &pll->pll_misc);
|
||||
|
||||
data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
|
||||
(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
|
||||
|
||||
if (clkid == CLOCK_ID_USB)
|
||||
data |= divp << PLLU_VCO_FREQ_SHIFT;
|
||||
else
|
||||
data |= divp << PLL_DIVP_SHIFT;
|
||||
writel(data, &pll->pll_base);
|
||||
|
||||
/* calculate the stable time */
|
||||
return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US;
|
||||
}
|
||||
|
||||
void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source,
|
||||
unsigned divisor)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
u32 value;
|
||||
|
||||
value = readl(reg);
|
||||
|
||||
value &= ~OUT_CLK_SOURCE_MASK;
|
||||
value |= source << OUT_CLK_SOURCE_SHIFT;
|
||||
|
||||
value &= ~OUT_CLK_DIVISOR_MASK;
|
||||
value |= divisor << OUT_CLK_DIVISOR_SHIFT;
|
||||
|
||||
writel(value, reg);
|
||||
}
|
||||
|
||||
void clock_ll_set_source(enum periph_id periph_id, unsigned source)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
|
||||
clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
|
||||
source << OUT_CLK_SOURCE_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the parent's rate and the required rate for the children, this works
|
||||
* out the peripheral clock divider to use, in 7.1 binary format.
|
||||
*
|
||||
* @param divider_bits number of divider bits (8 or 16)
|
||||
* @param parent_rate clock rate of parent clock in Hz
|
||||
* @param rate required clock rate for this clock
|
||||
* @return divider which should be used
|
||||
*/
|
||||
static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate,
|
||||
unsigned long rate)
|
||||
{
|
||||
u64 divider = parent_rate * 2;
|
||||
unsigned max_divider = 1 << divider_bits;
|
||||
|
||||
divider += rate - 1;
|
||||
do_div(divider, rate);
|
||||
|
||||
if ((s64)divider - 2 < 0)
|
||||
return 0;
|
||||
|
||||
if ((s64)divider - 2 >= max_divider)
|
||||
return -1;
|
||||
|
||||
return divider - 2;
|
||||
}
|
||||
|
||||
int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(clkid);
|
||||
int data = 0, div = 0, offset = 0;
|
||||
|
||||
if (!clock_id_is_pll(clkid))
|
||||
return -1;
|
||||
|
||||
if (pllout + 1 > pll_num_clkouts[clkid])
|
||||
return -1;
|
||||
|
||||
div = clk_get_divider(8, pll_rate[clkid], rate);
|
||||
|
||||
if (div < 0)
|
||||
return -1;
|
||||
|
||||
/* out2 and out4 are in the high part of the register */
|
||||
if (pllout == PLL_OUT2 || pllout == PLL_OUT4)
|
||||
offset = 16;
|
||||
|
||||
data = (div << PLL_OUT_RATIO_SHIFT) |
|
||||
PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN;
|
||||
clrsetbits_le32(&pll->pll_out[pllout >> 1],
|
||||
PLL_OUT_RATIO_MASK << offset, data << offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the parent's rate and the divider in 7.1 format, this works out the
|
||||
* resulting peripheral clock rate.
|
||||
*
|
||||
* @param parent_rate clock rate of parent clock in Hz
|
||||
* @param divider which should be used in 7.1 format
|
||||
* @return effective clock rate of peripheral
|
||||
*/
|
||||
static unsigned long get_rate_from_divider(unsigned long parent_rate,
|
||||
int divider)
|
||||
{
|
||||
u64 rate;
|
||||
|
||||
rate = (u64)parent_rate * 2;
|
||||
do_div(rate, divider + 2);
|
||||
return rate;
|
||||
}
|
||||
|
||||
unsigned long clock_get_periph_rate(enum periph_id periph_id,
|
||||
enum clock_id parent)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
|
||||
return get_rate_from_divider(pll_rate[parent],
|
||||
(readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the best available 7.1 format divisor given a parent clock rate and
|
||||
* required child clock rate. This function assumes that a second-stage
|
||||
* divisor is available which can divide by powers of 2 from 1 to 256.
|
||||
*
|
||||
* @param divider_bits number of divider bits (8 or 16)
|
||||
* @param parent_rate clock rate of parent clock in Hz
|
||||
* @param rate required clock rate for this clock
|
||||
* @param extra_div value for the second-stage divisor (not set if this
|
||||
* function returns -1.
|
||||
* @return divider which should be used, or -1 if nothing is valid
|
||||
*
|
||||
*/
|
||||
static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
|
||||
unsigned long rate, int *extra_div)
|
||||
{
|
||||
int shift;
|
||||
int best_divider = -1;
|
||||
int best_error = rate;
|
||||
|
||||
/* try dividers from 1 to 256 and find closest match */
|
||||
for (shift = 0; shift <= 8 && best_error > 0; shift++) {
|
||||
unsigned divided_parent = parent_rate >> shift;
|
||||
int divider = clk_get_divider(divider_bits, divided_parent,
|
||||
rate);
|
||||
unsigned effective_rate = get_rate_from_divider(divided_parent,
|
||||
divider);
|
||||
int error = rate - effective_rate;
|
||||
|
||||
/* Given a valid divider, look for the lowest error */
|
||||
if (divider != -1 && error < best_error) {
|
||||
best_error = error;
|
||||
*extra_div = 1 << shift;
|
||||
best_divider = divider;
|
||||
}
|
||||
}
|
||||
|
||||
/* return what we found - *extra_div will already be set */
|
||||
return best_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust peripheral PLL to use the given divider and source.
|
||||
*
|
||||
* @param periph_id peripheral to adjust
|
||||
* @param source Source number (0-3 or 0-7)
|
||||
* @param mux_bits Number of mux bits (2 or 4)
|
||||
* @param divider Required divider in 7.1 or 15.1 format
|
||||
* @return 0 if ok, -1 on error (requesting a parent clock which is not valid
|
||||
* for this peripheral)
|
||||
*/
|
||||
static int adjust_periph_pll(enum periph_id periph_id, int source,
|
||||
int mux_bits, unsigned divider)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
|
||||
clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK,
|
||||
divider << OUT_CLK_DIVISOR_SHIFT);
|
||||
udelay(1);
|
||||
|
||||
/* work out the source clock and set it */
|
||||
if (source < 0)
|
||||
return -1;
|
||||
if (mux_bits == 4) {
|
||||
clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK,
|
||||
source << OUT_CLK_SOURCE4_SHIFT);
|
||||
} else {
|
||||
clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
|
||||
source << OUT_CLK_SOURCE_SHIFT);
|
||||
}
|
||||
udelay(2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned clock_adjust_periph_pll_div(enum periph_id periph_id,
|
||||
enum clock_id parent, unsigned rate, int *extra_div)
|
||||
{
|
||||
unsigned effective_rate;
|
||||
int mux_bits, divider_bits, source;
|
||||
int divider;
|
||||
|
||||
/* work out the source clock and set it */
|
||||
source = get_periph_clock_source(periph_id, parent, &mux_bits,
|
||||
÷r_bits);
|
||||
|
||||
if (extra_div)
|
||||
divider = find_best_divider(divider_bits, pll_rate[parent],
|
||||
rate, extra_div);
|
||||
else
|
||||
divider = clk_get_divider(divider_bits, pll_rate[parent],
|
||||
rate);
|
||||
assert(divider >= 0);
|
||||
if (adjust_periph_pll(periph_id, source, mux_bits, divider))
|
||||
return -1U;
|
||||
debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate,
|
||||
get_periph_source_reg(periph_id),
|
||||
readl(get_periph_source_reg(periph_id)));
|
||||
|
||||
/* Check what we ended up with. This shouldn't matter though */
|
||||
effective_rate = clock_get_periph_rate(periph_id, parent);
|
||||
if (extra_div)
|
||||
effective_rate /= *extra_div;
|
||||
if (rate != effective_rate)
|
||||
debug("Requested clock rate %u not honored (got %u)\n",
|
||||
rate, effective_rate);
|
||||
return effective_rate;
|
||||
}
|
||||
|
||||
unsigned clock_start_periph_pll(enum periph_id periph_id,
|
||||
enum clock_id parent, unsigned rate)
|
||||
{
|
||||
unsigned effective_rate;
|
||||
|
||||
reset_set_enable(periph_id, 1);
|
||||
clock_enable(periph_id);
|
||||
|
||||
effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate,
|
||||
NULL);
|
||||
|
||||
reset_set_enable(periph_id, 0);
|
||||
return effective_rate;
|
||||
}
|
||||
|
||||
void clock_enable(enum periph_id clkid)
|
||||
{
|
||||
clock_set_enable(clkid, 1);
|
||||
}
|
||||
|
||||
void clock_disable(enum periph_id clkid)
|
||||
{
|
||||
clock_set_enable(clkid, 0);
|
||||
}
|
||||
|
||||
void reset_periph(enum periph_id periph_id, int us_delay)
|
||||
{
|
||||
/* Put peripheral into reset */
|
||||
reset_set_enable(periph_id, 1);
|
||||
udelay(us_delay);
|
||||
|
||||
/* Remove reset */
|
||||
reset_set_enable(periph_id, 0);
|
||||
|
||||
udelay(us_delay);
|
||||
}
|
||||
|
||||
void reset_cmplx_set_enable(int cpu, int which, int reset)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 mask;
|
||||
|
||||
/* Form the mask, which depends on the cpu chosen (2 or 4) */
|
||||
assert(cpu >= 0 && cpu < MAX_NUM_CPU);
|
||||
mask = which << cpu;
|
||||
|
||||
/* either enable or disable those reset for that CPU */
|
||||
if (reset)
|
||||
writel(mask, &clkrst->crc_cpu_cmplx_set);
|
||||
else
|
||||
writel(mask, &clkrst->crc_cpu_cmplx_clr);
|
||||
}
|
||||
|
||||
unsigned clock_get_rate(enum clock_id clkid)
|
||||
{
|
||||
struct clk_pll *pll;
|
||||
u32 base;
|
||||
u32 divm;
|
||||
u64 parent_rate;
|
||||
u64 rate;
|
||||
|
||||
parent_rate = osc_freq[clock_get_osc_freq()];
|
||||
if (clkid == CLOCK_ID_OSC)
|
||||
return parent_rate;
|
||||
|
||||
pll = get_pll(clkid);
|
||||
base = readl(&pll->pll_base);
|
||||
|
||||
/* Oh for bf_unpack()... */
|
||||
rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT);
|
||||
divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
|
||||
if (clkid == CLOCK_ID_USB)
|
||||
divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT;
|
||||
else
|
||||
divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
|
||||
do_div(rate, divm);
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output frequency you want for each PLL clock.
|
||||
* PLL output frequencies are programmed by setting their N, M and P values.
|
||||
* The governing equations are:
|
||||
* VCO = (Fi / m) * n, Fo = VCO / (2^p)
|
||||
* where Fo is the output frequency from the PLL.
|
||||
* Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
|
||||
* 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
|
||||
* Please see Tegra TRM section 5.3 to get the detail for PLL Programming
|
||||
*
|
||||
* @param n PLL feedback divider(DIVN)
|
||||
* @param m PLL input divider(DIVN)
|
||||
* @param p post divider(DIVP)
|
||||
* @param cpcon base PLL charge pump(CPCON)
|
||||
* @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
|
||||
* be overriden), 1 if PLL is already correct
|
||||
*/
|
||||
int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
|
||||
{
|
||||
u32 base_reg;
|
||||
u32 misc_reg;
|
||||
struct clk_pll *pll;
|
||||
|
||||
pll = get_pll(clkid);
|
||||
|
||||
base_reg = readl(&pll->pll_base);
|
||||
|
||||
/* Set BYPASS, m, n and p to PLL_BASE */
|
||||
base_reg &= ~PLL_DIVM_MASK;
|
||||
base_reg |= m << PLL_DIVM_SHIFT;
|
||||
|
||||
base_reg &= ~PLL_DIVN_MASK;
|
||||
base_reg |= n << PLL_DIVN_SHIFT;
|
||||
|
||||
base_reg &= ~PLL_DIVP_MASK;
|
||||
base_reg |= p << PLL_DIVP_SHIFT;
|
||||
|
||||
if (clkid == CLOCK_ID_PERIPH) {
|
||||
/*
|
||||
* If the PLL is already set up, check that it is correct
|
||||
* and record this info for clock_verify() to check.
|
||||
*/
|
||||
if (base_reg & PLL_BASE_OVRRIDE_MASK) {
|
||||
base_reg |= PLL_ENABLE_MASK;
|
||||
if (base_reg != readl(&pll->pll_base))
|
||||
pllp_valid = 0;
|
||||
return pllp_valid ? 1 : -1;
|
||||
}
|
||||
base_reg |= PLL_BASE_OVRRIDE_MASK;
|
||||
}
|
||||
|
||||
base_reg |= PLL_BYPASS_MASK;
|
||||
writel(base_reg, &pll->pll_base);
|
||||
|
||||
/* Set cpcon to PLL_MISC */
|
||||
misc_reg = readl(&pll->pll_misc);
|
||||
misc_reg &= ~PLL_CPCON_MASK;
|
||||
misc_reg |= cpcon << PLL_CPCON_SHIFT;
|
||||
writel(misc_reg, &pll->pll_misc);
|
||||
|
||||
/* Enable PLL */
|
||||
base_reg |= PLL_ENABLE_MASK;
|
||||
writel(base_reg, &pll->pll_base);
|
||||
|
||||
/* Disable BYPASS */
|
||||
base_reg &= ~PLL_BYPASS_MASK;
|
||||
writel(base_reg, &pll->pll_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clock_ll_start_uart(enum periph_id periph_id)
|
||||
{
|
||||
/* Assert UART reset and enable clock */
|
||||
reset_set_enable(periph_id, 1);
|
||||
clock_enable(periph_id);
|
||||
clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
|
||||
|
||||
/* wait for 2us */
|
||||
udelay(2);
|
||||
|
||||
/* De-assert reset to UART */
|
||||
reset_set_enable(periph_id, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
int clock_decode_periph_id(const void *blob, int node)
|
||||
{
|
||||
enum periph_id id;
|
||||
u32 cell[2];
|
||||
int err;
|
||||
|
||||
err = fdtdec_get_int_array(blob, node, "clocks", cell,
|
||||
ARRAY_SIZE(cell));
|
||||
if (err)
|
||||
return -1;
|
||||
id = clk_id_to_periph_id(cell[1]);
|
||||
assert(clock_periph_id_isvalid(id));
|
||||
return id;
|
||||
}
|
||||
#endif /* CONFIG_OF_CONTROL */
|
||||
|
||||
int clock_verify(void)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH);
|
||||
u32 reg = readl(&pll->pll_base);
|
||||
|
||||
if (!pllp_valid) {
|
||||
printf("Warning: PLLP %x is not correct\n", reg);
|
||||
return -1;
|
||||
}
|
||||
debug("PLLP %x is correct\n", reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clock_init(void)
|
||||
{
|
||||
pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY);
|
||||
pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH);
|
||||
pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL);
|
||||
pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
|
||||
pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
|
||||
pll_rate[CLOCK_ID_XCPU] = clock_get_rate(CLOCK_ID_XCPU);
|
||||
debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
|
||||
debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]);
|
||||
debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]);
|
||||
debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]);
|
||||
debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]);
|
||||
}
|
|
@ -22,12 +22,26 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#ifdef CONFIG_DISPLAY_CPUINFO
|
||||
void upstring(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print CPU information */
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
puts("TEGRA20\n");
|
||||
char soc_name[10];
|
||||
|
||||
strncpy(soc_name, CONFIG_SYS_SOC, 10);
|
||||
upstring(soc_name);
|
||||
puts(soc_name);
|
||||
puts("\n");
|
||||
|
||||
/* TBD: Add printf of major/minor rev info, stepping, etc. */
|
||||
return 0;
|
||||
|
|
|
@ -75,14 +75,14 @@ ulong get_timer_masked(void)
|
|||
/* current tick value */
|
||||
now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ);
|
||||
|
||||
if (now >= gd->lastinc) /* normal mode (non roll) */
|
||||
if (now >= gd->arch.lastinc) /* normal mode (non roll) */
|
||||
/* move stamp forward with absolute diff ticks */
|
||||
gd->tbl += (now - gd->lastinc);
|
||||
gd->arch.tbl += (now - gd->arch.lastinc);
|
||||
else /* we have rollover of incrementer */
|
||||
gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ))
|
||||
- gd->lastinc) + now;
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ))
|
||||
- gd->arch.lastinc) + now;
|
||||
gd->arch.lastinc = now;
|
||||
return gd->arch.tbl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
41
arch/arm/cpu/tegra114-common/Makefile
Normal file
41
arch/arm/cpu/tegra114-common/Makefile
Normal file
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2000-2008
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC)-common.o
|
||||
|
||||
COBJS-y += clock.o funcmux.o pinmux.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
655
arch/arm/cpu/tegra114-common/clock.c
Normal file
655
arch/arm/cpu/tegra114-common/clock.c
Normal file
|
@ -0,0 +1,655 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra114 Clock control functions */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/clk_rst.h>
|
||||
#include <asm/arch-tegra/timer.h>
|
||||
#include <div64.h>
|
||||
#include <fdtdec.h>
|
||||
|
||||
/*
|
||||
* Clock types that we can use as a source. The Tegra114 has muxes for the
|
||||
* peripheral clocks, and in most cases there are four options for the clock
|
||||
* source. This gives us a clock 'type' and exploits what commonality exists
|
||||
* in the device.
|
||||
*
|
||||
* Letters are obvious, except for T which means CLK_M, and S which means the
|
||||
* clock derived from 32KHz. Beware that CLK_M (also called OSC in the
|
||||
* datasheet) and PLL_M are different things. The former is the basic
|
||||
* clock supplied to the SOC from an external oscillator. The latter is the
|
||||
* memory clock PLL.
|
||||
*
|
||||
* See definitions in clock_id in the header file.
|
||||
*/
|
||||
enum clock_type_id {
|
||||
CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */
|
||||
CLOCK_TYPE_MCPA, /* and so on */
|
||||
CLOCK_TYPE_MCPT,
|
||||
CLOCK_TYPE_PCM,
|
||||
CLOCK_TYPE_PCMT,
|
||||
CLOCK_TYPE_PCMT16,
|
||||
CLOCK_TYPE_PDCT,
|
||||
CLOCK_TYPE_ACPT,
|
||||
CLOCK_TYPE_ASPTE,
|
||||
CLOCK_TYPE_PMDACD2T,
|
||||
CLOCK_TYPE_PCST,
|
||||
|
||||
CLOCK_TYPE_COUNT,
|
||||
CLOCK_TYPE_NONE = -1, /* invalid clock type */
|
||||
};
|
||||
|
||||
enum {
|
||||
CLOCK_MAX_MUX = 8 /* number of source options for each clock */
|
||||
};
|
||||
|
||||
enum {
|
||||
MASK_BITS_31_30 = 2, /* num of bits used to specify clock source */
|
||||
MASK_BITS_31_29,
|
||||
MASK_BITS_29_28,
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock source mux for each clock type. This just converts our enum into
|
||||
* a list of mux sources for use by the code.
|
||||
*
|
||||
* Note:
|
||||
* The extra column in each clock source array is used to store the mask
|
||||
* bits in its register for the source.
|
||||
*/
|
||||
#define CLK(x) CLOCK_ID_ ## x
|
||||
static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = {
|
||||
{ CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC),
|
||||
CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_29},
|
||||
{ CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO),
|
||||
CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE),
|
||||
MASK_BITS_31_29},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_29_28}
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock type for each peripheral clock source. We put the name in each
|
||||
* record just so it is easy to match things up
|
||||
*/
|
||||
#define TYPE(name, type) type
|
||||
static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
|
||||
/* 0x00 */
|
||||
TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM),
|
||||
TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x08 */
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_I2C5, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T),
|
||||
TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T),
|
||||
|
||||
/* 0x10 */
|
||||
TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA),
|
||||
|
||||
/* 0x18 */
|
||||
TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */
|
||||
TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x20 */
|
||||
TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT),
|
||||
TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT),
|
||||
TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT),
|
||||
|
||||
/* 0x28 */
|
||||
TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x30 */
|
||||
TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
|
||||
/* 0x38h */ /* Jumps to reg offset 0x3B0h */
|
||||
TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */
|
||||
TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x40 */
|
||||
TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */
|
||||
TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE),
|
||||
|
||||
/* 0x48 */
|
||||
TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE),
|
||||
TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE),
|
||||
TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */
|
||||
TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
|
||||
/* 0x50 */
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */
|
||||
TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT),
|
||||
};
|
||||
|
||||
/*
|
||||
* This array translates a periph_id to a periphc_internal_id
|
||||
*
|
||||
* Not present/matched up:
|
||||
* uint vi_sensor; _VI_SENSOR_0, 0x1A8
|
||||
* SPDIF - which is both 0x08 and 0x0c
|
||||
*
|
||||
*/
|
||||
#define NONE(name) (-1)
|
||||
#define OFFSET(name, value) PERIPHC_ ## name
|
||||
static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
|
||||
/* Low word: 31:0 */
|
||||
NONE(CPU),
|
||||
NONE(COP),
|
||||
NONE(TRIGSYS),
|
||||
NONE(RESERVED3),
|
||||
NONE(RTC),
|
||||
NONE(TMR),
|
||||
PERIPHC_UART1,
|
||||
PERIPHC_UART2, /* and vfir 0x68 */
|
||||
|
||||
/* 8 */
|
||||
NONE(GPIO),
|
||||
PERIPHC_SDMMC2,
|
||||
NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */
|
||||
PERIPHC_I2S1,
|
||||
PERIPHC_I2C1,
|
||||
PERIPHC_NDFLASH,
|
||||
PERIPHC_SDMMC1,
|
||||
PERIPHC_SDMMC4,
|
||||
|
||||
/* 16 */
|
||||
NONE(RESERVED16),
|
||||
PERIPHC_PWM,
|
||||
PERIPHC_I2S2,
|
||||
PERIPHC_EPP,
|
||||
PERIPHC_VI,
|
||||
PERIPHC_G2D,
|
||||
NONE(USBD),
|
||||
NONE(ISP),
|
||||
|
||||
/* 24 */
|
||||
PERIPHC_G3D,
|
||||
NONE(RESERVED25),
|
||||
PERIPHC_DISP2,
|
||||
PERIPHC_DISP1,
|
||||
PERIPHC_HOST1X,
|
||||
NONE(VCP),
|
||||
PERIPHC_I2S0,
|
||||
NONE(CACHE2),
|
||||
|
||||
/* Middle word: 63:32 */
|
||||
NONE(MEM),
|
||||
NONE(AHBDMA),
|
||||
NONE(APBDMA),
|
||||
NONE(RESERVED35),
|
||||
NONE(RESERVED36),
|
||||
NONE(STAT_MON),
|
||||
NONE(RESERVED38),
|
||||
NONE(RESERVED39),
|
||||
|
||||
/* 40 */
|
||||
NONE(KFUSE),
|
||||
NONE(SBC1), /* SBC1, 0x34, is this SPI1? */
|
||||
PERIPHC_NOR,
|
||||
NONE(RESERVED43),
|
||||
PERIPHC_SBC2,
|
||||
NONE(RESERVED45),
|
||||
PERIPHC_SBC3,
|
||||
PERIPHC_I2C5,
|
||||
|
||||
/* 48 */
|
||||
NONE(DSI),
|
||||
PERIPHC_TVO, /* also CVE 0x40 */
|
||||
PERIPHC_MIPI,
|
||||
PERIPHC_HDMI,
|
||||
NONE(CSI),
|
||||
PERIPHC_TVDAC,
|
||||
PERIPHC_I2C2,
|
||||
PERIPHC_UART3,
|
||||
|
||||
/* 56 */
|
||||
NONE(RESERVED56),
|
||||
PERIPHC_EMC,
|
||||
NONE(USB2),
|
||||
NONE(USB3),
|
||||
PERIPHC_MPE,
|
||||
PERIPHC_VDE,
|
||||
NONE(BSEA),
|
||||
NONE(BSEV),
|
||||
|
||||
/* Upper word 95:64 */
|
||||
PERIPHC_SPEEDO,
|
||||
PERIPHC_UART4,
|
||||
PERIPHC_UART5,
|
||||
PERIPHC_I2C3,
|
||||
PERIPHC_SBC4,
|
||||
PERIPHC_SDMMC3,
|
||||
NONE(PCIE),
|
||||
PERIPHC_OWR,
|
||||
|
||||
/* 72 */
|
||||
NONE(AFI),
|
||||
PERIPHC_CSITE,
|
||||
NONE(PCIEXCLK),
|
||||
NONE(AVPUCQ),
|
||||
NONE(RESERVED76),
|
||||
NONE(RESERVED77),
|
||||
NONE(RESERVED78),
|
||||
NONE(DTV),
|
||||
|
||||
/* 80 */
|
||||
PERIPHC_NANDSPEED,
|
||||
PERIPHC_I2CSLOW,
|
||||
NONE(DSIB),
|
||||
NONE(RESERVED83),
|
||||
NONE(IRAMA),
|
||||
NONE(IRAMB),
|
||||
NONE(IRAMC),
|
||||
NONE(IRAMD),
|
||||
|
||||
/* 88 */
|
||||
NONE(CRAM2),
|
||||
NONE(RESERVED89),
|
||||
NONE(MDOUBLER),
|
||||
NONE(RESERVED91),
|
||||
NONE(SUSOUT),
|
||||
NONE(RESERVED93),
|
||||
NONE(RESERVED94),
|
||||
NONE(RESERVED95),
|
||||
|
||||
/* V word: 31:0 */
|
||||
NONE(CPUG),
|
||||
NONE(CPULP),
|
||||
PERIPHC_G3D2,
|
||||
PERIPHC_MSELECT,
|
||||
PERIPHC_TSENSOR,
|
||||
PERIPHC_I2S3,
|
||||
PERIPHC_I2S4,
|
||||
PERIPHC_I2C4,
|
||||
|
||||
/* 08 */
|
||||
PERIPHC_SBC5,
|
||||
PERIPHC_SBC6,
|
||||
PERIPHC_AUDIO,
|
||||
NONE(APBIF),
|
||||
PERIPHC_DAM0,
|
||||
PERIPHC_DAM1,
|
||||
PERIPHC_DAM2,
|
||||
PERIPHC_HDA2CODEC2X,
|
||||
|
||||
/* 16 */
|
||||
NONE(ATOMICS),
|
||||
NONE(RESERVED17),
|
||||
NONE(RESERVED18),
|
||||
NONE(RESERVED19),
|
||||
NONE(RESERVED20),
|
||||
NONE(RESERVED21),
|
||||
NONE(RESERVED22),
|
||||
PERIPHC_ACTMON,
|
||||
|
||||
/* 24 */
|
||||
NONE(RESERVED24),
|
||||
NONE(RESERVED25),
|
||||
NONE(RESERVED26),
|
||||
NONE(RESERVED27),
|
||||
PERIPHC_SATA,
|
||||
PERIPHC_HDA,
|
||||
NONE(RESERVED30),
|
||||
NONE(RESERVED31),
|
||||
|
||||
/* W word: 31:0 */
|
||||
NONE(HDA2HDMICODEC),
|
||||
NONE(RESERVED1_SATACOLD),
|
||||
NONE(RESERVED2_PCIERX0),
|
||||
NONE(RESERVED3_PCIERX1),
|
||||
NONE(RESERVED4_PCIERX2),
|
||||
NONE(RESERVED5_PCIERX3),
|
||||
NONE(RESERVED6_PCIERX4),
|
||||
NONE(RESERVED7_PCIERX5),
|
||||
|
||||
/* 40 */
|
||||
NONE(CEC),
|
||||
NONE(PCIE2_IOBIST),
|
||||
NONE(EMC_IOBIST),
|
||||
NONE(HDMI_IOBIST),
|
||||
NONE(SATA_IOBIST),
|
||||
NONE(MIPI_IOBIST),
|
||||
NONE(EMC1_IOBIST),
|
||||
NONE(XUSB),
|
||||
|
||||
/* 48 */
|
||||
NONE(CILAB),
|
||||
NONE(CILCD),
|
||||
NONE(CILE),
|
||||
NONE(DSIA_LP),
|
||||
NONE(DSIB_LP),
|
||||
NONE(RESERVED21_ENTROPY),
|
||||
NONE(RESERVED22_W),
|
||||
NONE(RESERVED23_W),
|
||||
|
||||
/* 56 */
|
||||
NONE(RESERVED24_W),
|
||||
NONE(AMX0),
|
||||
NONE(ADX0),
|
||||
NONE(DVFS),
|
||||
NONE(XUSB_SS),
|
||||
NONE(EMC_DLL),
|
||||
NONE(MC1),
|
||||
NONE(EMC1),
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the oscillator frequency, from the corresponding hardware configuration
|
||||
* field. Note that T30/T114 support 3 new higher freqs, but we map back
|
||||
* to the old T20 freqs. Support for the higher oscillators is TBD.
|
||||
*/
|
||||
enum clock_osc_freq clock_get_osc_freq(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
|
||||
if (reg & 1) /* one of the newer freqs */
|
||||
printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
|
||||
|
||||
return reg >> 2; /* Map to most common (T20) freqs */
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
u32 *get_periph_source_reg(enum periph_id periph_id)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
enum periphc_internal_id internal_id;
|
||||
|
||||
/* Coresight is a special case */
|
||||
if (periph_id == PERIPH_ID_CSI)
|
||||
return &clkrst->crc_clk_src[PERIPH_ID_CSI+1];
|
||||
|
||||
assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT);
|
||||
internal_id = periph_id_to_internal_id[periph_id];
|
||||
assert(internal_id != -1);
|
||||
if (internal_id >= PERIPHC_VW_FIRST) {
|
||||
internal_id -= PERIPHC_VW_FIRST;
|
||||
return &clkrst->crc_clk_src_vw[internal_id];
|
||||
} else
|
||||
return &clkrst->crc_clk_src[internal_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a peripheral ID and the required source clock, this returns which
|
||||
* value should be programmed into the source mux for that peripheral.
|
||||
*
|
||||
* There is special code here to handle the one source type with 5 sources.
|
||||
*
|
||||
* @param periph_id peripheral to start
|
||||
* @param source PLL id of required parent clock
|
||||
* @param mux_bits Set to number of bits in mux register: 2 or 4
|
||||
* @param divider_bits Set to number of divider bits (8 or 16)
|
||||
* @return mux value (0-4, or -1 if not found)
|
||||
*/
|
||||
int get_periph_clock_source(enum periph_id periph_id,
|
||||
enum clock_id parent, int *mux_bits, int *divider_bits)
|
||||
{
|
||||
enum clock_type_id type;
|
||||
enum periphc_internal_id internal_id;
|
||||
int mux;
|
||||
|
||||
assert(clock_periph_id_isvalid(periph_id));
|
||||
|
||||
internal_id = periph_id_to_internal_id[periph_id];
|
||||
assert(periphc_internal_id_isvalid(internal_id));
|
||||
|
||||
type = clock_periph_type[internal_id];
|
||||
assert(clock_type_id_isvalid(type));
|
||||
|
||||
*mux_bits = clock_source[type][CLOCK_MAX_MUX];
|
||||
|
||||
if (type == CLOCK_TYPE_PCMT16)
|
||||
*divider_bits = 16;
|
||||
else
|
||||
*divider_bits = 8;
|
||||
|
||||
for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
|
||||
if (clock_source[type][mux] == parent)
|
||||
return mux;
|
||||
|
||||
/* if we get here, either us or the caller has made a mistake */
|
||||
printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
|
||||
parent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void clock_set_enable(enum periph_id periph_id, int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 *clk;
|
||||
u32 reg;
|
||||
|
||||
/* Enable/disable the clock to this peripheral */
|
||||
assert(clock_periph_id_isvalid(periph_id));
|
||||
if ((int)periph_id < (int)PERIPH_ID_VW_FIRST)
|
||||
clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
|
||||
else
|
||||
clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)];
|
||||
reg = readl(clk);
|
||||
if (enable)
|
||||
reg |= PERIPH_MASK(periph_id);
|
||||
else
|
||||
reg &= ~PERIPH_MASK(periph_id);
|
||||
writel(reg, clk);
|
||||
}
|
||||
|
||||
void reset_set_enable(enum periph_id periph_id, int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 *reset;
|
||||
u32 reg;
|
||||
|
||||
/* Enable/disable reset to the peripheral */
|
||||
assert(clock_periph_id_isvalid(periph_id));
|
||||
if (periph_id < PERIPH_ID_VW_FIRST)
|
||||
reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
|
||||
else
|
||||
reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)];
|
||||
reg = readl(reset);
|
||||
if (enable)
|
||||
reg |= PERIPH_MASK(periph_id);
|
||||
else
|
||||
reg &= ~PERIPH_MASK(periph_id);
|
||||
writel(reg, reset);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
/*
|
||||
* Convert a device tree clock ID to our peripheral ID. They are mostly
|
||||
* the same but we are very cautious so we check that a valid clock ID is
|
||||
* provided.
|
||||
*
|
||||
* @param clk_id Clock ID according to tegra114 device tree binding
|
||||
* @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
|
||||
*/
|
||||
enum periph_id clk_id_to_periph_id(int clk_id)
|
||||
{
|
||||
if (clk_id > PERIPH_ID_COUNT)
|
||||
return PERIPH_ID_NONE;
|
||||
|
||||
switch (clk_id) {
|
||||
case PERIPH_ID_RESERVED3:
|
||||
case PERIPH_ID_RESERVED16:
|
||||
case PERIPH_ID_RESERVED24:
|
||||
case PERIPH_ID_RESERVED35:
|
||||
case PERIPH_ID_RESERVED43:
|
||||
case PERIPH_ID_RESERVED45:
|
||||
case PERIPH_ID_RESERVED56:
|
||||
case PERIPH_ID_RESERVED76:
|
||||
case PERIPH_ID_RESERVED77:
|
||||
case PERIPH_ID_RESERVED78:
|
||||
case PERIPH_ID_RESERVED83:
|
||||
case PERIPH_ID_RESERVED89:
|
||||
case PERIPH_ID_RESERVED91:
|
||||
case PERIPH_ID_RESERVED93:
|
||||
case PERIPH_ID_RESERVED94:
|
||||
case PERIPH_ID_RESERVED95:
|
||||
return PERIPH_ID_NONE;
|
||||
default:
|
||||
return clk_id;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_OF_CONTROL */
|
||||
|
||||
void clock_early_init(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
|
||||
/*
|
||||
* PLLP output frequency set to 408Mhz
|
||||
* PLLC output frequency set to 600Mhz
|
||||
* PLLD output frequency set to 925Mhz
|
||||
*/
|
||||
switch (clock_get_osc_freq()) {
|
||||
case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12);
|
||||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12);
|
||||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12);
|
||||
break;
|
||||
case CLOCK_OSC_FREQ_19_2:
|
||||
default:
|
||||
/*
|
||||
* These are not supported. It is too early to print a
|
||||
* message and the UART likely won't work anyway due to the
|
||||
* oscillator being wrong.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */
|
||||
writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]);
|
||||
|
||||
/* PLLC_MISC: Set LOCK_ENABLE */
|
||||
writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc);
|
||||
udelay(2);
|
||||
|
||||
/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */
|
||||
writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc);
|
||||
udelay(2);
|
||||
}
|
63
arch/arm/cpu/tegra114-common/funcmux.c
Normal file
63
arch/arm/cpu/tegra114-common/funcmux.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra114 high-level function multiplexing */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/funcmux.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
|
||||
int funcmux_select(enum periph_id id, int config)
|
||||
{
|
||||
int bad_config = config != FUNCMUX_DEFAULT;
|
||||
|
||||
switch (id) {
|
||||
case PERIPH_ID_UART4:
|
||||
switch (config) {
|
||||
case FUNCMUX_UART4_GMI:
|
||||
pinmux_set_func(PINGRP_GMI_A16, PMUX_FUNC_UARTD);
|
||||
pinmux_set_func(PINGRP_GMI_A17, PMUX_FUNC_UARTD);
|
||||
pinmux_set_func(PINGRP_GMI_A18, PMUX_FUNC_UARTD);
|
||||
pinmux_set_func(PINGRP_GMI_A19, PMUX_FUNC_UARTD);
|
||||
|
||||
pinmux_set_io(PINGRP_GMI_A16, PMUX_PIN_OUTPUT);
|
||||
pinmux_set_io(PINGRP_GMI_A17, PMUX_PIN_INPUT);
|
||||
pinmux_set_io(PINGRP_GMI_A18, PMUX_PIN_INPUT);
|
||||
pinmux_set_io(PINGRP_GMI_A19, PMUX_PIN_OUTPUT);
|
||||
|
||||
pinmux_tristate_disable(PINGRP_GMI_A16);
|
||||
pinmux_tristate_disable(PINGRP_GMI_A17);
|
||||
pinmux_tristate_disable(PINGRP_GMI_A18);
|
||||
pinmux_tristate_disable(PINGRP_GMI_A19);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Add other periph IDs here as needed */
|
||||
|
||||
default:
|
||||
debug("%s: invalid periph_id %d", __func__, id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bad_config) {
|
||||
debug("%s: invalid config %d for periph_id %d", __func__,
|
||||
config, id);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
506
arch/arm/cpu/tegra114-common/pinmux.c
Normal file
506
arch/arm/cpu/tegra114-common/pinmux.c
Normal file
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra114 pin multiplexing functions */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
|
||||
struct tegra_pingroup_desc {
|
||||
const char *name;
|
||||
enum pmux_func funcs[4];
|
||||
enum pmux_func func_safe;
|
||||
enum pmux_vddio vddio;
|
||||
enum pmux_pin_io io;
|
||||
};
|
||||
|
||||
#define PMUX_MUXCTL_SHIFT 0
|
||||
#define PMUX_PULL_SHIFT 2
|
||||
#define PMUX_TRISTATE_SHIFT 4
|
||||
#define PMUX_TRISTATE_MASK (1 << PMUX_TRISTATE_SHIFT)
|
||||
#define PMUX_IO_SHIFT 5
|
||||
#define PMUX_OD_SHIFT 6
|
||||
#define PMUX_LOCK_SHIFT 7
|
||||
#define PMUX_IO_RESET_SHIFT 8
|
||||
|
||||
/* Convenient macro for defining pin group properties */
|
||||
#define PIN(pg_name, vdd, f0, f1, f2, f3, iod) \
|
||||
{ \
|
||||
.vddio = PMUX_VDDIO_ ## vdd, \
|
||||
.funcs = { \
|
||||
PMUX_FUNC_ ## f0, \
|
||||
PMUX_FUNC_ ## f1, \
|
||||
PMUX_FUNC_ ## f2, \
|
||||
PMUX_FUNC_ ## f3, \
|
||||
}, \
|
||||
.func_safe = PMUX_FUNC_RSVD1, \
|
||||
.io = PMUX_PIN_ ## iod, \
|
||||
}
|
||||
|
||||
/* Input and output pins */
|
||||
#define PINI(pg_name, vdd, f0, f1, f2, f3) \
|
||||
PIN(pg_name, vdd, f0, f1, f2, f3, INPUT)
|
||||
#define PINO(pg_name, vdd, f0, f1, f2, f3) \
|
||||
PIN(pg_name, vdd, f0, f1, f2, f3, OUTPUT)
|
||||
|
||||
const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
|
||||
/* NAME VDD f0 f1 f2 f3 */
|
||||
PINI(ULPI_DATA0, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA1, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA2, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA3, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA4, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA5, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA6, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA7, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_CLK, BB, SPI1, SPI5, UARTD, ULPI),
|
||||
PINI(ULPI_DIR, BB, SPI1, SPI5, UARTD, ULPI),
|
||||
PINI(ULPI_NXT, BB, SPI1, SPI5, UARTD, ULPI),
|
||||
PINI(ULPI_STP, BB, SPI1, SPI5, UARTD, ULPI),
|
||||
PINI(DAP3_FS, BB, I2S2, SPI5, DISPA, DISPB),
|
||||
PINI(DAP3_DIN, BB, I2S2, SPI5, DISPA, DISPB),
|
||||
PINI(DAP3_DOUT, BB, I2S2, SPI5, DISPA, DISPB),
|
||||
PINI(DAP3_SCLK, BB, I2S2, SPI5, DISPA, DISPB),
|
||||
PINI(GPIO_PV0, BB, USB, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GPIO_PV1, BB, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SDMMC1_CLK, SDMMC1, SDMMC1, CLK12, RSVD3, RSVD4),
|
||||
PINI(SDMMC1_CMD, SDMMC1, SDMMC1, SPDIF, SPI4, UARTA),
|
||||
PINI(SDMMC1_DAT3, SDMMC1, SDMMC1, SPDIF, SPI4, UARTA),
|
||||
PINI(SDMMC1_DAT2, SDMMC1, SDMMC1, PWM0, SPI4, UARTA),
|
||||
PINI(SDMMC1_DAT1, SDMMC1, SDMMC1, PWM1, SPI4, UARTA),
|
||||
PINI(SDMMC1_DAT0, SDMMC1, SDMMC1, RSVD2, SPI4, UARTA),
|
||||
PINI(GPIO_PV2, BB, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GPIO_PV3, BB, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK2_OUT, SDMMC1, EXTPERIPH2, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK2_REQ, SDMMC1, DAP, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_PWR1, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_PWR2, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_SDIN, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_SDOUT, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_WR_N, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_CS0_N, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_DC0, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_SCK, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_PWR0, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_PCLK, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_DE, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_HSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_VSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D0, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D1, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D2, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D3, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D4, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D5, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D6, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D7, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D8, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D9, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D10, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D11, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D12, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D13, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D14, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D15, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D16, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D17, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D18, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D19, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D20, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D21, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D22, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_D23, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_CS1_N, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_M1, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_DC1, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(HDMI_INT, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DDC_SCL, LCD, I2C4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DDC_SDA, LCD, I2C4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CRT_HSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CRT_VSYNC, LCD, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D0, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D1, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D2, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D3, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D4, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D5, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D6, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D7, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D8, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D9, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D10, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D11, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_PCLK, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_MCLK, VI, RSVD1, RSVD3, RSVD3, RSVD4),
|
||||
PINI(VI_VSYNC, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_HSYNC, VI, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(UART2_RXD, UART, UARTB, SPDIF, UARTA, SPI4),
|
||||
PINI(UART2_TXD, UART, UARTB, SPDIF, UARTA, SPI4),
|
||||
PINI(UART2_RTS_N, UART, UARTA, UARTB, RSVD3, SPI4),
|
||||
PINI(UART2_CTS_N, UART, UARTA, UARTB, RSVD3, SPI4),
|
||||
PINI(UART3_TXD, UART, UARTC, RSVD2, RSVD3, SPI4),
|
||||
PINI(UART3_RXD, UART, UARTC, RSVD2, RSVD3, SPI4),
|
||||
PINI(UART3_CTS_N, UART, UARTC, SDMMC1, DTV, SPI4),
|
||||
PINI(UART3_RTS_N, UART, UARTC, PWM0, DTV, DISPA),
|
||||
PINI(GPIO_PU0, UART, OWR, UARTA, RSVD3, RSVD4),
|
||||
PINI(GPIO_PU1, UART, RSVD1, UARTA, RSVD3, RSVD4),
|
||||
PINI(GPIO_PU2, UART, RSVD1, UARTA, RSVD3, RSVD4),
|
||||
PINI(GPIO_PU3, UART, PWM0, UARTA, DISPA, DISPB),
|
||||
PINI(GPIO_PU4, UART, PWM1, UARTA, DISPA, DISPB),
|
||||
PINI(GPIO_PU5, UART, PWM2, UARTA, DISPA, DISPB),
|
||||
PINI(GPIO_PU6, UART, PWM3, UARTA, USB, DISPB),
|
||||
PINI(GEN1_I2C_SDA, UART, I2C1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GEN1_I2C_SCL, UART, I2C1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DAP4_FS, UART, I2S3, RSVD2, DTV, RSVD4),
|
||||
PINI(DAP4_DIN, UART, I2S3, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DAP4_DOUT, UART, I2S3, RSVD2, DTV, RSVD4),
|
||||
PINI(DAP4_SCLK, UART, I2S3, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK3_OUT, UART, EXTPERIPH3, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK3_REQ, UART, DEV3, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GMI_WP_N, GMI, RSVD1, NAND, GMI, GMI_ALT),
|
||||
PINI(GMI_IORDY, GMI, SDMMC2, RSVD2, GMI, TRACE),
|
||||
PINI(GMI_WAIT, GMI, SPI4, NAND, GMI, DTV),
|
||||
PINI(GMI_ADV_N, GMI, RSVD1, NAND, GMI, TRACE),
|
||||
PINI(GMI_CLK, GMI, SDMMC2, NAND, GMI, TRACE),
|
||||
PINI(GMI_CS0_N, GMI, RSVD1, NAND, GMI, USB),
|
||||
PINI(GMI_CS1_N, GMI, RSVD1, NAND, GMI, SOC),
|
||||
PINI(GMI_CS2_N, GMI, SDMMC2, NAND, GMI, TRACE),
|
||||
PINI(GMI_CS3_N, GMI, SDMMC2, NAND, GMI, GMI_ALT),
|
||||
PINI(GMI_CS4_N, GMI, USB, NAND, GMI, TRACE),
|
||||
PINI(GMI_CS6_N, GMI, NAND, NAND_ALT, GMI, SPI4),
|
||||
PINI(GMI_CS7_N, GMI, NAND, NAND_ALT, GMI, SDMMC2),
|
||||
PINI(GMI_AD0, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD1, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD2, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD3, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD4, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD5, GMI, RSVD1, NAND, GMI, SPI4),
|
||||
PINI(GMI_AD6, GMI, RSVD1, NAND, GMI, SPI4),
|
||||
PINI(GMI_AD7, GMI, RSVD1, NAND, GMI, SPI4),
|
||||
PINI(GMI_AD8, GMI, PWM0, NAND, GMI, DTV),
|
||||
PINI(GMI_AD9, GMI, PWM1, NAND, GMI, CLDVFS),
|
||||
PINI(GMI_AD10, GMI, PWM2, NAND, GMI, CLDVFS),
|
||||
PINI(GMI_AD11, GMI, PWM3, NAND, GMI, USB),
|
||||
PINI(GMI_AD12, GMI, SDMMC2, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD13, GMI, SDMMC2, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD14, GMI, SDMMC2, NAND, GMI, DTV),
|
||||
PINI(GMI_AD15, GMI, SDMMC2, NAND, GMI, DTV),
|
||||
PINI(GMI_A16, GMI, UARTD, TRACE, GMI, GMI_ALT),
|
||||
PINI(GMI_A17, GMI, UARTD, RSVD2, GMI, TRACE),
|
||||
PINI(GMI_A18, GMI, UARTD, RSVD2, GMI, TRACE),
|
||||
PINI(GMI_A19, GMI, UARTD, SPI4, GMI, TRACE),
|
||||
PINI(GMI_WR_N, GMI, RSVD1, NAND, GMI, SPI4),
|
||||
PINI(GMI_OE_N, GMI, RSVD1, NAND, GMI, SOC),
|
||||
PINI(GMI_DQS, GMI, SDMMC2, NAND, GMI, TRACE),
|
||||
PINI(GMI_RST_N, GMI, NAND, NAND_ALT, GMI, RSVD4),
|
||||
PINI(GEN2_I2C_SCL, GMI, I2C2, RSVD2, GMI, RSVD4),
|
||||
PINI(GEN2_I2C_SDA, GMI, I2C2, RSVD2, GMI, RSVD4),
|
||||
PINI(SDMMC4_CLK, SDMMC4, SDMMC4, RSVD2, GMI, RSVD4),
|
||||
PINI(SDMMC4_CMD, SDMMC4, SDMMC4, RSVD2, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT0, SDMMC4, SDMMC4, SPI3, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT1, SDMMC4, SDMMC4, SPI3, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT2, SDMMC4, SDMMC4, SPI3, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT3, SDMMC4, SDMMC4, SPI3, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT4, SDMMC4, SDMMC4, SPI3, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT5, SDMMC4, SDMMC4, SPI3, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT6, SDMMC4, SDMMC4, SPI3, GMI, RSVD4),
|
||||
PINI(SDMMC4_DAT7, SDMMC4, SDMMC4, RSVD2, GMI, RSVD4),
|
||||
PINI(SDMMC4_RST_N, SDMMC4, RSVD1, RSVD2, RSVD3, SDMMC4),
|
||||
PINI(CAM_MCLK, CAM, VI, VI_ALT1, VI_ALT2, RSVD4),
|
||||
PINI(GPIO_PCC1, CAM, I2S4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GPIO_PBB0, CAM, I2S4, VI, VI_ALT1, VI_ALT3),
|
||||
PINI(CAM_I2C_SCL, CAM, VGP1, I2C3, RSVD3, RSVD4),
|
||||
PINI(CAM_I2C_SDA, CAM, VGP2, I2C3, RSVD3, RSVD4),
|
||||
PINI(GPIO_PBB3, CAM, VGP3, DISPA, DISPB, RSVD4),
|
||||
PINI(GPIO_PBB4, CAM, VGP4, DISPA, DISPB, RSVD4),
|
||||
PINI(GPIO_PBB5, CAM, VGP5, DISPA, DISPB, RSVD4),
|
||||
PINI(GPIO_PBB6, CAM, VGP6, DISPA, DISPB, RSVD4),
|
||||
PINI(GPIO_PBB7, CAM, I2S4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GPIO_PCC2, CAM, I2S4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(JTAG_RTCK, SYS, RTCK, RSVD2, RSVD3, RSVD4),
|
||||
PINI(PWR_I2C_SCL, SYS, I2CPWR, RSVD2, RSVD3, RSVD4),
|
||||
PINI(PWR_I2C_SDA, SYS, I2CPWR, RSVD2, RSVD3, RSVD4),
|
||||
PINI(KB_ROW0, SYS, KBC, RSVD2, DTV, RSVD4),
|
||||
PINI(KB_ROW1, SYS, KBC, RSVD2, DTV, RSVD4),
|
||||
PINI(KB_ROW2, SYS, KBC, RSVD2, DTV, SOC),
|
||||
PINI(KB_ROW3, SYS, KBC, DISPA, RSVD3, DISPB),
|
||||
PINI(KB_ROW4, SYS, KBC, DISPA, SPI2, DISPB),
|
||||
PINI(KB_ROW5, SYS, KBC, DISPA, SPI2, DISPB),
|
||||
PINI(KB_ROW6, SYS, KBC, DISPA, RSVD3, DISPB),
|
||||
PINI(KB_ROW7, SYS, KBC, RSVD2, CLDVFS, UARTA),
|
||||
PINI(KB_ROW8, SYS, KBC, RSVD2, RSVD3, UARTA),
|
||||
PINI(KB_ROW9, SYS, KBC, RSVD2, RSVD3, UARTA),
|
||||
PINI(KB_ROW10, SYS, KBC, RSVD2, RSVD3, UARTA),
|
||||
PINI(KB_ROW11, SYS, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(KB_ROW12, SYS, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(KB_ROW13, SYS, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(KB_ROW14, SYS, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(KB_ROW15, SYS, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(KB_COL0, SYS, KBC, USB, SPI2, EMC_DLL),
|
||||
PINI(KB_COL1, SYS, KBC, RSVD2, SPI2, EMC_DLL),
|
||||
PINI(KB_COL2, SYS, KBC, RSVD2, SPI2, RSVD4),
|
||||
PINI(KB_COL3, SYS, KBC, DISPA, PWM2, UARTA),
|
||||
PINI(KB_COL4, SYS, KBC, OWR, SDMMC3, UARTA),
|
||||
PINI(KB_COL5, SYS, KBC, RSVD2, SDMMC1, RSVD4),
|
||||
PINI(KB_COL6, SYS, KBC, RSVD2, SPI2, RSVD4),
|
||||
PINI(KB_COL7, SYS, KBC, RSVD2, SPI2, RSVD4),
|
||||
PINI(CLK_32K_OUT, SYS, BLINK, SOC, RSVD3, RSVD4),
|
||||
PINI(SYS_CLK_REQ, SYS, SYSCLK, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CORE_PWR_REQ, SYS, PWRON, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CPU_PWR_REQ, SYS, CPU, RSVD2, RSVD3, RSVD4),
|
||||
PINI(PWR_INT_N, SYS, PMI, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK_32K_IN, SYS, CLK, RSVD2, RSVD3, RSVD4),
|
||||
PINI(OWR, SYS, OWR, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DAP1_FS, AUDIO, I2S0, HDA, GMI, RSVD4),
|
||||
PINI(DAP1_DIN, AUDIO, I2S0, HDA, GMI, RSVD4),
|
||||
PINI(DAP1_DOUT, AUDIO, I2S0, HDA, GMI, RSVD4),
|
||||
PINI(DAP1_SCLK, AUDIO, I2S0, HDA, GMI, RSVD4),
|
||||
PINI(CLK1_REQ, AUDIO, DAP, DAP1, RSVD3, RSVD4),
|
||||
PINI(CLK1_OUT, AUDIO, EXTPERIPH1, DAP2, RSVD3, RSVD4),
|
||||
PINI(SPDIF_IN, AUDIO, SPDIF, USB, RSVD3, RSVD4),
|
||||
PINI(SPDIF_OUT, AUDIO, SPDIF, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DAP2_FS, AUDIO, I2S1, HDA, RSVD3, RSVD4),
|
||||
PINI(DAP2_DIN, AUDIO, I2S1, HDA, RSVD3, RSVD4),
|
||||
PINI(DAP2_DOUT, AUDIO, I2S1, HDA, RSVD3, RSVD4),
|
||||
PINI(DAP2_SCLK, AUDIO, I2S1, HDA, RSVD3, RSVD4),
|
||||
PINI(SPI2_MOSI, AUDIO, SPI6, CLDVFS, RSVD3, RSVD4),
|
||||
PINI(SPI2_MISO, AUDIO, SPI6, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SPI2_CS0_N, AUDIO, SPI6, SPI1, RSVD3, RSVD4),
|
||||
PINI(SPI2_SCK, AUDIO, SPI6, CLDVFS, RSVD3, RSVD4),
|
||||
PINI(SPI1_MOSI, AUDIO, RSVD1, SPI1, SPI2, DAP2),
|
||||
PINI(SPI1_SCK, AUDIO, RSVD1, SPI1, SPI2, RSVD4),
|
||||
PINI(SPI1_CS0_N, AUDIO, SPI6, SPI1, SPI2, RSVD4),
|
||||
PINI(SPI1_MISO, AUDIO, RSVD1, SPI1, SPI2, RSVD4),
|
||||
PINI(SPI2_CS1_N, AUDIO, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SPI2_CS2_N, AUDIO, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SDMMC3_CLK, SDMMC3, SDMMC3, RSVD2, RSVD3, SPI3),
|
||||
PINI(SDMMC3_CMD, SDMMC3, SDMMC3, PWM3, UARTA, SPI3),
|
||||
PINI(SDMMC3_DAT0, SDMMC3, SDMMC3, RSVD2, RSVD3, SPI3),
|
||||
PINI(SDMMC3_DAT1, SDMMC3, SDMMC3, PWM2, UARTA, SPI3),
|
||||
PINI(SDMMC3_DAT2, SDMMC3, SDMMC3, PWM1, DISPA, SPI3),
|
||||
PINI(SDMMC3_DAT3, SDMMC3, SDMMC3, PWM0, DISPB, SPI3),
|
||||
PINI(SDMMC3_DAT4, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SDMMC3_DAT5, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SDMMC3_DAT6, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SDMMC3_DAT7, SDMMC3, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(HDMI_CEC, SYS, CEC, SDMMC3, RSVD3, SOC),
|
||||
PINI(SDMMC1_WP_N, SDMMC1, SDMMC1, CLK12, SPI4, UARTA),
|
||||
PINI(SDMMC3_CD_N, SDMMC3, SDMMC3, OWR, RSVD3, RSVD4),
|
||||
PINI(SPI1_CS1_N, AUDIO, SPI6, RSVD2, SPI2, I2C1),
|
||||
PINI(SPI1_CS2_N, AUDIO, SPI6, SPI1, SPI2, I2C1),
|
||||
PINI(USB_VBUS_EN0, SYS, USB, RSVD2, RSVD3, RSVD4),
|
||||
PINI(USB_VBUS_EN1, SYS, USB, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SDMMC3_CLK_LB_IN, SDMMC3, SDMMC3, RSVD2, RSVD3, RSVD4),
|
||||
PINO(SDMMC3_CLK_LB_OUT, SDMMC3, SDMMC3, RSVD2, RSVD3, RSVD4),
|
||||
PINO(NAND_GMI_CLK_LB, GMI, SDMMC2, NAND, GMI, RSVD4),
|
||||
PINO(RESET_OUT_N, SYS, RSVD1, RSVD2, RSVD3, RESET_OUT_N),
|
||||
};
|
||||
|
||||
void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *tri = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
|
||||
reg = readl(tri);
|
||||
if (enable)
|
||||
reg |= PMUX_TRISTATE_MASK;
|
||||
else
|
||||
reg &= ~PMUX_TRISTATE_MASK;
|
||||
writel(reg, tri);
|
||||
}
|
||||
|
||||
void pinmux_tristate_enable(enum pmux_pingrp pin)
|
||||
{
|
||||
pinmux_set_tristate(pin, 1);
|
||||
}
|
||||
|
||||
void pinmux_tristate_disable(enum pmux_pingrp pin)
|
||||
{
|
||||
pinmux_set_tristate(pin, 0);
|
||||
}
|
||||
|
||||
void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pull = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and pupd */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_pupd_isvalid(pupd));
|
||||
|
||||
reg = readl(pull);
|
||||
reg &= ~(0x3 << PMUX_PULL_SHIFT);
|
||||
reg |= (pupd << PMUX_PULL_SHIFT);
|
||||
writel(reg, pull);
|
||||
}
|
||||
|
||||
void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *muxctl = &pmt->pmt_ctl[pin];
|
||||
int i, mux = -1;
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and func */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_func_isvalid(func));
|
||||
|
||||
/* Handle special values */
|
||||
if (func == PMUX_FUNC_SAFE)
|
||||
func = tegra_soc_pingroups[pin].func_safe;
|
||||
|
||||
if (func & PMUX_FUNC_RSVD1) {
|
||||
mux = func & 0x3;
|
||||
} else {
|
||||
/* Search for the appropriate function */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (tegra_soc_pingroups[pin].funcs[i] == func) {
|
||||
mux = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(mux != -1);
|
||||
|
||||
reg = readl(muxctl);
|
||||
reg &= ~(0x3 << PMUX_MUXCTL_SHIFT);
|
||||
reg |= (mux << PMUX_MUXCTL_SHIFT);
|
||||
writel(reg, muxctl);
|
||||
|
||||
}
|
||||
|
||||
void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_io = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and io */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_io_isvalid(io));
|
||||
|
||||
reg = readl(pin_io);
|
||||
reg &= ~(0x1 << PMUX_IO_SHIFT);
|
||||
reg |= (io & 0x1) << PMUX_IO_SHIFT;
|
||||
writel(reg, pin_io);
|
||||
}
|
||||
|
||||
static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_lock = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and lock */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_lock_isvalid(lock));
|
||||
|
||||
if (lock == PMUX_PIN_LOCK_DEFAULT)
|
||||
return 0;
|
||||
|
||||
reg = readl(pin_lock);
|
||||
reg &= ~(0x1 << PMUX_LOCK_SHIFT);
|
||||
if (lock == PMUX_PIN_LOCK_ENABLE)
|
||||
reg |= (0x1 << PMUX_LOCK_SHIFT);
|
||||
else {
|
||||
/* lock == DISABLE, which isn't possible */
|
||||
printf("%s: Warning: lock == %d, DISABLE is not allowed!\n",
|
||||
__func__, lock);
|
||||
}
|
||||
writel(reg, pin_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_od = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and od */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_od_isvalid(od));
|
||||
|
||||
if (od == PMUX_PIN_OD_DEFAULT)
|
||||
return 0;
|
||||
|
||||
reg = readl(pin_od);
|
||||
reg &= ~(0x1 << PMUX_OD_SHIFT);
|
||||
if (od == PMUX_PIN_OD_ENABLE)
|
||||
reg |= (0x1 << PMUX_OD_SHIFT);
|
||||
writel(reg, pin_od);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pinmux_set_ioreset(enum pmux_pingrp pin,
|
||||
enum pmux_pin_ioreset ioreset)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_ioreset = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and ioreset */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_ioreset_isvalid(ioreset));
|
||||
|
||||
if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
|
||||
return 0;
|
||||
|
||||
reg = readl(pin_ioreset);
|
||||
reg &= ~(0x1 << PMUX_IO_RESET_SHIFT);
|
||||
if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
|
||||
reg |= (0x1 << PMUX_IO_RESET_SHIFT);
|
||||
writel(reg, pin_ioreset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pinmux_config_pingroup(struct pingroup_config *config)
|
||||
{
|
||||
enum pmux_pingrp pin = config->pingroup;
|
||||
|
||||
pinmux_set_func(pin, config->func);
|
||||
pinmux_set_pullupdown(pin, config->pull);
|
||||
pinmux_set_tristate(pin, config->tristate);
|
||||
pinmux_set_io(pin, config->io);
|
||||
pinmux_set_lock(pin, config->lock);
|
||||
pinmux_set_od(pin, config->od);
|
||||
pinmux_set_ioreset(pin, config->ioreset);
|
||||
}
|
||||
|
||||
void pinmux_config_table(struct pingroup_config *config, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
pinmux_config_pingroup(&config[i]);
|
||||
}
|
|
@ -30,24 +30,6 @@
|
|||
#include <div64.h>
|
||||
#include <fdtdec.h>
|
||||
|
||||
/*
|
||||
* This is our record of the current clock rate of each clock. We don't
|
||||
* fill all of these in since we are only really interested in clocks which
|
||||
* we use as parents.
|
||||
*/
|
||||
static unsigned pll_rate[CLOCK_ID_COUNT];
|
||||
|
||||
/*
|
||||
* The oscillator frequency is fixed to one of four set values. Based on this
|
||||
* the other clocks are set up appropriately.
|
||||
*/
|
||||
static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
|
||||
13000000,
|
||||
19200000,
|
||||
12000000,
|
||||
26000000,
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock types that we can use as a source. The Tegra20 has muxes for the
|
||||
* peripheral clocks, and in most cases there are four options for the clock
|
||||
|
@ -76,12 +58,6 @@ enum clock_type_id {
|
|||
CLOCK_TYPE_NONE = -1, /* invalid clock type */
|
||||
};
|
||||
|
||||
/* return 1 if a peripheral ID is in range */
|
||||
#define clock_type_id_isvalid(id) ((id) >= 0 && \
|
||||
(id) < CLOCK_TYPE_COUNT)
|
||||
|
||||
char pllp_valid = 1; /* PLLP is set up correctly */
|
||||
|
||||
enum {
|
||||
CLOCK_MAX_MUX = 4 /* number of source options for each clock */
|
||||
};
|
||||
|
@ -192,10 +168,6 @@ enum periphc_internal_id {
|
|||
PERIPHC_NONE = -1,
|
||||
};
|
||||
|
||||
/* return 1 if a periphc_internal_id is in range */
|
||||
#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
|
||||
(id) < PERIPHC_COUNT)
|
||||
|
||||
/*
|
||||
* Clock type for each peripheral clock source. We put the name in each
|
||||
* record just so it is easy to match things up
|
||||
|
@ -396,19 +368,9 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
|
|||
NONE(CRAM2),
|
||||
};
|
||||
|
||||
/* number of clock outputs of a PLL */
|
||||
static const u8 pll_num_clkouts[] = {
|
||||
1, /* PLLC */
|
||||
1, /* PLLM */
|
||||
4, /* PLLP */
|
||||
1, /* PLLA */
|
||||
0, /* PLLU */
|
||||
0, /* PLLD */
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the oscillator frequency, from the corresponding hardware configuration
|
||||
* field.
|
||||
* field. T20 has 4 frequencies that it supports.
|
||||
*/
|
||||
enum clock_osc_freq clock_get_osc_freq(void)
|
||||
{
|
||||
|
@ -420,110 +382,8 @@ enum clock_osc_freq clock_get_osc_freq(void)
|
|||
return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
}
|
||||
|
||||
int clock_get_osc_bypass(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
return (reg & OSC_XOBP_MASK) >> OSC_XOBP_SHIFT;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the registers of the given pll */
|
||||
static struct clk_pll *get_pll(enum clock_id clkid)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
|
||||
assert(clock_id_is_pll(clkid));
|
||||
return &clkrst->crc_pll[clkid];
|
||||
}
|
||||
|
||||
int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
|
||||
u32 *divp, u32 *cpcon, u32 *lfcon)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(clkid);
|
||||
u32 data;
|
||||
|
||||
assert(clkid != CLOCK_ID_USB);
|
||||
|
||||
/* Safety check, adds to code size but is small */
|
||||
if (!clock_id_is_pll(clkid) || clkid == CLOCK_ID_USB)
|
||||
return -1;
|
||||
data = readl(&pll->pll_base);
|
||||
*divm = (data & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
|
||||
*divn = (data & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT;
|
||||
*divp = (data & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
|
||||
data = readl(&pll->pll_misc);
|
||||
*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT;
|
||||
*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
|
||||
u32 divp, u32 cpcon, u32 lfcon)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(clkid);
|
||||
u32 data;
|
||||
|
||||
/*
|
||||
* We cheat by treating all PLL (except PLLU) in the same fashion.
|
||||
* This works only because:
|
||||
* - same fields are always mapped at same offsets, except DCCON
|
||||
* - DCCON is always 0, doesn't conflict
|
||||
* - M,N, P of PLLP values are ignored for PLLP
|
||||
*/
|
||||
data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
|
||||
writel(data, &pll->pll_misc);
|
||||
|
||||
data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
|
||||
(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
|
||||
|
||||
if (clkid == CLOCK_ID_USB)
|
||||
data |= divp << PLLU_VCO_FREQ_SHIFT;
|
||||
else
|
||||
data |= divp << PLL_DIVP_SHIFT;
|
||||
writel(data, &pll->pll_base);
|
||||
|
||||
/* calculate the stable time */
|
||||
return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US;
|
||||
}
|
||||
|
||||
/* return 1 if a peripheral ID is in range and valid */
|
||||
static int clock_periph_id_isvalid(enum periph_id id)
|
||||
{
|
||||
if (id < PERIPH_ID_FIRST || id >= PERIPH_ID_COUNT)
|
||||
printf("Peripheral id %d out of range\n", id);
|
||||
else {
|
||||
switch (id) {
|
||||
case PERIPH_ID_RESERVED1:
|
||||
case PERIPH_ID_RESERVED2:
|
||||
case PERIPH_ID_RESERVED30:
|
||||
case PERIPH_ID_RESERVED35:
|
||||
case PERIPH_ID_RESERVED56:
|
||||
case PERIPH_ID_RESERVED74:
|
||||
case PERIPH_ID_RESERVED76:
|
||||
case PERIPH_ID_RESERVED77:
|
||||
case PERIPH_ID_RESERVED78:
|
||||
case PERIPH_ID_RESERVED79:
|
||||
case PERIPH_ID_RESERVED80:
|
||||
case PERIPH_ID_RESERVED81:
|
||||
case PERIPH_ID_RESERVED82:
|
||||
case PERIPH_ID_RESERVED83:
|
||||
case PERIPH_ID_RESERVED91:
|
||||
printf("Peripheral id %d is reserved\n", id);
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
static u32 *get_periph_source_reg(enum periph_id periph_id)
|
||||
u32 *get_periph_source_reg(enum periph_id periph_id)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
|
@ -535,154 +395,6 @@ static u32 *get_periph_source_reg(enum periph_id periph_id)
|
|||
return &clkrst->crc_clk_src[internal_id];
|
||||
}
|
||||
|
||||
void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source,
|
||||
unsigned divisor)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
u32 value;
|
||||
|
||||
value = readl(reg);
|
||||
|
||||
value &= ~OUT_CLK_SOURCE_MASK;
|
||||
value |= source << OUT_CLK_SOURCE_SHIFT;
|
||||
|
||||
value &= ~OUT_CLK_DIVISOR_MASK;
|
||||
value |= divisor << OUT_CLK_DIVISOR_SHIFT;
|
||||
|
||||
writel(value, reg);
|
||||
}
|
||||
|
||||
void clock_ll_set_source(enum periph_id periph_id, unsigned source)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
|
||||
clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
|
||||
source << OUT_CLK_SOURCE_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the parent's rate and the required rate for the children, this works
|
||||
* out the peripheral clock divider to use, in 7.1 binary format.
|
||||
*
|
||||
* @param divider_bits number of divider bits (8 or 16)
|
||||
* @param parent_rate clock rate of parent clock in Hz
|
||||
* @param rate required clock rate for this clock
|
||||
* @return divider which should be used
|
||||
*/
|
||||
static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate,
|
||||
unsigned long rate)
|
||||
{
|
||||
u64 divider = parent_rate * 2;
|
||||
unsigned max_divider = 1 << divider_bits;
|
||||
|
||||
divider += rate - 1;
|
||||
do_div(divider, rate);
|
||||
|
||||
if ((s64)divider - 2 < 0)
|
||||
return 0;
|
||||
|
||||
if ((s64)divider - 2 >= max_divider)
|
||||
return -1;
|
||||
|
||||
return divider - 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the parent's rate and the divider in 7.1 format, this works out the
|
||||
* resulting peripheral clock rate.
|
||||
*
|
||||
* @param parent_rate clock rate of parent clock in Hz
|
||||
* @param divider which should be used in 7.1 format
|
||||
* @return effective clock rate of peripheral
|
||||
*/
|
||||
static unsigned long get_rate_from_divider(unsigned long parent_rate,
|
||||
int divider)
|
||||
{
|
||||
u64 rate;
|
||||
|
||||
rate = (u64)parent_rate * 2;
|
||||
do_div(rate, divider + 2);
|
||||
return rate;
|
||||
}
|
||||
|
||||
unsigned long clock_get_periph_rate(enum periph_id periph_id,
|
||||
enum clock_id parent)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
|
||||
return get_rate_from_divider(pll_rate[parent],
|
||||
(readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
|
||||
}
|
||||
|
||||
int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout, unsigned rate)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(clkid);
|
||||
int data = 0, div = 0, offset = 0;
|
||||
|
||||
if (!clock_id_is_pll(clkid))
|
||||
return -1;
|
||||
|
||||
if (pllout + 1 > pll_num_clkouts[clkid])
|
||||
return -1;
|
||||
|
||||
div = clk_get_divider(8, pll_rate[clkid], rate);
|
||||
|
||||
if (div < 0)
|
||||
return -1;
|
||||
|
||||
/* out2 and out4 are in the high part of the register */
|
||||
if (pllout == PLL_OUT2 || pllout == PLL_OUT4)
|
||||
offset = 16;
|
||||
|
||||
data = (div << PLL_OUT_RATIO_SHIFT) |
|
||||
PLL_OUT_OVRRIDE | PLL_OUT_CLKEN | PLL_OUT_RSTN;
|
||||
clrsetbits_le32(&pll->pll_out[pllout >> 1],
|
||||
PLL_OUT_RATIO_MASK << offset, data << offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the best available 7.1 format divisor given a parent clock rate and
|
||||
* required child clock rate. This function assumes that a second-stage
|
||||
* divisor is available which can divide by powers of 2 from 1 to 256.
|
||||
*
|
||||
* @param divider_bits number of divider bits (8 or 16)
|
||||
* @param parent_rate clock rate of parent clock in Hz
|
||||
* @param rate required clock rate for this clock
|
||||
* @param extra_div value for the second-stage divisor (not set if this
|
||||
* function returns -1.
|
||||
* @return divider which should be used, or -1 if nothing is valid
|
||||
*
|
||||
*/
|
||||
static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
|
||||
unsigned long rate, int *extra_div)
|
||||
{
|
||||
int shift;
|
||||
int best_divider = -1;
|
||||
int best_error = rate;
|
||||
|
||||
/* try dividers from 1 to 256 and find closest match */
|
||||
for (shift = 0; shift <= 8 && best_error > 0; shift++) {
|
||||
unsigned divided_parent = parent_rate >> shift;
|
||||
int divider = clk_get_divider(divider_bits, divided_parent,
|
||||
rate);
|
||||
unsigned effective_rate = get_rate_from_divider(divided_parent,
|
||||
divider);
|
||||
int error = rate - effective_rate;
|
||||
|
||||
/* Given a valid divider, look for the lowest error */
|
||||
if (divider != -1 && error < best_error) {
|
||||
best_error = error;
|
||||
*extra_div = 1 << shift;
|
||||
best_divider = divider;
|
||||
}
|
||||
}
|
||||
|
||||
/* return what we found - *extra_div will already be set */
|
||||
return best_divider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a peripheral ID and the required source clock, this returns which
|
||||
* value should be programmed into the source mux for that peripheral.
|
||||
|
@ -695,7 +407,7 @@ static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
|
|||
* @param divider_bits Set to number of divider bits (8 or 16)
|
||||
* @return mux value (0-4, or -1 if not found)
|
||||
*/
|
||||
static int get_periph_clock_source(enum periph_id periph_id,
|
||||
int get_periph_clock_source(enum periph_id periph_id,
|
||||
enum clock_id parent, int *mux_bits, int *divider_bits)
|
||||
{
|
||||
enum clock_type_id type;
|
||||
|
@ -743,88 +455,6 @@ static int get_periph_clock_source(enum periph_id periph_id,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust peripheral PLL to use the given divider and source.
|
||||
*
|
||||
* @param periph_id peripheral to adjust
|
||||
* @param source Source number (0-3 or 0-7)
|
||||
* @param mux_bits Number of mux bits (2 or 4)
|
||||
* @param divider Required divider in 7.1 or 15.1 format
|
||||
* @return 0 if ok, -1 on error (requesting a parent clock which is not valid
|
||||
* for this peripheral)
|
||||
*/
|
||||
static int adjust_periph_pll(enum periph_id periph_id, int source,
|
||||
int mux_bits, unsigned divider)
|
||||
{
|
||||
u32 *reg = get_periph_source_reg(periph_id);
|
||||
|
||||
clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK,
|
||||
divider << OUT_CLK_DIVISOR_SHIFT);
|
||||
udelay(1);
|
||||
|
||||
/* work out the source clock and set it */
|
||||
if (source < 0)
|
||||
return -1;
|
||||
if (mux_bits == 4) {
|
||||
clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK,
|
||||
source << OUT_CLK_SOURCE4_SHIFT);
|
||||
} else {
|
||||
clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
|
||||
source << OUT_CLK_SOURCE_SHIFT);
|
||||
}
|
||||
udelay(2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned clock_adjust_periph_pll_div(enum periph_id periph_id,
|
||||
enum clock_id parent, unsigned rate, int *extra_div)
|
||||
{
|
||||
unsigned effective_rate;
|
||||
int mux_bits, divider_bits, source;
|
||||
int divider;
|
||||
|
||||
/* work out the source clock and set it */
|
||||
source = get_periph_clock_source(periph_id, parent, &mux_bits,
|
||||
÷r_bits);
|
||||
|
||||
if (extra_div)
|
||||
divider = find_best_divider(divider_bits, pll_rate[parent],
|
||||
rate, extra_div);
|
||||
else
|
||||
divider = clk_get_divider(divider_bits, pll_rate[parent],
|
||||
rate);
|
||||
assert(divider >= 0);
|
||||
if (adjust_periph_pll(periph_id, source, mux_bits, divider))
|
||||
return -1U;
|
||||
debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate,
|
||||
get_periph_source_reg(periph_id),
|
||||
readl(get_periph_source_reg(periph_id)));
|
||||
|
||||
/* Check what we ended up with. This shouldn't matter though */
|
||||
effective_rate = clock_get_periph_rate(periph_id, parent);
|
||||
if (extra_div)
|
||||
effective_rate /= *extra_div;
|
||||
if (rate != effective_rate)
|
||||
debug("Requested clock rate %u not honored (got %u)\n",
|
||||
rate, effective_rate);
|
||||
return effective_rate;
|
||||
}
|
||||
|
||||
unsigned clock_start_periph_pll(enum periph_id periph_id,
|
||||
enum clock_id parent, unsigned rate)
|
||||
{
|
||||
unsigned effective_rate;
|
||||
|
||||
reset_set_enable(periph_id, 1);
|
||||
clock_enable(periph_id);
|
||||
|
||||
effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate,
|
||||
NULL);
|
||||
|
||||
reset_set_enable(periph_id, 0);
|
||||
return effective_rate;
|
||||
}
|
||||
|
||||
void clock_set_enable(enum periph_id periph_id, int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
|
@ -842,16 +472,6 @@ void clock_set_enable(enum periph_id periph_id, int enable)
|
|||
writel(reg, clk);
|
||||
}
|
||||
|
||||
void clock_enable(enum periph_id clkid)
|
||||
{
|
||||
clock_set_enable(clkid, 1);
|
||||
}
|
||||
|
||||
void clock_disable(enum periph_id clkid)
|
||||
{
|
||||
clock_set_enable(clkid, 0);
|
||||
}
|
||||
|
||||
void reset_set_enable(enum periph_id periph_id, int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
|
@ -869,146 +489,6 @@ void reset_set_enable(enum periph_id periph_id, int enable)
|
|||
writel(reg, reset);
|
||||
}
|
||||
|
||||
void reset_periph(enum periph_id periph_id, int us_delay)
|
||||
{
|
||||
/* Put peripheral into reset */
|
||||
reset_set_enable(periph_id, 1);
|
||||
udelay(us_delay);
|
||||
|
||||
/* Remove reset */
|
||||
reset_set_enable(periph_id, 0);
|
||||
|
||||
udelay(us_delay);
|
||||
}
|
||||
|
||||
void reset_cmplx_set_enable(int cpu, int which, int reset)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 mask;
|
||||
|
||||
/* Form the mask, which depends on the cpu chosen. Tegra20 has 2 */
|
||||
assert(cpu >= 0 && cpu < 2);
|
||||
mask = which << cpu;
|
||||
|
||||
/* either enable or disable those reset for that CPU */
|
||||
if (reset)
|
||||
writel(mask, &clkrst->crc_cpu_cmplx_set);
|
||||
else
|
||||
writel(mask, &clkrst->crc_cpu_cmplx_clr);
|
||||
}
|
||||
|
||||
unsigned clock_get_rate(enum clock_id clkid)
|
||||
{
|
||||
struct clk_pll *pll;
|
||||
u32 base;
|
||||
u32 divm;
|
||||
u64 parent_rate;
|
||||
u64 rate;
|
||||
|
||||
parent_rate = osc_freq[clock_get_osc_freq()];
|
||||
if (clkid == CLOCK_ID_OSC)
|
||||
return parent_rate;
|
||||
|
||||
pll = get_pll(clkid);
|
||||
base = readl(&pll->pll_base);
|
||||
|
||||
/* Oh for bf_unpack()... */
|
||||
rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT);
|
||||
divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
|
||||
if (clkid == CLOCK_ID_USB)
|
||||
divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT;
|
||||
else
|
||||
divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
|
||||
do_div(rate, divm);
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output frequency you want for each PLL clock.
|
||||
* PLL output frequencies are programmed by setting their N, M and P values.
|
||||
* The governing equations are:
|
||||
* VCO = (Fi / m) * n, Fo = VCO / (2^p)
|
||||
* where Fo is the output frequency from the PLL.
|
||||
* Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
|
||||
* 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
|
||||
* Please see Tegra TRM section 5.3 to get the detail for PLL Programming
|
||||
*
|
||||
* @param n PLL feedback divider(DIVN)
|
||||
* @param m PLL input divider(DIVN)
|
||||
* @param p post divider(DIVP)
|
||||
* @param cpcon base PLL charge pump(CPCON)
|
||||
* @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
|
||||
* be overriden), 1 if PLL is already correct
|
||||
*/
|
||||
static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
|
||||
{
|
||||
u32 base_reg;
|
||||
u32 misc_reg;
|
||||
struct clk_pll *pll;
|
||||
|
||||
pll = get_pll(clkid);
|
||||
|
||||
base_reg = readl(&pll->pll_base);
|
||||
|
||||
/* Set BYPASS, m, n and p to PLL_BASE */
|
||||
base_reg &= ~PLL_DIVM_MASK;
|
||||
base_reg |= m << PLL_DIVM_SHIFT;
|
||||
|
||||
base_reg &= ~PLL_DIVN_MASK;
|
||||
base_reg |= n << PLL_DIVN_SHIFT;
|
||||
|
||||
base_reg &= ~PLL_DIVP_MASK;
|
||||
base_reg |= p << PLL_DIVP_SHIFT;
|
||||
|
||||
if (clkid == CLOCK_ID_PERIPH) {
|
||||
/*
|
||||
* If the PLL is already set up, check that it is correct
|
||||
* and record this info for clock_verify() to check.
|
||||
*/
|
||||
if (base_reg & PLL_BASE_OVRRIDE_MASK) {
|
||||
base_reg |= PLL_ENABLE_MASK;
|
||||
if (base_reg != readl(&pll->pll_base))
|
||||
pllp_valid = 0;
|
||||
return pllp_valid ? 1 : -1;
|
||||
}
|
||||
base_reg |= PLL_BASE_OVRRIDE_MASK;
|
||||
}
|
||||
|
||||
base_reg |= PLL_BYPASS_MASK;
|
||||
writel(base_reg, &pll->pll_base);
|
||||
|
||||
/* Set cpcon to PLL_MISC */
|
||||
misc_reg = readl(&pll->pll_misc);
|
||||
misc_reg &= ~PLL_CPCON_MASK;
|
||||
misc_reg |= cpcon << PLL_CPCON_SHIFT;
|
||||
writel(misc_reg, &pll->pll_misc);
|
||||
|
||||
/* Enable PLL */
|
||||
base_reg |= PLL_ENABLE_MASK;
|
||||
writel(base_reg, &pll->pll_base);
|
||||
|
||||
/* Disable BYPASS */
|
||||
base_reg &= ~PLL_BYPASS_MASK;
|
||||
writel(base_reg, &pll->pll_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clock_ll_start_uart(enum periph_id periph_id)
|
||||
{
|
||||
/* Assert UART reset and enable clock */
|
||||
reset_set_enable(periph_id, 1);
|
||||
clock_enable(periph_id);
|
||||
clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
|
||||
|
||||
/* wait for 2us */
|
||||
udelay(2);
|
||||
|
||||
/* De-assert reset to UART */
|
||||
reset_set_enable(periph_id, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
/*
|
||||
* Convert a device tree clock ID to our peripheral ID. They are mostly
|
||||
|
@ -1018,67 +498,34 @@ void clock_ll_start_uart(enum periph_id periph_id)
|
|||
* @param clk_id Clock ID according to tegra20 device tree binding
|
||||
* @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
|
||||
*/
|
||||
static enum periph_id clk_id_to_periph_id(int clk_id)
|
||||
enum periph_id clk_id_to_periph_id(int clk_id)
|
||||
{
|
||||
if (clk_id > 95)
|
||||
if (clk_id > PERIPH_ID_COUNT)
|
||||
return PERIPH_ID_NONE;
|
||||
|
||||
switch (clk_id) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 7:
|
||||
case 10:
|
||||
case 20:
|
||||
case 30:
|
||||
case 35:
|
||||
case 49:
|
||||
case 56:
|
||||
case 74:
|
||||
case 76:
|
||||
case 77:
|
||||
case 78:
|
||||
case 79:
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
case 83:
|
||||
case 91:
|
||||
case 95:
|
||||
case PERIPH_ID_RESERVED1:
|
||||
case PERIPH_ID_RESERVED2:
|
||||
case PERIPH_ID_RESERVED30:
|
||||
case PERIPH_ID_RESERVED35:
|
||||
case PERIPH_ID_RESERVED56:
|
||||
case PERIPH_ID_RESERVED74:
|
||||
case PERIPH_ID_RESERVED76:
|
||||
case PERIPH_ID_RESERVED77:
|
||||
case PERIPH_ID_RESERVED78:
|
||||
case PERIPH_ID_RESERVED79:
|
||||
case PERIPH_ID_RESERVED80:
|
||||
case PERIPH_ID_RESERVED81:
|
||||
case PERIPH_ID_RESERVED82:
|
||||
case PERIPH_ID_RESERVED83:
|
||||
case PERIPH_ID_RESERVED91:
|
||||
return PERIPH_ID_NONE;
|
||||
default:
|
||||
return clk_id;
|
||||
}
|
||||
}
|
||||
|
||||
int clock_decode_periph_id(const void *blob, int node)
|
||||
{
|
||||
enum periph_id id;
|
||||
u32 cell[2];
|
||||
int err;
|
||||
|
||||
err = fdtdec_get_int_array(blob, node, "clocks", cell,
|
||||
ARRAY_SIZE(cell));
|
||||
if (err)
|
||||
return -1;
|
||||
id = clk_id_to_periph_id(cell[1]);
|
||||
assert(clock_periph_id_isvalid(id));
|
||||
return id;
|
||||
}
|
||||
#endif /* CONFIG_OF_CONTROL */
|
||||
|
||||
int clock_verify(void)
|
||||
{
|
||||
struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH);
|
||||
u32 reg = readl(&pll->pll_base);
|
||||
|
||||
if (!pllp_valid) {
|
||||
printf("Warning: PLLP %x is not correct\n", reg);
|
||||
return -1;
|
||||
}
|
||||
debug("PLLX %x is correct\n", reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clock_early_init(void)
|
||||
{
|
||||
/*
|
||||
|
@ -1112,15 +559,3 @@ void clock_early_init(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void clock_init(void)
|
||||
{
|
||||
pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY);
|
||||
pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH);
|
||||
pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL);
|
||||
pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
|
||||
pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
|
||||
debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
|
||||
debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]);
|
||||
debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]);
|
||||
}
|
||||
|
|
|
@ -98,8 +98,8 @@ int funcmux_select(enum periph_id id, int config)
|
|||
break;
|
||||
|
||||
case PERIPH_ID_UART2:
|
||||
if (config == FUNCMUX_UART2_IRDA) {
|
||||
pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA);
|
||||
if (config == FUNCMUX_UART2_UAD) {
|
||||
pinmux_set_func(PINGRP_UAD, PMUX_FUNC_UARTB);
|
||||
pinmux_tristate_disable(PINGRP_UAD);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -390,7 +390,7 @@ const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
|
|||
PIN(UAA, BB, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS),
|
||||
PIN(UAB, BB, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS),
|
||||
PIN(UAC, BB, OWR, RSVD, RSVD, RSVD, RSVD4),
|
||||
PIN(UAD, UART, IRDA, SPDIF, UARTA, SPI4, SPDIF),
|
||||
PIN(UAD, UART, UARTB, SPDIF, UARTA, SPI4, SPDIF),
|
||||
PIN(UCA, UART, UARTC, RSVD, GMI, RSVD, RSVD4),
|
||||
PIN(UCB, UART, UARTC, PWM, GMI, RSVD, RSVD4),
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
* This is the place in SRAM where the SDRAM parameters are stored. There
|
||||
* are 4 blocks, one for each RAM code
|
||||
*/
|
||||
#define SDRAM_PARAMS_BASE (AP20_BASE_PA_SRAM + 0x188)
|
||||
#define SDRAM_PARAMS_BASE (NV_PA_BASE_SRAM + 0x188)
|
||||
|
||||
/* TODO: If we later add support for the Misc GP controller, refactor this */
|
||||
union xm2cfga_reg {
|
||||
|
|
44
arch/arm/cpu/tegra30-common/Makefile
Normal file
44
arch/arm/cpu/tegra30-common/Makefile
Normal file
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# (C) Copyright 2000-2008
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
# The AVP is ARMv4T architecture so we must use special compiler
|
||||
# flags for any startup files it might use.
|
||||
|
||||
LIB = $(obj)lib$(SOC)-common.o
|
||||
|
||||
COBJS-y += clock.o funcmux.o pinmux.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
618
arch/arm/cpu/tegra30-common/clock.c
Normal file
618
arch/arm/cpu/tegra30-common/clock.c
Normal file
|
@ -0,0 +1,618 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra30 Clock control functions */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch-tegra/clk_rst.h>
|
||||
#include <asm/arch-tegra/timer.h>
|
||||
#include <div64.h>
|
||||
#include <fdtdec.h>
|
||||
|
||||
/*
|
||||
* Clock types that we can use as a source. The Tegra30 has muxes for the
|
||||
* peripheral clocks, and in most cases there are four options for the clock
|
||||
* source. This gives us a clock 'type' and exploits what commonality exists
|
||||
* in the device.
|
||||
*
|
||||
* Letters are obvious, except for T which means CLK_M, and S which means the
|
||||
* clock derived from 32KHz. Beware that CLK_M (also called OSC in the
|
||||
* datasheet) and PLL_M are different things. The former is the basic
|
||||
* clock supplied to the SOC from an external oscillator. The latter is the
|
||||
* memory clock PLL.
|
||||
*
|
||||
* See definitions in clock_id in the header file.
|
||||
*/
|
||||
enum clock_type_id {
|
||||
CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */
|
||||
CLOCK_TYPE_MCPA, /* and so on */
|
||||
CLOCK_TYPE_MCPT,
|
||||
CLOCK_TYPE_PCM,
|
||||
CLOCK_TYPE_PCMT,
|
||||
CLOCK_TYPE_PCMT16,
|
||||
CLOCK_TYPE_PDCT,
|
||||
CLOCK_TYPE_ACPT,
|
||||
CLOCK_TYPE_ASPTE,
|
||||
CLOCK_TYPE_PMDACD2T,
|
||||
CLOCK_TYPE_PCST,
|
||||
|
||||
CLOCK_TYPE_COUNT,
|
||||
CLOCK_TYPE_NONE = -1, /* invalid clock type */
|
||||
};
|
||||
|
||||
enum {
|
||||
CLOCK_MAX_MUX = 8 /* number of source options for each clock */
|
||||
};
|
||||
|
||||
enum {
|
||||
MASK_BITS_31_30 = 2, /* num of bits used to specify clock source */
|
||||
MASK_BITS_31_29,
|
||||
MASK_BITS_29_28,
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock source mux for each clock type. This just converts our enum into
|
||||
* a list of mux sources for use by the code.
|
||||
*
|
||||
* Note:
|
||||
* The extra column in each clock source array is used to store the mask
|
||||
* bits in its register for the source.
|
||||
*/
|
||||
#define CLK(x) CLOCK_ID_ ## x
|
||||
static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = {
|
||||
{ CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_30},
|
||||
{ CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC),
|
||||
CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_31_29},
|
||||
{ CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO),
|
||||
CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE),
|
||||
MASK_BITS_31_29},
|
||||
{ CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC),
|
||||
CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
|
||||
MASK_BITS_29_28}
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock type for each peripheral clock source. We put the name in each
|
||||
* record just so it is easy to match things up
|
||||
*/
|
||||
#define TYPE(name, type) type
|
||||
static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
|
||||
/* 0x00 */
|
||||
TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM),
|
||||
TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x08 */
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T),
|
||||
TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T),
|
||||
|
||||
/* 0x10 */
|
||||
TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA),
|
||||
|
||||
/* 0x18 */
|
||||
TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */
|
||||
TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x20 */
|
||||
TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT),
|
||||
TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT),
|
||||
TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT),
|
||||
|
||||
/* 0x28 */
|
||||
TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x30 */
|
||||
TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
|
||||
/* 0x38h */ /* Jumps to reg offset 0x3B0h - new for T30 */
|
||||
TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA),
|
||||
TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */
|
||||
TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT),
|
||||
TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16),
|
||||
TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT),
|
||||
|
||||
/* 0x40 */
|
||||
TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT),
|
||||
TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */
|
||||
TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE),
|
||||
|
||||
/* 0x48 */
|
||||
TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE),
|
||||
TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE),
|
||||
TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */
|
||||
TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
|
||||
/* 0x50 */
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
|
||||
TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */
|
||||
TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT),
|
||||
TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT),
|
||||
};
|
||||
|
||||
/*
|
||||
* This array translates a periph_id to a periphc_internal_id
|
||||
*
|
||||
* Not present/matched up:
|
||||
* uint vi_sensor; _VI_SENSOR_0, 0x1A8
|
||||
* SPDIF - which is both 0x08 and 0x0c
|
||||
*
|
||||
*/
|
||||
#define NONE(name) (-1)
|
||||
#define OFFSET(name, value) PERIPHC_ ## name
|
||||
static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
|
||||
/* Low word: 31:0 */
|
||||
NONE(CPU),
|
||||
NONE(COP),
|
||||
NONE(TRIGSYS),
|
||||
NONE(RESERVED3),
|
||||
NONE(RESERVED4),
|
||||
NONE(TMR),
|
||||
PERIPHC_UART1,
|
||||
PERIPHC_UART2, /* and vfir 0x68 */
|
||||
|
||||
/* 8 */
|
||||
NONE(GPIO),
|
||||
PERIPHC_SDMMC2,
|
||||
NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */
|
||||
PERIPHC_I2S1,
|
||||
PERIPHC_I2C1,
|
||||
PERIPHC_NDFLASH,
|
||||
PERIPHC_SDMMC1,
|
||||
PERIPHC_SDMMC4,
|
||||
|
||||
/* 16 */
|
||||
NONE(RESERVED16),
|
||||
PERIPHC_PWM,
|
||||
PERIPHC_I2S2,
|
||||
PERIPHC_EPP,
|
||||
PERIPHC_VI,
|
||||
PERIPHC_G2D,
|
||||
NONE(USBD),
|
||||
NONE(ISP),
|
||||
|
||||
/* 24 */
|
||||
PERIPHC_G3D,
|
||||
NONE(RESERVED25),
|
||||
PERIPHC_DISP2,
|
||||
PERIPHC_DISP1,
|
||||
PERIPHC_HOST1X,
|
||||
NONE(VCP),
|
||||
PERIPHC_I2S0,
|
||||
NONE(CACHE2),
|
||||
|
||||
/* Middle word: 63:32 */
|
||||
NONE(MEM),
|
||||
NONE(AHBDMA),
|
||||
NONE(APBDMA),
|
||||
NONE(RESERVED35),
|
||||
NONE(RESERVED36),
|
||||
NONE(STAT_MON),
|
||||
NONE(RESERVED38),
|
||||
NONE(RESERVED39),
|
||||
|
||||
/* 40 */
|
||||
NONE(KFUSE),
|
||||
PERIPHC_SBC1,
|
||||
PERIPHC_NOR,
|
||||
NONE(RESERVED43),
|
||||
PERIPHC_SBC2,
|
||||
NONE(RESERVED45),
|
||||
PERIPHC_SBC3,
|
||||
PERIPHC_DVC_I2C,
|
||||
|
||||
/* 48 */
|
||||
NONE(DSI),
|
||||
PERIPHC_TVO, /* also CVE 0x40 */
|
||||
PERIPHC_MIPI,
|
||||
PERIPHC_HDMI,
|
||||
NONE(CSI),
|
||||
PERIPHC_TVDAC,
|
||||
PERIPHC_I2C2,
|
||||
PERIPHC_UART3,
|
||||
|
||||
/* 56 */
|
||||
NONE(RESERVED56),
|
||||
PERIPHC_EMC,
|
||||
NONE(USB2),
|
||||
NONE(USB3),
|
||||
PERIPHC_MPE,
|
||||
PERIPHC_VDE,
|
||||
NONE(BSEA),
|
||||
NONE(BSEV),
|
||||
|
||||
/* Upper word 95:64 */
|
||||
PERIPHC_SPEEDO,
|
||||
PERIPHC_UART4,
|
||||
PERIPHC_UART5,
|
||||
PERIPHC_I2C3,
|
||||
PERIPHC_SBC4,
|
||||
PERIPHC_SDMMC3,
|
||||
NONE(PCIE),
|
||||
PERIPHC_OWR,
|
||||
|
||||
/* 72 */
|
||||
NONE(AFI),
|
||||
PERIPHC_CSITE,
|
||||
NONE(PCIEXCLK),
|
||||
NONE(AVPUCQ),
|
||||
NONE(RESERVED76),
|
||||
NONE(RESERVED77),
|
||||
NONE(RESERVED78),
|
||||
NONE(DTV),
|
||||
|
||||
/* 80 */
|
||||
PERIPHC_NANDSPEED,
|
||||
PERIPHC_I2CSLOW,
|
||||
NONE(DSIB),
|
||||
NONE(RESERVED83),
|
||||
NONE(IRAMA),
|
||||
NONE(IRAMB),
|
||||
NONE(IRAMC),
|
||||
NONE(IRAMD),
|
||||
|
||||
/* 88 */
|
||||
NONE(CRAM2),
|
||||
NONE(RESERVED89),
|
||||
NONE(MDOUBLER),
|
||||
NONE(RESERVED91),
|
||||
NONE(SUSOUT),
|
||||
NONE(RESERVED93),
|
||||
NONE(RESERVED94),
|
||||
NONE(RESERVED95),
|
||||
|
||||
/* V word: 31:0 */
|
||||
NONE(CPUG),
|
||||
NONE(CPULP),
|
||||
PERIPHC_G3D2,
|
||||
PERIPHC_MSELECT,
|
||||
PERIPHC_TSENSOR,
|
||||
PERIPHC_I2S3,
|
||||
PERIPHC_I2S4,
|
||||
PERIPHC_I2C4,
|
||||
|
||||
/* 08 */
|
||||
PERIPHC_SBC5,
|
||||
PERIPHC_SBC6,
|
||||
PERIPHC_AUDIO,
|
||||
NONE(APBIF),
|
||||
PERIPHC_DAM0,
|
||||
PERIPHC_DAM1,
|
||||
PERIPHC_DAM2,
|
||||
PERIPHC_HDA2CODEC2X,
|
||||
|
||||
/* 16 */
|
||||
NONE(ATOMICS),
|
||||
NONE(RESERVED17),
|
||||
NONE(RESERVED18),
|
||||
NONE(RESERVED19),
|
||||
NONE(RESERVED20),
|
||||
NONE(RESERVED21),
|
||||
NONE(RESERVED22),
|
||||
PERIPHC_ACTMON,
|
||||
|
||||
/* 24 */
|
||||
NONE(RESERVED24),
|
||||
NONE(RESERVED25),
|
||||
NONE(RESERVED26),
|
||||
NONE(RESERVED27),
|
||||
PERIPHC_SATA,
|
||||
PERIPHC_HDA,
|
||||
NONE(RESERVED30),
|
||||
NONE(RESERVED31),
|
||||
|
||||
/* W word: 31:0 */
|
||||
NONE(HDA2HDMICODEC),
|
||||
NONE(SATACOLD),
|
||||
NONE(RESERVED0_PCIERX0),
|
||||
NONE(RESERVED1_PCIERX1),
|
||||
NONE(RESERVED2_PCIERX2),
|
||||
NONE(RESERVED3_PCIERX3),
|
||||
NONE(RESERVED4_PCIERX4),
|
||||
NONE(RESERVED5_PCIERX5),
|
||||
|
||||
/* 40 */
|
||||
NONE(CEC),
|
||||
NONE(RESERVED6_PCIE2),
|
||||
NONE(RESERVED7_EMC),
|
||||
NONE(RESERVED8_HDMI),
|
||||
NONE(RESERVED9_SATA),
|
||||
NONE(RESERVED10_MIPI),
|
||||
NONE(EX_RESERVED46),
|
||||
NONE(EX_RESERVED47),
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the oscillator frequency, from the corresponding hardware configuration
|
||||
* field. Note that T30 supports 3 new higher freqs, but we map back
|
||||
* to the old T20 freqs. Support for the higher oscillators is TBD.
|
||||
*/
|
||||
enum clock_osc_freq clock_get_osc_freq(void)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(&clkrst->crc_osc_ctrl);
|
||||
reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
|
||||
|
||||
if (reg & 1) /* one of the newer freqs */
|
||||
printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
|
||||
|
||||
return reg >> 2; /* Map to most common (T20) freqs */
|
||||
}
|
||||
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
u32 *get_periph_source_reg(enum periph_id periph_id)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
enum periphc_internal_id internal_id;
|
||||
|
||||
/* Coresight is a special case */
|
||||
if (periph_id == PERIPH_ID_CSI)
|
||||
return &clkrst->crc_clk_src[PERIPH_ID_CSI+1];
|
||||
|
||||
assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT);
|
||||
internal_id = periph_id_to_internal_id[periph_id];
|
||||
assert(internal_id != -1);
|
||||
if (internal_id >= PERIPHC_VW_FIRST) {
|
||||
internal_id -= PERIPHC_VW_FIRST;
|
||||
return &clkrst->crc_clk_src_vw[internal_id];
|
||||
} else
|
||||
return &clkrst->crc_clk_src[internal_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a peripheral ID and the required source clock, this returns which
|
||||
* value should be programmed into the source mux for that peripheral.
|
||||
*
|
||||
* There is special code here to handle the one source type with 5 sources.
|
||||
*
|
||||
* @param periph_id peripheral to start
|
||||
* @param source PLL id of required parent clock
|
||||
* @param mux_bits Set to number of bits in mux register: 2 or 4
|
||||
* @param divider_bits Set to number of divider bits (8 or 16)
|
||||
* @return mux value (0-4, or -1 if not found)
|
||||
*/
|
||||
int get_periph_clock_source(enum periph_id periph_id,
|
||||
enum clock_id parent, int *mux_bits, int *divider_bits)
|
||||
{
|
||||
enum clock_type_id type;
|
||||
enum periphc_internal_id internal_id;
|
||||
int mux;
|
||||
|
||||
assert(clock_periph_id_isvalid(periph_id));
|
||||
|
||||
internal_id = periph_id_to_internal_id[periph_id];
|
||||
assert(periphc_internal_id_isvalid(internal_id));
|
||||
|
||||
type = clock_periph_type[internal_id];
|
||||
assert(clock_type_id_isvalid(type));
|
||||
|
||||
*mux_bits = clock_source[type][CLOCK_MAX_MUX];
|
||||
|
||||
if (type == CLOCK_TYPE_PCMT16)
|
||||
*divider_bits = 16;
|
||||
else
|
||||
*divider_bits = 8;
|
||||
|
||||
for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
|
||||
if (clock_source[type][mux] == parent)
|
||||
return mux;
|
||||
|
||||
/* if we get here, either us or the caller has made a mistake */
|
||||
printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
|
||||
parent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void clock_set_enable(enum periph_id periph_id, int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 *clk;
|
||||
u32 reg;
|
||||
|
||||
/* Enable/disable the clock to this peripheral */
|
||||
assert(clock_periph_id_isvalid(periph_id));
|
||||
if ((int)periph_id < (int)PERIPH_ID_VW_FIRST)
|
||||
clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
|
||||
else
|
||||
clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)];
|
||||
reg = readl(clk);
|
||||
if (enable)
|
||||
reg |= PERIPH_MASK(periph_id);
|
||||
else
|
||||
reg &= ~PERIPH_MASK(periph_id);
|
||||
writel(reg, clk);
|
||||
}
|
||||
|
||||
void reset_set_enable(enum periph_id periph_id, int enable)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst =
|
||||
(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 *reset;
|
||||
u32 reg;
|
||||
|
||||
/* Enable/disable reset to the peripheral */
|
||||
assert(clock_periph_id_isvalid(periph_id));
|
||||
if (periph_id < PERIPH_ID_VW_FIRST)
|
||||
reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
|
||||
else
|
||||
reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)];
|
||||
reg = readl(reset);
|
||||
if (enable)
|
||||
reg |= PERIPH_MASK(periph_id);
|
||||
else
|
||||
reg &= ~PERIPH_MASK(periph_id);
|
||||
writel(reg, reset);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
/*
|
||||
* Convert a device tree clock ID to our peripheral ID. They are mostly
|
||||
* the same but we are very cautious so we check that a valid clock ID is
|
||||
* provided.
|
||||
*
|
||||
* @param clk_id Clock ID according to tegra30 device tree binding
|
||||
* @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
|
||||
*/
|
||||
enum periph_id clk_id_to_periph_id(int clk_id)
|
||||
{
|
||||
if (clk_id > PERIPH_ID_COUNT)
|
||||
return PERIPH_ID_NONE;
|
||||
|
||||
switch (clk_id) {
|
||||
case PERIPH_ID_RESERVED3:
|
||||
case PERIPH_ID_RESERVED4:
|
||||
case PERIPH_ID_RESERVED16:
|
||||
case PERIPH_ID_RESERVED24:
|
||||
case PERIPH_ID_RESERVED35:
|
||||
case PERIPH_ID_RESERVED43:
|
||||
case PERIPH_ID_RESERVED45:
|
||||
case PERIPH_ID_RESERVED56:
|
||||
case PERIPH_ID_RESERVED76:
|
||||
case PERIPH_ID_RESERVED77:
|
||||
case PERIPH_ID_RESERVED78:
|
||||
case PERIPH_ID_RESERVED83:
|
||||
case PERIPH_ID_RESERVED89:
|
||||
case PERIPH_ID_RESERVED91:
|
||||
case PERIPH_ID_RESERVED93:
|
||||
case PERIPH_ID_RESERVED94:
|
||||
case PERIPH_ID_RESERVED95:
|
||||
return PERIPH_ID_NONE;
|
||||
default:
|
||||
return clk_id;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_OF_CONTROL */
|
||||
|
||||
void clock_early_init(void)
|
||||
{
|
||||
/*
|
||||
* PLLP output frequency set to 408Mhz
|
||||
* PLLC output frequency set to 228Mhz
|
||||
*/
|
||||
switch (clock_get_osc_freq()) {
|
||||
case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8);
|
||||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 26, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
|
||||
break;
|
||||
|
||||
case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
|
||||
clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8);
|
||||
clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
|
||||
break;
|
||||
case CLOCK_OSC_FREQ_19_2:
|
||||
default:
|
||||
/*
|
||||
* These are not supported. It is too early to print a
|
||||
* message and the UART likely won't work anyway due to the
|
||||
* oscillator being wrong.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
57
arch/arm/cpu/tegra30-common/funcmux.c
Normal file
57
arch/arm/cpu/tegra30-common/funcmux.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra30 high-level function multiplexing */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/funcmux.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
|
||||
int funcmux_select(enum periph_id id, int config)
|
||||
{
|
||||
int bad_config = config != FUNCMUX_DEFAULT;
|
||||
|
||||
switch (id) {
|
||||
case PERIPH_ID_UART1:
|
||||
switch (config) {
|
||||
case FUNCMUX_UART1_ULPI:
|
||||
pinmux_set_func(PINGRP_ULPI_DATA0, PMUX_FUNC_UARTA);
|
||||
pinmux_set_func(PINGRP_ULPI_DATA1, PMUX_FUNC_UARTA);
|
||||
pinmux_set_func(PINGRP_ULPI_DATA2, PMUX_FUNC_UARTA);
|
||||
pinmux_set_func(PINGRP_ULPI_DATA3, PMUX_FUNC_UARTA);
|
||||
pinmux_tristate_disable(PINGRP_ULPI_DATA0);
|
||||
pinmux_tristate_disable(PINGRP_ULPI_DATA1);
|
||||
pinmux_tristate_disable(PINGRP_ULPI_DATA2);
|
||||
pinmux_tristate_disable(PINGRP_ULPI_DATA3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Add other periph IDs here as needed */
|
||||
|
||||
default:
|
||||
debug("%s: invalid periph_id %d", __func__, id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bad_config) {
|
||||
debug("%s: invalid config %d for periph_id %d", __func__,
|
||||
config, id);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
506
arch/arm/cpu/tegra30-common/pinmux.c
Normal file
506
arch/arm/cpu/tegra30-common/pinmux.c
Normal file
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra30 pin multiplexing functions */
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
|
||||
struct tegra_pingroup_desc {
|
||||
const char *name;
|
||||
enum pmux_func funcs[4];
|
||||
enum pmux_func func_safe;
|
||||
enum pmux_vddio vddio;
|
||||
enum pmux_pin_io io;
|
||||
};
|
||||
|
||||
#define PMUX_MUXCTL_SHIFT 0
|
||||
#define PMUX_PULL_SHIFT 2
|
||||
#define PMUX_TRISTATE_SHIFT 4
|
||||
#define PMUX_TRISTATE_MASK (1 << PMUX_TRISTATE_SHIFT)
|
||||
#define PMUX_IO_SHIFT 5
|
||||
#define PMUX_OD_SHIFT 6
|
||||
#define PMUX_LOCK_SHIFT 7
|
||||
#define PMUX_IO_RESET_SHIFT 8
|
||||
|
||||
/* Convenient macro for defining pin group properties */
|
||||
#define PIN(pg_name, vdd, f0, f1, f2, f3, iod) \
|
||||
{ \
|
||||
.vddio = PMUX_VDDIO_ ## vdd, \
|
||||
.funcs = { \
|
||||
PMUX_FUNC_ ## f0, \
|
||||
PMUX_FUNC_ ## f1, \
|
||||
PMUX_FUNC_ ## f2, \
|
||||
PMUX_FUNC_ ## f3, \
|
||||
}, \
|
||||
.func_safe = PMUX_FUNC_RSVD1, \
|
||||
.io = PMUX_PIN_ ## iod, \
|
||||
}
|
||||
|
||||
/* Input and output pins */
|
||||
#define PINI(pg_name, vdd, f0, f1, f2, f3) \
|
||||
PIN(pg_name, vdd, f0, f1, f2, f3, INPUT)
|
||||
#define PINO(pg_name, vdd, f0, f1, f2, f3) \
|
||||
PIN(pg_name, vdd, f0, f1, f2, f3, OUTPUT)
|
||||
|
||||
const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
|
||||
/* NAME VDD f0 f1 f2 f3 */
|
||||
PINI(ULPI_DATA0, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA1, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA2, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA3, BB, SPI3, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA4, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA5, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA6, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_DATA7, BB, SPI2, HSI, UARTA, ULPI),
|
||||
PINI(ULPI_CLK, BB, SPI1, RSVD2, UARTD, ULPI),
|
||||
PINI(ULPI_DIR, BB, SPI1, RSVD2, UARTD, ULPI),
|
||||
PINI(ULPI_NXT, BB, SPI1, RSVD2, UARTD, ULPI),
|
||||
PINI(ULPI_STP, BB, SPI1, RSVD2, UARTD, ULPI),
|
||||
PINI(DAP3_FS, BB, I2S2, RSVD2, DISPA, DISPB),
|
||||
PINI(DAP3_DIN, BB, I2S2, RSVD2, DISPA, DISPB),
|
||||
PINI(DAP3_DOUT, BB, I2S2, RSVD2, DISPA, DISPB),
|
||||
PINI(DAP3_SCLK, BB, I2S2, RSVD2, DISPA, DISPB),
|
||||
PINI(GPIO_PV0, BB, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GPIO_PV1, BB, RSVD1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SDMMC1_CLK, SDMMC1, SDMMC1, RSVD2, RSVD3, UARTA),
|
||||
PINI(SDMMC1_CMD, SDMMC1, SDMMC1, RSVD2, RSVD3, UARTA),
|
||||
PINI(SDMMC1_DAT3, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA),
|
||||
PINI(SDMMC1_DAT2, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA),
|
||||
PINI(SDMMC1_DAT1, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA),
|
||||
PINI(SDMMC1_DAT0, SDMMC1, SDMMC1, RSVD2, UARTE, UARTA),
|
||||
PINI(GPIO_PV2, SDMMC1, OWR, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GPIO_PV3, SDMMC1, CLK_12M_OUT, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK2_OUT, SDMMC1, EXTPERIPH2, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK2_REQ, SDMMC1, DAP, RSVD2, RSVD3, RSVD4),
|
||||
PINO(LCD_PWR1, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_PWR2, LCD, DISPA, DISPB, SPI5, HDCP),
|
||||
PINO(LCD_SDIN, LCD, DISPA, DISPB, SPI5, RSVD4),
|
||||
PINO(LCD_SDOUT, LCD, DISPA, DISPB, SPI5, HDCP),
|
||||
PINO(LCD_WR_N, LCD, DISPA, DISPB, SPI5, HDCP),
|
||||
PINO(LCD_CS0_N, LCD, DISPA, DISPB, SPI5, RSVD4),
|
||||
PINO(LCD_DC0, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_SCK, LCD, DISPA, DISPB, SPI5, HDCP),
|
||||
PINO(LCD_PWR0, LCD, DISPA, DISPB, SPI5, HDCP),
|
||||
PINO(LCD_PCLK, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_DE, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_HSYNC, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_VSYNC, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D0, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D1, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D2, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D3, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D4, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D5, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D6, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D7, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D8, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D9, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D10, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D11, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D12, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D13, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D14, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D15, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D16, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D17, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D18, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D19, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D20, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D21, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D22, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_D23, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_CS1_N, LCD, DISPA, DISPB, SPI5, RSVD4),
|
||||
PINO(LCD_M1, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINO(LCD_DC1, LCD, DISPA, DISPB, RSVD3, RSVD4),
|
||||
PINI(HDMI_INT, LCD, HDMI, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DDC_SCL, LCD, I2C4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DDC_SDA, LCD, I2C4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CRT_HSYNC, LCD, CRT, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CRT_VSYNC, LCD, CRT, RSVD2, RSVD3, RSVD4),
|
||||
PINI(VI_D0, VI, DDR, RSVD2, VI, RSVD4),
|
||||
PINI(VI_D1, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D2, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D3, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D4, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D5, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D6, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D7, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D8, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D9, VI, DDR, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_D10, VI, DDR, RSVD2, VI, RSVD4),
|
||||
PINI(VI_D11, VI, DDR, RSVD2, VI, RSVD4),
|
||||
PINI(VI_PCLK, VI, RSVD1, SDMMC2, VI, RSVD4),
|
||||
PINI(VI_MCLK, VI, VI, VI, VI, VI),
|
||||
PINI(VI_VSYNC, VI, DDR, RSVD2, VI, RSVD4),
|
||||
PINI(VI_HSYNC, VI, DDR, RSVD2, VI, RSVD4),
|
||||
PINI(UART2_RXD, UART, UARTB, SPDIF, UARTA, SPI4),
|
||||
PINI(UART2_TXD, UART, UARTB, SPDIF, UARTA, SPI4),
|
||||
PINI(UART2_RTS_N, UART, UARTA, UARTB, GMI, SPI4),
|
||||
PINI(UART2_CTS_N, UART, UARTA, UARTB, GMI, SPI4),
|
||||
PINI(UART3_TXD, UART, UARTC, RSVD2, GMI, RSVD4),
|
||||
PINI(UART3_RXD, UART, UARTC, RSVD2, GMI, RSVD4),
|
||||
PINI(UART3_CTS_N, UART, UARTC, RSVD2, GMI, RSVD4),
|
||||
PINI(UART3_RTS_N, UART, UARTC, PWM0, GMI, RSVD4),
|
||||
PINI(GPIO_PU0, UART, OWR, UARTA, GMI, RSVD4),
|
||||
PINI(GPIO_PU1, UART, RSVD1, UARTA, GMI, RSVD4),
|
||||
PINI(GPIO_PU2, UART, RSVD1, UARTA, GMI, RSVD4),
|
||||
PINI(GPIO_PU3, UART, PWM0, UARTA, GMI, RSVD4),
|
||||
PINI(GPIO_PU4, UART, PWM1, UARTA, GMI, RSVD4),
|
||||
PINI(GPIO_PU5, UART, PWM2, UARTA, GMI, RSVD4),
|
||||
PINI(GPIO_PU6, UART, PWM3, UARTA, GMI, RSVD4),
|
||||
PINI(GEN1_I2C_SDA, UART, I2C1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GEN1_I2C_SCL, UART, I2C1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(DAP4_FS, UART, I2S3, RSVD2, GMI, RSVD4),
|
||||
PINI(DAP4_DIN, UART, I2S3, RSVD2, GMI, RSVD4),
|
||||
PINI(DAP4_DOUT, UART, I2S3, RSVD2, GMI, RSVD4),
|
||||
PINI(DAP4_SCLK, UART, I2S3, RSVD2, GMI, RSVD4),
|
||||
PINI(CLK3_OUT, UART, EXTPERIPH3, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK3_REQ, UART, DEV3, RSVD2, RSVD3, RSVD4),
|
||||
PINI(GMI_WP_N, GMI, RSVD1, NAND, GMI, GMI_ALT),
|
||||
PINI(GMI_IORDY, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_WAIT, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_ADV_N, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_CLK, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_CS0_N, GMI, RSVD1, NAND, GMI, DTV),
|
||||
PINI(GMI_CS1_N, GMI, RSVD1, NAND, GMI, DTV),
|
||||
PINI(GMI_CS2_N, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_CS3_N, GMI, RSVD1, NAND, GMI, GMI_ALT),
|
||||
PINI(GMI_CS4_N, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_CS6_N, GMI, NAND, NAND_ALT, GMI, SATA),
|
||||
PINI(GMI_CS7_N, GMI, NAND, NAND_ALT, GMI, GMI_ALT),
|
||||
PINI(GMI_AD0, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD1, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD2, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD3, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD4, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD5, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD6, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD7, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD8, GMI, PWM0, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD9, GMI, PWM1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD10, GMI, PWM2, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD11, GMI, PWM3, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD12, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD13, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD14, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_AD15, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_A16, GMI, UARTD, SPI4, GMI, GMI_ALT),
|
||||
PINI(GMI_A17, GMI, UARTD, SPI4, GMI, DTV),
|
||||
PINI(GMI_A18, GMI, UARTD, SPI4, GMI, DTV),
|
||||
PINI(GMI_A19, GMI, UARTD, SPI4, GMI, RSVD4),
|
||||
PINI(GMI_WR_N, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_OE_N, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_DQS, GMI, RSVD1, NAND, GMI, RSVD4),
|
||||
PINI(GMI_RST_N, GMI, NAND, NAND_ALT, GMI, RSVD4),
|
||||
PINI(GEN2_I2C_SCL, GMI, I2C2, HDCP, GMI, RSVD4),
|
||||
PINI(GEN2_I2C_SDA, GMI, I2C2, HDCP, GMI, RSVD4),
|
||||
PINI(SDMMC4_CLK, SDMMC4, RSVD1, NAND, GMI, SDMMC4),
|
||||
PINI(SDMMC4_CMD, SDMMC4, I2C3, NAND, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT0, SDMMC4, UARTE, SPI3, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT1, SDMMC4, UARTE, SPI3, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT2, SDMMC4, UARTE, SPI3, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT3, SDMMC4, UARTE, SPI3, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT4, SDMMC4, I2C3, I2S4, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT5, SDMMC4, VGP3, I2S4, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT6, SDMMC4, VGP4, I2S4, GMI, SDMMC4),
|
||||
PINI(SDMMC4_DAT7, SDMMC4, VGP5, I2S4, GMI, SDMMC4),
|
||||
PINI(SDMMC4_RST_N, SDMMC4, VGP6, RSVD2, RSVD3, SDMMC4),
|
||||
PINI(CAM_MCLK, CAM, VI, RSVD2, VI_ALT2, SDMMC4),
|
||||
PINI(GPIO_PCC1, CAM, I2S4, RSVD2, RSVD3, SDMMC4),
|
||||
PINI(GPIO_PBB0, CAM, I2S4, RSVD2, RSVD3, SDMMC4),
|
||||
PINI(CAM_I2C_SCL, CAM, VGP1, I2C3, RSVD3, SDMMC4),
|
||||
PINI(CAM_I2C_SDA, CAM, VGP2, I2C3, RSVD3, SDMMC4),
|
||||
PINI(GPIO_PBB3, CAM, VGP3, DISPA, DISPB, SDMMC4),
|
||||
PINI(GPIO_PBB4, CAM, VGP4, DISPA, DISPB, SDMMC4),
|
||||
PINI(GPIO_PBB5, CAM, VGP5, DISPA, DISPB, SDMMC4),
|
||||
PINI(GPIO_PBB6, CAM, VGP6, DISPA, DISPB, SDMMC4),
|
||||
PINI(GPIO_PBB7, CAM, I2S4, RSVD2, RSVD3, SDMMC4),
|
||||
PINI(GPIO_PCC2, CAM, I2S4, RSVD2, RSVD3, RSVD4),
|
||||
PINI(JTAG_RTCK, SYS, RTCK, RSVD2, RSVD3, RSVD4),
|
||||
PINI(PWR_I2C_SCL, SYS, I2CPWR, RSVD2, RSVD3, RSVD4),
|
||||
PINI(PWR_I2C_SDA, SYS, I2CPWR, RSVD2, RSVD3, RSVD4),
|
||||
PINI(KB_ROW0, SYS, KBC, NAND, RSVD3, RSVD4),
|
||||
PINI(KB_ROW1, SYS, KBC, NAND, RSVD3, RSVD4),
|
||||
PINI(KB_ROW2, SYS, KBC, NAND, RSVD3, RSVD4),
|
||||
PINI(KB_ROW3, SYS, KBC, NAND, RSVD3, RSVD4),
|
||||
PINI(KB_ROW4, SYS, KBC, NAND, TRACE, RSVD4),
|
||||
PINI(KB_ROW5, SYS, KBC, NAND, TRACE, OWR),
|
||||
PINI(KB_ROW6, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW7, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW8, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW9, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW10, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW11, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW12, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW13, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW14, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_ROW15, SYS, KBC, NAND, SDMMC2, MIO),
|
||||
PINI(KB_COL0, SYS, KBC, NAND, TRACE, TEST),
|
||||
PINI(KB_COL1, SYS, KBC, NAND, TRACE, TEST),
|
||||
PINI(KB_COL2, SYS, KBC, NAND, TRACE, RSVD4),
|
||||
PINI(KB_COL3, SYS, KBC, NAND, TRACE, RSVD4),
|
||||
PINI(KB_COL4, SYS, KBC, NAND, TRACE, RSVD4),
|
||||
PINI(KB_COL5, SYS, KBC, NAND, TRACE, RSVD4),
|
||||
PINI(KB_COL6, SYS, KBC, NAND, TRACE, MIO),
|
||||
PINI(KB_COL7, SYS, KBC, NAND, TRACE, MIO),
|
||||
PINI(CLK_32K_OUT, SYS, BLINK, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SYS_CLK_REQ, SYS, SYSCLK, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CORE_PWR_REQ, SYS, CORE_PWR_REQ, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CPU_PWR_REQ, SYS, CPU_PWR_REQ, RSVD2, RSVD3, RSVD4),
|
||||
PINI(PWR_INT_N, SYS, PWR_INT_N, RSVD2, RSVD3, RSVD4),
|
||||
PINI(CLK_32K_IN, SYS, CLK_32K_IN, RSVD2, RSVD3, RSVD4),
|
||||
PINI(OWR, SYS, OWR, CEC, RSVD3, RSVD4),
|
||||
PINI(DAP1_FS, AUDIO, I2S0, HDA, GMI, SDMMC2),
|
||||
PINI(DAP1_DIN, AUDIO, I2S0, HDA, GMI, SDMMC2),
|
||||
PINI(DAP1_DOUT, AUDIO, I2S0, HDA, GMI, SDMMC2),
|
||||
PINI(DAP1_SCLK, AUDIO, I2S0, HDA, GMI, SDMMC2),
|
||||
PINI(CLK1_REQ, AUDIO, DAP, HDA, RSVD3, RSVD4),
|
||||
PINI(CLK1_OUT, AUDIO, EXTPERIPH1, RSVD2, RSVD3, RSVD4),
|
||||
PINI(SPDIF_IN, AUDIO, SPDIF, HDA, I2C1, SDMMC2),
|
||||
PINI(SPDIF_OUT, AUDIO, SPDIF, RSVD2, I2C1, SDMMC2),
|
||||
PINI(DAP2_FS, AUDIO, I2S1, HDA, RSVD3, GMI),
|
||||
PINI(DAP2_DIN, AUDIO, I2S1, HDA, RSVD3, GMI),
|
||||
PINI(DAP2_DOUT, AUDIO, I2S1, HDA, RSVD3, GMI),
|
||||
PINI(DAP2_SCLK, AUDIO, I2S1, HDA, RSVD3, GMI),
|
||||
PINI(SPI2_MOSI, AUDIO, SPI6, SPI2, GMI, GMI),
|
||||
PINI(SPI2_MISO, AUDIO, SPI6, SPI2, GMI, GMI),
|
||||
PINI(SPI2_CS0_N, AUDIO, SPI6, SPI2, GMI, GMI),
|
||||
PINI(SPI2_SCK, AUDIO, SPI6, SPI2, GMI, GMI),
|
||||
PINI(SPI1_MOSI, AUDIO, SPI2, SPI1, SPI2_ALT, GMI),
|
||||
PINI(SPI1_SCK, AUDIO, SPI2, SPI1, SPI2_ALT, GMI),
|
||||
PINI(SPI1_CS0_N, AUDIO, SPI2, SPI1, SPI2_ALT, GMI),
|
||||
PINI(SPI1_MISO, AUDIO, SPI3, SPI1, SPI2_ALT, RSVD4),
|
||||
PINI(SPI2_CS1_N, AUDIO, SPI3, SPI2, SPI2_ALT, I2C1),
|
||||
PINI(SPI2_CS2_N, AUDIO, SPI3, SPI2, SPI2_ALT, I2C1),
|
||||
PINI(SDMMC3_CLK, SDMMC3, UARTA, PWM2, SDMMC3, SPI3),
|
||||
PINI(SDMMC3_CMD, SDMMC3, UARTA, PWM3, SDMMC3, SPI2),
|
||||
PINI(SDMMC3_DAT0, SDMMC3, RSVD1, RSVD2, SDMMC3, SPI3),
|
||||
PINI(SDMMC3_DAT1, SDMMC3, RSVD1, RSVD2, SDMMC3, SPI3),
|
||||
PINI(SDMMC3_DAT2, SDMMC3, RSVD1, PWM1, SDMMC3, SPI3),
|
||||
PINI(SDMMC3_DAT3, SDMMC3, RSVD1, PWM0, SDMMC3, SPI3),
|
||||
PINI(SDMMC3_DAT4, SDMMC3, PWM1, SPI4, SDMMC3, SPI2),
|
||||
PINI(SDMMC3_DAT5, SDMMC3, PWM0, SPI4, SDMMC3, SPI2),
|
||||
PINI(SDMMC3_DAT6, SDMMC3, SPDIF, SPI4, SDMMC3, SPI2),
|
||||
PINI(SDMMC3_DAT7, SDMMC3, SPDIF, SPI4, SDMMC3, SPI2),
|
||||
PINI(PEX_L0_PRSNT_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L0_RST_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L0_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_WAKE_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L1_PRSNT_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L1_RST_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L1_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L2_PRSNT_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L2_RST_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(PEX_L2_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD3, RSVD4),
|
||||
PINI(HDMI_CEC, SYS, CEC, RSVD2, RSVD3, RSVD4),
|
||||
};
|
||||
|
||||
void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *tri = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
|
||||
reg = readl(tri);
|
||||
if (enable)
|
||||
reg |= PMUX_TRISTATE_MASK;
|
||||
else
|
||||
reg &= ~PMUX_TRISTATE_MASK;
|
||||
writel(reg, tri);
|
||||
}
|
||||
|
||||
void pinmux_tristate_enable(enum pmux_pingrp pin)
|
||||
{
|
||||
pinmux_set_tristate(pin, 1);
|
||||
}
|
||||
|
||||
void pinmux_tristate_disable(enum pmux_pingrp pin)
|
||||
{
|
||||
pinmux_set_tristate(pin, 0);
|
||||
}
|
||||
|
||||
void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pull = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and pupd */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_pupd_isvalid(pupd));
|
||||
|
||||
reg = readl(pull);
|
||||
reg &= ~(0x3 << PMUX_PULL_SHIFT);
|
||||
reg |= (pupd << PMUX_PULL_SHIFT);
|
||||
writel(reg, pull);
|
||||
}
|
||||
|
||||
void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *muxctl = &pmt->pmt_ctl[pin];
|
||||
int i, mux = -1;
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and func */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_func_isvalid(func));
|
||||
|
||||
/* Handle special values */
|
||||
if (func == PMUX_FUNC_SAFE)
|
||||
func = tegra_soc_pingroups[pin].func_safe;
|
||||
|
||||
if (func & PMUX_FUNC_RSVD1) {
|
||||
mux = func & 0x3;
|
||||
} else {
|
||||
/* Search for the appropriate function */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (tegra_soc_pingroups[pin].funcs[i] == func) {
|
||||
mux = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(mux != -1);
|
||||
|
||||
reg = readl(muxctl);
|
||||
reg &= ~(0x3 << PMUX_MUXCTL_SHIFT);
|
||||
reg |= (mux << PMUX_MUXCTL_SHIFT);
|
||||
writel(reg, muxctl);
|
||||
|
||||
}
|
||||
|
||||
void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_io = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and io */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_io_isvalid(io));
|
||||
|
||||
reg = readl(pin_io);
|
||||
reg &= ~(0x1 << PMUX_IO_SHIFT);
|
||||
reg |= (io & 0x1) << PMUX_IO_SHIFT;
|
||||
writel(reg, pin_io);
|
||||
}
|
||||
|
||||
static int pinmux_set_lock(enum pmux_pingrp pin, enum pmux_pin_lock lock)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_lock = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and lock */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_lock_isvalid(lock));
|
||||
|
||||
if (lock == PMUX_PIN_LOCK_DEFAULT)
|
||||
return 0;
|
||||
|
||||
reg = readl(pin_lock);
|
||||
reg &= ~(0x1 << PMUX_LOCK_SHIFT);
|
||||
if (lock == PMUX_PIN_LOCK_ENABLE)
|
||||
reg |= (0x1 << PMUX_LOCK_SHIFT);
|
||||
else {
|
||||
/* lock == DISABLE, which isn't possible */
|
||||
printf("%s: Warning: lock == %d, DISABLE is not allowed!\n",
|
||||
__func__, lock);
|
||||
}
|
||||
writel(reg, pin_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pinmux_set_od(enum pmux_pingrp pin, enum pmux_pin_od od)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_od = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and od */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_od_isvalid(od));
|
||||
|
||||
if (od == PMUX_PIN_OD_DEFAULT)
|
||||
return 0;
|
||||
|
||||
reg = readl(pin_od);
|
||||
reg &= ~(0x1 << PMUX_OD_SHIFT);
|
||||
if (od == PMUX_PIN_OD_ENABLE)
|
||||
reg |= (0x1 << PMUX_OD_SHIFT);
|
||||
writel(reg, pin_od);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pinmux_set_ioreset(enum pmux_pingrp pin,
|
||||
enum pmux_pin_ioreset ioreset)
|
||||
{
|
||||
struct pmux_tri_ctlr *pmt =
|
||||
(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
|
||||
u32 *pin_ioreset = &pmt->pmt_ctl[pin];
|
||||
u32 reg;
|
||||
|
||||
/* Error check on pin and ioreset */
|
||||
assert(pmux_pingrp_isvalid(pin));
|
||||
assert(pmux_pin_ioreset_isvalid(ioreset));
|
||||
|
||||
if (ioreset == PMUX_PIN_IO_RESET_DEFAULT)
|
||||
return 0;
|
||||
|
||||
reg = readl(pin_ioreset);
|
||||
reg &= ~(0x1 << PMUX_IO_RESET_SHIFT);
|
||||
if (ioreset == PMUX_PIN_IO_RESET_ENABLE)
|
||||
reg |= (0x1 << PMUX_IO_RESET_SHIFT);
|
||||
writel(reg, pin_ioreset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pinmux_config_pingroup(struct pingroup_config *config)
|
||||
{
|
||||
enum pmux_pingrp pin = config->pingroup;
|
||||
|
||||
pinmux_set_func(pin, config->func);
|
||||
pinmux_set_pullupdown(pin, config->pull);
|
||||
pinmux_set_tristate(pin, config->tristate);
|
||||
pinmux_set_io(pin, config->io);
|
||||
pinmux_set_lock(pin, config->lock);
|
||||
pinmux_set_od(pin, config->od);
|
||||
pinmux_set_ioreset(pin, config->ioreset);
|
||||
}
|
||||
|
||||
void pinmux_config_table(struct pingroup_config *config, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
pinmux_config_pingroup(&config[i]);
|
||||
}
|
5
arch/arm/dts/tegra114.dtsi
Normal file
5
arch/arm/dts/tegra114.dtsi
Normal file
|
@ -0,0 +1,5 @@
|
|||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "nvidia,tegra114";
|
||||
};
|
|
@ -4,220 +4,6 @@
|
|||
compatible = "nvidia,tegra20";
|
||||
interrupt-parent = <&intc>;
|
||||
|
||||
tegra_car: clock@60006000 {
|
||||
compatible = "nvidia,tegra20-car";
|
||||
reg = <0x60006000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
clocks {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
osc: clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
intc: interrupt-controller@50041000 {
|
||||
compatible = "nvidia,tegra20-gic";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
reg = < 0x50041000 0x1000 >,
|
||||
< 0x50040100 0x0100 >;
|
||||
};
|
||||
|
||||
i2c@7000c000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C000 0x100>;
|
||||
interrupts = < 70 >;
|
||||
/* PERIPH_ID_I2C1, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 12>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
i2c@7000c400 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C400 0x100>;
|
||||
interrupts = < 116 >;
|
||||
/* PERIPH_ID_I2C2, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 54>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
i2c@7000c500 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C500 0x100>;
|
||||
interrupts = < 124 >;
|
||||
/* PERIPH_ID_I2C3, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 67>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
i2c@7000d000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c-dvc";
|
||||
reg = <0x7000D000 0x200>;
|
||||
interrupts = < 85 >;
|
||||
/* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 47>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
i2s@70002800 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2s";
|
||||
reg = <0x70002800 0x200>;
|
||||
interrupts = < 45 >;
|
||||
dma-channel = < 2 >;
|
||||
};
|
||||
|
||||
i2s@70002a00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2s";
|
||||
reg = <0x70002a00 0x200>;
|
||||
interrupts = < 35 >;
|
||||
dma-channel = < 1 >;
|
||||
};
|
||||
|
||||
das@70000c00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-das";
|
||||
reg = <0x70000c00 0x80>;
|
||||
};
|
||||
|
||||
gpio: gpio@6000d000 {
|
||||
compatible = "nvidia,tegra20-gpio";
|
||||
reg = < 0x6000d000 0x1000 >;
|
||||
interrupts = < 64 65 66 67 87 119 121 >;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
pinmux: pinmux@70000000 {
|
||||
compatible = "nvidia,tegra20-pinmux";
|
||||
reg = < 0x70000014 0x10 /* Tri-state registers */
|
||||
0x70000080 0x20 /* Mux registers */
|
||||
0x700000a0 0x14 /* Pull-up/down registers */
|
||||
0x70000868 0xa8 >; /* Pad control registers */
|
||||
};
|
||||
|
||||
serial@70006000 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006000 0x40>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 68 >;
|
||||
};
|
||||
|
||||
serial@70006040 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006040 0x40>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 69 >;
|
||||
};
|
||||
|
||||
serial@70006200 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006200 0x100>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 78 >;
|
||||
};
|
||||
|
||||
serial@70006300 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006300 0x100>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 122 >;
|
||||
};
|
||||
|
||||
serial@70006400 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006400 0x100>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 123 >;
|
||||
};
|
||||
|
||||
sdhci@c8000000 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000000 0x200>;
|
||||
interrupts = < 46 >;
|
||||
};
|
||||
|
||||
sdhci@c8000200 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000200 0x200>;
|
||||
interrupts = < 47 >;
|
||||
};
|
||||
|
||||
sdhci@c8000400 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000400 0x200>;
|
||||
interrupts = < 51 >;
|
||||
};
|
||||
|
||||
sdhci@c8000600 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000600 0x200>;
|
||||
interrupts = < 63 >;
|
||||
};
|
||||
|
||||
usb@c5000000 {
|
||||
compatible = "nvidia,tegra20-ehci", "usb-ehci";
|
||||
reg = <0xc5000000 0x4000>;
|
||||
interrupts = < 52 >;
|
||||
phy_type = "utmi";
|
||||
clocks = <&tegra_car 22>; /* PERIPH_ID_USBD */
|
||||
nvidia,has-legacy-mode;
|
||||
};
|
||||
|
||||
usb@c5004000 {
|
||||
compatible = "nvidia,tegra20-ehci", "usb-ehci";
|
||||
reg = <0xc5004000 0x4000>;
|
||||
interrupts = < 53 >;
|
||||
phy_type = "ulpi";
|
||||
clocks = <&tegra_car 58>; /* PERIPH_ID_USB2 */
|
||||
};
|
||||
|
||||
usb@c5008000 {
|
||||
compatible = "nvidia,tegra20-ehci", "usb-ehci";
|
||||
reg = <0xc5008000 0x4000>;
|
||||
interrupts = < 129 >;
|
||||
phy_type = "utmi";
|
||||
clocks = <&tegra_car 59>; /* PERIPH_ID_USB3 */
|
||||
};
|
||||
|
||||
emc@7000f400 {
|
||||
#address-cells = < 1 >;
|
||||
#size-cells = < 0 >;
|
||||
compatible = "nvidia,tegra20-emc";
|
||||
reg = <0x7000f400 0x200>;
|
||||
};
|
||||
|
||||
kbc@7000e200 {
|
||||
compatible = "nvidia,tegra20-kbc";
|
||||
reg = <0x7000e200 0x0078>;
|
||||
};
|
||||
|
||||
nand: nand-controller@70008000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-nand";
|
||||
reg = <0x70008000 0x100>;
|
||||
};
|
||||
|
||||
pwm: pwm@7000a000 {
|
||||
compatible = "nvidia,tegra20-pwm";
|
||||
reg = <0x7000a000 0x100>;
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
host1x {
|
||||
compatible = "nvidia,tegra20-host1x", "simple-bus";
|
||||
reg = <0x50000000 0x00024000>;
|
||||
|
@ -316,4 +102,240 @@
|
|||
};
|
||||
};
|
||||
|
||||
intc: interrupt-controller@50041000 {
|
||||
compatible = "nvidia,tegra20-gic";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
reg = < 0x50041000 0x1000 >,
|
||||
< 0x50040100 0x0100 >;
|
||||
};
|
||||
|
||||
tegra_car: clock@60006000 {
|
||||
compatible = "nvidia,tegra20-car";
|
||||
reg = <0x60006000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
apbdma: dma {
|
||||
compatible = "nvidia,tegra20-apbdma";
|
||||
reg = <0x6000a000 0x1200>;
|
||||
interrupts = <0 104 0x04
|
||||
0 105 0x04
|
||||
0 106 0x04
|
||||
0 107 0x04
|
||||
0 108 0x04
|
||||
0 109 0x04
|
||||
0 110 0x04
|
||||
0 111 0x04
|
||||
0 112 0x04
|
||||
0 113 0x04
|
||||
0 114 0x04
|
||||
0 115 0x04
|
||||
0 116 0x04
|
||||
0 117 0x04
|
||||
0 118 0x04
|
||||
0 119 0x04>;
|
||||
};
|
||||
|
||||
gpio: gpio@6000d000 {
|
||||
compatible = "nvidia,tegra20-gpio";
|
||||
reg = < 0x6000d000 0x1000 >;
|
||||
interrupts = < 64 65 66 67 87 119 121 >;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
pinmux: pinmux@70000000 {
|
||||
compatible = "nvidia,tegra20-pinmux";
|
||||
reg = < 0x70000014 0x10 /* Tri-state registers */
|
||||
0x70000080 0x20 /* Mux registers */
|
||||
0x700000a0 0x14 /* Pull-up/down registers */
|
||||
0x70000868 0xa8 >; /* Pad control registers */
|
||||
};
|
||||
|
||||
das@70000c00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-das";
|
||||
reg = <0x70000c00 0x80>;
|
||||
};
|
||||
|
||||
i2s@70002800 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2s";
|
||||
reg = <0x70002800 0x200>;
|
||||
interrupts = < 45 >;
|
||||
dma-channel = < 2 >;
|
||||
};
|
||||
|
||||
i2s@70002a00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2s";
|
||||
reg = <0x70002a00 0x200>;
|
||||
interrupts = < 35 >;
|
||||
dma-channel = < 1 >;
|
||||
};
|
||||
|
||||
serial@70006000 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006000 0x40>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 68 >;
|
||||
};
|
||||
|
||||
serial@70006040 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006040 0x40>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 69 >;
|
||||
};
|
||||
|
||||
serial@70006200 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006200 0x100>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 78 >;
|
||||
};
|
||||
|
||||
serial@70006300 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006300 0x100>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 122 >;
|
||||
};
|
||||
|
||||
serial@70006400 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006400 0x100>;
|
||||
reg-shift = <2>;
|
||||
interrupts = < 123 >;
|
||||
};
|
||||
|
||||
nand: nand-controller@70008000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-nand";
|
||||
reg = <0x70008000 0x100>;
|
||||
};
|
||||
|
||||
pwm: pwm@7000a000 {
|
||||
compatible = "nvidia,tegra20-pwm";
|
||||
reg = <0x7000a000 0x100>;
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
i2c@7000c000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C000 0x100>;
|
||||
interrupts = < 70 >;
|
||||
/* PERIPH_ID_I2C1, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 12>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
spi@7000c380 {
|
||||
compatible = "nvidia,tegra20-sflash";
|
||||
reg = <0x7000c380 0x80>;
|
||||
interrupts = <0 39 0x04>;
|
||||
nvidia,dma-request-selector = <&apbdma 11>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
/* PERIPH_ID_SPI1, PLLP_OUT0 */
|
||||
clocks = <&tegra_car 43>;
|
||||
};
|
||||
|
||||
i2c@7000c400 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C400 0x100>;
|
||||
interrupts = < 116 >;
|
||||
/* PERIPH_ID_I2C2, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 54>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
i2c@7000c500 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C500 0x100>;
|
||||
interrupts = < 124 >;
|
||||
/* PERIPH_ID_I2C3, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 67>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
i2c@7000d000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra20-i2c-dvc";
|
||||
reg = <0x7000D000 0x200>;
|
||||
interrupts = < 85 >;
|
||||
/* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */
|
||||
clocks = <&tegra_car 47>, <&tegra_car 124>;
|
||||
};
|
||||
|
||||
kbc@7000e200 {
|
||||
compatible = "nvidia,tegra20-kbc";
|
||||
reg = <0x7000e200 0x0078>;
|
||||
};
|
||||
|
||||
emc@7000f400 {
|
||||
#address-cells = < 1 >;
|
||||
#size-cells = < 0 >;
|
||||
compatible = "nvidia,tegra20-emc";
|
||||
reg = <0x7000f400 0x200>;
|
||||
};
|
||||
|
||||
usb@c5000000 {
|
||||
compatible = "nvidia,tegra20-ehci", "usb-ehci";
|
||||
reg = <0xc5000000 0x4000>;
|
||||
interrupts = < 52 >;
|
||||
phy_type = "utmi";
|
||||
clocks = <&tegra_car 22>; /* PERIPH_ID_USBD */
|
||||
nvidia,has-legacy-mode;
|
||||
};
|
||||
|
||||
usb@c5004000 {
|
||||
compatible = "nvidia,tegra20-ehci", "usb-ehci";
|
||||
reg = <0xc5004000 0x4000>;
|
||||
interrupts = < 53 >;
|
||||
phy_type = "ulpi";
|
||||
clocks = <&tegra_car 58>; /* PERIPH_ID_USB2 */
|
||||
};
|
||||
|
||||
usb@c5008000 {
|
||||
compatible = "nvidia,tegra20-ehci", "usb-ehci";
|
||||
reg = <0xc5008000 0x4000>;
|
||||
interrupts = < 129 >;
|
||||
phy_type = "utmi";
|
||||
clocks = <&tegra_car 59>; /* PERIPH_ID_USB3 */
|
||||
};
|
||||
|
||||
sdhci@c8000000 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000000 0x200>;
|
||||
interrupts = < 46 >;
|
||||
};
|
||||
|
||||
sdhci@c8000200 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000200 0x200>;
|
||||
interrupts = < 47 >;
|
||||
};
|
||||
|
||||
sdhci@c8000400 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000400 0x200>;
|
||||
interrupts = < 51 >;
|
||||
};
|
||||
|
||||
sdhci@c8000600 {
|
||||
compatible = "nvidia,tegra20-sdhci";
|
||||
reg = <0xc8000600 0x200>;
|
||||
interrupts = < 63 >;
|
||||
};
|
||||
};
|
||||
|
|
165
arch/arm/dts/tegra30.dtsi
Normal file
165
arch/arm/dts/tegra30.dtsi
Normal file
|
@ -0,0 +1,165 @@
|
|||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "nvidia,tegra30";
|
||||
|
||||
tegra_car: clock@60006000 {
|
||||
compatible = "nvidia,tegra30-car", "nvidia,tegra20-car";
|
||||
reg = <0x60006000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
apbdma: dma {
|
||||
compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
|
||||
reg = <0x6000a000 0x1400>;
|
||||
interrupts = <0 104 0x04
|
||||
0 105 0x04
|
||||
0 106 0x04
|
||||
0 107 0x04
|
||||
0 108 0x04
|
||||
0 109 0x04
|
||||
0 110 0x04
|
||||
0 111 0x04
|
||||
0 112 0x04
|
||||
0 113 0x04
|
||||
0 114 0x04
|
||||
0 115 0x04
|
||||
0 116 0x04
|
||||
0 117 0x04
|
||||
0 118 0x04
|
||||
0 119 0x04
|
||||
0 128 0x04
|
||||
0 129 0x04
|
||||
0 130 0x04
|
||||
0 131 0x04
|
||||
0 132 0x04
|
||||
0 133 0x04
|
||||
0 134 0x04
|
||||
0 135 0x04
|
||||
0 136 0x04
|
||||
0 137 0x04
|
||||
0 138 0x04
|
||||
0 139 0x04
|
||||
0 140 0x04
|
||||
0 141 0x04
|
||||
0 142 0x04
|
||||
0 143 0x04>;
|
||||
};
|
||||
|
||||
i2c@7000c000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C000 0x100>;
|
||||
/* PERIPH_ID_I2C1, CLK_M */
|
||||
clocks = <&tegra_car 12>;
|
||||
};
|
||||
|
||||
i2c@7000c400 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C400 0x100>;
|
||||
/* PERIPH_ID_I2C2, CLK_M */
|
||||
clocks = <&tegra_car 54>;
|
||||
};
|
||||
|
||||
i2c@7000c500 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C500 0x100>;
|
||||
/* PERIPH_ID_I2C3, CLK_M */
|
||||
clocks = <&tegra_car 67>;
|
||||
};
|
||||
|
||||
i2c@7000c700 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
|
||||
reg = <0x7000C700 0x100>;
|
||||
/* PERIPH_ID_I2C4, CLK_M */
|
||||
clocks = <&tegra_car 103>;
|
||||
};
|
||||
|
||||
i2c@7000d000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
|
||||
reg = <0x7000D000 0x100>;
|
||||
/* PERIPH_ID_I2C_DVC, CLK_M */
|
||||
clocks = <&tegra_car 47>;
|
||||
};
|
||||
|
||||
spi@7000d400 {
|
||||
compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
|
||||
reg = <0x7000d400 0x200>;
|
||||
interrupts = <0 59 0x04>;
|
||||
nvidia,dma-request-selector = <&apbdma 15>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
/* PERIPH_ID_SBC1, PLLP_OUT0 */
|
||||
clocks = <&tegra_car 41>;
|
||||
};
|
||||
|
||||
spi@7000d600 {
|
||||
compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
|
||||
reg = <0x7000d600 0x200>;
|
||||
interrupts = <0 82 0x04>;
|
||||
nvidia,dma-request-selector = <&apbdma 16>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
/* PERIPH_ID_SBC2, PLLP_OUT0 */
|
||||
clocks = <&tegra_car 44>;
|
||||
};
|
||||
|
||||
spi@7000d800 {
|
||||
compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
|
||||
reg = <0x7000d480 0x200>;
|
||||
interrupts = <0 83 0x04>;
|
||||
nvidia,dma-request-selector = <&apbdma 17>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
/* PERIPH_ID_SBC3, PLLP_OUT0 */
|
||||
clocks = <&tegra_car 46>;
|
||||
};
|
||||
|
||||
spi@7000da00 {
|
||||
compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
|
||||
reg = <0x7000da00 0x200>;
|
||||
interrupts = <0 93 0x04>;
|
||||
nvidia,dma-request-selector = <&apbdma 18>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
/* PERIPH_ID_SBC4, PLLP_OUT0 */
|
||||
clocks = <&tegra_car 68>;
|
||||
};
|
||||
|
||||
spi@7000dc00 {
|
||||
compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
|
||||
reg = <0x7000dc00 0x200>;
|
||||
interrupts = <0 94 0x04>;
|
||||
nvidia,dma-request-selector = <&apbdma 27>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
/* PERIPH_ID_SBC5, PLLP_OUT0 */
|
||||
clocks = <&tegra_car 104>;
|
||||
};
|
||||
|
||||
spi@7000de00 {
|
||||
compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
|
||||
reg = <0x7000de00 0x200>;
|
||||
interrupts = <0 79 0x04>;
|
||||
nvidia,dma-request-selector = <&apbdma 28>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
/* PERIPH_ID_SBC6, PLLP_OUT0 */
|
||||
clocks = <&tegra_car 105>;
|
||||
};
|
||||
};
|
|
@ -37,23 +37,23 @@ int get_clocks(void)
|
|||
#ifdef CONFIG_FSL_ESDHC
|
||||
#ifdef CONFIG_FSL_USDHC
|
||||
#if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
#elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
||||
#elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC4_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
|
||||
#else
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
|
||||
#endif
|
||||
#else
|
||||
#if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
|
||||
#elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
|
||||
#elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC4_BASE_ADDR
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
|
||||
#else
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
|
||||
gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -48,8 +48,8 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp (gd->tbl)
|
||||
#define lastinc (gd->lastinc)
|
||||
#define timestamp (gd->arch.tbl)
|
||||
#define lastinc (gd->arch.lastinc)
|
||||
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
|
|
|
@ -65,6 +65,40 @@
|
|||
#define MT41J128MJT125_PHY_FIFO_WE 0x100
|
||||
#define MT41J128MJT125_IOCTRL_VALUE 0x18B
|
||||
|
||||
/* Micron MT41J256M8HX-15E */
|
||||
#define MT41J256M8HX15E_EMIF_READ_LATENCY 0x06
|
||||
#define MT41J256M8HX15E_EMIF_TIM1 0x0888A39B
|
||||
#define MT41J256M8HX15E_EMIF_TIM2 0x26337FDA
|
||||
#define MT41J256M8HX15E_EMIF_TIM3 0x501F830F
|
||||
#define MT41J256M8HX15E_EMIF_SDCFG 0x61C04B32
|
||||
#define MT41J256M8HX15E_EMIF_SDREF 0x0000093B
|
||||
#define MT41J256M8HX15E_ZQ_CFG 0x50074BE4
|
||||
#define MT41J256M8HX15E_DLL_LOCK_DIFF 0x1
|
||||
#define MT41J256M8HX15E_RATIO 0x40
|
||||
#define MT41J256M8HX15E_INVERT_CLKOUT 0x1
|
||||
#define MT41J256M8HX15E_RD_DQS 0x3B
|
||||
#define MT41J256M8HX15E_WR_DQS 0x85
|
||||
#define MT41J256M8HX15E_PHY_WR_DATA 0xC1
|
||||
#define MT41J256M8HX15E_PHY_FIFO_WE 0x100
|
||||
#define MT41J256M8HX15E_IOCTRL_VALUE 0x18B
|
||||
|
||||
/* Micron MT41J512M8RH-125 on EVM v1.5 */
|
||||
#define MT41J512M8RH125_EMIF_READ_LATENCY 0x06
|
||||
#define MT41J512M8RH125_EMIF_TIM1 0x0888A39B
|
||||
#define MT41J512M8RH125_EMIF_TIM2 0x26517FDA
|
||||
#define MT41J512M8RH125_EMIF_TIM3 0x501F84EF
|
||||
#define MT41J512M8RH125_EMIF_SDCFG 0x61C04BB2
|
||||
#define MT41J512M8RH125_EMIF_SDREF 0x0000093B
|
||||
#define MT41J512M8RH125_ZQ_CFG 0x50074BE4
|
||||
#define MT41J512M8RH125_DLL_LOCK_DIFF 0x1
|
||||
#define MT41J512M8RH125_RATIO 0x80
|
||||
#define MT41J512M8RH125_INVERT_CLKOUT 0x0
|
||||
#define MT41J512M8RH125_RD_DQS 0x3B
|
||||
#define MT41J512M8RH125_WR_DQS 0x3C
|
||||
#define MT41J512M8RH125_PHY_FIFO_WE 0xA5
|
||||
#define MT41J512M8RH125_PHY_WR_DATA 0x74
|
||||
#define MT41J512M8RH125_IOCTRL_VALUE 0x18B
|
||||
|
||||
/**
|
||||
* Configure SDRAM
|
||||
*/
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
/* PAD Control Fields */
|
||||
#define SLEWCTRL (0x1 << 6)
|
||||
#define RXACTIVE (0x1 << 5)
|
||||
#define PULLUP_EN (0x1 << 4) /* Pull UP Selection */
|
||||
#define PULLDOWN_EN (0x0 << 4) /* Pull Down Selection */
|
||||
#define PULLUP_EN (0x1 << 4) /* Pull Up Selection */
|
||||
#define PULLUDEN (0x0 << 3) /* Pull up enabled */
|
||||
#define PULLUDDIS (0x1 << 3) /* Pull up disabled */
|
||||
#define MODE(val) val /* used for Readability */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */
|
||||
#define BOOT_DEVICE_SPI 11
|
||||
#define BOOT_DEVICE_UART 65
|
||||
#define BOOT_DEVICE_USBETH 68
|
||||
#define BOOT_DEVICE_CPGMAC 70
|
||||
#define BOOT_DEVICE_MMC2_2 0xFF
|
||||
#endif
|
||||
|
|
|
@ -31,37 +31,37 @@
|
|||
static inline unsigned long get_cpu_clk_rate(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
return gd->cpu_clk_rate_hz;
|
||||
return gd->arch.cpu_clk_rate_hz;
|
||||
}
|
||||
|
||||
static inline unsigned long get_main_clk_rate(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
return gd->main_clk_rate_hz;
|
||||
return gd->arch.main_clk_rate_hz;
|
||||
}
|
||||
|
||||
static inline unsigned long get_mck_clk_rate(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
return gd->mck_rate_hz;
|
||||
return gd->arch.mck_rate_hz;
|
||||
}
|
||||
|
||||
static inline unsigned long get_plla_clk_rate(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
return gd->plla_rate_hz;
|
||||
return gd->arch.plla_rate_hz;
|
||||
}
|
||||
|
||||
static inline unsigned long get_pllb_clk_rate(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
return gd->pllb_rate_hz;
|
||||
return gd->arch.pllb_rate_hz;
|
||||
}
|
||||
|
||||
static inline u32 get_pllb_init(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
return gd->at91_pllb_usb_init;
|
||||
return gd->arch.at91_pllb_usb_init;
|
||||
}
|
||||
|
||||
static inline unsigned long get_macb_pclk_rate(unsigned int dev_id)
|
||||
|
|
|
@ -67,7 +67,11 @@ struct davinci_gpio_bank {
|
|||
|
||||
#define gpio_status() gpio_info()
|
||||
#define GPIO_NAME_SIZE 20
|
||||
#if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850)
|
||||
#define MAX_NUM_GPIOS 128
|
||||
#else
|
||||
#define MAX_NUM_GPIOS 144
|
||||
#endif
|
||||
#define GPIO_BANK(gp) (davinci_gpio_bank01 + ((gp) >> 5))
|
||||
#define GPIO_BIT(gp) ((gp) & 0x1F)
|
||||
|
||||
|
|
|
@ -23,67 +23,27 @@
|
|||
#include <asm/types.h>
|
||||
|
||||
/* Stabilization delays, in usec */
|
||||
#define PLL_STABILIZATION_DELAY (300)
|
||||
#define PLL_STABILIZATION_DELAY (300)
|
||||
#define IO_STABILIZATION_DELAY (1000)
|
||||
|
||||
#define NVBL_PLLP_KHZ (216000)
|
||||
|
||||
#define PLLX_ENABLED (1 << 30)
|
||||
#define CCLK_BURST_POLICY 0x20008888
|
||||
#define SUPER_CCLK_DIVIDER 0x80000000
|
||||
|
||||
/* Calculate clock fractional divider value from ref and target frequencies */
|
||||
#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2)
|
||||
#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2)
|
||||
|
||||
/* Calculate clock frequency value from reference and clock divider value */
|
||||
#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2))
|
||||
#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2))
|
||||
|
||||
/* AVP/CPU ID */
|
||||
#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */
|
||||
#define PG_UP_TAG_0 0x0
|
||||
#define PG_UP_TAG_0 0x0
|
||||
|
||||
#define CORESIGHT_UNLOCK 0xC5ACCE55;
|
||||
|
||||
/* AP20-Specific Base Addresses */
|
||||
|
||||
/* AP20 Base physical address of SDRAM. */
|
||||
#define AP20_BASE_PA_SDRAM 0x00000000
|
||||
/* AP20 Base physical address of internal SRAM. */
|
||||
#define AP20_BASE_PA_SRAM 0x40000000
|
||||
/* AP20 Size of internal SRAM (256KB). */
|
||||
#define AP20_BASE_PA_SRAM_SIZE 0x00040000
|
||||
/* AP20 Base physical address of flash. */
|
||||
#define AP20_BASE_PA_NOR_FLASH 0xD0000000
|
||||
/* AP20 Base physical address of boot information table. */
|
||||
#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM
|
||||
|
||||
/*
|
||||
* Super-temporary stacks for EXTREMELY early startup. The values chosen for
|
||||
* these addresses must be valid on ALL SOCs because this value is used before
|
||||
* we are able to differentiate between the SOC types.
|
||||
*
|
||||
* NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its
|
||||
* stack is placed below the AVP stack. Once the CPU stack has been moved,
|
||||
* the AVP is free to use the IRAM the CPU stack previously occupied if
|
||||
* it should need to do so.
|
||||
*
|
||||
* NOTE: In multi-processor CPU complex configurations, each processor will have
|
||||
* its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a
|
||||
* limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a
|
||||
* stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous
|
||||
* CPU.
|
||||
*/
|
||||
|
||||
/* Common AVP early boot stack limit */
|
||||
#define AVP_EARLY_BOOT_STACK_LIMIT \
|
||||
(AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2))
|
||||
/* Common AVP early boot stack size */
|
||||
#define AVP_EARLY_BOOT_STACK_SIZE 0x1000
|
||||
/* Common CPU early boot stack limit */
|
||||
#define CPU_EARLY_BOOT_STACK_LIMIT \
|
||||
(AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE)
|
||||
/* Common CPU early boot stack size */
|
||||
#define CPU_EARLY_BOOT_STACK_SIZE 0x1000
|
||||
/* AP base physical address of internal SRAM */
|
||||
#define NV_PA_BASE_SRAM 0x40000000
|
||||
|
||||
#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100)
|
||||
#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0)
|
||||
|
|
|
@ -41,8 +41,9 @@ void gpio_early_init(void); /* overrideable GPIO config */
|
|||
* an empty stub function will be called.
|
||||
*/
|
||||
|
||||
void pin_mux_usb(void); /* overrideable USB pinmux setup */
|
||||
void pin_mux_spi(void); /* overrideable SPI pinmux setup */
|
||||
void pin_mux_nand(void); /* overrideable NAND pinmux setup */
|
||||
void pin_mux_usb(void); /* overrideable USB pinmux setup */
|
||||
void pin_mux_spi(void); /* overrideable SPI pinmux setup */
|
||||
void pin_mux_nand(void); /* overrideable NAND pinmux setup */
|
||||
void pin_mux_display(void); /* overrideable DISPLAY pinmux setup */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _CLK_RST_H_
|
||||
#define _CLK_RST_H_
|
||||
#ifndef _TEGRA_CLK_RST_H_
|
||||
#define _TEGRA_CLK_RST_H_
|
||||
|
||||
/* PLL registers - there are several PLLs in the clock controller */
|
||||
struct clk_pll {
|
||||
|
@ -37,6 +37,12 @@ struct clk_pll_simple {
|
|||
uint pll_misc; /* other misc things */
|
||||
};
|
||||
|
||||
/* RST_DEV_(L,H,U,V,W)_(SET,CLR) and CLK_ENB_(L,H,U,V,W)_(SET,CLR) */
|
||||
struct clk_set_clr {
|
||||
uint set;
|
||||
uint clr;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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-
|
||||
|
@ -45,8 +51,10 @@ struct clk_pll_simple {
|
|||
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 */
|
||||
TEGRA_CLK_REGS = 3, /* Number of clock enable regs L/H/U */
|
||||
TEGRA_CLK_SOURCES = 64, /* Number of ppl clock sources L/H/U */
|
||||
TEGRA_CLK_REGS_VW = 2, /* Number of clock enable regs V/W */
|
||||
TEGRA_CLK_SOURCES_VW = 32, /* Number of ppl clock sources V/W*/
|
||||
};
|
||||
|
||||
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
|
||||
|
@ -82,14 +90,80 @@ struct clk_rst_ctlr {
|
|||
uint crc_reserved11; /* _reserved_11, 0xFC */
|
||||
|
||||
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_reserved20[64]; /* _reserved_20, 0x200-2fc */
|
||||
|
||||
/* _RST_DEV_L/H/U_SET_0 0x300 ~ 0x314 */
|
||||
struct clk_set_clr crc_rst_dev_ex[TEGRA_CLK_REGS];
|
||||
|
||||
uint crc_reserved30[2]; /* _reserved_30, 0x318, 0x31c */
|
||||
|
||||
/* _CLK_ENB_L/H/U_CLR_0 0x320 ~ 0x334 */
|
||||
struct clk_set_clr crc_clk_enb_ex[TEGRA_CLK_REGS];
|
||||
|
||||
uint crc_reserved31[2]; /* _reserved_31, 0x338, 0x33c */
|
||||
|
||||
uint crc_cpu_cmplx_set; /* _RST_CPU_CMPLX_SET_0, 0x340 */
|
||||
uint crc_cpu_cmplx_clr; /* _RST_CPU_CMPLX_CLR_0, 0x344 */
|
||||
|
||||
/* Additional (T30) registers */
|
||||
uint crc_clk_cpu_cmplx_set; /* _CLK_CPU_CMPLX_SET_0, 0x348 */
|
||||
uint crc_clk_cpu_cmplx_clr; /* _CLK_CPU_CMPLX_SET_0, 0x34c */
|
||||
|
||||
uint crc_reserved32[2]; /* _reserved_32, 0x350,0x354 */
|
||||
|
||||
uint crc_rst_dev_vw[TEGRA_CLK_REGS_VW]; /* _RST_DEVICES_V/W_0 */
|
||||
uint crc_clk_out_enb_vw[TEGRA_CLK_REGS_VW]; /* _CLK_OUT_ENB_V/W_0 */
|
||||
uint crc_cclkg_brst_pol; /* _CCLKG_BURST_POLICY_0, 0x368 */
|
||||
uint crc_super_cclkg_div; /* _SUPER_CCLKG_DIVIDER_0, 0x36C */
|
||||
uint crc_cclklp_brst_pol; /* _CCLKLP_BURST_POLICY_0, 0x370 */
|
||||
uint crc_super_cclkp_div; /* _SUPER_CCLKLP_DIVIDER_0, 0x374 */
|
||||
uint crc_clk_cpug_cmplx; /* _CLK_CPUG_CMPLX_0, 0x378 */
|
||||
uint crc_clk_cpulp_cmplx; /* _CLK_CPULP_CMPLX_0, 0x37C */
|
||||
uint crc_cpu_softrst_ctrl; /* _CPU_SOFTRST_CTRL_0, 0x380 */
|
||||
uint crc_cpu_softrst_ctrl1; /* _CPU_SOFTRST_CTR1L_0, 0x384 */
|
||||
uint crc_cpu_softrst_ctrl2; /* _CPU_SOFTRST_CTRL2_0, 0x388 */
|
||||
uint crc_reserved33[9]; /* _reserved_33, 0x38c-3ac */
|
||||
uint crc_clk_src_vw[TEGRA_CLK_SOURCES_VW]; /* _G3D2_0..., 0x3b0-0x42c */
|
||||
/* _RST_DEV_V/W_SET_0 0x430 ~ 0x43c */
|
||||
struct clk_set_clr crc_rst_dev_ex_vw[TEGRA_CLK_REGS_VW];
|
||||
/* _CLK_ENB_V/W_CLR_0 0x440 ~ 0x44c */
|
||||
struct clk_set_clr crc_clk_enb_ex_vw[TEGRA_CLK_REGS_VW];
|
||||
/* Additional (T114) registers */
|
||||
uint crc_rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
|
||||
uint crc_rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
|
||||
uint crc_rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
|
||||
uint crc_rst_cpulp_cmplx_clr; /* _RST_CPULP_CMPLX_CLR_0, 0x45C */
|
||||
uint crc_clk_cpug_cmplx_set; /* _CLK_CPUG_CMPLX_SET_0, 0x460 */
|
||||
uint crc_clk_cpug_cmplx_clr; /* _CLK_CPUG_CMPLX_CLR_0, 0x464 */
|
||||
uint crc_clk_cpulp_cmplx_set; /* _CLK_CPULP_CMPLX_SET_0, 0x468 */
|
||||
uint crc_clk_cpulp_cmplx_clr; /* _CLK_CPULP_CMPLX_CLR_0, 0x46C */
|
||||
uint crc_cpu_cmplx_status; /* _CPU_CMPLX_STATUS_0, 0x470 */
|
||||
uint crc_reserved40[1]; /* _reserved_40, 0x474 */
|
||||
uint crc_intstatus; /* __INTSTATUS_0, 0x478 */
|
||||
uint crc_intmask; /* __INTMASK_0, 0x47C */
|
||||
uint crc_utmip_pll_cfg0; /* _UTMIP_PLL_CFG0_0, 0x480 */
|
||||
uint crc_utmip_pll_cfg1; /* _UTMIP_PLL_CFG1_0, 0x484 */
|
||||
uint crc_utmip_pll_cfg2; /* _UTMIP_PLL_CFG2_0, 0x488 */
|
||||
|
||||
uint crc_plle_aux; /* _PLLE_AUX_0, 0x48C */
|
||||
uint crc_sata_pll_cfg0; /* _SATA_PLL_CFG0_0, 0x490 */
|
||||
uint crc_sata_pll_cfg1; /* _SATA_PLL_CFG1_0, 0x494 */
|
||||
uint crc_pcie_pll_cfg0; /* _PCIE_PLL_CFG0_0, 0x498 */
|
||||
|
||||
uint crc_prog_audio_dly_clk; /* _PROG_AUDIO_DLY_CLK_0, 0x49C */
|
||||
uint crc_audio_sync_clk_i2s0; /* _AUDIO_SYNC_CLK_I2S0_0, 0x4A0 */
|
||||
uint crc_audio_sync_clk_i2s1; /* _AUDIO_SYNC_CLK_I2S1_0, 0x4A4 */
|
||||
uint crc_audio_sync_clk_i2s2; /* _AUDIO_SYNC_CLK_I2S2_0, 0x4A8 */
|
||||
uint crc_audio_sync_clk_i2s3; /* _AUDIO_SYNC_CLK_I2S3_0, 0x4AC */
|
||||
uint crc_audio_sync_clk_i2s4; /* _AUDIO_SYNC_CLK_I2S4_0, 0x4B0 */
|
||||
uint crc_audio_sync_clk_spdif; /* _AUDIO_SYNC_CLK_SPDIF_0, 0x4B4 */
|
||||
};
|
||||
|
||||
/* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */
|
||||
#define CPU3_CLK_STP_SHIFT 11
|
||||
#define CPU2_CLK_STP_SHIFT 10
|
||||
#define CPU1_CLK_STP_SHIFT 9
|
||||
|
||||
#define CPU0_CLK_STP_SHIFT 8
|
||||
#define CPU0_CLK_STP_MASK (1U << CPU0_CLK_STP_SHIFT)
|
||||
|
||||
|
@ -120,6 +194,12 @@ struct clk_rst_ctlr {
|
|||
#define PLL_OUT_RATIO_MASK (0xffU << PLL_OUT_RATIO_SHIFT)
|
||||
|
||||
/* CLK_RST_CONTROLLER_PLLx_MISC_0 */
|
||||
#define PLL_DCCON_SHIFT 20
|
||||
#define PLL_DCCON_MASK (1U << PLL_DCCON_SHIFT)
|
||||
|
||||
#define PLL_LOCK_ENABLE_SHIFT 18
|
||||
#define PLL_LOCK_ENABLE_MASK (1U << PLL_LOCK_ENABLE_SHIFT)
|
||||
|
||||
#define PLL_CPCON_SHIFT 8
|
||||
#define PLL_CPCON_MASK (15U << PLL_CPCON_SHIFT)
|
||||
|
||||
|
@ -129,9 +209,23 @@ struct clk_rst_ctlr {
|
|||
#define PLLU_VCO_FREQ_SHIFT 20
|
||||
#define PLLU_VCO_FREQ_MASK (1U << PLLU_VCO_FREQ_SHIFT)
|
||||
|
||||
#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_SHIFT 30
|
||||
#define OSC_FREQ_MASK (3U << OSC_FREQ_SHIFT)
|
||||
#define OSC_XOBP_SHIFT 1
|
||||
#define OSC_XOBP_MASK (1U << OSC_XOBP_SHIFT)
|
||||
|
||||
|
@ -151,4 +245,84 @@ struct clk_rst_ctlr {
|
|||
#define OUT_CLK_SOURCE4_SHIFT 28
|
||||
#define OUT_CLK_SOURCE4_MASK (15U << OUT_CLK_SOURCE4_SHIFT)
|
||||
|
||||
#endif /* CLK_RST_H */
|
||||
/* CLK_RST_CONTROLLER_SCLK_BURST_POLICY */
|
||||
#define SCLK_SYS_STATE_SHIFT 28U
|
||||
#define SCLK_SYS_STATE_MASK (15U << SCLK_SYS_STATE_SHIFT)
|
||||
enum {
|
||||
SCLK_SYS_STATE_STDBY,
|
||||
SCLK_SYS_STATE_IDLE,
|
||||
SCLK_SYS_STATE_RUN,
|
||||
SCLK_SYS_STATE_IRQ = 4U,
|
||||
SCLK_SYS_STATE_FIQ = 8U,
|
||||
};
|
||||
#define SCLK_COP_FIQ_MASK (1 << 27)
|
||||
#define SCLK_CPU_FIQ_MASK (1 << 26)
|
||||
#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)
|
||||
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_CLKS,
|
||||
SCLK_SOURCE_PLLM_OUT1,
|
||||
};
|
||||
#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 */
|
||||
#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)
|
||||
|
||||
/* CLK_RST_CONTROLLER_CLK_SYSTEM_RATE */
|
||||
#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)
|
||||
|
||||
/* CLK_RST_CONTROLLER_RST_CPUxx_CMPLX_CLR */
|
||||
#define CLR_CPURESET0 (1 << 0)
|
||||
#define CLR_CPURESET1 (1 << 1)
|
||||
#define CLR_CPURESET2 (1 << 2)
|
||||
#define CLR_CPURESET3 (1 << 3)
|
||||
#define CLR_DBGRESET0 (1 << 12)
|
||||
#define CLR_DBGRESET1 (1 << 13)
|
||||
#define CLR_DBGRESET2 (1 << 14)
|
||||
#define CLR_DBGRESET3 (1 << 15)
|
||||
#define CLR_CORERESET0 (1 << 16)
|
||||
#define CLR_CORERESET1 (1 << 17)
|
||||
#define CLR_CORERESET2 (1 << 18)
|
||||
#define CLR_CORERESET3 (1 << 19)
|
||||
#define CLR_CXRESET0 (1 << 20)
|
||||
#define CLR_CXRESET1 (1 << 21)
|
||||
#define CLR_CXRESET2 (1 << 22)
|
||||
#define CLR_CXRESET3 (1 << 23)
|
||||
#define CLR_NONCPURESET (1 << 29)
|
||||
|
||||
#endif /* _TEGRA_CLK_RST_H_ */
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
/* Tegra clock control functions */
|
||||
|
||||
#ifndef _CLOCK_H
|
||||
#define _CLOCK_H
|
||||
#ifndef _TEGRA_CLOCK_H_
|
||||
#define _TEGRA_CLOCK_H_
|
||||
|
||||
/* Set of oscillator frequencies supported in the internal API. */
|
||||
enum clock_osc_freq {
|
||||
|
@ -82,7 +82,7 @@ int clock_set_pllout(enum clock_id clkid, enum pll_out_id pllout,
|
|||
* @returns 0 if ok, -1 on error (invalid clock id)
|
||||
*/
|
||||
int clock_ll_read_pll(enum clock_id clkid, u32 *divm, u32 *divn,
|
||||
u32 *divp, u32 *cpcon, u32 *lfcon);
|
||||
u32 *divp, u32 *cpcon, u32 *lfcon);
|
||||
|
||||
/*
|
||||
* Enable a clock
|
||||
|
@ -136,7 +136,7 @@ enum crc_reset_id {
|
|||
/**
|
||||
* Put parts of the CPU complex into or out of reset.\
|
||||
*
|
||||
* @param cpu cpu number (0 or 1 on Tegra2)
|
||||
* @param cpu cpu number (0 or 1 on Tegra2, 0-3 on Tegra3)
|
||||
* @param which which parts of the complex to affect (OR of crc_reset_id)
|
||||
* @param reset 1 to assert reset, 0 to de-assert
|
||||
*/
|
||||
|
@ -262,4 +262,59 @@ void clock_init(void);
|
|||
/* Initialize the PLLs */
|
||||
void clock_early_init(void);
|
||||
|
||||
#endif /* _CLOCK_H_ */
|
||||
/* Returns a pointer to the clock source register for a peripheral */
|
||||
u32 *get_periph_source_reg(enum periph_id periph_id);
|
||||
|
||||
/**
|
||||
* Given a peripheral ID and the required source clock, this returns which
|
||||
* value should be programmed into the source mux for that peripheral.
|
||||
*
|
||||
* There is special code here to handle the one source type with 5 sources.
|
||||
*
|
||||
* @param periph_id peripheral to start
|
||||
* @param source PLL id of required parent clock
|
||||
* @param mux_bits Set to number of bits in mux register: 2 or 4
|
||||
* @param divider_bits Set to number of divider bits (8 or 16)
|
||||
* @return mux value (0-4, or -1 if not found)
|
||||
*/
|
||||
int get_periph_clock_source(enum periph_id periph_id,
|
||||
enum clock_id parent, int *mux_bits, int *divider_bits);
|
||||
|
||||
/*
|
||||
* Convert a device tree clock ID to our peripheral ID. They are mostly
|
||||
* the same but we are very cautious so we check that a valid clock ID is
|
||||
* provided.
|
||||
*
|
||||
* @param clk_id Clock ID according to tegra30 device tree binding
|
||||
* @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
|
||||
*/
|
||||
enum periph_id clk_id_to_periph_id(int clk_id);
|
||||
|
||||
/**
|
||||
* Set the output frequency you want for each PLL clock.
|
||||
* PLL output frequencies are programmed by setting their N, M and P values.
|
||||
* The governing equations are:
|
||||
* VCO = (Fi / m) * n, Fo = VCO / (2^p)
|
||||
* where Fo is the output frequency from the PLL.
|
||||
* Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
|
||||
* 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
|
||||
* Please see Tegra TRM section 5.3 to get the detail for PLL Programming
|
||||
*
|
||||
* @param n PLL feedback divider(DIVN)
|
||||
* @param m PLL input divider(DIVN)
|
||||
* @param p post divider(DIVP)
|
||||
* @param cpcon base PLL charge pump(CPCON)
|
||||
* @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
|
||||
* be overriden), 1 if PLL is already correct
|
||||
*/
|
||||
int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon);
|
||||
|
||||
/* return 1 if a peripheral ID is in range */
|
||||
#define clock_type_id_isvalid(id) ((id) >= 0 && \
|
||||
(id) < CLOCK_TYPE_COUNT)
|
||||
|
||||
/* return 1 if a periphc_internal_id is in range */
|
||||
#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
|
||||
(id) < PERIPHC_COUNT)
|
||||
|
||||
#endif /* _TEGRA_CLOCK_H_ */
|
||||
|
|
39
arch/arm/include/asm/arch-tegra/funcmux.h
Normal file
39
arch/arm/include/asm/arch-tegra/funcmux.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra high-level function multiplexing */
|
||||
|
||||
#ifndef _TEGRA_FUNCMUX_H_
|
||||
#define _TEGRA_FUNCMUX_H_
|
||||
|
||||
/**
|
||||
* Select a config for a particular peripheral.
|
||||
*
|
||||
* Each peripheral can operate through a number of configurations,
|
||||
* which are sets of pins that it uses to bring out its signals.
|
||||
* The basic config is 0, and higher numbers indicate different
|
||||
* pinmux settings to bring the peripheral out on other pins,
|
||||
*
|
||||
* This function also disables tristate for the function's pins,
|
||||
* so that they operate in normal mode.
|
||||
*
|
||||
* @param id Peripheral id
|
||||
* @param config Configuration to use (FUNCMUX_...), 0 for default
|
||||
* @return 0 if ok, -1 on error (e.g. incorrect id or config)
|
||||
*/
|
||||
int funcmux_select(enum periph_id id, int config);
|
||||
|
||||
#endif /* _TEGRA_FUNCMUX_H_ */
|
40
arch/arm/include/asm/arch-tegra/gp_padctrl.h
Normal file
40
arch/arm/include/asm/arch-tegra/gp_padctrl.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* (C) Copyright 2010-2012
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA_GP_PADCTRL_H_
|
||||
#define _TEGRA_GP_PADCTRL_H_
|
||||
|
||||
#define GP_HIDREV 0x804
|
||||
|
||||
/* bit fields definitions for APB_MISC_GP_HIDREV register */
|
||||
#define HIDREV_CHIPID_SHIFT 8
|
||||
#define HIDREV_CHIPID_MASK (0xff << HIDREV_CHIPID_SHIFT)
|
||||
#define HIDREV_MAJORPREV_SHIFT 4
|
||||
#define HIDREV_MAJORPREV_MASK (0xf << HIDREV_MAJORPREV_SHIFT)
|
||||
|
||||
/* CHIPID field returned from APB_MISC_GP_HIDREV register */
|
||||
#define CHIPID_TEGRA20 0x20
|
||||
#define CHIPID_TEGRA30 0x30
|
||||
#define CHIPID_TEGRA114 0x35
|
||||
|
||||
#endif /* _TEGRA_GP_PADCTRL_H_ */
|
|
@ -128,5 +128,13 @@ struct pmc_ctlr {
|
|||
#define START_CP (1 << 8)
|
||||
|
||||
#define CPUPWRREQ_OE (1 << 16)
|
||||
#define CPUPWRREQ_POL (1 << 15)
|
||||
|
||||
#define CRAILID (0)
|
||||
#define CE0ID (14)
|
||||
#define C0NCID (15)
|
||||
#define CRAIL (1 << CRAILID)
|
||||
#define CE0 (1 << CE0ID)
|
||||
#define C0NC (1 << C0NCID)
|
||||
|
||||
#endif /* PMC_H */
|
||||
|
|
|
@ -40,6 +40,12 @@
|
|||
#define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400)
|
||||
#define NV_PA_NAND_BASE (NV_PA_APB_MISC_BASE + 0x8000)
|
||||
#define NV_PA_SPI_BASE (NV_PA_APB_MISC_BASE + 0xC380)
|
||||
#define NV_PA_SLINK1_BASE (NV_PA_APB_MISC_BASE + 0xD400)
|
||||
#define NV_PA_SLINK2_BASE (NV_PA_APB_MISC_BASE + 0xD600)
|
||||
#define NV_PA_SLINK3_BASE (NV_PA_APB_MISC_BASE + 0xD800)
|
||||
#define NV_PA_SLINK4_BASE (NV_PA_APB_MISC_BASE + 0xDA00)
|
||||
#define NV_PA_SLINK5_BASE (NV_PA_APB_MISC_BASE + 0xDC00)
|
||||
#define NV_PA_SLINK6_BASE (NV_PA_APB_MISC_BASE + 0xDE00)
|
||||
#define TEGRA_DVC_BASE (NV_PA_APB_MISC_BASE + 0xD000)
|
||||
#define NV_PA_PMC_BASE (NV_PA_APB_MISC_BASE + 0xE400)
|
||||
#define NV_PA_EMC_BASE (NV_PA_APB_MISC_BASE + 0xF400)
|
||||
|
@ -72,14 +78,23 @@ enum {
|
|||
SKU_ID_T25 = 0x18,
|
||||
SKU_ID_AP25E = 0x1b,
|
||||
SKU_ID_T25E = 0x1c,
|
||||
SKU_ID_T30 = 0x81, /* Cardhu value */
|
||||
SKU_ID_T114_ENG = 0x00, /* Dalmore value, unfused */
|
||||
};
|
||||
|
||||
/* These are the SOC categories that affect clocking */
|
||||
/*
|
||||
* These are used to distinguish SOC types for setting up clocks. Mostly
|
||||
* we can tell the clocking required by looking at the SOC sku_id, but
|
||||
* for T30 it is a user option as to whether to run PLLP in fast or slow
|
||||
* mode, so we have two options there.
|
||||
*/
|
||||
enum {
|
||||
TEGRA_SOC_T20,
|
||||
TEGRA_SOC_T25,
|
||||
TEGRA_SOC_T30,
|
||||
TEGRA_SOC_T114,
|
||||
|
||||
TEGRA_SOC_COUNT,
|
||||
TEGRA_SOC_CNT,
|
||||
TEGRA_SOC_UNKNOWN = -1,
|
||||
};
|
||||
|
||||
|
|
84
arch/arm/include/asm/arch-tegra/tegra_slink.h
Normal file
84
arch/arm/include/asm/arch-tegra/tegra_slink.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* NVIDIA Tegra SPI-SLINK controller
|
||||
*
|
||||
* Copyright 2010-2013 NVIDIA Corporation
|
||||
*
|
||||
* This software may be used and distributed according to the
|
||||
* terms of the GNU Public License, Version 2, incorporated
|
||||
* herein by reference.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA_SLINK_H_
|
||||
#define _TEGRA_SLINK_H_
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
struct slink_tegra {
|
||||
u32 command; /* SLINK_COMMAND_0 register */
|
||||
u32 command2; /* SLINK_COMMAND2_0 reg */
|
||||
u32 status; /* SLINK_STATUS_0 register */
|
||||
u32 reserved; /* Reserved offset 0C */
|
||||
u32 mas_data; /* SLINK_MAS_DATA_0 reg */
|
||||
u32 slav_data; /* SLINK_SLAVE_DATA_0 reg */
|
||||
u32 dma_ctl; /* SLINK_DMA_CTL_0 register */
|
||||
u32 status2; /* SLINK_STATUS2_0 reg */
|
||||
u32 rsvd[56]; /* 0x20 to 0xFF reserved */
|
||||
u32 tx_fifo; /* SLINK_TX_FIFO_0 reg off 100h */
|
||||
u32 rsvd2[31]; /* 0x104 to 0x17F reserved */
|
||||
u32 rx_fifo; /* SLINK_RX_FIFO_0 reg off 180h */
|
||||
};
|
||||
|
||||
/* COMMAND */
|
||||
#define SLINK_CMD_ENB (1 << 31)
|
||||
#define SLINK_CMD_GO (1 << 30)
|
||||
#define SLINK_CMD_M_S (1 << 28)
|
||||
#define SLINK_CMD_CK_SDA (1 << 21)
|
||||
#define SLINK_CMD_CS_POL (1 << 13)
|
||||
#define SLINK_CMD_CS_VAL (1 << 12)
|
||||
#define SLINK_CMD_CS_SOFT (1 << 11)
|
||||
#define SLINK_CMD_BIT_LENGTH (1 << 4)
|
||||
#define SLINK_CMD_BIT_LENGTH_MASK 0x0000001F
|
||||
/* COMMAND2 */
|
||||
#define SLINK_CMD2_TXEN (1 << 30)
|
||||
#define SLINK_CMD2_RXEN (1 << 31)
|
||||
#define SLINK_CMD2_SS_EN (1 << 18)
|
||||
#define SLINK_CMD2_SS_EN_SHIFT 18
|
||||
#define SLINK_CMD2_SS_EN_MASK 0x000C0000
|
||||
#define SLINK_CMD2_CS_ACTIVE_BETWEEN (1 << 17)
|
||||
/* STATUS */
|
||||
#define SLINK_STAT_BSY (1 << 31)
|
||||
#define SLINK_STAT_RDY (1 << 30)
|
||||
#define SLINK_STAT_ERR (1 << 29)
|
||||
#define SLINK_STAT_RXF_FLUSH (1 << 27)
|
||||
#define SLINK_STAT_TXF_FLUSH (1 << 26)
|
||||
#define SLINK_STAT_RXF_OVF (1 << 25)
|
||||
#define SLINK_STAT_TXF_UNR (1 << 24)
|
||||
#define SLINK_STAT_RXF_EMPTY (1 << 23)
|
||||
#define SLINK_STAT_RXF_FULL (1 << 22)
|
||||
#define SLINK_STAT_TXF_EMPTY (1 << 21)
|
||||
#define SLINK_STAT_TXF_FULL (1 << 20)
|
||||
#define SLINK_STAT_TXF_OVF (1 << 19)
|
||||
#define SLINK_STAT_RXF_UNR (1 << 18)
|
||||
#define SLINK_STAT_CUR_BLKCNT (1 << 15)
|
||||
/* STATUS2 */
|
||||
#define SLINK_STAT2_RXF_FULL_CNT (1 << 16)
|
||||
#define SLINK_STAT2_TXF_FULL_CNT (1 << 0)
|
||||
|
||||
#define SPI_TIMEOUT 1000
|
||||
#define TEGRA_SPI_MAX_FREQ 52000000
|
||||
|
||||
#endif /* _TEGRA_SLINK_H_ */
|
402
arch/arm/include/asm/arch-tegra114/clock-tables.h
Normal file
402
arch/arm/include/asm/arch-tegra114/clock-tables.h
Normal file
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra114 clock PLL tables */
|
||||
|
||||
#ifndef _TEGRA114_CLOCK_TABLES_H_
|
||||
#define _TEGRA114_CLOCK_TABLES_H_
|
||||
|
||||
/* The PLLs supported by the hardware */
|
||||
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_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_ID_COUNT, /* number of PLLs */
|
||||
CLOCK_ID_DISPLAY2, /* placeholder */
|
||||
CLOCK_ID_NONE = -1,
|
||||
};
|
||||
|
||||
/* The clocks supported by the hardware */
|
||||
enum periph_id {
|
||||
PERIPH_ID_FIRST,
|
||||
|
||||
/* Low word: 31:0 (DEVICES_L) */
|
||||
PERIPH_ID_CPU = PERIPH_ID_FIRST,
|
||||
PERIPH_ID_COP,
|
||||
PERIPH_ID_TRIGSYS,
|
||||
PERIPH_ID_RESERVED3,
|
||||
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_RESERVED16,
|
||||
PERIPH_ID_PWM,
|
||||
PERIPH_ID_I2S2,
|
||||
PERIPH_ID_EPP,
|
||||
PERIPH_ID_VI,
|
||||
PERIPH_ID_2D,
|
||||
PERIPH_ID_USBD,
|
||||
PERIPH_ID_ISP,
|
||||
|
||||
/* 24 */
|
||||
PERIPH_ID_3D,
|
||||
PERIPH_ID_RESERVED24,
|
||||
PERIPH_ID_DISP2,
|
||||
PERIPH_ID_DISP1,
|
||||
PERIPH_ID_HOST1X,
|
||||
PERIPH_ID_VCP,
|
||||
PERIPH_ID_I2S0,
|
||||
PERIPH_ID_CACHE2,
|
||||
|
||||
/* Middle word: 63:32 (DEVICES_H) */
|
||||
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_RESERVED43,
|
||||
PERIPH_ID_SBC2,
|
||||
PERIPH_ID_RESERVED45,
|
||||
PERIPH_ID_SBC3,
|
||||
PERIPH_ID_I2C5,
|
||||
|
||||
/* 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 (DEVICES_U) */
|
||||
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_PCIEXCLK,
|
||||
PERIPH_ID_AVPUCQ,
|
||||
PERIPH_ID_RESERVED76,
|
||||
PERIPH_ID_RESERVED77,
|
||||
PERIPH_ID_RESERVED78,
|
||||
PERIPH_ID_DTV,
|
||||
|
||||
/* 80 */
|
||||
PERIPH_ID_NANDSPEED,
|
||||
PERIPH_ID_I2CSLOW,
|
||||
PERIPH_ID_DSIB,
|
||||
PERIPH_ID_RESERVED83,
|
||||
PERIPH_ID_IRAMA,
|
||||
PERIPH_ID_IRAMB,
|
||||
PERIPH_ID_IRAMC,
|
||||
PERIPH_ID_IRAMD,
|
||||
|
||||
/* 88 */
|
||||
PERIPH_ID_CRAM2,
|
||||
PERIPH_ID_RESERVED89,
|
||||
PERIPH_ID_MDOUBLER,
|
||||
PERIPH_ID_RESERVED91,
|
||||
PERIPH_ID_SUSOUT,
|
||||
PERIPH_ID_RESERVED93,
|
||||
PERIPH_ID_RESERVED94,
|
||||
PERIPH_ID_RESERVED95,
|
||||
|
||||
PERIPH_ID_VW_FIRST,
|
||||
/* V word: 31:0 */
|
||||
PERIPH_ID_CPUG = PERIPH_ID_VW_FIRST,
|
||||
PERIPH_ID_CPULP,
|
||||
PERIPH_ID_3D2,
|
||||
PERIPH_ID_MSELECT,
|
||||
PERIPH_ID_TSENSOR,
|
||||
PERIPH_ID_I2S3,
|
||||
PERIPH_ID_I2S4,
|
||||
PERIPH_ID_I2C4,
|
||||
|
||||
/* 104 */
|
||||
PERIPH_ID_SBC5,
|
||||
PERIPH_ID_SBC6,
|
||||
PERIPH_ID_AUDIO,
|
||||
PERIPH_ID_APBIF,
|
||||
PERIPH_ID_DAM0,
|
||||
PERIPH_ID_DAM1,
|
||||
PERIPH_ID_DAM2,
|
||||
PERIPH_ID_HDA2CODEC2X,
|
||||
|
||||
/* 112 */
|
||||
PERIPH_ID_ATOMICS,
|
||||
PERIPH_ID_EX_RESERVED17,
|
||||
PERIPH_ID_EX_RESERVED18,
|
||||
PERIPH_ID_EX_RESERVED19,
|
||||
PERIPH_ID_EX_RESERVED20,
|
||||
PERIPH_ID_EX_RESERVED21,
|
||||
PERIPH_ID_EX_RESERVED22,
|
||||
PERIPH_ID_ACTMON,
|
||||
|
||||
/* 120 */
|
||||
PERIPH_ID_EX_RESERVED24,
|
||||
PERIPH_ID_EX_RESERVED25,
|
||||
PERIPH_ID_EX_RESERVED26,
|
||||
PERIPH_ID_EX_RESERVED27,
|
||||
PERIPH_ID_SATA,
|
||||
PERIPH_ID_HDA,
|
||||
PERIPH_ID_EX_RESERVED30,
|
||||
PERIPH_ID_EX_RESERVED31,
|
||||
|
||||
/* W word: 31:0 */
|
||||
PERIPH_ID_HDA2HDMICODEC,
|
||||
PERIPH_ID_RESERVED1_SATACOLD,
|
||||
PERIPH_ID_RESERVED2_PCIERX0,
|
||||
PERIPH_ID_RESERVED3_PCIERX1,
|
||||
PERIPH_ID_RESERVED4_PCIERX2,
|
||||
PERIPH_ID_RESERVED5_PCIERX3,
|
||||
PERIPH_ID_RESERVED6_PCIERX4,
|
||||
PERIPH_ID_RESERVED7_PCIERX5,
|
||||
|
||||
/* 136 */
|
||||
PERIPH_ID_CEC,
|
||||
PERIPH_ID_PCIE2_IOBIST,
|
||||
PERIPH_ID_EMC_IOBIST,
|
||||
PERIPH_ID_HDMI_IOBIST,
|
||||
PERIPH_ID_SATA_IOBIST,
|
||||
PERIPH_ID_MIPI_IOBIST,
|
||||
PERIPH_ID_EMC1_IOBIST,
|
||||
PERIPH_ID_XUSB,
|
||||
|
||||
/* 144 */
|
||||
PERIPH_ID_CILAB,
|
||||
PERIPH_ID_CILCD,
|
||||
PERIPH_ID_CILE,
|
||||
PERIPH_ID_DSIA_LP,
|
||||
PERIPH_ID_DSIB_LP,
|
||||
PERIPH_ID_RESERVED21_ENTROPY,
|
||||
PERIPH_ID_RESERVED22_W,
|
||||
PERIPH_ID_RESERVED23_W,
|
||||
|
||||
/* 152 */
|
||||
PERIPH_ID_RESERVED24_W,
|
||||
PERIPH_ID_AMX0,
|
||||
PERIPH_ID_ADX0,
|
||||
PERIPH_ID_DVFS,
|
||||
PERIPH_ID_XUSB_SS,
|
||||
PERIPH_ID_EMC_DLL,
|
||||
PERIPH_ID_MC1,
|
||||
PERIPH_ID_EMC1,
|
||||
|
||||
PERIPH_ID_COUNT,
|
||||
PERIPH_ID_NONE = -1,
|
||||
};
|
||||
|
||||
enum pll_out_id {
|
||||
PLL_OUT1,
|
||||
PLL_OUT2,
|
||||
PLL_OUT3,
|
||||
PLL_OUT4
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock peripheral IDs which sadly don't match up with PERIPH_ID. we want
|
||||
* callers to use the PERIPH_ID for all access to peripheral clocks to avoid
|
||||
* confusion bewteen PERIPH_ID_... and PERIPHC_...
|
||||
*
|
||||
* We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be
|
||||
* confusing.
|
||||
*/
|
||||
enum periphc_internal_id {
|
||||
/* 0x00 */
|
||||
PERIPHC_I2S1,
|
||||
PERIPHC_I2S2,
|
||||
PERIPHC_SPDIF_OUT,
|
||||
PERIPHC_SPDIF_IN,
|
||||
PERIPHC_PWM,
|
||||
PERIPHC_05h,
|
||||
PERIPHC_SBC2,
|
||||
PERIPHC_SBC3,
|
||||
|
||||
/* 0x08 */
|
||||
PERIPHC_08h,
|
||||
PERIPHC_I2C1,
|
||||
PERIPHC_I2C5,
|
||||
PERIPHC_0bh,
|
||||
PERIPHC_0ch,
|
||||
PERIPHC_SBC1,
|
||||
PERIPHC_DISP1,
|
||||
PERIPHC_DISP2,
|
||||
|
||||
/* 0x10 */
|
||||
PERIPHC_CVE,
|
||||
PERIPHC_11h,
|
||||
PERIPHC_VI,
|
||||
PERIPHC_13h,
|
||||
PERIPHC_SDMMC1,
|
||||
PERIPHC_SDMMC2,
|
||||
PERIPHC_G3D,
|
||||
PERIPHC_G2D,
|
||||
|
||||
/* 0x18 */
|
||||
PERIPHC_NDFLASH,
|
||||
PERIPHC_SDMMC4,
|
||||
PERIPHC_VFIR,
|
||||
PERIPHC_EPP,
|
||||
PERIPHC_MPE,
|
||||
PERIPHC_MIPI,
|
||||
PERIPHC_UART1,
|
||||
PERIPHC_UART2,
|
||||
|
||||
/* 0x20 */
|
||||
PERIPHC_HOST1X,
|
||||
PERIPHC_21h,
|
||||
PERIPHC_TVO,
|
||||
PERIPHC_HDMI,
|
||||
PERIPHC_24h,
|
||||
PERIPHC_TVDAC,
|
||||
PERIPHC_I2C2,
|
||||
PERIPHC_EMC,
|
||||
|
||||
/* 0x28 */
|
||||
PERIPHC_UART3,
|
||||
PERIPHC_29h,
|
||||
PERIPHC_VI_SENSOR,
|
||||
PERIPHC_2bh,
|
||||
PERIPHC_2ch,
|
||||
PERIPHC_SBC4,
|
||||
PERIPHC_I2C3,
|
||||
PERIPHC_SDMMC3,
|
||||
|
||||
/* 0x30 */
|
||||
PERIPHC_UART4,
|
||||
PERIPHC_UART5,
|
||||
PERIPHC_VDE,
|
||||
PERIPHC_OWR,
|
||||
PERIPHC_NOR,
|
||||
PERIPHC_CSITE,
|
||||
PERIPHC_I2S0,
|
||||
PERIPHC_37h,
|
||||
|
||||
PERIPHC_VW_FIRST,
|
||||
/* 0x38 */
|
||||
PERIPHC_G3D2 = PERIPHC_VW_FIRST,
|
||||
PERIPHC_MSELECT,
|
||||
PERIPHC_TSENSOR,
|
||||
PERIPHC_I2S3,
|
||||
PERIPHC_I2S4,
|
||||
PERIPHC_I2C4,
|
||||
PERIPHC_SBC5,
|
||||
PERIPHC_SBC6,
|
||||
|
||||
/* 0x40 */
|
||||
PERIPHC_AUDIO,
|
||||
PERIPHC_41h,
|
||||
PERIPHC_DAM0,
|
||||
PERIPHC_DAM1,
|
||||
PERIPHC_DAM2,
|
||||
PERIPHC_HDA2CODEC2X,
|
||||
PERIPHC_ACTMON,
|
||||
PERIPHC_EXTPERIPH1,
|
||||
|
||||
/* 0x48 */
|
||||
PERIPHC_EXTPERIPH2,
|
||||
PERIPHC_EXTPERIPH3,
|
||||
PERIPHC_NANDSPEED,
|
||||
PERIPHC_I2CSLOW,
|
||||
PERIPHC_SYS,
|
||||
PERIPHC_SPEEDO,
|
||||
PERIPHC_4eh,
|
||||
PERIPHC_4fh,
|
||||
|
||||
/* 0x50 */
|
||||
PERIPHC_50h,
|
||||
PERIPHC_51h,
|
||||
PERIPHC_52h,
|
||||
PERIPHC_53h,
|
||||
PERIPHC_SATAOOB,
|
||||
PERIPHC_SATA,
|
||||
PERIPHC_HDA,
|
||||
|
||||
PERIPHC_COUNT,
|
||||
|
||||
PERIPHC_NONE = -1,
|
||||
};
|
||||
|
||||
/* Converts a clock number to a clock register: 0=L, 1=H, 2=U, 0=V, 1=W */
|
||||
#define PERIPH_REG(id) \
|
||||
(id < PERIPH_ID_VW_FIRST) ? \
|
||||
((id) >> 5) : ((id - PERIPH_ID_VW_FIRST) >> 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_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_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)
|
||||
|
||||
#endif /* _TEGRA114_CLOCK_TABLES_H_ */
|
28
arch/arm/include/asm/arch-tegra114/clock.h
Normal file
28
arch/arm/include/asm/arch-tegra114/clock.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra114 clock control functions */
|
||||
|
||||
#ifndef _TEGRA114_CLOCK_H_
|
||||
#define _TEGRA114_CLOCK_H_
|
||||
|
||||
#include <asm/arch-tegra/clock.h>
|
||||
|
||||
/* CLK_RST_CONTROLLER_OSC_CTRL_0 */
|
||||
#define OSC_FREQ_SHIFT 28
|
||||
#define OSC_FREQ_MASK (0xF << OSC_FREQ_SHIFT)
|
||||
|
||||
#endif /* _TEGRA114_CLOCK_H_ */
|
35
arch/arm/include/asm/arch-tegra114/flow.h
Normal file
35
arch/arm/include/asm/arch-tegra114/flow.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA114_FLOW_H_
|
||||
#define _TEGRA114_FLOW_H_
|
||||
|
||||
struct flow_ctlr {
|
||||
u32 halt_cpu_events;
|
||||
u32 halt_cop_events;
|
||||
u32 cpu_csr;
|
||||
u32 cop_csr;
|
||||
u32 xrq_events;
|
||||
u32 halt_cpu1_events;
|
||||
u32 cpu1_csr;
|
||||
u32 halt_cpu2_events;
|
||||
u32 cpu2_csr;
|
||||
u32 halt_cpu3_events;
|
||||
u32 cpu3_csr;
|
||||
u32 cluster_control;
|
||||
};
|
||||
|
||||
#endif /* _TEGRA114_FLOW_H_ */
|
31
arch/arm/include/asm/arch-tegra114/funcmux.h
Normal file
31
arch/arm/include/asm/arch-tegra114/funcmux.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Tegra114 high-level function multiplexing */
|
||||
|
||||
#ifndef _TEGRA114_FUNCMUX_H_
|
||||
#define _TEGRA114_FUNCMUX_H_
|
||||
|
||||
#include <asm/arch-tegra/funcmux.h>
|
||||
|
||||
/* Configs supported by the func mux */
|
||||
enum {
|
||||
FUNCMUX_DEFAULT = 0, /* default config */
|
||||
|
||||
/* UART configs */
|
||||
FUNCMUX_UART4_GMI = 0,
|
||||
};
|
||||
#endif /* _TEGRA114_FUNCMUX_H_ */
|
59
arch/arm/include/asm/arch-tegra114/gp_padctrl.h
Normal file
59
arch/arm/include/asm/arch-tegra114/gp_padctrl.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA114_GP_PADCTRL_H_
|
||||
#define _TEGRA114_GP_PADCTRL_H_
|
||||
|
||||
#include <asm/arch-tegra/gp_padctrl.h>
|
||||
|
||||
/* APB_MISC_GP and padctrl registers */
|
||||
struct apb_misc_gp_ctlr {
|
||||
u32 modereg; /* 0x00: APB_MISC_GP_MODEREG */
|
||||
u32 hidrev; /* 0x04: APB_MISC_GP_HIDREV */
|
||||
u32 reserved0[22]; /* 0x08 - 0x5C: */
|
||||
u32 emu_revid; /* 0x60: APB_MISC_GP_EMU_REVID */
|
||||
u32 xactor_scratch; /* 0x64: APB_MISC_GP_XACTOR_SCRATCH */
|
||||
u32 aocfg1; /* 0x68: APB_MISC_GP_AOCFG1PADCTRL */
|
||||
u32 aocfg2; /* 0x6c: APB_MISC_GP_AOCFG2PADCTRL */
|
||||
u32 atcfg1; /* 0x70: APB_MISC_GP_ATCFG1PADCTRL */
|
||||
u32 atcfg2; /* 0x74: APB_MISC_GP_ATCFG2PADCTRL */
|
||||
u32 atcfg3; /* 0x78: APB_MISC_GP_ATCFG3PADCTRL */
|
||||
u32 atcfg4; /* 0x7C: APB_MISC_GP_ATCFG4PADCTRL */
|
||||
u32 atcfg5; /* 0x80: APB_MISC_GP_ATCFG5PADCTRL */
|
||||
u32 cdev1cfg; /* 0x84: APB_MISC_GP_CDEV1CFGPADCTRL */
|
||||
u32 cdev2cfg; /* 0x88: APB_MISC_GP_CDEV2CFGPADCTRL */
|
||||
u32 csuscfg; /* 0x8C: APB_MISC_GP_CSUSCFGPADCTRL */
|
||||
u32 dap1cfg; /* 0x90: APB_MISC_GP_DAP1CFGPADCTRL */
|
||||
u32 dap2cfg; /* 0x94: APB_MISC_GP_DAP2CFGPADCTRL */
|
||||
u32 dap3cfg; /* 0x98: APB_MISC_GP_DAP3CFGPADCTRL */
|
||||
u32 dap4cfg; /* 0x9C: APB_MISC_GP_DAP4CFGPADCTRL */
|
||||
u32 dbgcfg; /* 0xA0: APB_MISC_GP_DBGCFGPADCTRL */
|
||||
u32 lcdcfg1; /* 0xA4: APB_MISC_GP_LCDCFG1PADCTRL */
|
||||
u32 lcdcfg2; /* 0xA8: APB_MISC_GP_LCDCFG2PADCTRL */
|
||||
u32 sdio2cfg; /* 0xAC: APB_MISC_GP_SDIO2CFGPADCTRL */
|
||||
u32 sdio3cfg; /* 0xB0: APB_MISC_GP_SDIO3CFGPADCTRL */
|
||||
u32 spicfg; /* 0xB4: APB_MISC_GP_SPICFGPADCTRL */
|
||||
u32 uaacfg; /* 0xB8: APB_MISC_GP_UAACFGPADCTRL */
|
||||
u32 uabcfg; /* 0xBC: APB_MISC_GP_UABCFGPADCTRL */
|
||||
u32 uart2cfg; /* 0xC0: APB_MISC_GP_UART2CFGPADCTRL */
|
||||
u32 uart3cfg; /* 0xC4: APB_MISC_GP_UART3CFGPADCTRL */
|
||||
u32 vicfg1; /* 0xC8: APB_MISC_GP_VICFG1PADCTRL */
|
||||
u32 vivttgen; /* 0xCC: APB_MISC_GP_VIVTTGENPADCTRL */
|
||||
u32 reserved1[7]; /* 0xD0-0xE8: */
|
||||
u32 sdio1cfg; /* 0xEC: APB_MISC_GP_SDIO1CFGPADCTRL */
|
||||
};
|
||||
|
||||
#endif /* _TEGRA114_GP_PADCTRL_H_ */
|
30
arch/arm/include/asm/arch-tegra114/gpio.h
Normal file
30
arch/arm/include/asm/arch-tegra114/gpio.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA114_GPIO_H_
|
||||
#define _TEGRA114_GPIO_H_
|
||||
|
||||
/*
|
||||
* The Tegra114 GPIO controller has 246 GPIOS in 8 banks of 4 ports,
|
||||
* each with 8 GPIOs.
|
||||
*/
|
||||
#define TEGRA_GPIO_PORTS 4 /* number of ports per bank */
|
||||
#define TEGRA_GPIO_BANKS 8 /* number of banks */
|
||||
|
||||
#include <asm/arch-tegra/gpio.h>
|
||||
#include <asm/arch-tegra30/gpio.h>
|
||||
|
||||
#endif /* _TEGRA114_GPIO_H_ */
|
22
arch/arm/include/asm/arch-tegra114/hardware.h
Normal file
22
arch/arm/include/asm/arch-tegra114/hardware.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA114_HARDWARE_H_
|
||||
#define _TEGRA114_HARDWARE_H_
|
||||
|
||||
/* include tegra specific hardware definitions */
|
||||
|
||||
#endif /* _TEGRA114_HARDWARE_H_ */
|
618
arch/arm/include/asm/arch-tegra114/pinmux.h
Normal file
618
arch/arm/include/asm/arch-tegra114/pinmux.h
Normal file
|
@ -0,0 +1,618 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA114_PINMUX_H_
|
||||
#define _TEGRA114_PINMUX_H_
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
PINGRP_ULPI_DATA0 = 0, /* offset 0x3000 */
|
||||
PINGRP_ULPI_DATA1,
|
||||
PINGRP_ULPI_DATA2,
|
||||
PINGRP_ULPI_DATA3,
|
||||
PINGRP_ULPI_DATA4,
|
||||
PINGRP_ULPI_DATA5,
|
||||
PINGRP_ULPI_DATA6,
|
||||
PINGRP_ULPI_DATA7,
|
||||
PINGRP_ULPI_CLK,
|
||||
PINGRP_ULPI_DIR,
|
||||
PINGRP_ULPI_NXT,
|
||||
PINGRP_ULPI_STP,
|
||||
PINGRP_DAP3_FS,
|
||||
PINGRP_DAP3_DIN,
|
||||
PINGRP_DAP3_DOUT,
|
||||
PINGRP_DAP3_SCLK,
|
||||
PINGRP_GPIO_PV0,
|
||||
PINGRP_GPIO_PV1,
|
||||
PINGRP_SDMMC1_CLK,
|
||||
PINGRP_SDMMC1_CMD,
|
||||
PINGRP_SDMMC1_DAT3,
|
||||
PINGRP_SDMMC1_DAT2,
|
||||
PINGRP_SDMMC1_DAT1,
|
||||
PINGRP_SDMMC1_DAT0,
|
||||
PINGRP_GPIO_PV2,
|
||||
PINGRP_GPIO_PV3,
|
||||
PINGRP_CLK2_OUT,
|
||||
PINGRP_CLK2_REQ,
|
||||
PINGRP_LCD_PWR1,
|
||||
PINGRP_LCD_PWR2,
|
||||
PINGRP_LCD_SDIN,
|
||||
PINGRP_LCD_SDOUT,
|
||||
PINGRP_LCD_WR_N,
|
||||
PINGRP_LCD_CS0_N,
|
||||
PINGRP_LCD_DC0,
|
||||
PINGRP_LCD_SCK,
|
||||
PINGRP_LCD_PWR0,
|
||||
PINGRP_LCD_PCLK,
|
||||
PINGRP_LCD_DE,
|
||||
PINGRP_LCD_HSYNC,
|
||||
PINGRP_LCD_VSYNC,
|
||||
PINGRP_LCD_D0,
|
||||
PINGRP_LCD_D1,
|
||||
PINGRP_LCD_D2,
|
||||
PINGRP_LCD_D3,
|
||||
PINGRP_LCD_D4,
|
||||
PINGRP_LCD_D5,
|
||||
PINGRP_LCD_D6,
|
||||
PINGRP_LCD_D7,
|
||||
PINGRP_LCD_D8,
|
||||
PINGRP_LCD_D9,
|
||||
PINGRP_LCD_D10,
|
||||
PINGRP_LCD_D11,
|
||||
PINGRP_LCD_D12,
|
||||
PINGRP_LCD_D13,
|
||||
PINGRP_LCD_D14,
|
||||
PINGRP_LCD_D15,
|
||||
PINGRP_LCD_D16,
|
||||
PINGRP_LCD_D17,
|
||||
PINGRP_LCD_D18,
|
||||
PINGRP_LCD_D19,
|
||||
PINGRP_LCD_D20,
|
||||
PINGRP_LCD_D21,
|
||||
PINGRP_LCD_D22,
|
||||
PINGRP_LCD_D23,
|
||||
PINGRP_LCD_CS1_N,
|
||||
PINGRP_LCD_M1,
|
||||
PINGRP_LCD_DC1,
|
||||
PINGRP_HDMI_INT,
|
||||
PINGRP_DDC_SCL,
|
||||
PINGRP_DDC_SDA,
|
||||
PINGRP_CRT_HSYNC,
|
||||
PINGRP_CRT_VSYNC,
|
||||
PINGRP_VI_D0,
|
||||
PINGRP_VI_D1,
|
||||
PINGRP_VI_D2,
|
||||
PINGRP_VI_D3,
|
||||
PINGRP_VI_D4,
|
||||
PINGRP_VI_D5,
|
||||
PINGRP_VI_D6,
|
||||
PINGRP_VI_D7,
|
||||
PINGRP_VI_D8,
|
||||
PINGRP_VI_D9,
|
||||
PINGRP_VI_D10,
|
||||
PINGRP_VI_D11,
|
||||
PINGRP_VI_PCLK,
|
||||
PINGRP_VI_MCLK,
|
||||
PINGRP_VI_VSYNC,
|
||||
PINGRP_VI_HSYNC,
|
||||
PINGRP_UART2_RXD,
|
||||
PINGRP_UART2_TXD,
|
||||
PINGRP_UART2_RTS_N,
|
||||
PINGRP_UART2_CTS_N,
|
||||
PINGRP_UART3_TXD,
|
||||
PINGRP_UART3_RXD,
|
||||
PINGRP_UART3_CTS_N,
|
||||
PINGRP_UART3_RTS_N,
|
||||
PINGRP_GPIO_PU0,
|
||||
PINGRP_GPIO_PU1,
|
||||
PINGRP_GPIO_PU2,
|
||||
PINGRP_GPIO_PU3,
|
||||
PINGRP_GPIO_PU4,
|
||||
PINGRP_GPIO_PU5,
|
||||
PINGRP_GPIO_PU6,
|
||||
PINGRP_GEN1_I2C_SDA,
|
||||
PINGRP_GEN1_I2C_SCL,
|
||||
PINGRP_DAP4_FS,
|
||||
PINGRP_DAP4_DIN,
|
||||
PINGRP_DAP4_DOUT,
|
||||
PINGRP_DAP4_SCLK,
|
||||
PINGRP_CLK3_OUT,
|
||||
PINGRP_CLK3_REQ,
|
||||
PINGRP_GMI_WP_N,
|
||||
PINGRP_GMI_IORDY,
|
||||
PINGRP_GMI_WAIT,
|
||||
PINGRP_GMI_ADV_N,
|
||||
PINGRP_GMI_CLK,
|
||||
PINGRP_GMI_CS0_N,
|
||||
PINGRP_GMI_CS1_N,
|
||||
PINGRP_GMI_CS2_N,
|
||||
PINGRP_GMI_CS3_N,
|
||||
PINGRP_GMI_CS4_N,
|
||||
PINGRP_GMI_CS6_N,
|
||||
PINGRP_GMI_CS7_N,
|
||||
PINGRP_GMI_AD0,
|
||||
PINGRP_GMI_AD1,
|
||||
PINGRP_GMI_AD2,
|
||||
PINGRP_GMI_AD3,
|
||||
PINGRP_GMI_AD4,
|
||||
PINGRP_GMI_AD5,
|
||||
PINGRP_GMI_AD6,
|
||||
PINGRP_GMI_AD7,
|
||||
PINGRP_GMI_AD8,
|
||||
PINGRP_GMI_AD9,
|
||||
PINGRP_GMI_AD10,
|
||||
PINGRP_GMI_AD11,
|
||||
PINGRP_GMI_AD12,
|
||||
PINGRP_GMI_AD13,
|
||||
PINGRP_GMI_AD14,
|
||||
PINGRP_GMI_AD15,
|
||||
PINGRP_GMI_A16,
|
||||
PINGRP_GMI_A17,
|
||||
PINGRP_GMI_A18,
|
||||
PINGRP_GMI_A19,
|
||||
PINGRP_GMI_WR_N,
|
||||
PINGRP_GMI_OE_N,
|
||||
PINGRP_GMI_DQS,
|
||||
PINGRP_GMI_RST_N,
|
||||
PINGRP_GEN2_I2C_SCL,
|
||||
PINGRP_GEN2_I2C_SDA,
|
||||
PINGRP_SDMMC4_CLK,
|
||||
PINGRP_SDMMC4_CMD,
|
||||
PINGRP_SDMMC4_DAT0,
|
||||
PINGRP_SDMMC4_DAT1,
|
||||
PINGRP_SDMMC4_DAT2,
|
||||
PINGRP_SDMMC4_DAT3,
|
||||
PINGRP_SDMMC4_DAT4,
|
||||
PINGRP_SDMMC4_DAT5,
|
||||
PINGRP_SDMMC4_DAT6,
|
||||
PINGRP_SDMMC4_DAT7,
|
||||
PINGRP_SDMMC4_RST_N,
|
||||
PINGRP_CAM_MCLK,
|
||||
PINGRP_GPIO_PCC1,
|
||||
PINGRP_GPIO_PBB0,
|
||||
PINGRP_CAM_I2C_SCL,
|
||||
PINGRP_CAM_I2C_SDA,
|
||||
PINGRP_GPIO_PBB3,
|
||||
PINGRP_GPIO_PBB4,
|
||||
PINGRP_GPIO_PBB5,
|
||||
PINGRP_GPIO_PBB6,
|
||||
PINGRP_GPIO_PBB7,
|
||||
PINGRP_GPIO_PCC2,
|
||||
PINGRP_JTAG_RTCK,
|
||||
PINGRP_PWR_I2C_SCL,
|
||||
PINGRP_PWR_I2C_SDA,
|
||||
PINGRP_KB_ROW0,
|
||||
PINGRP_KB_ROW1,
|
||||
PINGRP_KB_ROW2,
|
||||
PINGRP_KB_ROW3,
|
||||
PINGRP_KB_ROW4,
|
||||
PINGRP_KB_ROW5,
|
||||
PINGRP_KB_ROW6,
|
||||
PINGRP_KB_ROW7,
|
||||
PINGRP_KB_ROW8,
|
||||
PINGRP_KB_ROW9,
|
||||
PINGRP_KB_ROW10,
|
||||
PINGRP_KB_ROW11,
|
||||
PINGRP_KB_ROW12,
|
||||
PINGRP_KB_ROW13,
|
||||
PINGRP_KB_ROW14,
|
||||
PINGRP_KB_ROW15,
|
||||
PINGRP_KB_COL0,
|
||||
PINGRP_KB_COL1,
|
||||
PINGRP_KB_COL2,
|
||||
PINGRP_KB_COL3,
|
||||
PINGRP_KB_COL4,
|
||||
PINGRP_KB_COL5,
|
||||
PINGRP_KB_COL6,
|
||||
PINGRP_KB_COL7,
|
||||
PINGRP_CLK_32K_OUT,
|
||||
PINGRP_SYS_CLK_REQ,
|
||||
PINGRP_CORE_PWR_REQ,
|
||||
PINGRP_CPU_PWR_REQ,
|
||||
PINGRP_PWR_INT_N,
|
||||
PINGRP_CLK_32K_IN,
|
||||
PINGRP_OWR,
|
||||
PINGRP_DAP1_FS,
|
||||
PINGRP_DAP1_DIN,
|
||||
PINGRP_DAP1_DOUT,
|
||||
PINGRP_DAP1_SCLK,
|
||||
PINGRP_CLK1_REQ,
|
||||
PINGRP_CLK1_OUT,
|
||||
PINGRP_SPDIF_IN,
|
||||
PINGRP_SPDIF_OUT,
|
||||
PINGRP_DAP2_FS,
|
||||
PINGRP_DAP2_DIN,
|
||||
PINGRP_DAP2_DOUT,
|
||||
PINGRP_DAP2_SCLK,
|
||||
PINGRP_SPI2_MOSI,
|
||||
PINGRP_SPI2_MISO,
|
||||
PINGRP_SPI2_CS0_N,
|
||||
PINGRP_SPI2_SCK,
|
||||
PINGRP_SPI1_MOSI,
|
||||
PINGRP_SPI1_SCK,
|
||||
PINGRP_SPI1_CS0_N,
|
||||
PINGRP_SPI1_MISO,
|
||||
PINGRP_SPI2_CS1_N,
|
||||
PINGRP_SPI2_CS2_N,
|
||||
PINGRP_SDMMC3_CLK,
|
||||
PINGRP_SDMMC3_CMD,
|
||||
PINGRP_SDMMC3_DAT0,
|
||||
PINGRP_SDMMC3_DAT1,
|
||||
PINGRP_SDMMC3_DAT2,
|
||||
PINGRP_SDMMC3_DAT3,
|
||||
PINGRP_SDMMC3_DAT4,
|
||||
PINGRP_SDMMC3_DAT5,
|
||||
PINGRP_SDMMC3_DAT6,
|
||||
PINGRP_SDMMC3_DAT7,
|
||||
PINGRP_PEX_L0_PRSNT_N,
|
||||
PINGRP_PEX_L0_RST_N,
|
||||
PINGRP_PEX_L0_CLKREQ_N,
|
||||
PINGRP_PEX_WAKE_N,
|
||||
PINGRP_PEX_L1_PRSNT_N,
|
||||
PINGRP_PEX_L1_RST_N,
|
||||
PINGRP_PEX_L1_CLKREQ_N,
|
||||
PINGRP_PEX_L2_PRSNT_N,
|
||||
PINGRP_PEX_L2_RST_N,
|
||||
PINGRP_PEX_L2_CLKREQ_N,
|
||||
PINGRP_HDMI_CEC, /* offset 0x33e0 */
|
||||
PINGRP_SDMMC1_WP_N,
|
||||
PINGRP_SDMMC3_CD_N,
|
||||
PINGRP_SPI1_CS1_N,
|
||||
PINGRP_SPI1_CS2_N,
|
||||
PINGRP_USB_VBUS_EN0, /* offset 0x33f4 */
|
||||
PINGRP_USB_VBUS_EN1,
|
||||
PINGRP_SDMMC3_CLK_LB_IN,
|
||||
PINGRP_SDMMC3_CLK_LB_OUT,
|
||||
PINGRP_NAND_GMI_CLK_LB,
|
||||
PINGRP_RESET_OUT_N,
|
||||
PINGRP_COUNT,
|
||||
};
|
||||
|
||||
enum pdrive_pingrp {
|
||||
PDRIVE_PINGROUP_AO1 = 0, /* offset 0x868 */
|
||||
PDRIVE_PINGROUP_AO2,
|
||||
PDRIVE_PINGROUP_AT1,
|
||||
PDRIVE_PINGROUP_AT2,
|
||||
PDRIVE_PINGROUP_AT3,
|
||||
PDRIVE_PINGROUP_AT4,
|
||||
PDRIVE_PINGROUP_AT5,
|
||||
PDRIVE_PINGROUP_CDEV1,
|
||||
PDRIVE_PINGROUP_CDEV2,
|
||||
PDRIVE_PINGROUP_CSUS,
|
||||
PDRIVE_PINGROUP_DAP1,
|
||||
PDRIVE_PINGROUP_DAP2,
|
||||
PDRIVE_PINGROUP_DAP3,
|
||||
PDRIVE_PINGROUP_DAP4,
|
||||
PDRIVE_PINGROUP_DBG,
|
||||
PDRIVE_PINGROUP_LCD1,
|
||||
PDRIVE_PINGROUP_LCD2,
|
||||
PDRIVE_PINGROUP_SDIO2,
|
||||
PDRIVE_PINGROUP_SDIO3,
|
||||
PDRIVE_PINGROUP_SPI,
|
||||
PDRIVE_PINGROUP_UAA,
|
||||
PDRIVE_PINGROUP_UAB,
|
||||
PDRIVE_PINGROUP_UART2,
|
||||
PDRIVE_PINGROUP_UART3,
|
||||
PDRIVE_PINGROUP_VI1 = 24, /* offset 0x8c8 */
|
||||
PDRIVE_PINGROUP_SDIO1 = 33, /* offset 0x8ec */
|
||||
PDRIVE_PINGROUP_CRT = 36, /* offset 0x8f8 */
|
||||
PDRIVE_PINGROUP_DDC,
|
||||
PDRIVE_PINGROUP_GMA,
|
||||
PDRIVE_PINGROUP_GMB,
|
||||
PDRIVE_PINGROUP_GMC,
|
||||
PDRIVE_PINGROUP_GMD,
|
||||
PDRIVE_PINGROUP_GME,
|
||||
PDRIVE_PINGROUP_GMF,
|
||||
PDRIVE_PINGROUP_GMG,
|
||||
PDRIVE_PINGROUP_GMH,
|
||||
PDRIVE_PINGROUP_OWR,
|
||||
PDRIVE_PINGROUP_UAD,
|
||||
PDRIVE_PINGROUP_GPV,
|
||||
PDRIVE_PINGROUP_DEV3 = 49, /* offset 0x92c */
|
||||
PDRIVE_PINGROUP_CEC = 52, /* offset 0x938 */
|
||||
PDRIVE_PINGROUP_AT6,
|
||||
PDRIVE_PINGROUP_DAP5,
|
||||
PDRIVE_PINGROUP_VBUS,
|
||||
PDRIVE_PINGROUP_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_I2C1,
|
||||
PMUX_FUNC_I2C2,
|
||||
PMUX_FUNC_I2C3,
|
||||
PMUX_FUNC_IDE,
|
||||
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_SDMMC1,
|
||||
PMUX_FUNC_SDMMC2,
|
||||
PMUX_FUNC_SDMMC3,
|
||||
PMUX_FUNC_SDMMC4,
|
||||
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_BLINK,
|
||||
PMUX_FUNC_CEC,
|
||||
PMUX_FUNC_CLK12,
|
||||
PMUX_FUNC_DAP,
|
||||
PMUX_FUNC_DAPSDMMC2,
|
||||
PMUX_FUNC_DDR,
|
||||
PMUX_FUNC_DEV3,
|
||||
PMUX_FUNC_DTV,
|
||||
PMUX_FUNC_VI_ALT1,
|
||||
PMUX_FUNC_VI_ALT2,
|
||||
PMUX_FUNC_VI_ALT3,
|
||||
PMUX_FUNC_EMC_DLL,
|
||||
PMUX_FUNC_EXTPERIPH1,
|
||||
PMUX_FUNC_EXTPERIPH2,
|
||||
PMUX_FUNC_EXTPERIPH3,
|
||||
PMUX_FUNC_GMI_ALT,
|
||||
PMUX_FUNC_HDA,
|
||||
PMUX_FUNC_HSI,
|
||||
PMUX_FUNC_I2C4,
|
||||
PMUX_FUNC_I2C5,
|
||||
PMUX_FUNC_I2CPWR,
|
||||
PMUX_FUNC_I2S0,
|
||||
PMUX_FUNC_I2S1,
|
||||
PMUX_FUNC_I2S2,
|
||||
PMUX_FUNC_I2S3,
|
||||
PMUX_FUNC_I2S4,
|
||||
PMUX_FUNC_NAND_ALT,
|
||||
PMUX_FUNC_POPSDIO4,
|
||||
PMUX_FUNC_POPSDMMC4,
|
||||
PMUX_FUNC_PWM0,
|
||||
PMUX_FUNC_PWM1,
|
||||
PMUX_FUNC_PWM2,
|
||||
PMUX_FUNC_PWM3,
|
||||
PMUX_FUNC_SATA,
|
||||
PMUX_FUNC_SPI5,
|
||||
PMUX_FUNC_SPI6,
|
||||
PMUX_FUNC_SYSCLK,
|
||||
PMUX_FUNC_VGP1,
|
||||
PMUX_FUNC_VGP2,
|
||||
PMUX_FUNC_VGP3,
|
||||
PMUX_FUNC_VGP4,
|
||||
PMUX_FUNC_VGP5,
|
||||
PMUX_FUNC_VGP6,
|
||||
|
||||
PMUX_FUNC_USB,
|
||||
PMUX_FUNC_SOC,
|
||||
PMUX_FUNC_CPU,
|
||||
PMUX_FUNC_CLK,
|
||||
PMUX_FUNC_PWRON,
|
||||
PMUX_FUNC_PMI,
|
||||
PMUX_FUNC_CLDVFS,
|
||||
PMUX_FUNC_RESET_OUT_N,
|
||||
|
||||
PMUX_FUNC_SAFE,
|
||||
PMUX_FUNC_MAX,
|
||||
|
||||
PMUX_FUNC_RSVD1 = 0x8000,
|
||||
PMUX_FUNC_RSVD2 = 0x8001,
|
||||
PMUX_FUNC_RSVD3 = 0x8002,
|
||||
PMUX_FUNC_RSVD4 = 0x8003,
|
||||
};
|
||||
|
||||
/* return 1 if a pmux_func is in range */
|
||||
#define pmux_func_isvalid(func) ((((func) >= 0) && ((func) < PMUX_FUNC_MAX)) \
|
||||
|| (((func) >= PMUX_FUNC_RSVD1) && ((func) <= PMUX_FUNC_RSVD4)))
|
||||
|
||||
/* return 1 if a pingrp is in range */
|
||||
#define pmux_pingrp_isvalid(pin) (((pin) >= 0) && ((pin) < PINGRP_COUNT))
|
||||
|
||||
/* The pullup/pulldown state of a pin group */
|
||||
enum pmux_pull {
|
||||
PMUX_PULL_NORMAL = 0,
|
||||
PMUX_PULL_DOWN,
|
||||
PMUX_PULL_UP,
|
||||
};
|
||||
/* return 1 if a pin_pupd_is in range */
|
||||
#define pmux_pin_pupd_isvalid(pupd) (((pupd) >= PMUX_PULL_NORMAL) && \
|
||||
((pupd) <= 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,
|
||||
};
|
||||
/* return 1 if a pin_tristate_is in range */
|
||||
#define pmux_pin_tristate_isvalid(tristate) (((tristate) >= PMUX_TRI_NORMAL) \
|
||||
&& ((tristate) <= PMUX_TRI_TRISTATE))
|
||||
|
||||
enum pmux_pin_io {
|
||||
PMUX_PIN_OUTPUT = 0,
|
||||
PMUX_PIN_INPUT = 1,
|
||||
};
|
||||
/* return 1 if a pin_io_is in range */
|
||||
#define pmux_pin_io_isvalid(io) (((io) >= PMUX_PIN_OUTPUT) && \
|
||||
((io) <= PMUX_PIN_INPUT))
|
||||
|
||||
enum pmux_pin_lock {
|
||||
PMUX_PIN_LOCK_DEFAULT = 0,
|
||||
PMUX_PIN_LOCK_DISABLE,
|
||||
PMUX_PIN_LOCK_ENABLE,
|
||||
};
|
||||
/* return 1 if a pin_lock is in range */
|
||||
#define pmux_pin_lock_isvalid(lock) (((lock) >= PMUX_PIN_LOCK_DEFAULT) && \
|
||||
((lock) <= PMUX_PIN_LOCK_ENABLE))
|
||||
|
||||
enum pmux_pin_od {
|
||||
PMUX_PIN_OD_DEFAULT = 0,
|
||||
PMUX_PIN_OD_DISABLE,
|
||||
PMUX_PIN_OD_ENABLE,
|
||||
};
|
||||
/* return 1 if a pin_od is in range */
|
||||
#define pmux_pin_od_isvalid(od) (((od) >= PMUX_PIN_OD_DEFAULT) && \
|
||||
((od) <= PMUX_PIN_OD_ENABLE))
|
||||
|
||||
enum pmux_pin_ioreset {
|
||||
PMUX_PIN_IO_RESET_DEFAULT = 0,
|
||||
PMUX_PIN_IO_RESET_DISABLE,
|
||||
PMUX_PIN_IO_RESET_ENABLE,
|
||||
};
|
||||
/* return 1 if a pin_ioreset_is in range */
|
||||
#define pmux_pin_ioreset_isvalid(ioreset) \
|
||||
(((ioreset) >= PMUX_PIN_IO_RESET_DEFAULT) && \
|
||||
((ioreset) <= PMUX_PIN_IO_RESET_ENABLE))
|
||||
|
||||
/* 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_CAM,
|
||||
PMUX_VDDIO_GMI,
|
||||
PMUX_VDDIO_PEXCTL,
|
||||
PMUX_VDDIO_SDMMC1,
|
||||
PMUX_VDDIO_SDMMC3,
|
||||
PMUX_VDDIO_SDMMC4,
|
||||
|
||||
PMUX_VDDIO_NONE
|
||||
};
|
||||
|
||||
/* T114 pin drive group and pin mux registers */
|
||||
#define PDRIVE_PINGROUP_OFFSET (0x868 >> 2)
|
||||
#define PMUX_OFFSET ((0x3000 >> 2) - PDRIVE_PINGROUP_OFFSET - \
|
||||
PDRIVE_PINGROUP_COUNT)
|
||||
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_reserved2; /* ABP_MISC_PP_ reserved offset 0C */
|
||||
uint pmt_reserved3; /* ABP_MISC_PP_ reserved offset 10 */
|
||||
uint pmt_reserved4[4]; /* _TRI_STATE_REG_A/B/C/D in t20 */
|
||||
uint pmt_cfg_ctl; /* _CONFIG_CTL_0, offset 24 */
|
||||
|
||||
uint pmt_reserved[528]; /* ABP_MISC_PP_ reserved offs 28-864 */
|
||||
|
||||
uint pmt_drive[PDRIVE_PINGROUP_COUNT]; /* pin drive grps offs 868 */
|
||||
uint pmt_reserved5[PMUX_OFFSET];
|
||||
uint pmt_ctl[PINGRP_COUNT]; /* mux/pupd/tri regs, offset 0x3000 */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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_... */
|
||||
enum pmux_pin_io io; /* input or output PMUX_PIN_... */
|
||||
enum pmux_pin_lock lock; /* lock enable/disable PMUX_PIN... */
|
||||
enum pmux_pin_od od; /* open-drain or push-pull driver */
|
||||
enum pmux_pin_ioreset ioreset; /* input/output reset PMUX_PIN... */
|
||||
};
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Set the pull up/down feature for a pin group */
|
||||
void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
|
||||
|
||||
/* Set the mux function for a pin group */
|
||||
void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
|
||||
|
||||
/* Set the complete configuration for a pin group */
|
||||
void pinmux_config_pingroup(struct pingroup_config *config);
|
||||
|
||||
/* Set a pin group to tristate or normal */
|
||||
void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
|
||||
|
||||
/* Set a pin group as input or output */
|
||||
void pinmux_set_io(enum pmux_pingrp pin, enum pmux_pin_io io);
|
||||
|
||||
/**
|
||||
* Configure 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);
|
||||
|
||||
/* Set a group of pins from a table */
|
||||
void pinmux_init(void);
|
||||
|
||||
#endif /* _TEGRA114_PINMUX_H_ */
|
23
arch/arm/include/asm/arch-tegra114/pmu.h
Normal file
23
arch/arm/include/asm/arch-tegra114/pmu.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA114_PMU_H_
|
||||
#define _TEGRA114_PMU_H_
|
||||
|
||||
/* Set core and CPU voltages to nominal levels */
|
||||
int pmu_set_nominal(void);
|
||||
|
||||
#endif /* _TEGRA114_PMU_H_ */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue