diff options
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/arm1176/bcm2835/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/arm1176/bcm2835/mbox.c | 164 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/board.c | 4 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/clock_am33xx.c (renamed from arch/arm/cpu/armv7/am33xx/clock.c) | 33 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/clock_ti814x.c | 406 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/ddr.c | 104 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/emif4.c | 57 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/mem.c | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/am33xx/sys_info.c | 5 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/cache_v7.c | 3 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/exynos/power.c | 45 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/hwinit-common.c | 35 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/lowlevel_init.S | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/timer.c | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/start.S | 7 |
18 files changed, 806 insertions, 70 deletions
diff --git a/arch/arm/cpu/arm1176/bcm2835/Makefile b/arch/arm/cpu/arm1176/bcm2835/Makefile index 95da6a8..135de42 100644 --- a/arch/arm/cpu/arm1176/bcm2835/Makefile +++ b/arch/arm/cpu/arm1176/bcm2835/Makefile @@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := init.o reset.o timer.o +COBJS := init.o reset.o timer.o mbox.o SRCS := $(SOBJS:.o=.c) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/arm1176/bcm2835/mbox.c b/arch/arm/cpu/arm1176/bcm2835/mbox.c new file mode 100644 index 0000000..fd65e33 --- /dev/null +++ b/arch/arm/cpu/arm1176/bcm2835/mbox.c @@ -0,0 +1,164 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * 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. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/mbox.h> + +#define TIMEOUT (100 * 1000) /* 100mS in uS */ + +int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv) +{ + struct bcm2835_mbox_regs *regs = + (struct bcm2835_mbox_regs *)BCM2835_MBOX_PHYSADDR; + ulong endtime = get_timer(0) + TIMEOUT; + u32 val; + + debug("time: %lu timeout: %lu\n", get_timer(0), endtime); + + if (send & BCM2835_CHAN_MASK) { + printf("mbox: Illegal mbox data 0x%08x\n", send); + return -1; + } + + /* Drain any stale responses */ + + for (;;) { + val = readl(®s->status); + if (val & BCM2835_MBOX_STATUS_RD_EMPTY) + break; + if (get_timer(0) >= endtime) { + printf("mbox: Timeout draining stale responses\n"); + return -1; + } + val = readl(®s->read); + } + + /* Wait for space to send */ + + for (;;) { + val = readl(®s->status); + if (!(val & BCM2835_MBOX_STATUS_WR_FULL)) + break; + if (get_timer(0) >= endtime) { + printf("mbox: Timeout waiting for send space\n"); + return -1; + } + } + + /* Send the request */ + + val = BCM2835_MBOX_PACK(chan, send); + debug("mbox: TX raw: 0x%08x\n", val); + writel(val, ®s->write); + + /* Wait for the response */ + + for (;;) { + val = readl(®s->status); + if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY)) + break; + if (get_timer(0) >= endtime) { + printf("mbox: Timeout waiting for response\n"); + return -1; + } + } + + /* Read the response */ + + val = readl(®s->read); + debug("mbox: RX raw: 0x%08x\n", val); + + /* Validate the response */ + + if (BCM2835_MBOX_UNPACK_CHAN(val) != chan) { + printf("mbox: Response channel mismatch\n"); + return -1; + } + + *recv = BCM2835_MBOX_UNPACK_DATA(val); + + return 0; +} + +#ifdef DEBUG +void dump_buf(struct bcm2835_mbox_hdr *buffer) +{ + u32 *p; + u32 words; + int i; + + p = (u32 *)buffer; + words = buffer->buf_size / 4; + for (i = 0; i < words; i++) + printf(" 0x%04x: 0x%08x\n", i * 4, p[i]); +} +#endif + +int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer) +{ + int ret; + u32 rbuffer; + struct bcm2835_mbox_tag_hdr *tag; + int tag_index; + +#ifdef DEBUG + printf("mbox: TX buffer\n"); + dump_buf(buffer); +#endif + + ret = bcm2835_mbox_call_raw(chan, (u32)buffer, &rbuffer); + if (ret) + return ret; + if (rbuffer != (u32)buffer) { + printf("mbox: Response buffer mismatch\n"); + return -1; + } + +#ifdef DEBUG + printf("mbox: RX buffer\n"); + dump_buf(buffer); +#endif + + /* Validate overall response status */ + + if (buffer->code != BCM2835_MBOX_RESP_CODE_SUCCESS) { + printf("mbox: Header response code invalid\n"); + return -1; + } + + /* Validate each tag's response status */ + + tag = (void *)(buffer + 1); + tag_index = 0; + while (tag->tag) { + if (!(tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE)) { + printf("mbox: Tag %d missing val_len response bit\n", + tag_index); + return -1; + } + /* + * Clear the reponse bit so clients can just look right at the + * length field without extra processing + */ + tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE; + tag = (void *)(((u8 *)tag) + sizeof(*tag) + tag->val_buf_size); + tag_index++; + } + + return 0; +} diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4668b3c..7a8c2d0 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -32,7 +32,7 @@ COBJS += cache_v7.o COBJS += cpu.o COBJS += syslib.o -ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6),) +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI814X),) SOBJS += lowlevel_init.o endif diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile index 70c443e..c97e30d 100644 --- a/arch/arm/cpu/armv7/am33xx/Makefile +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -16,7 +16,8 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -COBJS += clock.o +COBJS-$(CONFIG_AM33XX) += clock_am33xx.o +COBJS-$(CONFIG_TI814X) += clock_ti814x.o COBJS += sys_info.o COBJS += mem.o COBJS += ddr.o diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index e35a3e3..885fb2d 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -141,11 +141,11 @@ int arch_misc_init(void) { #ifdef CONFIG_AM335X_USB0 musb_register(&otg0_plat, &otg0_board_data, - (void *)AM335X_USB0_OTG_BASE); + (void *)USB0_OTG_BASE); #endif #ifdef CONFIG_AM335X_USB1 musb_register(&otg1_plat, &otg1_board_data, - (void *)AM335X_USB1_OTG_BASE); + (void *)USB1_OTG_BASE); #endif return 0; } diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c index d7d98d1..afc0d92 100644 --- a/arch/arm/cpu/armv7/am33xx/clock.c +++ b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c @@ -1,9 +1,9 @@ /* - * clock.c + * clock_am33xx.c * * clocks for AM33XX based boards * - * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -42,6 +42,35 @@ #define CPGMAC0_IDLE 0x30000 #define DPLL_CLKDCOLDO_GATE_CTRL 0x300 +#define OSC (V_OSCK/1000000) + +#define MPUPLL_M CONFIG_SYS_MPUCLK +#define MPUPLL_N (OSC-1) +#define MPUPLL_M2 1 + +/* Core PLL Fdll = 1 GHZ, */ +#define COREPLL_M 1000 +#define COREPLL_N (OSC-1) + +#define COREPLL_M4 10 /* CORE_CLKOUTM4 = 200 MHZ */ +#define COREPLL_M5 8 /* CORE_CLKOUTM5 = 250 MHZ */ +#define COREPLL_M6 4 /* CORE_CLKOUTM6 = 500 MHZ */ + +/* + * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll + * frequency needs to be set to 960 MHZ. Hence, + * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below + */ +#define PERPLL_M 960 +#define PERPLL_N (OSC-1) +#define PERPLL_M2 5 + +/* DDR Freq is 266 MHZ for now */ +/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */ +#define DDRPLL_M 266 +#define DDRPLL_N (OSC-1) +#define DDRPLL_M2 1 + const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER; const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP; const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL; diff --git a/arch/arm/cpu/armv7/am33xx/clock_ti814x.c b/arch/arm/cpu/armv7/am33xx/clock_ti814x.c new file mode 100644 index 0000000..cb4210f --- /dev/null +++ b/arch/arm/cpu/armv7/am33xx/clock_ti814x.c @@ -0,0 +1,406 @@ +/* + * clock_ti814x.c + * + * Clocks for TI814X based boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated + * + * 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. + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +/* PRCM */ +#define PRCM_MOD_EN 0x2 + +/* CLK_SRC */ +#define OSC_SRC0 0 +#define OSC_SRC1 1 + +#define L3_OSC_SRC OSC_SRC0 + +#define OSC_0_FREQ 20 + +#define DCO_HS2_MIN 500 +#define DCO_HS2_MAX 1000 +#define DCO_HS1_MIN 1000 +#define DCO_HS1_MAX 2000 + +#define SELFREQDCO_HS2 0x00000801 +#define SELFREQDCO_HS1 0x00001001 + +#define MPU_N 0x1 +#define MPU_M 0x3C +#define MPU_M2 1 +#define MPU_CLKCTRL 0x1 + +#define L3_N 19 +#define L3_M 880 +#define L3_M2 4 +#define L3_CLKCTRL 0x801 + +#define DDR_N 19 +#define DDR_M 666 +#define DDR_M2 2 +#define DDR_CLKCTRL 0x801 + +/* ADPLLJ register values */ +#define ADPLLJ_CLKCTRL_HS2 0x00000801 /* HS2 mode, TINT2 = 1 */ +#define ADPLLJ_CLKCTRL_HS1 0x00001001 /* HS1 mode, TINT2 = 1 */ +#define ADPLLJ_CLKCTRL_CLKDCOLDOEN (1 << 29) +#define ADPLLJ_CLKCTRL_IDLE (1 << 23) +#define ADPLLJ_CLKCTRL_CLKOUTEN (1 << 20) +#define ADPLLJ_CLKCTRL_CLKOUTLDOEN (1 << 19) +#define ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ (1 << 17) +#define ADPLLJ_CLKCTRL_LPMODE (1 << 12) +#define ADPLLJ_CLKCTRL_DRIFTGUARDIAN (1 << 11) +#define ADPLLJ_CLKCTRL_REGM4XEN (1 << 10) +#define ADPLLJ_CLKCTRL_TINITZ (1 << 0) +#define ADPLLJ_CLKCTRL_CLKDCO (ADPLLJ_CLKCTRL_CLKDCOLDOEN | \ + ADPLLJ_CLKCTRL_CLKOUTEN | \ + ADPLLJ_CLKCTRL_CLKOUTLDOEN | \ + ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ) + +#define ADPLLJ_STATUS_PHASELOCK (1 << 10) +#define ADPLLJ_STATUS_FREQLOCK (1 << 9) +#define ADPLLJ_STATUS_PHSFRQLOCK (ADPLLJ_STATUS_PHASELOCK | \ + ADPLLJ_STATUS_FREQLOCK) +#define ADPLLJ_STATUS_BYPASSACK (1 << 8) +#define ADPLLJ_STATUS_BYPASS (1 << 0) +#define ADPLLJ_STATUS_BYPASSANDACK (ADPLLJ_STATUS_BYPASSACK | \ + ADPLLJ_STATUS_BYPASS) + +#define ADPLLJ_TENABLE_ENB (1 << 0) +#define ADPLLJ_TENABLEDIV_ENB (1 << 0) + +#define ADPLLJ_M2NDIV_M2SHIFT 16 + +#define MPU_PLL_BASE (PLL_SUBSYS_BASE + 0x048) +#define L3_PLL_BASE (PLL_SUBSYS_BASE + 0x110) +#define DDR_PLL_BASE (PLL_SUBSYS_BASE + 0x290) + +struct ad_pll { + unsigned int pwrctrl; + unsigned int clkctrl; + unsigned int tenable; + unsigned int tenablediv; + unsigned int m2ndiv; + unsigned int mn2div; + unsigned int fracdiv; + unsigned int bwctrl; + unsigned int fracctrl; + unsigned int status; + unsigned int m3div; + unsigned int rampctrl; +}; + +#define OSC_SRC_CTRL (PLL_SUBSYS_BASE + 0x2C0) + +/* PRCM */ +#define CM_DEFAULT_BASE (PRCM_BASE + 0x0500) + +struct cm_def { + unsigned int resv0[2]; + unsigned int l3fastclkstctrl; + unsigned int resv1[1]; + unsigned int pciclkstctrl; + unsigned int resv2[1]; + unsigned int ducaticlkstctrl; + unsigned int resv3[1]; + unsigned int emif0clkctrl; + unsigned int emif1clkctrl; + unsigned int dmmclkctrl; + unsigned int fwclkctrl; + unsigned int resv4[10]; + unsigned int usbclkctrl; + unsigned int resv5[1]; + unsigned int sataclkctrl; + unsigned int resv6[4]; + unsigned int ducaticlkctrl; + unsigned int pciclkctrl; +}; + +#define CM_ALWON_BASE (PRCM_BASE + 0x1400) + +struct cm_alwon { + unsigned int l3slowclkstctrl; + unsigned int ethclkstctrl; + unsigned int l3medclkstctrl; + unsigned int mmu_clkstctrl; + unsigned int mmucfg_clkstctrl; + unsigned int ocmc0clkstctrl; + unsigned int vcpclkstctrl; + unsigned int mpuclkstctrl; + unsigned int sysclk4clkstctrl; + unsigned int sysclk5clkstctrl; + unsigned int sysclk6clkstctrl; + unsigned int rtcclkstctrl; + unsigned int l3fastclkstctrl; + unsigned int resv0[67]; + unsigned int mcasp0clkctrl; + unsigned int mcasp1clkctrl; + unsigned int mcasp2clkctrl; + unsigned int mcbspclkctrl; + unsigned int uart0clkctrl; + unsigned int uart1clkctrl; + unsigned int uart2clkctrl; + unsigned int gpio0clkctrl; + unsigned int gpio1clkctrl; + unsigned int i2c0clkctrl; + unsigned int i2c1clkctrl; + unsigned int mcasp345clkctrl; + unsigned int atlclkctrl; + unsigned int mlbclkctrl; + unsigned int pataclkctrl; + unsigned int resv1[1]; + unsigned int uart3clkctrl; + unsigned int uart4clkctrl; + unsigned int uart5clkctrl; + unsigned int wdtimerclkctrl; + unsigned int spiclkctrl; + unsigned int mailboxclkctrl; + unsigned int spinboxclkctrl; + unsigned int mmudataclkctrl; + unsigned int resv2[2]; + unsigned int mmucfgclkctrl; + unsigned int resv3[2]; + unsigned int ocmc0clkctrl; + unsigned int vcpclkctrl; + unsigned int resv4[2]; + unsigned int controlclkctrl; + unsigned int resv5[2]; + unsigned int gpmcclkctrl; + unsigned int ethernet0clkctrl; + unsigned int resv6[1]; + unsigned int mpuclkctrl; + unsigned int debugssclkctrl; + unsigned int l3clkctrl; + unsigned int l4hsclkctrl; + unsigned int l4lsclkctrl; + unsigned int rtcclkctrl; + unsigned int tpccclkctrl; + unsigned int tptc0clkctrl; + unsigned int tptc1clkctrl; + unsigned int tptc2clkctrl; + unsigned int tptc3clkctrl; + unsigned int resv7[4]; + unsigned int dcan01clkctrl; + unsigned int mmchs0clkctrl; + unsigned int mmchs1clkctrl; + unsigned int mmchs2clkctrl; + unsigned int custefuseclkctrl; +}; + + +const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE; +const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE; + +/* + * Enable the peripheral clock for required peripherals + */ +static void enable_per_clocks(void) +{ + /* UART0 */ + writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl); + while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN) + ; + + /* HSMMC1 */ + writel(PRCM_MOD_EN, &cmalwon->mmchs1clkctrl); + while (readl(&cmalwon->mmchs1clkctrl) != PRCM_MOD_EN) + ; +} + +/* + * select the HS1 or HS2 for DCO Freq + * return : CLKCTRL + */ +static u32 pll_dco_freq_sel(u32 clkout_dco) +{ + if (clkout_dco >= DCO_HS2_MIN && clkout_dco < DCO_HS2_MAX) + return SELFREQDCO_HS2; + else if (clkout_dco >= DCO_HS1_MIN && clkout_dco < DCO_HS1_MAX) + return SELFREQDCO_HS1; + else + return -1; +} + +/* + * select the sigma delta config + * return: sigma delta val + */ +static u32 pll_sigma_delta_val(u32 clkout_dco) +{ + u32 sig_val = 0; + float frac_div; + + frac_div = (float) clkout_dco / 250; + frac_div = frac_div + 0.90; + sig_val = (int)frac_div; + sig_val = sig_val << 24; + + return sig_val; +} + +/* + * configure individual ADPLLJ + */ +static void pll_config(u32 base, u32 n, u32 m, u32 m2, + u32 clkctrl_val, int adpllj) +{ + const struct ad_pll *adpll = (struct ad_pll *)base; + u32 m2nval, mn2val, read_clkctrl = 0, clkout_dco = 0; + u32 sig_val = 0, hs_mod = 0; + + m2nval = (m2 << ADPLLJ_M2NDIV_M2SHIFT) | n; + mn2val = m; + + /* calculate clkout_dco */ + clkout_dco = ((OSC_0_FREQ / (n+1)) * m); + + /* sigma delta & Hs mode selection skip for ADPLLS*/ + if (adpllj) { + sig_val = pll_sigma_delta_val(clkout_dco); + hs_mod = pll_dco_freq_sel(clkout_dco); + } + + /* by-pass pll */ + read_clkctrl = readl(&adpll->clkctrl); + writel((read_clkctrl | ADPLLJ_CLKCTRL_IDLE), &adpll->clkctrl); + while ((readl(&adpll->status) & ADPLLJ_STATUS_BYPASSANDACK) + != ADPLLJ_STATUS_BYPASSANDACK) + ; + + /* clear TINITZ */ + read_clkctrl = readl(&adpll->clkctrl); + writel((read_clkctrl & ~ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl); + + /* + * ref_clk = 20/(n + 1); + * clkout_dco = ref_clk * m; + * clk_out = clkout_dco/m2; + */ + read_clkctrl = readl(&adpll->clkctrl) & + ~(ADPLLJ_CLKCTRL_LPMODE | + ADPLLJ_CLKCTRL_DRIFTGUARDIAN | + ADPLLJ_CLKCTRL_REGM4XEN); + writel(m2nval, &adpll->m2ndiv); + writel(mn2val, &adpll->mn2div); + + /* Skip for modena(ADPLLS) */ + if (adpllj) { + writel(sig_val, &adpll->fracdiv); + writel((read_clkctrl | hs_mod), &adpll->clkctrl); + } + + /* Load M2, N2 dividers of ADPLL */ + writel(ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv); + writel(~ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv); + + /* Load M, N dividers of ADPLL */ + writel(ADPLLJ_TENABLE_ENB, &adpll->tenable); + writel(~ADPLLJ_TENABLE_ENB, &adpll->tenable); + + /* Configure CLKDCOLDOEN,CLKOUTLDOEN,CLKOUT Enable BITS */ + read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_CLKDCO; + if (adpllj) + writel((read_clkctrl | ADPLLJ_CLKCTRL_CLKDCO), + &adpll->clkctrl); + + /* Enable TINTZ and disable IDLE(PLL in Active & Locked Mode */ + read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_IDLE; + writel((read_clkctrl | ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl); + + /* Wait for phase and freq lock */ + while ((readl(&adpll->status) & ADPLLJ_STATUS_PHSFRQLOCK) != + ADPLLJ_STATUS_PHSFRQLOCK) + ; +} + +static void unlock_pll_control_mmr(void) +{ + /* TRM 2.10.1.4 and 3.2.7-3.2.11 */ + writel(0x1EDA4C3D, 0x481C5040); + writel(0x2FF1AC2B, 0x48140060); + writel(0xF757FDC0, 0x48140064); + writel(0xE2BC3A6D, 0x48140068); + writel(0x1EBF131D, 0x4814006c); + writel(0x6F361E05, 0x48140070); +} + +static void mpu_pll_config(void) +{ + pll_config(MPU_PLL_BASE, MPU_N, MPU_M, MPU_M2, MPU_CLKCTRL, 0); +} + +static void l3_pll_config(void) +{ + u32 l3_osc_src, rd_osc_src = 0; + + l3_osc_src = L3_OSC_SRC; + rd_osc_src = readl(OSC_SRC_CTRL); + + if (OSC_SRC0 == l3_osc_src) + writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL); + else + writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL); + + pll_config(L3_PLL_BASE, L3_N, L3_M, L3_M2, L3_CLKCTRL, 1); +} + +void ddr_pll_config(unsigned int ddrpll_m) +{ + pll_config(DDR_PLL_BASE, DDR_N, DDR_M, DDR_M2, DDR_CLKCTRL, 1); +} + +void enable_emif_clocks(void) {}; + +void enable_dmm_clocks(void) +{ + writel(PRCM_MOD_EN, &cmdef->fwclkctrl); + writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl); + writel(PRCM_MOD_EN, &cmdef->emif0clkctrl); + while ((readl(&cmdef->emif0clkctrl)) != PRCM_MOD_EN) + ; + writel(PRCM_MOD_EN, &cmdef->emif1clkctrl); + while ((readl(&cmdef->emif1clkctrl)) != PRCM_MOD_EN) + ; + while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300) + ; + writel(PRCM_MOD_EN, &cmdef->dmmclkctrl); + while ((readl(&cmdef->dmmclkctrl)) != PRCM_MOD_EN) + ; + writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl); + while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100) + ; +} + +/* + * Configure the PLL/PRCM for necessary peripherals + */ +void pll_init() +{ + unlock_pll_control_mmr(); + + /* Enable the control module */ + writel(PRCM_MOD_EN, &cmalwon->controlclkctrl); + + mpu_pll_config(); + + l3_pll_config(); + + /* Enable the required peripherals */ + enable_per_clocks(); +} diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c index 448cc40..d1e2fd3 100644 --- a/arch/arm/cpu/armv7/am33xx/ddr.c +++ b/arch/arm/cpu/armv7/am33xx/ddr.c @@ -24,15 +24,20 @@ http://www.ti.com/ /** * Base address for EMIF instances */ -static struct emif_reg_struct *emif_reg = { - (struct emif_reg_struct *)EMIF4_0_CFG_BASE}; +static struct emif_reg_struct *emif_reg[2] = { + (struct emif_reg_struct *)EMIF4_0_CFG_BASE, + (struct emif_reg_struct *)EMIF4_1_CFG_BASE}; /** - * Base address for DDR instance + * Base addresses for DDR PHY cmd/data regs */ -static struct ddr_regs *ddr_reg[2] = { - (struct ddr_regs *)DDR_PHY_BASE_ADDR, - (struct ddr_regs *)DDR_PHY_BASE_ADDR2}; +static struct ddr_cmd_regs *ddr_cmd_reg[2] = { + (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR, + (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2}; + +static struct ddr_data_regs *ddr_data_reg[2] = { + (struct ddr_data_regs *)DDR_PHY_DATA_ADDR, + (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2}; /** * Base address for ddr io control instances @@ -43,7 +48,7 @@ static struct ddr_cmdtctrl *ioctrl_reg = { /** * Configure SDRAM */ -void config_sdram(const struct emif_regs *regs) +void config_sdram(const struct emif_regs *regs, int nr) { if (regs->zq_config) { /* @@ -51,68 +56,85 @@ void config_sdram(const struct emif_regs *regs) * about 570us for a delay, which will be long enough * to configure things. */ - writel(0x2800, &emif_reg->emif_sdram_ref_ctrl); - writel(regs->zq_config, &emif_reg->emif_zq_config); + writel(0x2800, &emif_reg[nr]->emif_sdram_ref_ctrl); + writel(regs->zq_config, &emif_reg[nr]->emif_zq_config); writel(regs->sdram_config, &cstat->secure_emif_sdram_config); + writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); } - writel(regs->sdram_config, &emif_reg->emif_sdram_config); - writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl); - writel(regs->ref_ctrl, &emif_reg->emif_sdram_ref_ctrl_shdw); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); + writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); } /** * Set SDRAM timings */ -void set_sdram_timings(const struct emif_regs *regs) +void set_sdram_timings(const struct emif_regs *regs, int nr) { - writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1); - writel(regs->sdram_tim1, &emif_reg->emif_sdram_tim_1_shdw); - writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2); - writel(regs->sdram_tim2, &emif_reg->emif_sdram_tim_2_shdw); - writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3); - writel(regs->sdram_tim3, &emif_reg->emif_sdram_tim_3_shdw); + writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1); + writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw); + writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2); + writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw); + writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3); + writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw); } /** * Configure DDR PHY */ -void config_ddr_phy(const struct emif_regs *regs) +void config_ddr_phy(const struct emif_regs *regs, int nr) { - writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1); - writel(regs->emif_ddr_phy_ctlr_1, &emif_reg->emif_ddr_phy_ctrl_1_shdw); + writel(regs->emif_ddr_phy_ctlr_1, + &emif_reg[nr]->emif_ddr_phy_ctrl_1); + writel(regs->emif_ddr_phy_ctlr_1, + &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw); } /** * Configure DDR CMD control registers */ -void config_cmd_ctrl(const struct cmd_control *cmd) +void config_cmd_ctrl(const struct cmd_control *cmd, int nr) { - writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio); - writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff); - writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout); + writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio); + writel(cmd->cmd0dldiff, &ddr_cmd_reg[nr]->cm0dldiff); + writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout); - writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio); - writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff); - writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout); + writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio); + writel(cmd->cmd1dldiff, &ddr_cmd_reg[nr]->cm1dldiff); + writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout); - writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio); - writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff); - writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout); + writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio); + writel(cmd->cmd2dldiff, &ddr_cmd_reg[nr]->cm2dldiff); + writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout); } /** * Configure DDR DATA registers */ -void config_ddr_data(int macrono, const struct ddr_data *data) +void config_ddr_data(const struct ddr_data *data, int nr) { - writel(data->datardsratio0, &ddr_reg[macrono]->dt0rdsratio0); - writel(data->datawdsratio0, &ddr_reg[macrono]->dt0wdsratio0); - writel(data->datawiratio0, &ddr_reg[macrono]->dt0wiratio0); - writel(data->datagiratio0, &ddr_reg[macrono]->dt0giratio0); - writel(data->datafwsratio0, &ddr_reg[macrono]->dt0fwsratio0); - writel(data->datawrsratio0, &ddr_reg[macrono]->dt0wrsratio0); - writel(data->datauserank0delay, &ddr_reg[macrono]->dt0rdelays0); - writel(data->datadldiff0, &ddr_reg[macrono]->dt0dldiff0); + int i; + + for (i = 0; i < DDR_DATA_REGS_NR; i++) { + writel(data->datardsratio0, + &(ddr_data_reg[nr]+i)->dt0rdsratio0); + writel(data->datawdsratio0, + &(ddr_data_reg[nr]+i)->dt0wdsratio0); + writel(data->datawiratio0, + &(ddr_data_reg[nr]+i)->dt0wiratio0); + writel(data->datagiratio0, + &(ddr_data_reg[nr]+i)->dt0giratio0); + writel(data->datafwsratio0, + &(ddr_data_reg[nr]+i)->dt0fwsratio0); + writel(data->datawrsratio0, + &(ddr_data_reg[nr]+i)->dt0wrsratio0); + writel(data->datauserank0delay, + &(ddr_data_reg[nr]+i)->dt0rdelays0); + writel(data->datadldiff0, + &(ddr_data_reg[nr]+i)->dt0dldiff0); + } } void config_io_ctrl(unsigned long val) diff --git a/arch/arm/cpu/armv7/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c index 01e3a52..aa84e96 100644 --- a/arch/arm/cpu/armv7/am33xx/emif4.c +++ b/arch/arm/cpu/armv7/am33xx/emif4.c @@ -44,44 +44,65 @@ void dram_init_banksize(void) #ifdef CONFIG_SPL_BUILD -static struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR; +static struct dmm_lisa_map_regs *hw_lisa_map_regs = + (struct dmm_lisa_map_regs *)DMM_BASE; +static struct vtp_reg *vtpreg[2] = { + (struct vtp_reg *)VTP0_CTRL_ADDR, + (struct vtp_reg *)VTP1_CTRL_ADDR}; +#ifdef CONFIG_AM33XX static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR; +#endif + +void config_dmm(const struct dmm_lisa_map_regs *regs) +{ + enable_dmm_clocks(); + + writel(0, &hw_lisa_map_regs->dmm_lisa_map_3); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_2); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_1); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_0); -static void config_vtp(void) + writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3); + writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2); + writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1); + writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0); +} + +static void config_vtp(int nr) { - writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE, - &vtpreg->vtp0ctrlreg); - writel(readl(&vtpreg->vtp0ctrlreg) & (~VTP_CTRL_START_EN), - &vtpreg->vtp0ctrlreg); - writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN, - &vtpreg->vtp0ctrlreg); + writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE, + &vtpreg[nr]->vtp0ctrlreg); + writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN), + &vtpreg[nr]->vtp0ctrlreg); + writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN, + &vtpreg[nr]->vtp0ctrlreg); /* Poll for READY */ - while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) != + while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) != VTP_CTRL_READY) ; } void config_ddr(unsigned int pll, unsigned int ioctrl, const struct ddr_data *data, const struct cmd_control *ctrl, - const struct emif_regs *regs) + const struct emif_regs *regs, int nr) { enable_emif_clocks(); ddr_pll_config(pll); - config_vtp(); - config_cmd_ctrl(ctrl); - - config_ddr_data(0, data); - config_ddr_data(1, data); + config_vtp(nr); + config_cmd_ctrl(ctrl, nr); + config_ddr_data(data, nr); +#ifdef CONFIG_AM33XX config_io_ctrl(ioctrl); /* Set CKE to be controlled by EMIF/DDR PHY */ writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl); +#endif /* Program EMIF instance */ - config_ddr_phy(regs); - set_sdram_timings(regs); - config_sdram(regs); + config_ddr_phy(regs, nr); + set_sdram_timings(regs, nr); + config_sdram(regs, nr); } #endif diff --git a/arch/arm/cpu/armv7/am33xx/mem.c b/arch/arm/cpu/armv7/am33xx/mem.c index b8f54ab..b86b0de 100644 --- a/arch/arm/cpu/armv7/am33xx/mem.c +++ b/arch/arm/cpu/armv7/am33xx/mem.c @@ -83,7 +83,7 @@ void gpmc_init(void) /* global settings */ writel(0x00000008, &gpmc_cfg->sysconfig); writel(0x00000100, &gpmc_cfg->irqstatus); - writel(0x00000200, &gpmc_cfg->irqenable); + writel(0x00000100, &gpmc_cfg->irqenable); writel(0x00000012, &gpmc_cfg->config); /* * Disable the GPMC0 config set by ROM code diff --git a/arch/arm/cpu/armv7/am33xx/sys_info.c b/arch/arm/cpu/armv7/am33xx/sys_info.c index 507b618..5fd8b47 100644 --- a/arch/arm/cpu/armv7/am33xx/sys_info.c +++ b/arch/arm/cpu/armv7/am33xx/sys_info.c @@ -98,6 +98,9 @@ int print_cpuinfo(void) case AM335X: cpu_s = "AM335X"; break; + case TI81XX: + cpu_s = "TI81XX"; + break; default: cpu_s = "Unknown cpu type"; break; @@ -120,7 +123,7 @@ int print_cpuinfo(void) sec_s = "?"; } - printf("AM%s-%s rev %d\n", + printf("%s-%s rev %d\n", cpu_s, sec_s, get_cpu_rev()); /* TODO: Print ARM and DDR frequencies */ diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index 5f6d039..8748c14 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -340,6 +340,9 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop) { } +void arm_init_domains(void) +{ +} #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ #ifndef CONFIG_SYS_ICACHE_OFF diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index d4bce6d..6375a81 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -95,3 +95,48 @@ void set_dp_phy_ctrl(unsigned int enable) if (cpu_is_exynos5()) exynos5_dp_phy_control(enable); } + +static void exynos5_set_ps_hold_ctrl(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* Set PS-Hold high */ + setbits_le32(&power->ps_hold_control, + EXYNOS_PS_HOLD_CONTROL_DATA_HIGH); +} + +void set_ps_hold_ctrl(void) +{ + if (cpu_is_exynos5()) + exynos5_set_ps_hold_ctrl(); +} + + +static void exynos5_set_xclkout(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* use xxti for xclk out */ + clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK, + PMU_DEBUG_XXTI); +} + +void set_xclkout(void) +{ + if (cpu_is_exynos5()) + exynos5_set_xclkout(); +} + +/* Enables hardware tripping to power off the system when TMU fails */ +void set_hw_thermal_trip(void) +{ + if (cpu_is_exynos5()) { + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/ + setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP); + } +} diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 0efc80d..55e82ba 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -36,7 +36,7 @@ COBJS += emif-common.o COBJS += vc.o endif -ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),) COBJS += boot-common.o SOBJS += lowlevel_init.o endif diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 05ff2e8..70d16a8 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -34,6 +34,12 @@ #include <asm/emif.h> #include <asm/omap_common.h> #include <linux/compiler.h> +#include <asm/cache.h> +#include <asm/system.h> + +#define ARMV7_DCACHE_WRITEBACK 0xe +#define ARMV7_DOMAIN_CLIENT 1 +#define ARMV7_DOMAIN_MASK (0x3 << 0) DECLARE_GLOBAL_DATA_PTR; @@ -269,4 +275,33 @@ void enable_caches(void) /* Enable D-cache. I-cache is already enabled in start.S */ dcache_enable(); } + +void dram_bank_mmu_setup(int bank) +{ + bd_t *bd = gd->bd; + int i; + + u32 start = bd->bi_dram[bank].start >> 20; + u32 size = bd->bi_dram[bank].size >> 20; + u32 end = start + size; + + debug("%s: bank: %d\n", __func__, bank); + for (i = start; i < end; i++) + set_section_dcache(i, ARMV7_DCACHE_WRITEBACK); + +} + +void arm_init_domains(void) +{ + u32 reg; + + reg = get_dacr(); + /* + * Set DOMAIN to client access so that all permissions + * set in pagetables are validated by the mmu. + */ + reg &= ~ARMV7_DOMAIN_MASK; + reg |= ARMV7_DOMAIN_CLIENT; + set_dacr(reg); +} #endif diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 3581077..b933fe8 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -26,6 +26,7 @@ * MA 02111-1307 USA */ +#include <config.h> #include <asm/arch/omap.h> #include <asm/arch/spl.h> #include <linux/linkage.h> diff --git a/arch/arm/cpu/armv7/omap-common/timer.c b/arch/arm/cpu/armv7/omap-common/timer.c index 36bea5f..507f687 100644 --- a/arch/arm/cpu/armv7/omap-common/timer.c +++ b/arch/arm/cpu/armv7/omap-common/timer.c @@ -34,6 +34,7 @@ #include <common.h> #include <asm/io.h> +#include <asm/arch/cpu.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index fa5fad1..36a4c3c 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -254,7 +254,6 @@ ENTRY(c_runtime_cpu_setup) #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 /* !Tegra */ @@ -310,6 +309,12 @@ ENTRY(cpu_init_cp15) #endif mcr p15, 0, r0, c1, c0, 0 +#ifdef CONFIG_ARM_ERRATA_716044 + mrc p15, 0, r0, c1, c0, 0 @ read system control register + orr r0, r0, #1 << 11 @ set bit #11 + mcr p15, 0, r0, c1, c0, 0 @ write system control register +#endif + #ifdef CONFIG_ARM_ERRATA_742230 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 4 @ set bit #4 |