diff options
author | Chanho Park <chanho61.park@samsung.com> | 2015-07-02 11:15:10 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2015-07-02 17:54:30 +0900 |
commit | c6a25c0cef7b737ad85ebffe82da90ec51c046c2 (patch) | |
tree | da232ffa7442a6479a17ea0628c793e9b339f07b | |
parent | 190649fb4309d1bc0fe7732fd0f951cb6440f935 (diff) | |
download | u-boot-artik-c6a25c0cef7b737ad85ebffe82da90ec51c046c2.tar.gz u-boot-artik-c6a25c0cef7b737ad85ebffe82da90ec51c046c2.tar.bz2 u-boot-artik-c6a25c0cef7b737ad85ebffe82da90ec51c046c2.zip |
artik5: sync sources from exynos3250
This patch bomb is from exynos3250 sources because we don't have any git
history for that. Instead of maintaining full git history, I just merge
the sources.
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
207 files changed, 61525 insertions, 1033 deletions
@@ -340,7 +340,19 @@ else PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc endif PLATFORM_LIBS += $(PLATFORM_LIBGCC) -export PLATFORM_LIBS +PLATFORM_SPL_LIBS += $(PLATFORM_LIBGCC) +ifeq ($(SOC),exynos) +ifdef CONFIG_SECURE_BOOT +ifneq ($(CONFIG_CPU_EXYNOS5430)$(CONFIG_CPU_EXYNOS5412)$(CONFIG_CPU_EXYNOS5260)$(CONFIG_CPU_EXYNOS4415)$(CONFIG_CPU_EXYNOS3250),) +PLATFORM_LIBS += -L $(CPUDIR)/$(SOC)/ -lsecureboot_u-boot_v24 +else ifeq ($(CONFIG_SMDK5410), y) +PLATFORM_LIBS += -L $(CPUDIR)/$(SOC)/ -lsecureboot_u-boot_v23 +else +PLATFORM_LIBS += -L $(CPUDIR)/$(SOC)/ -lsecureboot_u-boot_v21 +endif +endif +endif +export PLATFORM_SPL_LIBS # Special flags for CPP when processing the linker script. # Pass the version down so we can handle backwards compatibility @@ -488,6 +500,19 @@ endif $(obj)u-boot: depend \ $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds +ifeq ($(SOC),exynos) +ifeq ($(CONFIG_SECURE_BOOT),y) +ifeq ($(CONFIG_CPU_EXYNOS5430), y) + cp $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v24_sss_v6.txt $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v24.a +else ifneq ($(CONFIG_CPU_EXYNOS5412)$(CONFIG_CPU_EXYNOS5260)$(CONFIG_CPU_EXYNOS4415)$(CONFIG_CPU_EXYNOS3250),) + cp $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v24_sss_v5.txt $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v24.a +else ifeq ($(CONFIG_SMDK5410), y) + cp $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v23.txt $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v23.a +else + cp $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v21.txt $(CPUDIR)/$(SOC)/libsecureboot_u-boot_v21.a +endif +endif +endif $(GEN_UBOOT) ifeq ($(CONFIG_KALLSYMS),y) smap=`$(call SYSTEM_MAP,u-boot) | \ @@ -749,7 +774,7 @@ clean: $(obj)tools/gdb/{astest,gdbcont,gdbsend} \ $(obj)tools/gen_eth_addr $(obj)tools/img2srec \ $(obj)tools/mk{env,}image $(obj)tools/mpc86x_clk \ - $(obj)tools/mk{smdk5250,}spl \ + $(obj)tools/mk{smdk5250,smdk5410,smdk4x12,smdk5412,}spl \ $(obj)tools/ncb $(obj)tools/ubsha1 @rm -f $(obj)board/cray/L1/{bootscript.c,bootscript.image} \ $(obj)board/matrix_vision/*/bootscript.img \ diff --git a/arch/arm/cpu/armv7/exynos/Makefile b/arch/arm/cpu/armv7/exynos/Makefile index 9119961d9..18a09a547 100644 --- a/arch/arm/cpu/armv7/exynos/Makefile +++ b/arch/arm/cpu/armv7/exynos/Makefile @@ -22,7 +22,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o -COBJS += clock.o power.o soc.o system.o pinmux.o +COBJS += clock.o power.o soc.o system.o pinmux.o movi_partition.o + +ifdef CONFIG_SECURE_BOOT +COBJS += security_check.o +COBJS += ace_sha.o +endif SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/exynos/ace_sha.c b/arch/arm/cpu/armv7/exynos/ace_sha.c new file mode 100644 index 000000000..9d57315e3 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/ace_sha.c @@ -0,0 +1,354 @@ +/* + * Advanced Crypto Engine - SHA Firmware + * + * Copyright (c) 2010 Samsung Electronics + * + * 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/arch/ace_sfr.h> +#include <asm/arch/ace_sha.h> + + +#if defined(CONFIG_ARCH_EXYNOS) + +/***************************************************************** + Definitions +*****************************************************************/ +#define ACE_read_sfr(_sfr_) \ + (*(volatile unsigned int*)(ACE_SFR_BASE + _sfr_)) +#define ACE_write_sfr(_sfr_, _val_) \ + do {*(volatile unsigned int*)(ACE_SFR_BASE + _sfr_) \ + = (unsigned int)(_val_); } while (0) + + +/* SHA1 value for the message of zero length */ +const unsigned char sha1_digest_emptymsg[20] = { + 0xDA, 0x39, 0xA3, 0xEE, 0x5E, 0x6B, 0x4B, 0x0D, + 0x32, 0x55, 0xBF, 0xFF, 0x95, 0x60, 0x18, 0x90, + 0xAF, 0xD8, 0x07, 0x09}; + +/* SHA256 value for the message of zero length */ +const unsigned char sha256_digest_emptymsg[32] = { + 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, + 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, + 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, + 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55}; + +unsigned int change_endian( + unsigned int input +) +{ + return (unsigned int)(((input & (0x000000ffUL)) << 24) ^ + ((input & (0x0000ff00UL)) << 8) ^ + ((input & (0x00ff0000UL)) >> 8) ^ + ((input & (0xff000000UL)) >> 24)); +} + +int ace_sha_engine( + struct ace_hash_ctx *ctx, + unsigned char *pOut, + const unsigned char *pIn, + size_t dataLen +) +{ + unsigned int reg; + unsigned int *buffer; + unsigned int block_size, digest_size; + int transformmode = 0; + int i = 0; + + block_size = (ctx->alg == ALG_SHA1) ? SHA1_BLOCK_LEN : SHA256_BLOCK_LEN; + digest_size = (ctx->alg == ALG_SHA1) ? SHA1_DIGEST_LEN : SHA256_DIGEST_LEN; + + if (pOut == NULL) { + if (dataLen == 0) + return 0; + else if (dataLen < digest_size) + return -1; + transformmode = 1; + } + + if (dataLen == 0) { + for (i = 0; i < block_size - 8; i++) + ctx->buffer[i] = 0; + ctx->buffer[0] = 0x80; + + reg = change_endian(ctx->prelen_high); + for (i = 0; i < 4; i++) + (ctx->buffer + block_size - 8)[i] = ((unsigned char *)®)[i]; + reg = change_endian(ctx->prelen_low); + for (i = 0; i < 4; i++) + (ctx->buffer + block_size - 4)[i] = ((unsigned char *)®)[i]; + + pIn = ctx->buffer; + + dataLen = block_size; + transformmode = 1; + } + + /* Flush HRDMA */ + ACE_write_sfr(ACE_FC_HRDMAC, ACE_FC_HRDMACFLUSH_ON); + ACE_write_sfr(ACE_FC_HRDMAC, ACE_FC_HRDMACFLUSH_OFF); + + /* Set byte swap of data in */ + ACE_write_sfr(ACE_HASH_BYTESWAP, + ACE_HASH_SWAPDI_ON | ACE_HASH_SWAPDO_ON | ACE_HASH_SWAPIV_ON); + + /* Select Hash input mux as external source */ + reg = ACE_read_sfr(ACE_FC_FIFOCTRL); + reg = (reg & ~ACE_FC_SELHASH_MASK) | ACE_FC_SELHASH_EXOUT; + ACE_write_sfr(ACE_FC_FIFOCTRL, reg); + + /* Set Hash as SHA1 or SHA256 and start Hash engine */ + if (ctx->alg == ALG_SHA1) + reg = ACE_HASH_ENGSEL_SHA1HASH | ACE_HASH_STARTBIT_ON; + else + reg = ACE_HASH_ENGSEL_SHA256HASH | ACE_HASH_STARTBIT_ON; + + /* Set IV */ + if ((ctx->prelen_low | ctx->prelen_high) != 0) { + reg |= ACE_HASH_USERIV_EN; + buffer = (unsigned int *)ctx->state; + ACE_write_sfr(ACE_HASH_IV1, buffer[0]); + ACE_write_sfr(ACE_HASH_IV2, buffer[1]); + ACE_write_sfr(ACE_HASH_IV3, buffer[2]); + ACE_write_sfr(ACE_HASH_IV4, buffer[3]); + ACE_write_sfr(ACE_HASH_IV5, buffer[4]); + + if (ctx->alg == ALG_SHA256) { + ACE_write_sfr(ACE_HASH_IV6, buffer[5]); + ACE_write_sfr(ACE_HASH_IV7, buffer[6]); + ACE_write_sfr(ACE_HASH_IV8, buffer[7]); + } + } else + reg &= ~ACE_HASH_USERIV_EN; + ACE_write_sfr(ACE_HASH_CONTROL, reg); + + /* Enable FIFO mode */ + ACE_write_sfr(ACE_HASH_FIFO_MODE, ACE_HASH_FIFO_ON); + + /* Clean the cache with input region if it's cacheable */ + + if (transformmode) { + /* Set message length */ + ACE_write_sfr(ACE_HASH_MSGSIZE_LOW, 0); + ACE_write_sfr(ACE_HASH_MSGSIZE_HIGH, 0x80000000); + + /* Set pre-message length */ + ACE_write_sfr(ACE_HASH_PRELEN_LOW, 0); + ACE_write_sfr(ACE_HASH_PRELEN_HIGH, 0); + } else { + /* Set message length */ + ACE_write_sfr(ACE_HASH_MSGSIZE_LOW, dataLen); + ACE_write_sfr(ACE_HASH_MSGSIZE_HIGH, 0); + + /* Set pre-message length */ + ACE_write_sfr(ACE_HASH_PRELEN_LOW, ctx->prelen_low); + ACE_write_sfr(ACE_HASH_PRELEN_HIGH, ctx->prelen_high); + } + + /* Set HRDMA */ + ACE_write_sfr(ACE_FC_HRDMAS, (unsigned int)virt_to_phys(pIn)); + ACE_write_sfr(ACE_FC_HRDMAL, dataLen); + + while (!(ACE_read_sfr(ACE_FC_INTPEND) & ACE_FC_HRDMA)) + ; + ACE_write_sfr(ACE_FC_INTPEND, ACE_FC_HRDMA); + + if (transformmode) { + /* Set Pause bit */ + ACE_write_sfr(ACE_HASH_CONTROL2, ACE_HASH_PAUSE_ON); + + while ((ACE_read_sfr(ACE_HASH_STATUS) & + ACE_HASH_PARTIALDONE_MASK) == ACE_HASH_PARTIALDONE_OFF) + ; + + /* Clear PARTIAL_DONE bit */ + ACE_write_sfr(ACE_HASH_STATUS, ACE_HASH_PARTIALDONE_ON); + + if (pOut == NULL) { + /* Update chaining variables */ + buffer = (unsigned int *)ctx->state; + + /* Update pre-message length */ + /* Note that the unit of pre-message length is a BIT! + * */ + ctx->prelen_low += (dataLen << 3); + if (ctx->prelen_low < (dataLen << 3)) + ctx->prelen_high++; + ctx->prelen_high += (dataLen >> 29); + } else { + /* Read hash result */ + buffer = (unsigned int *)pOut; + } + } else { + while ((ACE_read_sfr(ACE_HASH_STATUS) & ACE_HASH_MSGDONE_MASK) + == ACE_HASH_MSGDONE_OFF) + ; + + /* Clear MSG_DONE bit */ + ACE_write_sfr(ACE_HASH_STATUS, ACE_HASH_MSGDONE_ON); + + /* Read hash result */ + buffer = (unsigned int *)pOut; + } + + buffer[0] = ACE_read_sfr(ACE_HASH_RESULT1); + buffer[1] = ACE_read_sfr(ACE_HASH_RESULT2); + buffer[2] = ACE_read_sfr(ACE_HASH_RESULT3); + buffer[3] = ACE_read_sfr(ACE_HASH_RESULT4); + buffer[4] = ACE_read_sfr(ACE_HASH_RESULT5); + + if (ctx->alg == ALG_SHA256) { + buffer[5] = ACE_read_sfr(ACE_HASH_RESULT6); + buffer[6] = ACE_read_sfr(ACE_HASH_RESULT7); + buffer[7] = ACE_read_sfr(ACE_HASH_RESULT8); + } + + return 0; +} + +int ace_hash_sha_init( + struct ace_hash_ctx *ctx, + int alg +) +{ + ctx->alg = alg; + ctx->buflen = 0; + ctx->prelen_high = ctx->prelen_low = 0; + + return 0; +} + +int ace_hash_sha_update( + struct ace_hash_ctx *ctx, + unsigned char *pData, + unsigned int dataLen +) +{ + const unsigned char *src; + size_t partlen, tmplen, block_size; + int ret = 0; + int i; + + partlen = ctx->buflen; + src = pData; + + block_size = (ctx->alg == ALG_SHA1) ? SHA1_BLOCK_LEN : SHA256_BLOCK_LEN; + + if (partlen != 0) { + if (partlen + dataLen < block_size) { + for (i = 0; i < dataLen; i++) + (ctx->buffer + partlen)[i] = src[i]; + + ctx->buflen += dataLen; + return ret; + } else { + tmplen = block_size - partlen; + for (i = 0; i < tmplen; i++) + (ctx->buffer + partlen)[i] = src[i]; + + ret = ace_sha_engine(ctx, NULL, ctx->buffer, block_size); + if (ret) + return ret; + + dataLen -= tmplen; + src += tmplen; + } + } + + partlen = dataLen & (block_size - 1); + dataLen -= partlen; + + if (dataLen > 0) { + ret = ace_sha_engine(ctx, NULL, src, dataLen); + if (ret) + return ret; + } + + for (i = 0; i < partlen; i++) + ctx->buffer[i] = (src + dataLen)[i]; + ctx->buflen = partlen; + + return ret; +} + +int ace_hash_sha_final( + struct ace_hash_ctx *ctx, + unsigned char *pOut +) +{ + return ace_sha_engine(ctx, pOut, ctx->buffer, ctx->buflen); +} + +/***************************************************************** + Functions +*****************************************************************/ +/** + * @brief This function computes hash value of input (pBuf[0]..pBuf[buflen-1]). + * + * @param pOut A pointer to the output buffer. When operation is completed + * 20/32 bytes are copied to pOut[0]...pOut[31]. Thus, a user + * should allocate at least 20/32 bytes at pOut in advance. + * @param pBuf A pointer to the input buffer + * @param bufLen Byte length of input buffer + * + * @return 0 Success + * + * @remark This function assumes that pBuf is a physical address of input buffer. + * + * @version V1.00 + * @b Revision History + * - V01.00 2009.11.13/djpark Initial Version + * - V01.10 2010.10.19/djpark Modification to support C210/V310 + */ +int ace_hash_sha_digest( + unsigned char *pOut, + unsigned char *pBuf, + unsigned int bufLen, + int alg +) +{ + struct ace_hash_ctx ctx; + int ret; + + if (pOut == NULL) + return -1; + + if (bufLen == 0) { + if (alg == ALG_SHA1) + memcpy(pOut, sha1_digest_emptymsg, SHA1_DIGEST_LEN); + else + memcpy(pOut, sha256_digest_emptymsg, + SHA256_DIGEST_LEN); + return 0; + } + + ret = ace_hash_sha_init(&ctx, alg); + if (ret) + return -1; + + ret = ace_sha_engine(&ctx, pOut, pBuf, bufLen); + if (ret) + return -1; + + return 0; +} + +#endif + diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 330bd75da..7d6f149f3 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -49,6 +49,14 @@ static unsigned long exynos4_get_pll_clk(int pllreg) r = readl(&clk->vpll_con0); k = readl(&clk->vpll_con1); break; +#ifdef CONFIG_CPU_EXYNOS3250 + case BPLL: + r = readl(&clk->bpll_con0); + break; + case UPLL: + r = readl(&clk->upll_con0); + break; +#endif default: printf("Unsupported PLL (%d)\n", pllreg); return 0; @@ -83,10 +91,15 @@ static unsigned long exynos4_get_pll_clk(int pllreg) /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */ fout = (m + k / 1024) * (freq / (p * (1 << s))); } else { - if (s < 1) - s = 1; - /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ - fout = m * (freq / (p * (1 << (s - 1)))); + if ((s5p_cpu_id == 0x4415) || (s5p_cpu_id == 0x3250)) { + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV)) */ + fout = m * (freq / (p * (1 << s))); + } else { + if (s < 1) + s = 1; + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ + fout = m * (freq / (p * (1 << (s - 1)))); + } } return fout; @@ -95,10 +108,19 @@ static unsigned long exynos4_get_pll_clk(int pllreg) /* exynos5: return pll clock frequency */ static unsigned long exynos5_get_pll_clk(int pllreg) { +#ifdef CONFIG_CPU_EXYNOS5410 + struct exynos5410_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); +#elif defined(CONFIG_CPU_EXYNOS5412) + struct exynos5412_clock *clk = + (struct exynos5412_clock *)samsung_get_base_clock(); +#else struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); +#endif unsigned long r, m, p, s, k = 0, mask, fout; unsigned int freq; + unsigned int clk_mux_stat_cdrex, mpll_fout_sel; switch (pllreg) { case APLL: @@ -115,6 +137,22 @@ static unsigned long exynos5_get_pll_clk(int pllreg) r = readl(&clk->vpll_con0); k = readl(&clk->vpll_con1); break; +#if defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5412) + case KPLL: + r = readl(&clk->kpll_con0); + break; + case BPLL: + r = readl(&clk->bpll_con0); + break; + case CPLL: + r = readl(&clk->cpll_con0); + break; +#endif +#if defined(CONFIG_CPU_EXYNOS5412) + case SPLL: + r = readl(&clk->spll_con0); + break; +#endif default: printf("Unsupported PLL (%d)\n", pllreg); return 0; @@ -126,7 +164,9 @@ static unsigned long exynos5_get_pll_clk(int pllreg) * EPLL_CON: MIDV [24:16] * VPLL_CON: MIDV [24:16] */ - if (pllreg == APLL || pllreg == MPLL) + if (pllreg == APLL || pllreg == MPLL || + pllreg == KPLL || pllreg == BPLL || + pllreg == CPLL || pllreg == SPLL) mask = 0x3ff; else mask = 0x1ff; @@ -149,12 +189,162 @@ static unsigned long exynos5_get_pll_clk(int pllreg) /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */ fout = (m + k / 1024) * (freq / (p * (1 << s))); } else { +#if defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5412) + s += 1; +#else if (s < 1) s = 1; +#endif /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ fout = m * (freq / (p * (1 << (s - 1)))); + + /* Check mpll_fout_sel status for Rev1.0 */ + if ((pllreg == MPLL) && (s5p_cpu_id == 0x5250) && + (s5p_get_cpu_rev() >= 0x1)) { + clk_mux_stat_cdrex = readl(&clk->mux_stat_cdrex); + + mpll_fout_sel = ( clk_mux_stat_cdrex >> 16 ) && 0x1; + + if(mpll_fout_sel) + fout = fout >> 1; + } + } + + return fout; +} + +static unsigned long exynos5260_get_pll_clk(int pllreg) +{ + struct exynos5260_clock_egl *clk_egl = + (struct exynos5260_clock_egl *)samsung_get_base_clock_egl(); + struct exynos5260_clock_kfc *clk_kfc = + (struct exynos5260_clock_kfc *)samsung_get_base_clock_kfc(); + struct exynos5260_clock_mif *clk_mif = + (struct exynos5260_clock_mif *)samsung_get_base_clock_mif(); + unsigned long r, m, p, s, k = 0, mask, fout; + unsigned int pll_ratio = 0; + unsigned int freq; + + switch (pllreg) { + case EGL_PLL: + r = readl(&clk_egl->egl_pll_con0); + break; + case EGL_DPLL: + r = readl(&clk_egl->egl_dpll_con0); + break; + case KFC_PLL: + r = readl(&clk_kfc->kfc_pll_con0); + break; + case MEM_PLL: + r = readl(&clk_mif->mem_pll_con0); + pll_ratio = (readl(&clk_mif->clk_div_mif) >> 4) & 0x7; + break; + case BUS_PLL: + r = readl(&clk_mif->bus_pll_con0); + pll_ratio = (readl(&clk_mif->clk_div_mif) >> 8) & 0x7; + break; + case MEDIA_PLL: + r = readl(&clk_mif->media_pll_con0); + pll_ratio = readl(&clk_mif->clk_div_mif) & 0x7; + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; } + /* + * PLL_CON: MIDV [25:16] + */ + mask = 0x3ff; + m = (r >> 9) & mask; + + /* PDIV [13:8] */ + p = (r >> 3) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + freq = CONFIG_SYS_CLK_FREQ; + + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV)) */ + fout = m * (freq / (p * (1 << s))); + fout = fout / ((unsigned long)pll_ratio + 1); + + return fout; +} + +static unsigned long exynos5430_get_pll_clk(int pllreg) +{ + struct exynos5430_clock_egl *clk_egl = + (struct exynos5430_clock_egl *)exynos5430_get_base_clock_egl(); + struct exynos5430_clock_kfc *clk_kfc = + (struct exynos5430_clock_kfc *)exynos5430_get_base_clock_kfc(); + struct exynos5430_clock_mif *clk_mif = + (struct exynos5430_clock_mif *)exynos5430_get_base_clock_mif(); + struct exynos5430_clock_top *clk_top = + (struct exynos5430_clock_top *)exynos5430_get_base_clock_top(); + struct exynos5430_clock_cpif *clk_cpif = + (struct exynos5430_clock_cpif *) + exynos5430_get_base_clock_cpif(); + unsigned long r, m, p, s, k = 0, mask, fout; + unsigned int pll_ratio = 0; + unsigned int bus_pll_sub_sel = 0; + unsigned int freq; + + switch (pllreg) { + case EGL_PLL: + r = readl(&clk_egl->egl_pll_con0); + break; + case EGL_DPLL: + r = readl(&clk_egl->egl_dpll_con0); + break; + case KFC_PLL: + r = readl(&clk_kfc->kfc_pll_con0); + break; + case MEM_PLL: + r = readl(&clk_mif->mem_pll_con0); + pll_ratio = (readl(&clk_mif->clk_div_mif0) >> 4) & 0x3; + break; + case BUS_PLL: + bus_pll_sub_sel = readl(&clk_mif->clk_mux_sel_mif1); + if (bus_pll_sub_sel & 0x1) { + r = readl(&clk_mif->bus_pll_con0); + pll_ratio = readl(&clk_mif->clk_div_mif0) & 0x3; + } else { + r = readl(&clk_mif->bus_dpll_con0); + } + break; + case MFC_PLL: + r = readl(&clk_mif->mfc_pll_con0); + pll_ratio = (readl(&clk_mif->clk_div_mif0) >> 8) & 0x3; + break; + case ISP_PLL: + r = readl(&clk_top->isp_pll_con0); + break; + case MPHY_PLL: + r = readl(&clk_cpif->mphy_pll_con0); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * PLL_CON: MIDV [25:16] + */ + mask = 0x3ff; + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + freq = CONFIG_SYS_CLK_FREQ; + + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV)) */ + fout = m * (freq / (p * (1 << s))); + fout = fout / ((unsigned long)pll_ratio + 1); + return fout; } @@ -202,6 +392,50 @@ static unsigned long exynos5_get_arm_clk(void) return armclk; } +/* exynos5260: return ARM clock frequency */ +static unsigned long exynos5260_get_arm_clk(void) +{ + struct exynos5260_clock_egl *clk = + (struct exynos5260_clock_egl *)samsung_get_base_clock_egl(); + unsigned long div; + unsigned long armclk; + unsigned int egl1_ratio; + unsigned int egl2_ratio; + + div = readl(&clk->clk_div_egl); + + /* EGL1_RATIO: [2:0], EGL2_RATIO: [6:4] */ + egl1_ratio = (div >> 0) & 0x7; + egl2_ratio = (div >> 4) & 0x7; + + armclk = get_pll_clk(APLL) / (egl1_ratio + 1); + armclk /= (egl2_ratio + 1); + + return armclk; +} + +/* exynos5430: return ARM clock frequency */ +static unsigned long exynos5430_get_arm_clk(void) +{ + struct exynos5430_clock_egl *clk = + (struct exynos5430_clock_egl *)exynos5430_get_base_clock_egl(); + unsigned long div; + unsigned long armclk; + unsigned int egl1_ratio; + unsigned int egl2_ratio; + + div = readl(&clk->clk_div_egl0); + + /* EGL1_RATIO: [2:0], EGL2_RATIO: [6:4] */ + egl1_ratio = (div >> 0) & 0x7; + egl2_ratio = (div >> 4) & 0x7; + + armclk = get_pll_clk(APLL) / (unsigned long)(egl1_ratio + 1); + armclk /= (unsigned long)(egl2_ratio + 1); + + return armclk; +} + /* exynos4: return pwm clock frequency */ static unsigned long exynos4_get_pwm_clk(void) { @@ -211,6 +445,11 @@ static unsigned long exynos4_get_pwm_clk(void) unsigned int sel; unsigned int ratio; + if (s5p_cpu_id == 0x4415) + return 100000000; + else if (s5p_cpu_id == 0x3250) + return 50000000; + if (s5p_get_cpu_rev() == 0) { /* * CLK_SRC_PERIL0 @@ -234,7 +473,7 @@ static unsigned long exynos4_get_pwm_clk(void) */ ratio = readl(&clk->div_peril3); ratio = ratio & 0xf; - } else if (s5p_get_cpu_rev() == 1) { + } else if (s5p_get_cpu_rev() >= 1) { sclk = get_pll_clk(MPLL); ratio = 8; } else @@ -250,18 +489,63 @@ static unsigned long exynos5_get_pwm_clk(void) { struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); - unsigned long pclk, sclk; + unsigned long pclk, div_aclk_pre, div_aclk; unsigned int ratio; /* * CLK_DIV_PERIC3 * PWM_RATIO [3:0] */ - ratio = readl(&clk->div_peric3); - ratio = ratio & 0xf; - sclk = get_pll_clk(MPLL); + div_aclk_pre = readl(&clk->div_top1); + div_aclk_pre = (div_aclk_pre >> 24)& 0x7; - pclk = sclk / (ratio + 1); + div_aclk = readl(&clk->div_top0); + div_aclk = div_aclk& 0x7; + + pclk = (get_pll_clk(MPLL) / (div_aclk_pre + 1)) / (div_aclk +1); + + return pclk; +} + +/* exynos5260: return pwm clock frequency */ +static unsigned long exynos5260_get_pwm_clk(void) +{ + struct exynos5260_clock_top *clk = + (struct exynos5260_clock_top *)samsung_get_base_clock_top(); + unsigned long pclk; + unsigned int aclk_peri_66_ratio; + + /* + * CLK_DIV_TOP_PERI2[23:20] + * ACLK_PERI_66_RATIO + */ + aclk_peri_66_ratio = readl(&clk->clk_div_top_peri2); + aclk_peri_66_ratio = (aclk_peri_66_ratio >> 20)& 0xf; + + pclk = get_pll_clk(BUS_PLL) / (aclk_peri_66_ratio + 1); + + return pclk; +} + +/* exynos5430: return pwm clock frequency */ +static unsigned long exynos5430_get_pwm_clk(void) +{ + struct exynos5430_clock_top *clk = + (struct exynos5430_clock_top *)exynos5430_get_base_clock_top(); + unsigned long pclk; + unsigned int clk_div_top3; + unsigned int aclk_peri_66_ratio_a, aclk_peri_66_ratio_b; + + /* + * CLK_DIV_TOP3 + * ACLK_PERI_66_RATIO_A[10:8], ACLK_PERI_66_RATIO_B[14:12] + */ + clk_div_top3 = readl(&clk->clk_div_top3); + aclk_peri_66_ratio_a = ((clk_div_top3 >> 8) & 0x7) + 1; + aclk_peri_66_ratio_b = ((clk_div_top3 >> 12) & 0x7) + 1; + + pclk = get_pll_clk(BUS_PLL) / (unsigned long)aclk_peri_66_ratio_a; + pclk = pclk / (unsigned long)aclk_peri_66_ratio_b; return pclk; } @@ -274,6 +558,7 @@ static unsigned long exynos4_get_uart_clk(int dev_index) unsigned long uclk, sclk; unsigned int sel; unsigned int ratio; + unsigned int mpll_ratio_pre; /* * CLK_SRC_PERIL0 @@ -287,12 +572,18 @@ static unsigned long exynos4_get_uart_clk(int dev_index) sel = readl(&clk->src_peril0); sel = (sel >> (dev_index << 2)) & 0xf; - if (sel == 0x6) + if (sel == 0x6) { sclk = get_pll_clk(MPLL); - else if (sel == 0x7) +#ifdef CONFIG_CPU_EXYNOS3250 + mpll_ratio_pre = (readl(&clk->div_top) >> 28) && 0x3; + sclk = sclk / MPLL_PRE_DIV / (mpll_ratio_pre + 1); +#endif + } else if (sel == 0x7) sclk = get_pll_clk(EPLL); else if (sel == 0x8) sclk = get_pll_clk(VPLL); + else if ((sel == 0x0) ||(sel == 0x1)) + sclk = CONFIG_SYS_CLK_FREQ; else return 0; @@ -332,17 +623,31 @@ static unsigned long exynos5_get_uart_clk(int dev_index) * UART5_SEL [23:20] */ sel = readl(&clk->src_peric0); +#if defined(CONFIG_CPU_EXYNOS5412) + sel = (sel >> ((dev_index + 1) << 2)) & 0xf; +#else sel = (sel >> (dev_index << 2)) & 0xf; +#endif +#if defined(CONFIG_CPU_EXYNOS5412) + if (sel == 0x3) + sclk = get_pll_clk(MPLL); + else if (sel == 0x6) + sclk = get_pll_clk(EPLL); + else + return 0; +#else if (sel == 0x6) sclk = get_pll_clk(MPLL); else if (sel == 0x7) sclk = get_pll_clk(EPLL); else if (sel == 0x8) sclk = get_pll_clk(VPLL); + else if (sel == 0x9) + sclk = get_pll_clk(CPLL); else return 0; - +#endif /* * CLK_DIV_PERIC0 * UART0_RATIO [3:0] @@ -353,13 +658,196 @@ static unsigned long exynos5_get_uart_clk(int dev_index) * UART5_RATIO [23:20] */ ratio = readl(&clk->div_peric0); +#if defined(CONFIG_CPU_EXYNOS5412) + ratio = (ratio >> ((dev_index + 2) << 2)) & 0xf; +#else ratio = (ratio >> (dev_index << 2)) & 0xf; +#endif + + uclk = sclk / (ratio + 1); + + return uclk; +} + +/* exynos5260: return uart clock frequency */ +static unsigned long exynos5260_get_uart_clk(int dev_index) +{ + struct exynos5260_clock_top *clk = + (struct exynos5260_clock_top *)samsung_get_base_clock_top(); + unsigned long uclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_MUX_SEL_TOP_PERI1 + * - UART0_SEL [20], UART1_SEL [12], UART2_SEL [16] + * + * CLK_DIV_TOP_PERI1 + * - UART0_RATIO [27:24], UART1_RATIO [19:16], UART2_RATIO [23:20] + */ + sel = readl(&clk->clk_mux_sel_top_peri1); + ratio = readl(&clk->clk_div_top_peri1); + + switch (dev_index) { + case 0: + sel = (sel >> 20) & 0xf; + ratio = (ratio >> 24) & 0xf; + break; + case 1: + ratio = (ratio >> 16) & 0xf; + sel = (sel >> 16) & 0xf; + break; + case 2: + sel = (sel >> 12) & 0xf; + ratio = (ratio >> 20) & 0xf; + break; + } + + if (sel) { + sclk = get_pll_clk(BUS_PLL); + } else { + sclk = CONFIG_SYS_CLK_FREQ; + return 0; + } uclk = sclk / (ratio + 1); return uclk; } +/* exynos5430: return uart clock frequency */ +static unsigned long exynos5430_get_uart_clk(int dev_index) +{ + struct exynos5430_clock_top *clk = + (struct exynos5430_clock_top *)exynos5430_get_base_clock_top(); + unsigned long uclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_MUX_SEL_TOP_PERI1 + * - UART0_SEL [20], UART1_SEL [12], UART2_SEL [16] + * + * CLK_DIV_TOP_PERI1 + * - UART0_RATIO [27:24], UART1_RATIO [19:16], UART2_RATIO [23:20] + */ + sel = readl(&clk->clk_mux_sel_top_peric0); + ratio = readl(&clk->clk_div_top_peric2); + + switch (dev_index) { + case 0: + sel = (sel >> 12) & 0x1; + ratio = (ratio >> 0) & 0xf; + break; + case 1: + sel = (sel >> 16) & 0x1; + ratio = (ratio >> 4) & 0xf; + break; + case 2: + sel = (sel >> 20) & 0x1; + ratio = (ratio >> 8) & 0xf; + break; + } + + if (sel) { + sclk = get_pll_clk(BUS_PLL); + } else { + sclk = CONFIG_SYS_CLK_FREQ; + } + + uclk = sclk / (ratio + 1); + + return uclk; +} + +/* exynos4: get the usbdrd clock */ +static unsigned int exynos4_get_usbdrd_clk(void) +{ + /* TODO */ + return 0; +} + +/* exynos5: get the usbdrd clock */ +#if defined(CONFIG_CPU_EXYNOS5260) +static unsigned long exynos5_get_usbdrd_clk(void) +{ + struct exynos5260_clock_top *clk = + (struct exynos5260_clock_top *)samsung_get_base_clock_top(); + unsigned int addr; + unsigned int ratio; + unsigned long sclk; + + sclk = 24000000; + + /* + * CLK_DIV_TOP_FSYS0 + * SCLK_FSYS_USBDRD30_SUSPEND_CLK_RATIO[7:4] + */ + addr = (unsigned int)&clk->clk_div_top_fsys0; + ratio = readl(addr); + + ratio = (ratio >> 4) & 0xff; + + return (sclk / (ratio + 1)); +} +#else +static unsigned long exynos5_get_usbdrd_clk(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int addr; + unsigned int sel; + unsigned int ratio; + unsigned long sclk; + + sel = readl(&clk->src_fsys); + sel = (sel >> 28) & 0xf; + +#if defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5412) + sclk = 24000000; +#else + if (sel == 0x0) + sclk = get_pll_clk(MPLL); + else { + printf("Can't get SCLK_CPLL\n"); + return 0; + } +#endif + + /* + * CLK_DIV_FSYS0 + * USBDRD30_RATIO[27:24], SATA_RATIO[23:20] + */ + addr = (unsigned int)&clk->div_fsys0; + ratio = readl(addr); + + ratio = (ratio >> 24) & 0xff; + + return (sclk / (ratio + 1)); +} +#endif +static unsigned long exynos5430_get_usbdrd_clk(void) +{ + struct exynos5430_clock_top *clk = + (struct exynos5430_clock_top *)exynos5430_get_base_clock_top(); + unsigned int addr; + unsigned int ratio; + unsigned long sclk; + + sclk = CONFIG_SYS_CLK_FREQ; + + /* + * CLK_DIV_TOP_FSYS2 + * SCLK_USBDRD30_RATIO[3:0] + */ + addr = (unsigned int)&clk->clk_div_top_fsys2; + ratio = readl(addr); + + ratio = ratio & 0xff; + + return (sclk / (ratio + 1)); +} + /* exynos4: set the mmc clock */ static void exynos4_set_mmc_clk(int dev_index, unsigned int div) { @@ -371,18 +859,29 @@ static void exynos4_set_mmc_clk(int dev_index, unsigned int div) /* * CLK_DIV_FSYS1 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] + * MMC0_RATIO [3:0], MMC1_RATIO [16:19] * CLK_DIV_FSYS2 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] + * MMC2_RATIO [3:0], MMC3_RATIO [16:19] + * CLK_DIV_FSYS3 + * MMC4_PRE_RATIO [15:8] + * MMC4_RATIO [3:0] */ if (dev_index < 2) { addr = (unsigned int)&clk->div_fsys1; - } else { + } else if (2 <= dev_index && dev_index < 4) { addr = (unsigned int)&clk->div_fsys2; dev_index -= 2; + } else { + addr = (unsigned int)&clk->div_fsys3; + dev_index = 0; } val = readl(addr); + /* clear MMCx_PRE_RATIO */ val &= ~(0xff << ((dev_index << 4) + 8)); + /* clear MMCx_RATIO */ + val &= ~(0xff << (dev_index << 4)); val |= (div & 0xff) << ((dev_index << 4) + 8); writel(val, addr); } @@ -398,20 +897,359 @@ static void exynos5_set_mmc_clk(int dev_index, unsigned int div) /* * CLK_DIV_FSYS1 * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] + * MMC0_RATIO [3:0], MMC1_RATIO [16:19] * CLK_DIV_FSYS2 * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] + * MMC2_RATIO [3:0], MMC3_RATIO [16:19] */ +#if defined(CONFIG_CPU_EXYNOS5412) + addr = (unsigned int)&clk->div_fsys1; +#else if (dev_index < 2) { addr = (unsigned int)&clk->div_fsys1; } else { addr = (unsigned int)&clk->div_fsys2; dev_index -= 2; } +#endif +#if defined(CONFIG_CPU_EXYNOS5412) val = readl(addr); + if (dev_index == 0) { + val &= ~(0x3ff); + val |= (div & 0x3ff); + } else { + val &= ~(((0x3ff) << dev_index * 10)); + val |= ((div & 0x3ff) << (dev_index * 10)); + } + writel(val, addr); +#else + val = readl(addr); + /* clear MMCx_PRE_RATIO */ val &= ~(0xff << ((dev_index << 4) + 8)); + /* clear MMCx_RATIO */ + val &= ~(0xff << (dev_index << 4)); val |= (div & 0xff) << ((dev_index << 4) + 8); writel(val, addr); +#endif +} + +/* exynos5260: set the mmc clock */ +static void exynos5260_set_mmc_clk(int dev_index, unsigned int div) +{ + struct exynos5260_clock_top *clk = + (struct exynos5260_clock_top *)samsung_get_base_clock_top(); + unsigned int addr; + unsigned int ratio; + + /* + * CLK_DIV_TOP_FSYS0 + * SCLK_FSYS_MMC0_SDCLKIN_B_RATIO[23:16] + * SCLK_FSYS_MMC0_SDCLKIN_A_RATIO[15:12] + * CLK_DIV_TOP_FSYS1 + * SCLK_FSYS_MMC2_SDCLKIN_B_RATIO[23:16] + * SCLK_FSYS_MMC2_SDCLKIN_A_RATIO[15:12] + * SCLK_FSYS_MMC1_SDCLKIN_B_RATIO[11:4] + * SCLK_FSYS_MMC1_SDCLKIN_A_RATIO[3:0] + */ + if (dev_index == 0) { + addr = (unsigned int)&clk->clk_div_top_fsys0; + ratio = readl(addr); + /* set SCLK_FSYS_MMC0_SDCLKIN_A_RATIO for div_1 */ + ratio &= ~(0xf << 12); + /* set SCLK_FSYS_MMC0_SDCLKIN_B_RATIO */ + ratio &= ~(0xff << 16); + ratio |= ((div & 0xff) << 16); + } else { + addr = (unsigned int)&clk->clk_div_top_fsys1; + ratio = readl(addr); + /* set SCLK_FSYS_MMCx_SDCLKIN_A_RATIO for div_1 */ + ratio &= ~(0xf << ((dev_index - 1) * 12)); + /* get SCLK_FSYS_MMCx_SDCLKIN_B_RATIO */ + ratio &= ~(0xff << (((dev_index - 1) * 12) + 4)); + ratio |= ((div & 0xff) << (((dev_index - 1) * 12) + 4)); + } + + writel(ratio, addr); +} + +/* exynos5430: set the mmc clock */ +static void exynos5430_set_mmc_clk(int dev_index, unsigned int div) +{ + struct exynos5430_clock_top *clk = + (struct exynos5430_clock_top *)exynos5430_get_base_clock_top(); + unsigned int ratio, addr; + + /* + * CLK_DIV_TOP_FSYS0 + * SCLK_MMC1_B_RATIO[23:16], SCLK_MMC1_A_RATIO[15:12] + * SCLK_MMC0_B_RATIO[11:4], SCLK_MMC0_A_RATIO[3:0] + * CLK_DIV_TOP_FSYS1 + * SCLK_MMC2_B_RATIO[11:4], SCLK_MMC2_A_RATIO[3:0] + */ + if (dev_index < 2) { + addr = (unsigned int)&clk->clk_div_top_fsys0; + ratio = readl(addr); + /* clear SCLK_MMCx_A_RATIO */ + ratio &= ~(0xf << (dev_index * 12)); + /* clear SCLK_MMCx_B_RATIO */ + ratio &= ~(0xff << ((dev_index * 12) + 4)); + /* set SCLK_MMCx_B_RATIO */ + ratio |= ((div & 0xff) << ((dev_index * 12) + 4)); + } else { + addr = (unsigned int)&clk->clk_div_top_fsys1; + ratio = readl(addr); + /* clear SCLK_MMCx_A_RATIO */ + ratio &= ~(0xf); + /* clear SCLK_MMCx_B_RATIO */ + ratio &= ~(0xff << 4); + /* set SCLK_MMCx_B_RATIO */ + ratio |= ((div & 0xff) << 4); + } + + writel(ratio, addr); +} + +/* exynos4: get the mmc clock */ +static unsigned int exynos4_get_mmc_clk(int dev_index) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned int addr; + unsigned int sel; + unsigned int pre_ratio, ratio; + unsigned long sclk; + unsigned int mpll_ratio_pre; + + sel = readl(&clk->src_fsys); + sel = (sel >> (dev_index << 2)) & 0xf; + + if (sel == 0x6) { + sclk = get_pll_clk(MPLL); +#ifdef CONFIG_CPU_EXYNOS3250 + mpll_ratio_pre = (readl(&clk->div_top) >> 28) && 0x3; + sclk = sclk / MPLL_PRE_DIV / (mpll_ratio_pre + 1); +#endif + } else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + /* + * CLK_DIV_FSYS1 + * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] + * MMC0_RATIO [3:0], MMC1_RATIO [16:19] + * CLK_DIV_FSYS2 + * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] + * MMC2_RATIO [3:0], MMC3_RATIO [16:19] + * CLK_DIV_FSYS3 + * MMC4_PRE_RATIO [15:8] + * MMC4_RATIO [3:0] + */ + if (dev_index < 2) { + addr = (unsigned int)&clk->div_fsys1; + } else if (2 <= dev_index && dev_index < 4) { + addr = (unsigned int)&clk->div_fsys2; + dev_index -= 2; + } else { + addr = (unsigned int)&clk->div_fsys3; + dev_index = 0; + } + + ratio = readl(addr); + /* get MMCx_PRE_RATIO */ + pre_ratio = (ratio >> ((dev_index << 4) + 8)) & 0xff; + /* get MMCx_RATIO */ + ratio = (ratio >> (dev_index << 4)) & 0xff; + + return (sclk / (pre_ratio + 1)) / (ratio + 1); +} + +/* exynos5: get the mmc clock */ +static unsigned long exynos5_get_mmc_clk(int dev_index) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int addr; + unsigned int sel; + unsigned int pre_ratio, ratio; + unsigned long sclk; + + sel = readl(&clk->src_fsys); +#if defined(CONFIG_CPU_EXYNOS5412) + sel = (sel >> ((dev_index + 2) << 2)) & 0xf; +#else + sel = (sel >> (dev_index << 2)) & 0xf; +#endif + +#if defined(CONFIG_CPU_EXYNOS5412) + if (sel == 0x3) + sclk = get_pll_clk(MPLL); + else if (sel == 0x4) + sclk = get_pll_clk(SPLL); + else if (sel == 0x6) + sclk = get_pll_clk(EPLL); + else + return 0; +#else + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; +#endif + + /* + * CLK_DIV_FSYS1 + * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] + * MMC0_RATIO [3:0], MMC1_RATIO [16:19] + * CLK_DIV_FSYS2 + * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] + * MMC2_RATIO [3:0], MMC3_RATIO [16:19] + */ +#if defined(CONFIG_CPU_EXYNOS5412) + addr = (unsigned int)&clk->div_fsys1; +#else + if (dev_index < 2) { + addr = (unsigned int)&clk->div_fsys1; + } else { + addr = (unsigned int)&clk->div_fsys2; + dev_index -= 2; + } +#endif + + ratio = readl(addr); +#if defined(CONFIG_CPU_EXYNOS5412) + if (dev_index == 0) + ratio = ratio & 0x3ff; + else + ratio = (ratio >> (dev_index * 10)) & 0x3ff; + + return sclk / (ratio + 1); +#else + /* get MMCx_PRE_RATIO */ + pre_ratio = (ratio >> ((dev_index << 4) + 8)) & 0xff; + /* get MMCx_RATIO */ + ratio = (ratio >> (dev_index << 4)) & 0xff; + + return (sclk / (pre_ratio + 1)) / (ratio + 1); +#endif +} + +/* exynos5260: get the mmc clock */ +static unsigned long exynos5260_get_mmc_clk(int dev_index) +{ + struct exynos5260_clock_top *clk = + (struct exynos5260_clock_top *)samsung_get_base_clock_top(); + unsigned int sel, sel_a, sel_b; + unsigned int ratio, ratio_a, ratio_b; + unsigned long sclk; + + sel = readl(&clk->clk_mux_sel_top_fsys); + sel_b = (sel >> (24 - (dev_index * 8))) & 0x1; + + if (sel_b) { + sclk = get_pll_clk(MEDIA_PLL); + } else { + sel_a = (sel >> (20 - (dev_index * 8))) & 0x1; + if (sel_a) { + sclk = get_pll_clk(BUS_PLL); + } else { + sclk = CONFIG_SYS_CLK_FREQ; + } + } + + /* + * CLK_DIV_TOP_FSYS0 + * SCLK_FSYS_MMC0_SDCLKIN_B_RATIO[23:16] + * SCLK_FSYS_MMC0_SDCLKIN_A_RATIO[15:12] + * CLK_DIV_TOP_FSYS1 + * SCLK_FSYS_MMC2_SDCLKIN_B_RATIO[23:16] + * SCLK_FSYS_MMC2_SDCLKIN_A_RATIO[15:12] + * SCLK_FSYS_MMC1_SDCLKIN_B_RATIO[11:4] + * SCLK_FSYS_MMC1_SDCLKIN_A_RATIO[3:0] + */ + if (dev_index == 0) { + ratio = readl(&clk->clk_div_top_fsys0); + /* get SCLK_FSYS_MMC0_SDCLKIN_A_RATIO */ + ratio_a = (ratio >> 12) & 0xf; + /* get SCLK_FSYS_MMC0_SDCLKIN_B_RATIO */ + ratio_b = (ratio >> 16) & 0xff; + } else { + ratio = readl(&clk->clk_div_top_fsys1); + /* get SCLK_FSYS_MMCx_SDCLKIN_A_RATIO */ + ratio_a = (ratio >> ((dev_index - 1) * 12)) & 0xf; + /* get SCLK_FSYS_MMCx_SDCLKIN_B_RATIO */ + ratio_b = (ratio >> (((dev_index - 1) * 12) + 4)) & 0xff; + } + + return (sclk / (ratio_a + 1)) / (ratio_b + 1); +} + +/* exynos5430: get the mmc clock */ +#define MMC0_SRC_MASK 0x1111 +#define MMCx_SRC_MASK 0x0011 +#define MMC_SRC_ISP_PLL 0x1000 +#define MMC_SRC_MPHY_PLL_USER 0x0100 +#define MMC_SRC_MFC_PLL_USER 0x0010 +#define MMC_SRC_BUS_PLL_USER 0x0001 + +static unsigned long exynos5430_get_mmc_clk(int dev_index) +{ + struct exynos5430_clock_top *clk = + (struct exynos5430_clock_top *)exynos5430_get_base_clock_top(); + unsigned int sel, sel_mmc; + unsigned int ratio, ratio_a, ratio_b; + unsigned long sclk; + + sel = readl(&clk->clk_mux_sel_top_fsys0); + + if (dev_index == 0) { + sel_mmc = sel & MMC0_SRC_MASK; + } else { + sel_mmc = (sel >> (24 - ((2 - dev_index) * 8))) & MMCx_SRC_MASK; + } + + /* get src pll clock */ + if (sel_mmc & MMC_SRC_ISP_PLL) { + sclk = get_pll_clk(ISP_PLL); + } else if(sel_mmc & MMC_SRC_MPHY_PLL_USER) { + sclk = get_pll_clk(MPHY_PLL); + } else if(sel_mmc & MMC_SRC_MFC_PLL_USER) { + sclk = get_pll_clk(MFC_PLL); + } else if(sel_mmc & MMC_SRC_BUS_PLL_USER) { + sclk = get_pll_clk(BUS_PLL); + } else { + sclk = CONFIG_SYS_CLK_FREQ; + } + + /* + * CLK_DIV_TOP_FSYS0 + * SCLK_MMC1_B_RATIO[23:16], SCLK_MMC1_A_RATIO[15:12] + * SCLK_MMC0_B_RATIO[11:4], SCLK_MMC0_A_RATIO[3:0] + * CLK_DIV_TOP_FSYS1 + * SCLK_MMC2_B_RATIO[11:4], SCLK_MMC2_A_RATIO[3:0] + */ + if (dev_index < 2) { + ratio = readl(&clk->clk_div_top_fsys0); + /* get SCLK_MMCx_A_RATIO */ + ratio_a = (ratio >> (dev_index * 12)) & 0xf; + /* get SCLK_MMCx_B_RATIO */ + ratio_b = (ratio >> ((dev_index * 12) + 4)) & 0xff; + } else { + ratio = readl(&clk->clk_div_top_fsys1); + /* get SCLK_MMCx_A_RATIO */ + ratio_a = (ratio >> 0) & 0xf; + /* get SCLK_MMCx_B_RATIO */ + ratio_b = (ratio >> 4) & 0xff; + } + + return (sclk / (ratio_a + 1)) / (ratio_b + 1); } /* get_lcd_clk: return lcd clock frequency */ @@ -431,12 +1269,18 @@ static unsigned long exynos4_get_lcd_clk(void) sel = sel & 0xf; /* - * 0x6: SCLK_MPLL + * 0x6: SCLK_MPLL * 3250 : SCLK_MPLL_PRE_DIV (MPLL/2) * 0x7: SCLK_EPLL * 0x8: SCLK_VPLL */ if (sel == 0x6) + { +#ifdef CONFIG_CPU_EXYNOS3250 + sclk = get_pll_clk(MPLL)/2; +#else sclk = get_pll_clk(MPLL); +#endif + } else if (sel == 0x7) sclk = get_pll_clk(EPLL); else if (sel == 0x8) @@ -514,7 +1358,11 @@ void exynos4_set_lcd_clk(void) * set fimd ratio */ cfg &= ~(0xf); +#ifdef CONFIG_SHIRI_LCD + cfg |= 0xf; +#else cfg |= 0x1; +#endif writel(cfg, &clk->div_lcd0); } @@ -574,50 +1422,110 @@ void exynos4_set_mipi_clk(void) * set mipi ratio */ cfg &= ~(0xf << 16); +#ifdef CONFIG_SHIRI_LCD + cfg |= (0x0 << 16); +#else cfg |= (0x1 << 16); +#endif writel(cfg, &clk->div_lcd0); } unsigned long get_pll_clk(int pllreg) { - if (cpu_is_exynos5()) - return exynos5_get_pll_clk(pllreg); - else + if (cpu_is_exynos5()) { + if (s5p_cpu_id == 0x5260) { + return exynos5260_get_pll_clk(pllreg); + } else if(s5p_cpu_id == 0x5430) { + return exynos5430_get_pll_clk(pllreg); + } else { + return exynos5_get_pll_clk(pllreg); + } + } else return exynos4_get_pll_clk(pllreg); } unsigned long get_arm_clk(void) { - if (cpu_is_exynos5()) - return exynos5_get_arm_clk(); - else + if (cpu_is_exynos5()) { + if (s5p_cpu_id == 0x5260) { + return exynos5260_get_arm_clk(); + } else if(s5p_cpu_id == 0x5430) { + return exynos5430_get_arm_clk(); + } else { + return exynos5_get_arm_clk(); + } + } else return exynos4_get_arm_clk(); } unsigned long get_pwm_clk(void) { - if (cpu_is_exynos5()) - return exynos5_get_pwm_clk(); - else + if (cpu_is_exynos5()) { + if (s5p_cpu_id == 0x5260) { + return exynos5260_get_pwm_clk(); + } else if(s5p_cpu_id == 0x5430) { + return exynos5430_get_pwm_clk(); + } else { + return exynos5_get_pwm_clk(); + } + } else return exynos4_get_pwm_clk(); } unsigned long get_uart_clk(int dev_index) { - if (cpu_is_exynos5()) - return exynos5_get_uart_clk(dev_index); - else + if (cpu_is_exynos5()) { + if (s5p_cpu_id == 0x5260) { + return exynos5260_get_uart_clk(dev_index); + } else if(s5p_cpu_id == 0x5430) { + return exynos5430_get_uart_clk(dev_index); + } else { + return exynos5_get_uart_clk(dev_index); + } + } else return exynos4_get_uart_clk(dev_index); } -void set_mmc_clk(int dev_index, unsigned int div) +unsigned long get_usbdrd_clk(void) { if (cpu_is_exynos5()) - exynos5_set_mmc_clk(dev_index, div); + if(s5p_cpu_id == 0x5430) { + return exynos5430_get_usbdrd_clk(); + } else { + return exynos5_get_usbdrd_clk(); + } else + return exynos4_get_usbdrd_clk(); +} + +void set_mmc_clk(int dev_index, unsigned int div) +{ + if (cpu_is_exynos5()) { + if (s5p_cpu_id == 0x5260) { + exynos5260_set_mmc_clk(dev_index, div); + } else if(s5p_cpu_id == 0x5430) { + exynos5430_set_mmc_clk(dev_index, div); + } else { + exynos5_set_mmc_clk(dev_index, div); + } + } else exynos4_set_mmc_clk(dev_index, div); } +unsigned long get_mmc_clk(int dev_index) +{ + if (cpu_is_exynos5()) { + if (s5p_cpu_id == 0x5260) { + return exynos5260_get_mmc_clk(dev_index); + } else if(s5p_cpu_id == 0x5430) { + return exynos5430_get_mmc_clk(dev_index); + } else { + return exynos5_get_mmc_clk(dev_index); + } + } else + return exynos4_get_mmc_clk(dev_index); +} + unsigned long get_lcd_clk(void) { if (cpu_is_exynos4()) diff --git a/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v21.txt b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v21.txt Binary files differnew file mode 100644 index 000000000..9363b359e --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v21.txt diff --git a/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v23.txt b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v23.txt Binary files differnew file mode 100644 index 000000000..2b370acbd --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v23.txt diff --git a/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v24_sss_v5.txt b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v24_sss_v5.txt Binary files differnew file mode 100644 index 000000000..1c63bac23 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v24_sss_v5.txt diff --git a/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v24_sss_v6.txt b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v24_sss_v6.txt Binary files differnew file mode 100644 index 000000000..c6e39c2c9 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/libsecureboot_u-boot_v24_sss_v6.txt diff --git a/arch/arm/cpu/armv7/exynos/movi_partition.c b/arch/arm/cpu/armv7/exynos/movi_partition.c new file mode 100644 index 000000000..6d1bc00df --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/movi_partition.c @@ -0,0 +1,132 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/movi_partition.h> +#include <asm/arch/cpu.h> + +#ifdef DEBUG_MOVI_PARTITION +#define dbg(x...) printf(x) +#else +#define dbg(x...) do { } while (0) +#endif + +raw_area_t raw_area_control; + +int init_raw_area_table(block_dev_desc_t * dev_desc, int location) +{ + int i; + int part_num = 0; + member_t *image; + + /* init raw_area will be 16MB */ + raw_area_control.start_blk = 16*1024*1024/MOVI_BLKSIZE; + raw_area_control.next_raw_area = 0; + strcpy(raw_area_control.description, "initial raw table"); + + image = raw_area_control.image; + + /* For eMMC partition BLOCK Change*/ + + /* image 0 should be fwbl1 */ + image[part_num].start_blk = location; + image[part_num].used_blk = MOVI_BL1_BLKCNT; + image[part_num].size = PART_SIZE_BL1; + image[part_num].attribute = 0x0; + strcpy(image[part_num].description, "bl1"); + dbg("fwbl1: %d\n", image[part_num].start_blk); + part_num++; + + /* image 1 should be bl2 */ + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_BL1_BLKCNT; + image[part_num].used_blk = MOVI_BL2_BLKCNT; + image[part_num].size = PART_SIZE_BL2; + image[part_num].attribute = 0x1; + strcpy(image[part_num].description, "bl2"); + dbg("bl2: %d\n", image[part_num].start_blk); + part_num++; + + /* image 2 should be u-boot */ + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_BL2_BLKCNT; + image[part_num].used_blk = MOVI_UBOOT_BLKCNT; + image[part_num].size = PART_SIZE_UBOOT; + image[part_num].attribute = 0x2; + strcpy(image[part_num].description, "u-boot"); + dbg("u-boot: %d\n", image[part_num].start_blk); + part_num++; + + /* image 3 should be TrustZone S/W */ + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_UBOOT_BLKCNT; + image[part_num].used_blk = MOVI_TZSW_BLKCNT; + image[part_num].size = PART_SIZE_TZSW; + image[part_num].attribute = 0x3; + strcpy(image[part_num].description, "TrustZone S/W"); + dbg("TrustZone S/W: %d\n", image[part_num].start_blk); + part_num++; + + /* image 4 should be environment */ + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_TZSW_BLKCNT; + image[part_num].used_blk = MOVI_ENV_BLKCNT; + image[part_num].size = CONFIG_ENV_SIZE; + image[part_num].attribute = 0x4; + strcpy(image[part_num].description, "environment"); + dbg("env: %d\n", image[part_num].start_blk); + + + /* For eMMC partition BLOCK Change*/ + if (location == 0) + image[part_num].start_blk = image[part_num].start_blk + 1; + part_num++; + + /* image 5 should be kernel */ + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_ENV_BLKCNT; + image[part_num].used_blk = MOVI_ZIMAGE_BLKCNT; + image[part_num].size = PART_SIZE_KERNEL; + image[part_num].attribute = 0x5; + strcpy(image[part_num].description, "kernel"); + dbg("knl: %d\n", image[part_num].start_blk); + part_num++; + + /* image 6 should be RFS */ + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_ZIMAGE_BLKCNT; + image[part_num].used_blk = MOVI_ROOTFS_BLKCNT; + image[part_num].size = PART_SIZE_ROOTFS; + image[part_num].attribute = 0x6; + strcpy(image[part_num].description, "rfs"); + dbg("rfs: %d\n", image[part_num].start_blk); + part_num++; + +#ifdef CONFIG_CHARGER_LOGO + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_ROOTFS_BLKCNT; + image[part_num].used_blk = MOVI_CHARGER_LOGO_BLKCNT; + image[part_num].size = PART_SIZE_CHARGER_LOGO; + image[part_num].attribute = 0x7; + strcpy(image[part_num].description, "charger"); + dbg("charger: %d\n", image[part_num].start_blk); + part_num++; +#endif +#ifdef CONFIG_BOOT_LOGO + image[part_num].start_blk = image[part_num - 1].start_blk + MOVI_CHARGER_LOGO_BLKCNT; + image[part_num].used_blk = MOVI_BOOT_LOGO_BLKCNT; + image[part_num].size = PART_SIZE_BOOT_LOGO; + image[part_num].attribute = 0x8; + strcpy(image[part_num].description, "bootlogo"); + dbg("bootlogo: %d\n", image[part_num].start_blk); + part_num++; +#endif + for (i = part_num; i < 15; i++) { + raw_area_control.image[i].start_blk = 0; + raw_area_control.image[i].used_blk = 0; + } + return 0; +} + diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index d2b7d2cba..6521670a1 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -26,10 +26,10 @@ #include <asm/arch/pinmux.h> #include <asm/arch/sromc.h> -static void exynos5_uart_config(int peripheral) +static void exynos4_uart_config(int peripheral) { - struct exynos5_gpio_part1 *gpio1 = - (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1(); struct s5p_gpio_bank *bank; int i, start, count; @@ -61,30 +61,316 @@ static void exynos5_uart_config(int peripheral) } } +static void exynos5_uart_config(int peripheral) +{ + struct exynos5412_gpio_part4 *gpio4 = + (struct exynos5412_gpio_part4 *) samsung_get_base_gpio_part4(); + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); + struct exynos5260_gpio_part3 *gpio3 = + (struct exynos5260_gpio_part3 *) samsung_get_base_gpio_part3(); + struct s5p_gpio_bank *bank; + int i, start, count; + + switch (peripheral) { + case PERIPH_ID_UART0: + if(s5p_cpu_id == 0x5412) { + bank = &gpio4->a0; + start = 0; + count = 4; + } else { + bank = &gpio1->a0; + start = 0; + count = 4; + } + break; + case PERIPH_ID_UART1: + if((s5p_cpu_id == 0x5250) && (s5p_get_cpu_rev() >= 0x1)) { + bank = &gpio1->d0; + start = 0; + count = 4; + } else if(s5p_cpu_id == 0x5260) { + bank = &gpio1->a1; + start = 0; + count = 4; + } else if(s5p_cpu_id == 0x5412) { + bank = &gpio4->a0; + start = 4; + count = 4; + } else { + bank = &gpio1->a0; + start = 4; + count = 4; + } + break; + case PERIPH_ID_UART2: + if(s5p_cpu_id == 0x5260) { + bank = &gpio1->a1; + start = 4; + count = 2; + } else if(s5p_cpu_id == 0x5412) { + bank = &gpio4->a1; + start = 0; + count = 4; + } else { + bank = &gpio1->a1; + start = 0; + count = 4; + } + break; + case PERIPH_ID_UART3: + if(s5p_cpu_id == 0x5260) { + bank = &gpio3->z1; + start = 0; + count = 4; + } else if(s5p_cpu_id == 0x5412) { + bank = &gpio4->a1; + start = 4; + count = 2; + } + break; + } + for (i = start; i < start + count; i++) { + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + } +} + +static void exynos5430_uart_config(int peripheral) +{ + struct exynos5430_gpio_peric *gpio_peric = + (struct exynos5430_gpio_peric *) + exynos5430_get_base_gpio_peric(); + struct s5p_gpio_bank *bank; + int i, start, count; + + switch (peripheral) { + case PERIPH_ID_UART0: + bank = &gpio_peric->d0; + start = 0; + count = 4; + break; + case PERIPH_ID_UART1: + bank = &gpio_peric->d1; + start = 0; + count = 4; + break; + case PERIPH_ID_UART2: + bank = &gpio_peric->d1; + start = 4; + count = 2; + break; + } + for (i = start; i < start + count; i++) { + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + } +} + +static int exynos4_mmc_config(int peripheral, int flags) +{ + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *) samsung_get_base_gpio_part2(); + struct s5p_gpio_bank *bank, *bank_ext; + int i, bank_ext_bit; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + bank = &gpio2->k0; + bank_ext = &gpio2->l0; + bank_ext_bit = 0; + break; + case PERIPH_ID_SDMMC1: + bank = &gpio2->k1; + bank_ext = NULL; + break; + case PERIPH_ID_SDMMC2: + bank = &gpio2->k2; + bank_ext = &gpio2->k3; + bank_ext_bit = 3; + break; + case PERIPH_ID_SDMMC3: + bank = &gpio2->k3; + bank_ext = NULL; + break; + } + if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { + debug("SDMMC device %d does not support 8bit mode", + peripheral); + return -1; + } + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = bank_ext_bit; i <= (bank_ext_bit + 3); i++) { + if (peripheral == PERIPH_ID_SDMMC0) + s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x2)); + else + s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3)); + + s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); + } + } + for (i = 0; i < 2; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + for (i = 2; i <= 6; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + return 0; +} + static int exynos5_mmc_config(int peripheral, int flags) { struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); struct s5p_gpio_bank *bank, *bank_ext; - int i; + int i, bank_ext_bit; switch (peripheral) { case PERIPH_ID_SDMMC0: bank = &gpio1->c0; bank_ext = &gpio1->c1; + bank_ext_bit = 0; break; case PERIPH_ID_SDMMC1: - bank = &gpio1->c1; + bank = &gpio1->c2; bank_ext = NULL; break; case PERIPH_ID_SDMMC2: - bank = &gpio1->c2; - bank_ext = &gpio1->c3; + bank = &gpio1->c3; + bank_ext = &gpio1->c4; + bank_ext_bit = 3; break; case PERIPH_ID_SDMMC3: - bank = &gpio1->c3; + bank = &gpio1->c4; + bank_ext = NULL; + break; + } + if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { + debug("SDMMC device %d does not support 8bit mode", + peripheral); + return -1; + } + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = bank_ext_bit; i <= (bank_ext_bit + 3); i++) { + if (peripheral == PERIPH_ID_SDMMC0) + s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x2)); + else + s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3)); + + s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); + } + } + for (i = 0; i < 2; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + for (i = 2; i <= 6; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + return 0; +} + +static int exynos5412_mmc_config(int peripheral, int flags) +{ + struct exynos5412_gpio_part2 *gpio2 = + (struct exynos5412_gpio_part2 *) samsung_get_base_gpio_part2(); + struct s5p_gpio_bank *bank, *bank_data, *bank_ext; + int i, bank_bit, bank_data_bit, bank_ext_bit; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + bank = &gpio2->c0; + bank_data = &gpio2->c0; + bank_ext = &gpio2->c3; + bank_bit = 0; + bank_data_bit = 3; + bank_ext_bit = 0; + break; + case PERIPH_ID_SDMMC1: + bank = &gpio2->c1; + bank_data = &gpio2->c1; + bank_ext = &gpio2->d1; + bank_bit = 0; + bank_data_bit = 3; + bank_ext_bit = 4; + break; + case PERIPH_ID_SDMMC2: + bank = &gpio2->c2; + bank_data = &gpio2->c2; + bank_ext = NULL; + bank_bit = 0; + bank_data_bit = 3; + bank_ext_bit = 0; + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { + debug("SDMMC device %d does not support 8bit mode", + peripheral); + return -1; + } + + s5p_gpio_cfg_pin(bank, 2, GPIO_FUNC(0x1)); + s5p_gpio_set_pull(bank, 2, GPIO_PULL_UP); + s5p_gpio_set_drv(bank, 2, GPIO_DRV_4X); + s5p_gpio_set_value(bank, 2, 1); + + for (i = bank_bit; i < bank_bit + 2; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + for (i = bank_data_bit; i < bank_data_bit + 4; i++) { + s5p_gpio_cfg_pin(bank_data, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank_data, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank_data, i, GPIO_DRV_4X); + } + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = bank_ext_bit; i < bank_ext_bit + 4; i++) { + s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); + } + } + return 0; +} + +static int exynos5260_mmc_config(int peripheral, int flags) +{ + struct exynos5260_gpio_part2 *gpio2 = + (struct exynos5260_gpio_part2 *) samsung_get_base_gpio_part2(); + struct s5p_gpio_bank *bank, *bank_ext; + int i, bank_ext_bit; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + bank = &gpio2->c0; + bank_ext = &gpio2->c3; + bank_ext_bit = 0; + break; + case PERIPH_ID_SDMMC1: + bank = &gpio2->c1; + bank_ext = &gpio2->c4; + bank_ext_bit = 0; + break; + case PERIPH_ID_SDMMC2: + bank = &gpio2->c2; bank_ext = NULL; break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; } if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { debug("SDMMC device %d does not support 8bit mode", @@ -92,8 +378,8 @@ static int exynos5_mmc_config(int peripheral, int flags) return -1; } if (flags & PINMUX_FLAG_8BIT_MODE) { - for (i = 3; i <= 6; i++) { - s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3)); + for (i = bank_ext_bit; i <= (bank_ext_bit + 3); i++) { + s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x2)); s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); } @@ -103,7 +389,7 @@ static int exynos5_mmc_config(int peripheral, int flags) s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); } - for (i = 3; i <= 6; i++) { + for (i = 2; i <= 6; i++) { s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); s5p_gpio_set_pull(bank, i, GPIO_PULL_UP); s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); @@ -111,6 +397,71 @@ static int exynos5_mmc_config(int peripheral, int flags) return 0; } +static int exynos5430_mmc_config(int peripheral, int flags) +{ + struct exynos5430_gpio_fsys *gpio_fsys = + (struct exynos5430_gpio_fsys *) + exynos5430_get_base_gpio_fsys(); + struct s5p_gpio_bank *bank, *bank_data, *bank_ext_data; + int i, bank_bit, bank_bit_cnt; + int bank_data_bit, bank_ext_data_bit; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + bank = &gpio_fsys->r0; + bank_data = &gpio_fsys->r1; + bank_ext_data = &gpio_fsys->r1; + bank_bit = 0; + bank_bit_cnt = 4; + bank_data_bit = 0; + bank_ext_data_bit = 4; + break; + case PERIPH_ID_SDMMC1: + bank = &gpio_fsys->r2; + bank_data = &gpio_fsys->r3; + bank_ext_data = &gpio_fsys->r3; + bank_bit = 0; + bank_bit_cnt = 2; + bank_data_bit = 0; + bank_ext_data_bit = 4; + break; + case PERIPH_ID_SDMMC2: + bank = &gpio_fsys->r4; + bank_data = &gpio_fsys->r4; + bank_ext_data = NULL; + bank_bit = 0; + bank_bit_cnt = 4; + bank_data_bit = 4; + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext_data) { + debug("SDMMC device %d does not support 8bit mode", + peripheral); + return -1; + } + for (i = bank_bit; i < bank_bit_cnt; i++) { + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); + } + for (i = bank_data_bit; i < (bank_data_bit + 4); i++) { + s5p_gpio_cfg_pin(bank_data, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank_data, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank_data, i, GPIO_DRV_4X); + } + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = bank_ext_data_bit; i < (bank_ext_data_bit + 4); i++) { + s5p_gpio_cfg_pin(bank_ext_data, i, GPIO_FUNC(0x2)); + s5p_gpio_set_pull(bank_ext_data, i, GPIO_PULL_UP); + s5p_gpio_set_drv(bank_ext_data, i, GPIO_DRV_4X); + } + } + return 0; +} + static void exynos5_sromc_config(int flags) { struct exynos5_gpio_part1 *gpio1 = @@ -184,6 +535,62 @@ static void exynos5_sromc_config(int flags) } } +static void exynos5_input_config(int peripheral) +{ + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); + struct s5p_gpio_bank *bank; + int i, start = 0, count = 0; + + switch (peripheral) { + case PERIPH_ID_INPUT_X0_0: + bank = &gpio1->x0; + start = 0; + count = 1; + break; + case PERIPH_ID_INPUT_X2_0: + bank = &gpio1->x2; + start = 0; + count = 1; + break; + } + for (i = start; i < start + count; i++) { + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_direction_input(bank, i); + } +} + +static void exynos5430_input_config(int peripheral) +{ + struct exynos5430_gpio_alive *gpio_alive = + (struct exynos5430_gpio_alive *) + exynos5430_get_base_gpio_alive(); + struct s5p_gpio_bank *bank; + int i, start = 0, count = 0; + + switch (peripheral) { + case PERIPH_ID_INPUT_A0_3: + bank = &gpio_alive->a0; + start = 3; + count = 1; + break; + case PERIPH_ID_INPUT_A2_0: + bank = &gpio_alive->a2; + start = 0; + count = 1; + break; + case PERIPH_ID_INPUT_A2_1: + bank = &gpio_alive->a2; + start = 1; + count = 1; + break; + } + for (i = start; i < start + count; i++) { + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_direction_input(bank, i); + } +} + static int exynos5_pinmux_config(int peripheral, int flags) { switch (peripheral) { @@ -191,15 +598,85 @@ static int exynos5_pinmux_config(int peripheral, int flags) case PERIPH_ID_UART1: case PERIPH_ID_UART2: case PERIPH_ID_UART3: - exynos5_uart_config(peripheral); + if (s5p_cpu_id == 0x5430) { + exynos5430_uart_config(peripheral); + } else { + exynos5_uart_config(peripheral); + } break; case PERIPH_ID_SDMMC0: case PERIPH_ID_SDMMC1: case PERIPH_ID_SDMMC2: case PERIPH_ID_SDMMC3: - return exynos5_mmc_config(peripheral, flags); + if (s5p_cpu_id == 0x5430) { + return exynos5430_mmc_config(peripheral, flags); + } else if (s5p_cpu_id == 0x5260) { + return exynos5260_mmc_config(peripheral, flags); + } else if (s5p_cpu_id == 0x5412) { + return exynos5412_mmc_config(peripheral, flags); + } else { + return exynos5_mmc_config(peripheral, flags); + } case PERIPH_ID_SROMC: - exynos5_sromc_config(flags); + if (s5p_cpu_id != 0x5260) { + exynos5_sromc_config(flags); + } + break; + case PERIPH_ID_INPUT_X0_0: + case PERIPH_ID_INPUT_X2_0: + case PERIPH_ID_INPUT_A0_3: + case PERIPH_ID_INPUT_A2_0: + case PERIPH_ID_INPUT_A2_1: + if (s5p_cpu_id == 0x5430) { + exynos5430_input_config(peripheral); + } else { + exynos5_input_config(peripheral); + } + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + +static void exynos4_input_config(int peripheral) +{ + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *) samsung_get_base_gpio_part2(); + struct s5p_gpio_bank *bank; + int i, start = 0, count = 0; + + switch (peripheral) { + case PERIPH_ID_INPUT_X0_0: + bank = &gpio2->x0; + start = 0; + count = 1; + break; + } + for (i = start; i < start + count; i++) { + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); + s5p_gpio_direction_input(bank, i); + } +} + +static int exynos4_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + exynos4_uart_config(peripheral); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC3: + return exynos4_mmc_config(peripheral, flags); + case PERIPH_ID_INPUT_X0_0: + exynos4_input_config(peripheral); break; default: debug("%s: invalid peripheral %d", __func__, peripheral); @@ -213,6 +690,8 @@ int exynos_pinmux_config(int peripheral, int flags) { if (cpu_is_exynos5()) return exynos5_pinmux_config(peripheral, flags); + else if (cpu_is_exynos4()) + return exynos4_pinmux_config(peripheral, flags); else { debug("pinmux functionality not supported\n"); return -1; diff --git a/arch/arm/cpu/armv7/exynos/security_check.c b/arch/arm/cpu/armv7/exynos/security_check.c new file mode 100644 index 000000000..978a5a6d7 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/security_check.c @@ -0,0 +1,50 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/movi_partition.h> + +#include "uboot_sb21.h" + +void security_check(void) +{ + unsigned int secure_context_base; + int ret; + + /* Set Secure Context Base Address*/ + secure_context_base = CONFIG_SYS_SDRAM_BASE + PART_SIZE_BL1 - 1024; + + /* Verify Kernel */ + ret = check_signature((SB20_CONTEXT *)secure_context_base, + (unsigned char *)CONFIG_SECURE_KERNEL_BASE, CONFIG_SECURE_KERNEL_SIZE - 256, + (unsigned char *)(CONFIG_SECURE_KERNEL_BASE + + CONFIG_SECURE_KERNEL_SIZE - 256), 256); + if (ret) { + printf("Kernel Integrity check fail\nSystem Halt...."); + while (1); + } + printf("Kernel Integirty check success.\n"); + +#ifdef CONFIG_SECURE_ROOTFS + /* Verify rootfs */ + ret = check_signature((SB20_CONTEXT *)secure_context_base, + (unsigned char *)CONFIG_SECURE_ROOTFS_BASE, CONFIG_SECURE_ROOTFS_SIZE - 256, + (unsigned char *)(CONFIG_SECURE_ROOTFS_BASE + + CONFIG_SECURE_ROOTFS_SIZE - 256), 256); + if (ret) { + printf("rootfs Integrity check fail\nSystem Halt...."); + while (1); + } + printf("rootfs Integirty check success.\n"); +#endif +} + diff --git a/arch/arm/cpu/armv7/exynos/soc.c b/arch/arm/cpu/armv7/exynos/soc.c index dcfcec22d..d60fd04fd 100644 --- a/arch/arm/cpu/armv7/exynos/soc.c +++ b/arch/arm/cpu/armv7/exynos/soc.c @@ -26,5 +26,8 @@ void reset_cpu(ulong addr) { +#if defined(CONFIG_RAMDUMP_MODE) + writel(0x0, CONFIG_RAMDUMP_SCRATCH); +#endif writel(0x1, samsung_get_base_swreset()); } diff --git a/arch/arm/cpu/armv7/exynos/uboot_sb21.h b/arch/arm/cpu/armv7/exynos/uboot_sb21.h new file mode 100644 index 000000000..841bf74a8 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/uboot_sb21.h @@ -0,0 +1,125 @@ +#ifndef _UBOOT_SB21_H +#define _UBOOT_SB21_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined(CONFIG_CPU_EXYNOS5430) || defined(CONFIG_CPU_EXYNOS5412) || defined(CONFIG_CPU_EXYNOS5260) || defined(CONFIG_CPU_EXYNOS4415) || defined(CONFIG_CPU_EXYNOS3250) +#define CONFIG_SECURE_BOOT_V24 +#elif defined(CONFIG_SMDK5410) +#define CONFIG_SECURE_BOOT_V23 +#else +#define CONFIG_SECURE_BOOT_V20 +#endif + +//////////////////////////////////////////////////////////////////////// +// SecureBoot return value define +#define SB_OK 0x00000000 +#define SB_OFF 0x80000000 + +//------------------------------------------------------------------------ +#define SB_ERROR_VALIDATE_PUBLIC_KEY_INFO 0xFFF10000 +#define SB_ERROR_VERIFY_PSS_RSA_SIGNATURE 0xFFF20000 +#define SB_ERROR_CHECK_INTEGRITY_CODE 0xFFF30000 + +//------------------------------------------------------------------------ +// added for Secure Boot 2.0 +#define SB_ERROR_GENERATE_PSS_RSA_SIGNATURE 0xFFF40000 +#define SB_ERROR_GENERATE_PUBLIC_KEY_INFO 0xFFF50000 +#define SB_ERROR_GENERATE_SB_CONTEXT 0xFFF60000 +#define SB_ERROR_ENCRYPTION 0xFFF70000 + +#define SB_ERROR_AES_PARM 0x0000A000 +#define SB_ERROR_AES_SET_ALGO 0x0000B000 +#define SB_ERROR_AES_ENCRYPT 0x0000C000 +#define SB_ERROR_AES_DECRYPT 0x0000D000 + +//------------------------------------------------------------------------ +#define SB_ERROR_HMAC_SHA1_SET_INFO 0x00000010 +#define SB_ERROR_HMAC_SHA1_INIT 0x00000020 +#define SB_ERROR_HMAC_SHA1_UPDATE 0x00000030 +#define SB_ERROR_HMAC_SHA1_FINAL 0x00000040 +#define SB_ERROR_MEM_CMP 0x00000050 +#define SB_ERROR_SHA1_INIT 0x00000060 +#define SB_ERROR_SHA1_UPDATE 0x00000070 +#define SB_ERROR_SHA1_FINAL 0x00000080 +#define SB_ERROR_VERIFY_RSA_PSS 0x00000090 + +//////////////////////////////////////////////////////////////////////// +//------------------------------------------- +#define SB20_MAX_EFUSE_DATA_LEN 20 + +#define SB_MAX_RSA_KEY (2048/8) +#define SB_MAX_SIGN_LEN SB_MAX_RSA_KEY + +#ifdef CONFIG_SECURE_BOOT_V20 +#define SB20_HMAC_SHA1_LEN 20 +#else +#define SB20_HMAC_SHA1_LEN 32 +#endif + +//------------------------------------------- +typedef struct +{ + int rsa_n_Len; + unsigned char rsa_n[SB_MAX_RSA_KEY]; + int rsa_e_Len; + unsigned char rsa_e[4]; +} SB_RSAPubKey; + +//------------------------------------------- +typedef struct +{ + SB_RSAPubKey rsaPubKey; + unsigned char signedData[SB20_HMAC_SHA1_LEN]; +} SB_PubKeyInfo; + +//------------------------------------------- +typedef struct +{ + SB_RSAPubKey stage2PubKey; + int code_SignedDataLen; + unsigned char code_SignedData[SB_MAX_SIGN_LEN]; + SB_PubKeyInfo pubKeyInfo; + unsigned char func_ptr_BaseAddr[128]; + unsigned char reservedData[80]; +} SB20_CONTEXT; + +typedef struct +{ + unsigned int codesignerversion; + unsigned int ap_info; + unsigned long long time; + unsigned int build_count; + unsigned char description[36]; +} SB24_INFO; + +typedef struct +{ + SB24_INFO context_info; + SB_RSAPubKey stage2PubKey; + unsigned char func_ptr_BaseAddr[128]; + unsigned char reservedData[12]; + SB_PubKeyInfo pubKeyInfo; + int code_SignedDataLen; + unsigned char code_SignedData[SB_MAX_SIGN_LEN]; +} SB24_CONTEXT; + +#if defined(CONFIG_SECURE_BOOT_V24) +#define SB20_CONTEXT SB24_CONTEXT +#endif + +int check_signature( + SB20_CONTEXT *sbContext, + unsigned char *data, + unsigned int dataLen, + unsigned char *signedData, + unsigned int signedDataLen ); + +#ifdef __cplusplus +} +#endif + +#endif /* _UBOOT_SB21_H */ diff --git a/arch/arm/cpu/armv7/s5p-common/cpu_info.c b/arch/arm/cpu/armv7/s5p-common/cpu_info.c index 16427333a..853052cfc 100644 --- a/arch/arm/cpu/armv7/s5p-common/cpu_info.c +++ b/arch/arm/cpu/armv7/s5p-common/cpu_info.c @@ -22,8 +22,12 @@ */ #include <common.h> #include <asm/io.h> +#include <asm/arch/clock.h> #include <asm/arch/clk.h> +/* Each chip has own unique ID */ +unsigned int s5p_chip_id[2] = {0x0, 0x0}; + /* Default is s5pc100 */ unsigned int s5p_cpu_id = 0xC100; /* Default is EVT1 */ @@ -46,11 +50,52 @@ u32 get_device_type(void) #ifdef CONFIG_DISPLAY_CPUINFO int print_cpuinfo(void) { +#if defined(CONFIG_EXYNOS5) || defined(CONFIG_ARCH_EXYNOS5) + unsigned int cpuid; + unsigned int subrev; + + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid)); + subrev = (readl(EXYNOS5_PRO_ID) & 0x0000000F); + + printf("CPU: %s%x Rev%x.%x [Samsung SOC on SMP Platform Base on ARM CortexA%d]\n" \ + , s5p_get_cpu_name(), s5p_cpu_id, s5p_cpu_rev, subrev, ((cpuid >> 4) & 0xf)); + +#if defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5412) + unsigned int apll = get_pll_clk(APLL); + unsigned int kpll = get_pll_clk(KPLL); + unsigned int mpll = get_pll_clk(MPLL); + unsigned int bpll = get_pll_clk(BPLL); + + printf("APLL = %ldMHz, KPLL = %ldMHz\n", apll/1000000, kpll/1000000); + printf("MPLL = %ldMHz, BPLL = %ldMHz\n", mpll/1000000, bpll/1000000); +#elif defined(CONFIG_CPU_EXYNOS5260) || defined(CONFIG_CPU_EXYNOS5430) + if (s5p_cpu_rev != 0) + return 0; + unsigned int egl_pll = get_pll_clk(EGL_PLL); + unsigned int kfc_pll = get_pll_clk(KFC_PLL); + unsigned int mem_pll = get_pll_clk(MEM_PLL); + unsigned int bus_pll = get_pll_clk(BUS_PLL); + + printf("EGL_PLL = %ldMHz, KFC_PLL = %ldMHz\n", + egl_pll/1000000, kfc_pll/1000000); + printf("MEM_PLL = %ldMHz, BUS_PLL = %ldMHz\n", + mem_pll/1000000, bus_pll/1000000); + +#endif +#else char buf[32]; - printf("CPU:\t%s%X@%sMHz\n", + if (s5p_cpu_id == 0x4412 || s5p_cpu_id == 0x4212 || s5p_cpu_id == 0x3250) { + printf("CPU: %s%X [Samsung SOC on SMP Platform Base on ARM CortexA9]\n", + s5p_get_cpu_name(), s5p_cpu_id); + printf("APLL = %ldMHz, MPLL = %ldMHz\n", + get_pll_clk(APLL)/1000000, get_pll_clk(MPLL)/1000000); + } + else + printf("CPU:\t%s%X@%sMHz\n", s5p_get_cpu_name(), s5p_cpu_id, strmhz(buf, get_arm_clk())); +#endif return 0; } diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c index 58d279e00..c796be497 100644 --- a/arch/arm/cpu/armv7/s5p-common/pwm.c +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c @@ -114,9 +114,6 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns) if (tcmp == tcnt) tcmp--; - if (tcmp < 0) - tcmp = 0; - /* Update the PWM register block. */ offset = pwm_id * 3; if (pwm_id < 4) { @@ -167,8 +164,14 @@ int pwm_init(int pwm_id, int div, int invert) val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id); writel(val, &pwm->tcfg1); +#ifdef CONFIG_CPU_EXYNOS5410 + timer_rate_hz = 2500000; +#elif defined(CONFIG_CPU_EXYNOS5412) + timer_rate_hz = 1800000; +#else timer_rate_hz = get_pwm_clk() / ((prescaler + 1) * (div + 1)); +#endif timer_rate_hz = timer_rate_hz / 100; diff --git a/arch/arm/include/asm/arch-exynos/ace_sfr.h b/arch/arm/include/asm/arch-exynos/ace_sfr.h new file mode 100644 index 000000000..0dc819d2b --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/ace_sfr.h @@ -0,0 +1,543 @@ +/* + * Header file for Advanced Crypto Engine - SFR definitions + * + * Copyright (c) 2010 Samsung Electronics + * + * 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 __ACE_SFR_H__ +#define __ACE_SFR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <common.h> + +#if defined(CONFIG_ARCH_EXYNOS) + +#if defined(CONFIG_CPU_EXYNOS5430) +#define SSS_VERSION_6_1 +#else +#define SSS_VERSION_5_1 +#endif + +/***************************************************************** + SFR Addresses +*****************************************************************/ +#if defined(CONFIG_ARCH_EXYNOS) +#if defined(SSS_VERSION_5_1) +#define ACE_SFR_BASE (0x10830000) +#define ACE_FC_OFFSET (0x0) +#define ACE_AES_OFFSET (0x200) +#define ACE_TDES_OFFSET (0x300) +#define ACE_HASH_OFFSET (0x400) +#define ACE_PKA_OFFSET (0x700) +#else +#define ACE_SFR_BASE (0x11100000) +#define ACE_FC_OFFSET (0x0) +#define ACE_AES_OFFSET (0x0400) +#define ACE_TDES_OFFSET (0x0800) +#define ACE_HASH_OFFSET (0x1000) +#define ACE_PKA_OFFSET (0x4000) +#endif +#else +#error No ARCH is defined. +#endif + +/* Feed control registers */ +#define ACE_FC_INTSTAT (ACE_FC_OFFSET + 0x00) +#define ACE_FC_INTENSET (ACE_FC_OFFSET + 0x04) +#define ACE_FC_INTENCLR (ACE_FC_OFFSET + 0x08) +#define ACE_FC_INTPEND (ACE_FC_OFFSET + 0x0C) +#define ACE_FC_FIFOSTAT (ACE_FC_OFFSET + 0x10) +#define ACE_FC_FIFOCTRL (ACE_FC_OFFSET + 0x14) +#define ACE_FC_GLOBAL (ACE_FC_OFFSET + 0x18) +#define ACE_FC_BRDMAS (ACE_FC_OFFSET + 0x20) +#define ACE_FC_BRDMAL (ACE_FC_OFFSET + 0x24) +#define ACE_FC_BRDMAC (ACE_FC_OFFSET + 0x28) +#define ACE_FC_BTDMAS (ACE_FC_OFFSET + 0x30) +#define ACE_FC_BTDMAL (ACE_FC_OFFSET + 0x34) +#define ACE_FC_BTDMAC (ACE_FC_OFFSET + 0x38) +#define ACE_FC_HRDMAS (ACE_FC_OFFSET + 0x40) +#define ACE_FC_HRDMAL (ACE_FC_OFFSET + 0x44) +#define ACE_FC_HRDMAC (ACE_FC_OFFSET + 0x48) +#define ACE_FC_PKDMAS (ACE_FC_OFFSET + 0x50) +#define ACE_FC_PKDMAL (ACE_FC_OFFSET + 0x54) +#define ACE_FC_PKDMAC (ACE_FC_OFFSET + 0x58) +#define ACE_FC_PKDMAO (ACE_FC_OFFSET + 0x5C) + +/* AES control registers */ +#define ACE_AES_CONTROL (ACE_AES_OFFSET + 0x00) +#define ACE_AES_STATUS (ACE_AES_OFFSET + 0x04) + +#define ACE_AES_IN1 (ACE_AES_OFFSET + 0x10) +#define ACE_AES_IN2 (ACE_AES_OFFSET + 0x14) +#define ACE_AES_IN3 (ACE_AES_OFFSET + 0x18) +#define ACE_AES_IN4 (ACE_AES_OFFSET + 0x1C) + +#define ACE_AES_OUT1 (ACE_AES_OFFSET + 0x20) +#define ACE_AES_OUT2 (ACE_AES_OFFSET + 0x24) +#define ACE_AES_OUT3 (ACE_AES_OFFSET + 0x28) +#define ACE_AES_OUT4 (ACE_AES_OFFSET + 0x2C) + +#define ACE_AES_IV1 (ACE_AES_OFFSET + 0x30) +#define ACE_AES_IV2 (ACE_AES_OFFSET + 0x34) +#define ACE_AES_IV3 (ACE_AES_OFFSET + 0x38) +#define ACE_AES_IV4 (ACE_AES_OFFSET + 0x3C) + +#define ACE_AES_CNT1 (ACE_AES_OFFSET + 0x40) +#define ACE_AES_CNT2 (ACE_AES_OFFSET + 0x44) +#define ACE_AES_CNT3 (ACE_AES_OFFSET + 0x48) +#define ACE_AES_CNT4 (ACE_AES_OFFSET + 0x4C) + +#define ACE_AES_KEY1 (ACE_AES_OFFSET + 0x80) +#define ACE_AES_KEY2 (ACE_AES_OFFSET + 0x84) +#define ACE_AES_KEY3 (ACE_AES_OFFSET + 0x88) +#define ACE_AES_KEY4 (ACE_AES_OFFSET + 0x8C) +#define ACE_AES_KEY5 (ACE_AES_OFFSET + 0x90) +#define ACE_AES_KEY6 (ACE_AES_OFFSET + 0x94) +#define ACE_AES_KEY7 (ACE_AES_OFFSET + 0x98) +#define ACE_AES_KEY8 (ACE_AES_OFFSET + 0x9C) + +/* TDES control registers */ +#define ACE_TDES_CONTROL (ACE_TDES_OFFSET + 0x00) +#define ACE_TDES_STATUS (ACE_TDES_OFFSET + 0x04) + +#define ACE_TDES_KEY11 (ACE_TDES_OFFSET + 0x10) +#define ACE_TDES_KEY12 (ACE_TDES_OFFSET + 0x14) +#define ACE_TDES_KEY21 (ACE_TDES_OFFSET + 0x18) +#define ACE_TDES_KEY22 (ACE_TDES_OFFSET + 0x1C) +#define ACE_TDES_KEY31 (ACE_TDES_OFFSET + 0x20) +#define ACE_TDES_KEY32 (ACE_TDES_OFFSET + 0x24) + +#define ACE_TDES_IV1 (ACE_TDES_OFFSET + 0x28) +#define ACE_TDES_IV2 (ACE_TDES_OFFSET + 0x2C) + +#define ACE_TDES_IN1 (ACE_TDES_OFFSET + 0x30) +#define ACE_TDES_IN2 (ACE_TDES_OFFSET + 0x34) + +#define ACE_TDES_OUT1 (ACE_TDES_OFFSET + 0x38) +#define ACE_TDES_OUT2 (ACE_TDES_OFFSET + 0x3C) + +/* HASH control registers */ +#if defined(CONFIG_ARCH_EXYNOS) +#if defined(SSS_VERSION_5_1) +#define ACE_HASH_CONTROL (ACE_HASH_OFFSET + 0x00) +#define ACE_HASH_CONTROL2 (ACE_HASH_OFFSET + 0x04) +#define ACE_HASH_FIFO_MODE (ACE_HASH_OFFSET + 0x08) +#define ACE_HASH_BYTESWAP (ACE_HASH_OFFSET + 0x0C) +#define ACE_HASH_STATUS (ACE_HASH_OFFSET + 0x10) +#define ACE_HASH_MSGSIZE_LOW (ACE_HASH_OFFSET + 0x20) +#define ACE_HASH_MSGSIZE_HIGH (ACE_HASH_OFFSET + 0x24) +#define ACE_HASH_PRELEN_LOW (ACE_HASH_OFFSET + 0x28) +#define ACE_HASH_PRELEN_HIGH (ACE_HASH_OFFSET + 0x2C) + +#define ACE_HASH_IN1 (ACE_HASH_OFFSET + 0x30) +#define ACE_HASH_IN2 (ACE_HASH_OFFSET + 0x34) +#define ACE_HASH_IN3 (ACE_HASH_OFFSET + 0x38) +#define ACE_HASH_IN4 (ACE_HASH_OFFSET + 0x3C) +#define ACE_HASH_IN5 (ACE_HASH_OFFSET + 0x40) +#define ACE_HASH_IN6 (ACE_HASH_OFFSET + 0x44) +#define ACE_HASH_IN7 (ACE_HASH_OFFSET + 0x48) +#define ACE_HASH_IN8 (ACE_HASH_OFFSET + 0x4C) +#define ACE_HASH_IN9 (ACE_HASH_OFFSET + 0x50) +#define ACE_HASH_IN10 (ACE_HASH_OFFSET + 0x54) +#define ACE_HASH_IN11 (ACE_HASH_OFFSET + 0x58) +#define ACE_HASH_IN12 (ACE_HASH_OFFSET + 0x5C) +#define ACE_HASH_IN13 (ACE_HASH_OFFSET + 0x60) +#define ACE_HASH_IN14 (ACE_HASH_OFFSET + 0x64) +#define ACE_HASH_IN15 (ACE_HASH_OFFSET + 0x68) +#define ACE_HASH_IN16 (ACE_HASH_OFFSET + 0x6C) + +#define ACE_HASH_HMAC_KEY_IN1 (ACE_HASH_OFFSET + 0x70) +#define ACE_HASH_HMAC_KEY_IN2 (ACE_HASH_OFFSET + 0x74) +#define ACE_HASH_HMAC_KEY_IN3 (ACE_HASH_OFFSET + 0x78) +#define ACE_HASH_HMAC_KEY_IN4 (ACE_HASH_OFFSET + 0x7C) +#define ACE_HASH_HMAC_KEY_IN5 (ACE_HASH_OFFSET + 0x80) +#define ACE_HASH_HMAC_KEY_IN6 (ACE_HASH_OFFSET + 0x84) +#define ACE_HASH_HMAC_KEY_IN7 (ACE_HASH_OFFSET + 0x88) +#define ACE_HASH_HMAC_KEY_IN8 (ACE_HASH_OFFSET + 0x8C) +#define ACE_HASH_HMAC_KEY_IN9 (ACE_HASH_OFFSET + 0x90) +#define ACE_HASH_HMAC_KEY_IN10 (ACE_HASH_OFFSET + 0x94) +#define ACE_HASH_HMAC_KEY_IN11 (ACE_HASH_OFFSET + 0x98) +#define ACE_HASH_HMAC_KEY_IN12 (ACE_HASH_OFFSET + 0x9C) +#define ACE_HASH_HMAC_KEY_IN13 (ACE_HASH_OFFSET + 0xA0) +#define ACE_HASH_HMAC_KEY_IN14 (ACE_HASH_OFFSET + 0xA4) +#define ACE_HASH_HMAC_KEY_IN15 (ACE_HASH_OFFSET + 0xA8) +#define ACE_HASH_HMAC_KEY_IN16 (ACE_HASH_OFFSET + 0xAC) + +#define ACE_HASH_IV1 (ACE_HASH_OFFSET + 0xB0) +#define ACE_HASH_IV2 (ACE_HASH_OFFSET + 0xB4) +#define ACE_HASH_IV3 (ACE_HASH_OFFSET + 0xB8) +#define ACE_HASH_IV4 (ACE_HASH_OFFSET + 0xBC) +#define ACE_HASH_IV5 (ACE_HASH_OFFSET + 0xC0) +#define ACE_HASH_IV6 (ACE_HASH_OFFSET + 0xC4) +#define ACE_HASH_IV7 (ACE_HASH_OFFSET + 0xC8) +#define ACE_HASH_IV8 (ACE_HASH_OFFSET + 0xCC) + +#define ACE_HASH_RESULT1 (ACE_HASH_OFFSET + 0x100) +#define ACE_HASH_RESULT2 (ACE_HASH_OFFSET + 0x104) +#define ACE_HASH_RESULT3 (ACE_HASH_OFFSET + 0x108) +#define ACE_HASH_RESULT4 (ACE_HASH_OFFSET + 0x10C) +#define ACE_HASH_RESULT5 (ACE_HASH_OFFSET + 0x110) +#define ACE_HASH_RESULT6 (ACE_HASH_OFFSET + 0x114) +#define ACE_HASH_RESULT7 (ACE_HASH_OFFSET + 0x118) +#define ACE_HASH_RESULT8 (ACE_HASH_OFFSET + 0x11C) + +#define ACE_HASH_SEED1 (ACE_HASH_OFFSET + 0x140) +#define ACE_HASH_SEED2 (ACE_HASH_OFFSET + 0x144) +#define ACE_HASH_SEED3 (ACE_HASH_OFFSET + 0x148) +#define ACE_HASH_SEED4 (ACE_HASH_OFFSET + 0x14C) +#define ACE_HASH_SEED5 (ACE_HASH_OFFSET + 0x150) + +#define ACE_HASH_PRNG1 (ACE_HASH_OFFSET + 0x160) +#define ACE_HASH_PRNG2 (ACE_HASH_OFFSET + 0x164) +#define ACE_HASH_PRNG3 (ACE_HASH_OFFSET + 0x168) +#define ACE_HASH_PRNG4 (ACE_HASH_OFFSET + 0x16C) +#define ACE_HASH_PRNG5 (ACE_HASH_OFFSET + 0x170) +#else +#define ACE_HASH_CONTROL (ACE_HASH_OFFSET + 0x00) +#define ACE_HASH_CONTROL2 (ACE_HASH_OFFSET + 0x04) +#define ACE_HASH_FIFO_MODE (ACE_HASH_OFFSET + 0x08) +#define ACE_HASH_BYTESWAP (ACE_HASH_OFFSET + 0x0C) +#define ACE_HASH_STATUS (ACE_HASH_OFFSET + 0x10) +#define ACE_HASH_MSGSIZE_LOW (ACE_HASH_OFFSET + 0x20) +#define ACE_HASH_MSGSIZE_HIGH (ACE_HASH_OFFSET + 0x24) +#define ACE_HASH_PRELEN_LOW (ACE_HASH_OFFSET + 0x30) +#define ACE_HASH_PRELEN_HIGH (ACE_HASH_OFFSET + 0x34) + +#define ACE_HASH_IN1 (ACE_HASH_OFFSET + 0x40) +#define ACE_HASH_IN2 (ACE_HASH_OFFSET + 0x44) +#define ACE_HASH_IN3 (ACE_HASH_OFFSET + 0x48) +#define ACE_HASH_IN4 (ACE_HASH_OFFSET + 0x4C) +#define ACE_HASH_IN5 (ACE_HASH_OFFSET + 0x50) +#define ACE_HASH_IN6 (ACE_HASH_OFFSET + 0x54) +#define ACE_HASH_IN7 (ACE_HASH_OFFSET + 0x58) +#define ACE_HASH_IN8 (ACE_HASH_OFFSET + 0x5C) +#define ACE_HASH_IN9 (ACE_HASH_OFFSET + 0x60) +#define ACE_HASH_IN10 (ACE_HASH_OFFSET + 0x64) +#define ACE_HASH_IN11 (ACE_HASH_OFFSET + 0x68) +#define ACE_HASH_IN12 (ACE_HASH_OFFSET + 0x6C) +#define ACE_HASH_IN13 (ACE_HASH_OFFSET + 0x70) +#define ACE_HASH_IN14 (ACE_HASH_OFFSET + 0x74) +#define ACE_HASH_IN15 (ACE_HASH_OFFSET + 0x78) +#define ACE_HASH_IN16 (ACE_HASH_OFFSET + 0x7C) +#define ACE_HASH_IN17 (ACE_HASH_OFFSET + 0x80) +#define ACE_HASH_IN18 (ACE_HASH_OFFSET + 0x84) +#define ACE_HASH_IN19 (ACE_HASH_OFFSET + 0x88) +#define ACE_HASH_IN20 (ACE_HASH_OFFSET + 0x8C) +#define ACE_HASH_IN21 (ACE_HASH_OFFSET + 0x90) +#define ACE_HASH_IN22 (ACE_HASH_OFFSET + 0x94) +#define ACE_HASH_IN23 (ACE_HASH_OFFSET + 0x98) +#define ACE_HASH_IN24 (ACE_HASH_OFFSET + 0x9C) +#define ACE_HASH_IN25 (ACE_HASH_OFFSET + 0xA0) +#define ACE_HASH_IN26 (ACE_HASH_OFFSET + 0xA4) +#define ACE_HASH_IN27 (ACE_HASH_OFFSET + 0xA8) +#define ACE_HASH_IN28 (ACE_HASH_OFFSET + 0xAC) +#define ACE_HASH_IN29 (ACE_HASH_OFFSET + 0xB0) +#define ACE_HASH_IN30 (ACE_HASH_OFFSET + 0xB4) +#define ACE_HASH_IN31 (ACE_HASH_OFFSET + 0xB8) +#define ACE_HASH_IN32 (ACE_HASH_OFFSET + 0xBC) + +#define ACE_HASH_HMAC_KEY_IN1 (ACE_HASH_OFFSET + 0x100) +#define ACE_HASH_HMAC_KEY_IN2 (ACE_HASH_OFFSET + 0x104) +#define ACE_HASH_HMAC_KEY_IN3 (ACE_HASH_OFFSET + 0x108) +#define ACE_HASH_HMAC_KEY_IN4 (ACE_HASH_OFFSET + 0x10C) +#define ACE_HASH_HMAC_KEY_IN5 (ACE_HASH_OFFSET + 0x110) +#define ACE_HASH_HMAC_KEY_IN6 (ACE_HASH_OFFSET + 0x114) +#define ACE_HASH_HMAC_KEY_IN7 (ACE_HASH_OFFSET + 0x118) +#define ACE_HASH_HMAC_KEY_IN8 (ACE_HASH_OFFSET + 0x11C) +#define ACE_HASH_HMAC_KEY_IN9 (ACE_HASH_OFFSET + 0x120) +#define ACE_HASH_HMAC_KEY_IN10 (ACE_HASH_OFFSET + 0x124) +#define ACE_HASH_HMAC_KEY_IN11 (ACE_HASH_OFFSET + 0x128) +#define ACE_HASH_HMAC_KEY_IN12 (ACE_HASH_OFFSET + 0x12C) +#define ACE_HASH_HMAC_KEY_IN13 (ACE_HASH_OFFSET + 0x130) +#define ACE_HASH_HMAC_KEY_IN14 (ACE_HASH_OFFSET + 0x134) +#define ACE_HASH_HMAC_KEY_IN15 (ACE_HASH_OFFSET + 0x138) +#define ACE_HASH_HMAC_KEY_IN16 (ACE_HASH_OFFSET + 0x13C) + +#define ACE_HASH_IV1 (ACE_HASH_OFFSET + 0x180) +#define ACE_HASH_IV2 (ACE_HASH_OFFSET + 0x184) +#define ACE_HASH_IV3 (ACE_HASH_OFFSET + 0x188) +#define ACE_HASH_IV4 (ACE_HASH_OFFSET + 0x18C) +#define ACE_HASH_IV5 (ACE_HASH_OFFSET + 0x190) +#define ACE_HASH_IV6 (ACE_HASH_OFFSET + 0x194) +#define ACE_HASH_IV7 (ACE_HASH_OFFSET + 0x198) +#define ACE_HASH_IV8 (ACE_HASH_OFFSET + 0x19C) + +#define ACE_HASH_RESULT1 (ACE_HASH_OFFSET + 0x1C0) +#define ACE_HASH_RESULT2 (ACE_HASH_OFFSET + 0x1C4) +#define ACE_HASH_RESULT3 (ACE_HASH_OFFSET + 0x1C8) +#define ACE_HASH_RESULT4 (ACE_HASH_OFFSET + 0x1CC) +#define ACE_HASH_RESULT5 (ACE_HASH_OFFSET + 0x1D0) +#define ACE_HASH_RESULT6 (ACE_HASH_OFFSET + 0x1D4) +#define ACE_HASH_RESULT7 (ACE_HASH_OFFSET + 0x1D8) +#define ACE_HASH_RESULT8 (ACE_HASH_OFFSET + 0x1DC) + +#define ACE_HASH_SEED1 (ACE_HASH_OFFSET + 0x200) +#define ACE_HASH_SEED2 (ACE_HASH_OFFSET + 0x204) +#define ACE_HASH_SEED3 (ACE_HASH_OFFSET + 0x208) +#define ACE_HASH_SEED4 (ACE_HASH_OFFSET + 0x20C) +#define ACE_HASH_SEED5 (ACE_HASH_OFFSET + 0x210) + +#define ACE_HASH_PRNG1 (ACE_HASH_OFFSET + 0x214) +#define ACE_HASH_PRNG2 (ACE_HASH_OFFSET + 0x218) +#define ACE_HASH_PRNG3 (ACE_HASH_OFFSET + 0x21C) +#define ACE_HASH_PRNG4 (ACE_HASH_OFFSET + 0x220) +#define ACE_HASH_PRNG5 (ACE_HASH_OFFSET + 0x224) +#endif +#else +#error No ARCH is defined. +#endif + +/* PKA control registers */ +#define ACE_PKA_SFR0 (ACE_PKA_OFFSET + 0x00) +#define ACE_PKA_SFR1 (ACE_PKA_OFFSET + 0x04) +#define ACE_PKA_SFR2 (ACE_PKA_OFFSET + 0x08) +#define ACE_PKA_SFR3 (ACE_PKA_OFFSET + 0x0C) +#define ACE_PKA_SFR4 (ACE_PKA_OFFSET + 0x10) + + +/***************************************************************** + OFFSET +*****************************************************************/ + +/* ACE_FC_INT */ +#define ACE_FC_PKDMA (1 << 0) +#define ACE_FC_HRDMA (1 << 1) +#define ACE_FC_BTDMA (1 << 2) +#define ACE_FC_BRDMA (1 << 3) +#define ACE_FC_PRNG_ERROR (1 << 4) +#define ACE_FC_MSG_DONE (1 << 5) +#define ACE_FC_PRNG_DONE (1 << 6) +#define ACE_FC_PARTIAL_DONE (1 << 7) + +/* ACE_FC_FIFOSTAT */ +#define ACE_FC_PKFIFO_EMPTY (1 << 0) +#define ACE_FC_PKFIFO_FULL (1 << 1) +#define ACE_FC_HRFIFO_EMPTY (1 << 2) +#define ACE_FC_HRFIFO_FULL (1 << 3) +#define ACE_FC_BTFIFO_EMPTY (1 << 4) +#define ACE_FC_BTFIFO_FULL (1 << 5) +#define ACE_FC_BRFIFO_EMPTY (1 << 6) +#define ACE_FC_BRFIFO_FULL (1 << 7) + +/* ACE_FC_FIFOCTRL */ +#define ACE_FC_SELHASH_MASK (3 << 0) +#define ACE_FC_SELHASH_EXOUT (0 << 0) // independent source +#define ACE_FC_SELHASH_BCIN (1 << 0) // block cipher input +#define ACE_FC_SELHASH_BCOUT (2 << 0) // block cipher output +#define ACE_FC_SELBC_MASK (1 << 2) +#define ACE_FC_SELBC_AES (0 << 2) // AES +#define ACE_FC_SELBC_DES (1 << 2) // DES + +/* ACE_FC_GLOBAL */ +#define ACE_FC_SSS_RESET (1 << 0) +#define ACE_FC_DMA_RESET (1 << 1) +#define ACE_FC_AES_RESET (1 << 2) +#define ACE_FC_DES_RESET (1 << 3) +#define ACE_FC_HASH_RESET (1 << 4) +#define ACE_FC_AXI_ENDIAN_MASK (3 << 6) +#define ACE_FC_AXI_ENDIAN_LE (0 << 6) +#define ACE_FC_AXI_ENDIAN_BIBE (1 << 6) +#define ACE_FC_AXI_ENDIAN_WIBE (2 << 6) + +/* Feed control - BRDMA control */ +#define ACE_FC_BRDMACFLUSH_OFF (0 << 0) +#define ACE_FC_BRDMACFLUSH_ON (1 << 0) +#define ACE_FC_BRDMACSWAP_ON (1 << 1) +#define ACE_FC_BRDMACARPROT_MASK (0x7 << 2) +#define ACE_FC_BRDMACARPROT_OFS (2) +#define ACE_FC_BRDMACARCACHE_MASK (0xF << 5) +#define ACE_FC_BRDMACARCACHE_OFS (5) + +/* Feed control - BTDMA control */ +#define ACE_FC_BTDMACFLUSH_OFF (0 << 0) +#define ACE_FC_BTDMACFLUSH_ON (1 << 0) +#define ACE_FC_BTDMACSWAP_ON (1 << 1) +#define ACE_FC_BTDMACAWPROT_MASK (0x7 << 2) +#define ACE_FC_BTDMACAWPROT_OFS (2) +#define ACE_FC_BTDMACAWCACHE_MASK (0xF << 5) +#define ACE_FC_BTDMACAWCACHE_OFS (5) + +/* Feed control - HRDMA control */ +#define ACE_FC_HRDMACFLUSH_OFF (0 << 0) +#define ACE_FC_HRDMACFLUSH_ON (1 << 0) +#define ACE_FC_HRDMACSWAP_ON (1 << 1) + +/* Feed control - PKDMA control */ +#define ACE_FC_PKDMACBYTESWAP_ON (1 << 3) +#define ACE_FC_PKDMACDESEND_ON (1 << 2) +#define ACE_FC_PKDMACTRANSMIT_ON (1 << 1) +#define ACE_FC_PKDMACFLUSH_ON (1 << 0) + +/* Feed control - PKDMA offset */ +#define ACE_FC_SRAMOFFSET_MASK (0xFFF) + +/* AES control */ +#define ACE_AES_MODE_MASK (1 << 0) +#define ACE_AES_MODE_ENC (0 << 0) +#define ACE_AES_MODE_DEC (1 << 0) +#define ACE_AES_OPERMODE_MASK (3 << 1) +#define ACE_AES_OPERMODE_ECB (0 << 1) +#define ACE_AES_OPERMODE_CBC (1 << 1) +#define ACE_AES_OPERMODE_CTR (2 << 1) +#define ACE_AES_FIFO_MASK (1 << 3) +#define ACE_AES_FIFO_OFF (0 << 3) // CPU mode +#define ACE_AES_FIFO_ON (1 << 3) // FIFO mode +#define ACE_AES_KEYSIZE_MASK (3 << 4) +#define ACE_AES_KEYSIZE_128 (0 << 4) +#define ACE_AES_KEYSIZE_192 (1 << 4) +#define ACE_AES_KEYSIZE_256 (2 << 4) +#define ACE_AES_KEYCNGMODE_MASK (1 << 6) +#define ACE_AES_KEYCNGMODE_OFF (0 << 6) +#define ACE_AES_KEYCNGMODE_ON (1 << 6) +#define ACE_AES_SWAP_MASK (0x1F << 7) +#define ACE_AES_SWAPKEY_OFF (0 << 7) +#define ACE_AES_SWAPKEY_ON (1 << 7) +#define ACE_AES_SWAPCNT_OFF (0 << 8) +#define ACE_AES_SWAPCNT_ON (1 << 8) +#define ACE_AES_SWAPIV_OFF (0 << 9) +#define ACE_AES_SWAPIV_ON (1 << 9) +#define ACE_AES_SWAPDO_OFF (0 << 10) +#define ACE_AES_SWAPDO_ON (1 << 10) +#define ACE_AES_SWAPDI_OFF (0 << 11) +#define ACE_AES_SWAPDI_ON (1 << 11) +#define ACE_AES_COUNTERSIZE_MASK (3 << 12) +#define ACE_AES_COUNTERSIZE_128 (0 << 12) +#define ACE_AES_COUNTERSIZE_64 (1 << 12) +#define ACE_AES_COUNTERSIZE_32 (2 << 12) +#define ACE_AES_COUNTERSIZE_16 (3 << 12) + +/* AES status */ +#define ACE_AES_OUTRDY_MASK (1 << 0) +#define ACE_AES_OUTRDY_OFF (0 << 0) +#define ACE_AES_OUTRDY_ON (1 << 0) +#define ACE_AES_INRDY_MASK (1 << 1) +#define ACE_AES_INRDY_OFF (0 << 1) +#define ACE_AES_INRDY_ON (1 << 1) +#define ACE_AES_BUSY_MASK (1 << 2) +#define ACE_AES_BUSY_OFF (0 << 2) +#define ACE_AES_BUSY_ON (1 << 2) + +/* TDES control */ +#define ACE_TDES_MODE_MASK (1 << 0) +#define ACE_TDES_MODE_ENC (0 << 0) +#define ACE_TDES_MODE_DEC (1 << 0) +#define ACE_TDES_OPERMODE_MASK (1 << 1) +#define ACE_TDES_OPERMODE_ECB (0 << 1) +#define ACE_TDES_OPERMODE_CBC (1 << 1) +#define ACE_TDES_SEL_MASK (3 << 3) +#define ACE_TDES_SEL_DES (0 << 3) +#define ACE_TDES_SEL_TDESEDE (1 << 3) // TDES EDE mode +#define ACE_TDES_SEL_TDESEEE (3 << 3) // TDES EEE mode +#define ACE_TDES_FIFO_MASK (1 << 5) +#define ACE_TDES_FIFO_OFF (0 << 5) // CPU mode +#define ACE_TDES_FIFO_ON (1 << 5) // FIFO mode +#define ACE_TDES_SWAP_MASK (0xF << 6) +#define ACE_TDES_SWAPKEY_OFF (0 << 6) +#define ACE_TDES_SWAPKEY_ON (1 << 6) +#define ACE_TDES_SWAPIV_OFF (0 << 7) +#define ACE_TDES_SWAPIV_ON (1 << 7) +#define ACE_TDES_SWAPDO_OFF (0 << 8) +#define ACE_TDES_SWAPDO_ON (1 << 8) +#define ACE_TDES_SWAPDI_OFF (0 << 9) +#define ACE_TDES_SWAPDI_ON (1 << 9) + +/* TDES status */ +#define ACE_TDES_OUTRDY_MASK (1 << 0) +#define ACE_TDES_OUTRDY_OFF (0 << 0) +#define ACE_TDES_OUTRDY_ON (1 << 0) +#define ACE_TDES_INRDY_MASK (1 << 1) +#define ACE_TDES_INRDY_OFF (0 << 1) +#define ACE_TDES_INRDY_ON (1 << 1) +#define ACE_TDES_BUSY_MASK (1 << 2) +#define ACE_TDES_BUSY_OFF (0 << 2) +#define ACE_TDES_BUSY_ON (1 << 2) + +/* Hash control */ +#define ACE_HASH_ENGSEL_MASK (0xF << 0) +#define ACE_HASH_ENGSEL_SHA1HASH (0x0 << 0) +#define ACE_HASH_ENGSEL_SHA1HMAC (0x1 << 0) +#define ACE_HASH_ENGSEL_SHA1HMACIN (0x1 << 0) +#define ACE_HASH_ENGSEL_SHA1HMACOUT (0x9 << 0) +#define ACE_HASH_ENGSEL_MD5HASH (0x2 << 0) +#define ACE_HASH_ENGSEL_MD5HMAC (0x3 << 0) +#define ACE_HASH_ENGSEL_MD5HMACIN (0x3 << 0) +#define ACE_HASH_ENGSEL_MD5HMACOUT (0xB << 0) +#define ACE_HASH_ENGSEL_SHA256HASH (0x4 << 0) +#define ACE_HASH_ENGSEL_SHA256HMAC (0x5 << 0) +#if defined(CONFIG_ARCH_EXYNOS) +#define ACE_HASH_ENGSEL_PRNG (0x8 << 0) +#endif +#define ACE_HASH_STARTBIT_ON (1 << 4) +#define ACE_HASH_USERIV_EN (1 << 5) + +/* Hash control 2 */ +#if defined(CONFIG_ARCH_EXYNOS) +#define ACE_HASH_PAUSE_ON (1 << 0) +#endif + +/* Hash control - FIFO mode */ +#define ACE_HASH_FIFO_MASK (1 << 0) +#define ACE_HASH_FIFO_OFF (0 << 0) +#define ACE_HASH_FIFO_ON (1 << 0) + +/* Hash control - byte swap */ +#if defined(CONFIG_ARCH_EXYNOS) +#define ACE_HASH_SWAP_MASK (0xF << 0) +#endif +#define ACE_HASH_SWAPKEY_OFF (0 << 0) +#define ACE_HASH_SWAPKEY_ON (1 << 0) +#define ACE_HASH_SWAPIV_OFF (0 << 1) +#define ACE_HASH_SWAPIV_ON (1 << 1) +#define ACE_HASH_SWAPDO_OFF (0 << 2) +#define ACE_HASH_SWAPDO_ON (1 << 2) +#define ACE_HASH_SWAPDI_OFF (0 << 3) +#define ACE_HASH_SWAPDI_ON (1 << 3) + +/* Hash status */ +#define ACE_HASH_BUFRDY_MASK (1 << 0) +#define ACE_HASH_BUFRDY_OFF (0 << 0) +#define ACE_HASH_BUFRDY_ON (1 << 0) +#define ACE_HASH_SEEDSETTING_MASK (1 << 1) +#define ACE_HASH_SEEDSETTING_OFF (0 << 1) +#define ACE_HASH_SEEDSETTING_ON (1 << 1) +#define ACE_HASH_PRNGBUSY_MASK (1 << 2) +#define ACE_HASH_PRNGBUSY_OFF (0 << 2) +#define ACE_HASH_PRNGBUSY_ON (1 << 2) +#define ACE_HASH_PARTIALDONE_MASK (1 << 4) +#define ACE_HASH_PARTIALDONE_OFF (0 << 4) +#define ACE_HASH_PARTIALDONE_ON (1 << 4) +#define ACE_HASH_PRNGDONE_MASK (1 << 5) +#define ACE_HASH_PRNGDONE_OFF (0 << 5) +#define ACE_HASH_PRNGDONE_ON (1 << 5) +#define ACE_HASH_MSGDONE_MASK (1 << 6) +#define ACE_HASH_MSGDONE_OFF (0 << 6) +#define ACE_HASH_MSGDONE_ON (1 << 6) +#define ACE_HASH_PRNGERROR_MASK (1 << 7) +#define ACE_HASH_PRNGERROR_OFF (0 << 7) +#define ACE_HASH_PRNGERROR_ON (1 << 7) + +/* To Do: SFRs for PKA */ + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/arch/arm/include/asm/arch-exynos/ace_sha.h b/arch/arm/include/asm/arch-exynos/ace_sha.h new file mode 100644 index 000000000..c84334f11 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/ace_sha.h @@ -0,0 +1,85 @@ +/* + * Header file for SHA firmware + * + * Copyright (c) 2010 Samsung Electronics + * + * 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 __ACE_FW_SHA_H__ +#define __ACE_FW_SHA_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_ARCH_EXYNOS) + +/* Hash Code Length */ +#define SHA1_DIGEST_LEN 20 +#define SHA1_BLOCK_LEN 64 +#define SHA256_DIGEST_LEN 32 +#define SHA256_BLOCK_LEN 64 + +enum { + ALG_SHA1, + ALG_SHA256, +}; + +struct ace_hash_ctx { + int alg; + size_t buflen; + unsigned char buffer[SHA256_BLOCK_LEN]; + unsigned int state[SHA256_DIGEST_LEN/4]; + unsigned int prelen_high; + unsigned int prelen_low; +}; + +/***************************************************************** + Functions +*****************************************************************/ +int ace_hash_sha_digest( + unsigned char *pOut, + unsigned char *pBuf, + unsigned int bufLen, + int alg +); + +int ace_hash_sha_init( + struct ace_hash_ctx *ctx, + int alg +); + +int ace_hash_sha_update( + struct ace_hash_ctx *ctx, + unsigned char *pData, + unsigned int dataLen +); + +int ace_hash_sha_final( + struct ace_hash_ctx *ctx, + unsigned char *pOut +); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h index 637fb4bd1..699fa8fb6 100644 --- a/arch/arm/include/asm/arch-exynos/clk.h +++ b/arch/arm/include/asm/arch-exynos/clk.h @@ -27,11 +27,33 @@ #define EPLL 2 #define HPLL 3 #define VPLL 4 +#define KPLL 5 +#define BPLL 6 +#define CPLL 7 +#define SPLL 8 +#define UPLL 9 + +/* EXYNOS5260, EXYNOS5430 PLL */ +#define EGL_PLL 0 +#define EGL_DPLL 1 +#define KFC_PLL 2 +#define MEM_PLL 3 +#define BUS_PLL 4 +#define MEDIA_PLL 5 + +/* EXYNOS5430 PLL */ +#define MFC_PLL 5 +#define ISP_PLL 6 +#define MPHY_PLL 7 + +#define MPLL_PRE_DIV 2 unsigned long get_pll_clk(int pllreg); unsigned long get_arm_clk(void); unsigned long get_pwm_clk(void); unsigned long get_uart_clk(int dev_index); +unsigned long get_mmc_clk(int dev_index); +unsigned long get_usbdrd_clk(void); void set_mmc_clk(int dev_index, unsigned int div); unsigned long get_lcd_clk(void); void set_lcd_clk(void); diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h index 50da95803..f2a26b6d3 100644 --- a/arch/arm/include/asm/arch-exynos/clock.h +++ b/arch/arm/include/asm/arch-exynos/clock.h @@ -23,8 +23,750 @@ #define __ASM_ARM_ARCH_CLOCK_H_ #ifndef __ASSEMBLY__ +#ifdef CONFIG_CPU_EXYNOS3250 struct exynos4_clock { - unsigned char res1[0x4200]; + /*CMU_LEFTBUS*/ + unsigned char res1[0x4200]; /* 0x1003_4200 */ + unsigned int src_leftbus; + unsigned char res2[0x1fc]; + unsigned int mux_stat_leftbus; + unsigned char res4[0xfc]; + unsigned int div_leftbus; + unsigned char res5[0xfc]; + unsigned int div_stat_leftbus; + unsigned char res6[0xfc]; + unsigned int gate_bus_leftbus;; + unsigned char res7[0xfc]; + unsigned int gate_ip_leftbus; + unsigned char res8[0x1fc]; + unsigned int clkout_leftbus; /* 0x1003_4A00 */ + unsigned int clkout_leftbus_div_stat; + /*CMU_RIGHTBUS*/ + unsigned char res9[0x37f8]; + unsigned int src_rightbus; /* 0x1003_8200 */ + unsigned char res10[0x1fc]; + unsigned int mux_stat_rightbus; + unsigned char res11[0xfc]; + unsigned int div_rightbus; + unsigned char res12[0xfc]; + unsigned int div_stat_rightbus; + unsigned char res13[0xfc]; + unsigned int gate_bus_rightbus; + unsigned char res14[0x5c]; + unsigned int gate_bus_perir; + unsigned char res15[0x9c]; + unsigned int gate_ip_rightbus; + unsigned char res16[0x15c]; + unsigned int gate_ip_perir; + unsigned char res17[0x9c]; + unsigned int clkout_rightbus; /* 0x1003_8A00 */ + unsigned int clkout_rightbus_div_stat; + /*CMU_TOP*/ + unsigned char res18[0x3608]; + unsigned int mpll_lock; /* 0x1003_C010 */ + unsigned char res20[0xc]; + unsigned int vpll_lock; + unsigned char res101[0xc]; + unsigned int upll_lock; + unsigned char res21[0xdc]; + unsigned int mpll_con0; /* 0x1003_C110 */ + unsigned int mpll_con1; + unsigned int mpll_con2; + unsigned char res22[0x4]; + unsigned int vpll_con0; /* 0x1003_C120 */ + unsigned int vpll_con1; + unsigned int vpll_con2; + unsigned char res222[0x4]; + unsigned int upll_con0; /* 0x1003_C130 */ + unsigned int upll_con1; + unsigned int upll_con2; + unsigned char res23[0xd4]; + unsigned int src_top0; /* 0x1003_C210 */ + unsigned int src_top1; + unsigned char res24[0x8]; + unsigned int src_cam; /* 0x1003_C220*/ + unsigned char res105[0x4]; + unsigned int src_mfc; + unsigned int src_g3d; + unsigned char res102[0x4]; + unsigned int src_lcd0; + unsigned int src_isp; + unsigned char res103[0x4]; + unsigned int src_fsys; + unsigned char res25[0xc]; + unsigned int src_peril0; + unsigned int src_peril1; + unsigned int src_cam1; + unsigned char res26[0xb4]; + unsigned int src_mask_top; /* 0x1003_C310 */ + unsigned char res27[0xc]; + unsigned int src_mask_cam; + unsigned char res28[0x10]; + unsigned int src_mask_lcd0; + unsigned int src_mask_isp; + unsigned char res104[0x4]; + unsigned int src_mask_fsys; + unsigned char res29[0xc]; + unsigned int src_mask_peril0; + unsigned int src_mask_peril1; + unsigned char res30[0xb8]; + unsigned int mux_stat_top; /* 0x1003_C410 */ + unsigned int mux_stat_top1; + unsigned char res31[0x10]; + unsigned int mux_stat_mfc; + unsigned int mux_stat_g3d; + unsigned char res32[0xe0]; + unsigned int div_top; + unsigned char res33[0xc]; + unsigned int div_cam; + unsigned char res106[0x4]; + unsigned int div_mfc; + unsigned int div_g3d; + unsigned char res107[0x4]; + unsigned int div_lcd0; + unsigned int div_isp; + unsigned char res108[0x4]; + unsigned int div_fsys0; + unsigned int div_fsys1; + unsigned int div_fsys2; + unsigned int div_fsys3; + unsigned int div_peril0; + unsigned int div_peril1; + unsigned int div_peril2; + unsigned int div_peril3; + unsigned int div_peril4; + unsigned int div_peril5; + unsigned int div_cam1; + unsigned char res34[0x14]; + unsigned int div2_ratio; + unsigned char res35[0x8c]; + unsigned int div_stat_top; /* 0x1003_C610 */ + unsigned char res36[0xc]; + unsigned int div_stat_cam; + unsigned char res110[0x4]; + unsigned int div_stat_mfc; + unsigned int div_stat_g3d; + unsigned char res111[0x4]; + unsigned int div_stat_lcd0; + unsigned int div_stat_isp; + unsigned char res112[0x4]; + unsigned int div_stat_fsys0; + unsigned int div_stat_fsys1; + unsigned int div_stat_fsys2; + unsigned char res113[0x4]; + unsigned int div_stat_peril0; + unsigned int div_stat_peril1; + unsigned int div_stat_peril2; + unsigned int div_stat_peril3; + unsigned int div_stat_peril4; + unsigned int div_stat_peril5; + unsigned int div_stat_cam1; + unsigned char res37[0x14]; + unsigned int div2_stat; + unsigned char res114[0x9c]; + unsigned int gate_bus_cam; /* 0x1003_C720 */ + unsigned char res115[0x4]; + unsigned int gate_bus_mfc; + unsigned int gate_bus_g3d; + unsigned char res116[0x4]; + unsigned int gate_bus_lcd0; + unsigned int gate_bus_cam1; + unsigned char res117[0x4]; + unsigned int gate_bus_fsys0; + unsigned int gate_bus_fsys1; + unsigned char res118[0x8]; + unsigned int gate_bus_peril; + unsigned char res119[0xcc]; + unsigned int gate_sclk_cam; /* 0x1003_C820 */ + unsigned char res120[0x4]; + unsigned int gate_sclk_mfc; + unsigned int gate_sclk_g3d; + unsigned char res121[0x4]; + unsigned int gate_sclk_lcd0; + unsigned int gate_sclk_isp; + unsigned char res122[0x4]; + unsigned int gate_sclk_fsys; + unsigned char res123[0xc]; + unsigned int gate_sclk_peril; + unsigned char res38[0xcc]; + unsigned int gate_ip_cam; /* 0x1003_C920 */ + unsigned char res1283[0x4]; + unsigned int gate_ip_mfc; + unsigned int gate_ip_g3d; + unsigned char res124[0x4]; + unsigned int gate_ip_lcd0; + unsigned int gate_ip_isp; + unsigned char res39[0x4]; + unsigned int gate_ip_fsys; + unsigned char res40[0xc]; + unsigned int gate_ip_peril; + unsigned char res42[0x1c]; + unsigned int gate_block; + unsigned char res43[0x8c]; + unsigned int clkout_cmu_top; /* 0x1003_CA00 */ + unsigned int clkout_cmu_top_div_stat; + + /*CMU_CPU */ + unsigned char res44[0x75f8]; + unsigned int apll_lock; /* 0x1004_4000 */ + unsigned char res45[0xfc]; + unsigned int apll_con0; /* 0x1004_4100 */ + unsigned int apll_con1; + unsigned int apll_con2; + unsigned char res46[0xf4]; + unsigned int src_cpu; /* 0x1004_4200 */ + unsigned char res47[0x1fc]; + unsigned int mux_stat_cpu; /* 0x1004_4400 */ + unsigned char res48[0xfc]; + unsigned int div_cpu0; /* 0x1004_4500 */ + unsigned int div_cpu1; + unsigned char res49[0xf8]; + unsigned int div_stat_cpu0; /* 0x1004_4600 */ + unsigned int div_stat_cpu1; + unsigned char res50[0xf8]; + unsigned int gate_bus_cpu; /* 0x1004_4700 */ + unsigned char res51[0xfc]; + unsigned int gate_sclk_cpu; /* 0x1004_4800 */ + unsigned char res52[0xfc]; + unsigned int gate_ip_cpu; /* 0x1004_4900 */ + unsigned char res53[0xfc]; + unsigned int clkout_cmu_cpu; /* 0x1004_4A00 */ + unsigned int clkout_cmu_cpu_div_stat; + unsigned char res54[0x5f8]; + unsigned int armclk_stopctrl; /* 0x1004_5000 */ + unsigned int atclk_stopctrl; + unsigned int arm_ema_ctrl; + unsigned int arm_ema_status; + unsigned char res855[0x10]; + unsigned int pwr_ctrl; + unsigned int pwr_ctr2; + unsigned char res55[0xD8]; + unsigned int apll_con0_l8; /* 0x1004_5100 */ + unsigned int apll_con0_l7; + unsigned int apll_con0_l6; + unsigned int apll_con0_l5; + unsigned int apll_con0_l4; + unsigned int apll_con0_l3; + unsigned int apll_con0_l2; + unsigned int apll_con0_l1; + unsigned int iem_control; + unsigned char res56[0xdc]; + unsigned int apll_con1_l8; /* 0x1004_5200 */ + unsigned int apll_con1_l7; + unsigned int apll_con1_l6; + unsigned int apll_con1_l5; + unsigned int apll_con1_l4; + unsigned int apll_con1_l3; + unsigned int apll_con1_l2; + unsigned int apll_con1_l1; + unsigned char res57[0xe0]; + unsigned int div_iem_l8; /* 0x1004_5300 */ + unsigned int div_iem_l7; + unsigned int div_iem_l6; + unsigned int div_iem_l5; + unsigned int div_iem_l4; + unsigned int div_iem_l3; + unsigned int div_iem_l2; + unsigned int div_iem_l1; + unsigned char res58[0xf0]; + unsigned int cpu_status; /* 0x1004_5410 */ + + /*CMU_ISP*/ + unsigned char res59[0x2eec]; + unsigned int div_isp0; /* 0x1004_8300 */ + unsigned int div_isp1; + unsigned char res60[0xf8]; + unsigned int div_stat_isp0; /* 0x1004_8400 */ + unsigned int div_stat_isp1; + unsigned char res61[0x2f8]; + unsigned int gate_bus_isp0; /* 0x1004_8700 */ + unsigned int gate_bus_isp1; + unsigned int gate_bus_isp2; + unsigned int gate_bus_isp3; + unsigned char res62[0xf0]; + unsigned int gate_ip_isp0; /* 0x1004_8800 */ + unsigned int gate_ip_isp1; + unsigned char res63[0xf8]; + unsigned int isp_gate_sclk_isp; /* 0x1004_8900 */ + unsigned char res64[0xfc]; + unsigned int clkout_cmu_isp; /* 0x1004_8A00 */ + unsigned int clkout_cmu_isp_div_stat; + unsigned char res880[0xf8]; + unsigned int isp_spare0; + unsigned int isp_spare1; + unsigned int isp_spare2; + unsigned int isp_spare3; + /*CMU_ACP*/ + unsigned char res65[0x4077f0]; + unsigned int src_acp; /* 0x1045_0300 */ + unsigned int src_mask_acp; + unsigned char res66[0xf8]; + unsigned int mux_stat_acp0; /* 0x1045_0400 */ + unsigned int mux_stat_acp1; + unsigned char res67[0xf8]; + unsigned int div_acp0; /* 0x1045_0500 */ + unsigned int div_acp1; + unsigned char res68[0xf8]; + unsigned int div_stat_acp0; /* 0x1045_0600 */ + unsigned int div_stat_acp1; + unsigned char res69[0xf8]; + unsigned int gate_bus_acp0; /* 0x1045_0700 */ + unsigned int gate_bus_acp1; + unsigned char res70[0xf8]; + unsigned int gate_sclk_acp; /* 0x1045_0800 */ + unsigned char res71[0xfc]; + unsigned int gate_ip_acp; /* 0x1045_0900 */ + unsigned int gate_ip_acp1; + unsigned char res72[0xf8]; + unsigned int clkout_cmu_acp; /* 0x1045_0A00 */ + unsigned int clkout_cmu_acp_div_stat; + unsigned char res790[0x5f8]; + unsigned int dcgidx_map0; + unsigned int dcgidx_map1; + unsigned int dcgidx_map2; + unsigned char res791[0x14]; + unsigned int dcgperf_map0; + unsigned int dcgperf_map1; + unsigned char res792[0x18]; + unsigned int dvcidx_map; + unsigned char res793[0x1c]; + unsigned int freq_cpu; + unsigned int freq_dpm; + unsigned char res794[0x18]; + unsigned int dvsemclk_en; + unsigned int maxperf; + unsigned char res795[0xf78]; + unsigned int acp_spare0; /*0x1045_2000*/ + unsigned int acp_spare1; + unsigned int acp_spare2; + unsigned int acp_spare3; + unsigned int acp_spare4; + + /*CMU_DMC*/ + unsigned char res73[0x16DFF4]; + unsigned char res74[0x110]; + unsigned int bpll_lock; /* 0x105c_0118 */ + unsigned char res76[0xfc]; + unsigned int bpll_con0; /* 0x105c_0218 */ + unsigned int bpll_con1; + unsigned int bpll_con2; + unsigned char res77[0xdc]; + unsigned int src_dmc; /* 0x105c_0300 */ + unsigned char res78[0xfc]; + unsigned int mux_stat_dmc; /* 0x105c_0400 */ + unsigned char res79[0xfc]; + unsigned int div_dyn_freq_scale; /* 0x105c_0500 */ + unsigned int div_dmc1; + unsigned char res80[0xf8]; + unsigned int div_stat_dmc0; /* 0x105c_0600 */ + unsigned int div_stat_dmc1; + unsigned char res81[0xf8]; + unsigned int gate_bus_dmc0; /* 0x105c_0700 */ + unsigned int gate_bus_dmc1; + unsigned int gate_bus_dmc2; + unsigned int gate_bus_dmc3; + unsigned char res82[0xf0]; + unsigned int gate_clk_dmc; /* 0x105c_0800 */ + unsigned char res83[0xfc]; + unsigned int gate_ip_dmc0; /* 0x105c_0900 */ + unsigned int gate_ip_dmc1; + unsigned char res84[0xf8]; + unsigned int clkout_cmu_dmc; /* 0x105c_0A00 */ + unsigned int clkout_cmu_dmc_div_stat; + unsigned char res841[0x688]; + unsigned int dmc_freq_ctrl; /* 0x105c_1090 */ + unsigned int dmc_pause_ctrl; + unsigned int ddrphy_lock_ctrl; + unsigned char res842[0x74]; + unsigned int epll_lock; + unsigned int epll_con0; + unsigned int epll_con1; + unsigned int epll_con2; + unsigned int clk_src_epll; + unsigned int clk_mux_stat_epll; + unsigned char res843[0xED8]; + unsigned int semaphore0; /* 0x105c_2000 */ + unsigned int semaphore1; + unsigned int semaphore2; + unsigned int cmu_dmc_spare0; + unsigned int cmu_dmc_spare1; + unsigned char res844[0xFEC]; + unsigned int divdmc_ratio_dyn_clk_gate_con; /* 0x105c_3000 */ +}; +#elif defined(CONFIG_CPU_EXYNOS4415) +struct exynos4_clock { + unsigned char res0[0x200]; /* 0x1003_4200 */ + unsigned int src_cdrex; + unsigned char res1[0x3ffc]; + unsigned int src_leftbus; + unsigned char res2[0x1fc]; + unsigned int mux_stat_leftbus; + unsigned char res3[0xfc]; + unsigned int div_leftbus; + unsigned char res4[0xfc]; + unsigned int div_stat_leftbus; + unsigned char res5[0xfc]; + unsigned int gate_bus_leftbus; + unsigned char res6[0x2c]; + unsigned int gate_bus_image; + unsigned char res7[0xcc]; + unsigned int gate_ip_leftbus; + unsigned char res8[0x12c]; + unsigned int gate_ip_image; + unsigned char res9[0xcc]; + unsigned int clkout_leftbus; /* 0x1003_4A00 */ + unsigned int clkout_leftbus_div_stat; + unsigned char res10[0x37f8]; + unsigned int src_rightbus; /* 0x1003_8200 */ + unsigned char res11[0x1fc]; + unsigned int mux_stat_rightbus; + unsigned char res12[0xfc]; + unsigned int div_rightbus; + unsigned char res13[0xfc]; + unsigned int div_stat_rightbus; + unsigned char res14[0xfc]; + unsigned int gate_bus_rightbus; + unsigned char res15[0x5c]; + unsigned int gate_bus_perir; + unsigned char res16[0x9c]; + unsigned int gate_ip_rightbus; + unsigned char res17[0x15c]; + unsigned int gate_ip_perir; + unsigned char res18[0x9c]; + unsigned int clkout_rightbus; /* 0x1003_8A00 */ + unsigned int clkout_rightbus_div_stat; + unsigned char res19[0x3608]; + unsigned int epll_lock; /* 0x1003_C010 */ + unsigned char res20[0xc]; + unsigned int vpll_lock; + unsigned char res21[0xc]; + unsigned int mphy_pll_lock; + unsigned char res22[0xdc]; + unsigned int epll_con0; /* 0x1003_C110 */ + unsigned int epll_con1; + unsigned int epll_con2; + unsigned char res23[0x4]; + unsigned int vpll_con0; /* 0x1003_C120 */ + unsigned int vpll_con1; + unsigned int vpll_con2; + unsigned char res24[0x4]; + unsigned int mphy_pll_con0; + unsigned int mphy_pll_con1; + unsigned int mphy_pll_con2; + unsigned char res25[0xd4]; + unsigned int src_top0; /* 0x1003_C210 */ + unsigned int src_top1; + unsigned char res26[0x8]; + unsigned int src_cam0; + unsigned int src_tv; + unsigned int src_mfc; + unsigned int src_g3d0; + unsigned char res27[0x4]; + unsigned int src_lcd0; + unsigned int src_isp; + unsigned int src_maudio; + unsigned int src_fsys; + unsigned char res28[0xc]; + unsigned int src_peril0; + unsigned int src_peril1; + unsigned int src_cam1; + unsigned char res29[0xb4]; + unsigned int src_mask_top; /* 0x1003_C310 */ + unsigned char res30[0xc]; + unsigned int src_mask_cam0; + unsigned int src_mask_tv; + unsigned char res31[0xc]; + unsigned int src_mask_lcd0; + unsigned int src_mask_isp; + unsigned int src_mask_maudio; + unsigned int src_mask_fsys; + unsigned char res32[0xc]; + unsigned int src_mask_peril0; + unsigned int src_mask_peril1; + unsigned char res33[0xb8]; + unsigned int mux_stat_top0; /* 0x1003_C410 */ + unsigned int mux_stat_top1; + unsigned char res34[0x10]; + unsigned int mux_stat_mfc; + unsigned int mux_stat_g3d; + unsigned char res35[0x28]; + unsigned int mux_stat_cam1; + unsigned char res36[0xb4]; + unsigned int div_top; + unsigned char res37[0xc]; + unsigned int div_cam0; + unsigned int div_tv; + unsigned int div_mfc; + unsigned int div_g3d; + unsigned char res38[0x4]; + unsigned int div_lcd0; + unsigned int div_isp; + unsigned int div_maudio; + unsigned int div_fsys0; + unsigned int div_fsys1; + unsigned int div_fsys2; + unsigned int div_fsys3; + unsigned int div_peril0; + unsigned int div_peril1; + unsigned int div_peril2; + unsigned int div_peril3; + unsigned int div_peril4; + unsigned int div_peril5; + unsigned int div_cam1; + unsigned int div_isp1_ts; + unsigned char res39[0x10]; + unsigned int div2_ratio; + unsigned char res40[0x8c]; + unsigned int div_stat_top; /* 0x1003_C610 */ + unsigned char res41[0xc]; + unsigned int div_stat_cam0; + unsigned int div_stat_tv; + unsigned int div_stat_mfc; + unsigned int div_stat_g3d; + unsigned char res42[0x4]; + unsigned int div_stat_lcd0; + unsigned int div_stat_isp; + unsigned int div_stat_maudio; + unsigned int div_stat_fsys0; + unsigned int div_stat_fsys1; + unsigned int div_stat_fsys2; + unsigned int div_stat_fsys3; + unsigned int div_stat_peril0; + unsigned int div_stat_peril1; + unsigned int div_stat_peril2; + unsigned int div_stat_peril3; + unsigned int div_stat_peril4; + unsigned int div_stat_peril5; + unsigned int div_stat_cam1; + unsigned char res43[0x14]; + unsigned int div2_stat; + unsigned char res44[0x9c]; + unsigned int gate_bus_cam0; /* 0x1003_C720 */ + unsigned int gate_bus_tv; + unsigned int gate_bus_mfc; + unsigned int gate_bus_g3d; + unsigned char res45[0x4]; + unsigned int gate_bus_lcd0; + unsigned int gate_bus_cam1; + unsigned char res46[0x4]; + unsigned int gate_bus_fsys0; + unsigned int gate_bus_fsys1; + unsigned char res47[0x8]; + unsigned int gate_bus_peril; + unsigned char res48[0xcc]; + unsigned int gate_sclk_cam; /* 0x1003_C820 */ + unsigned int gate_sclk_tv; + unsigned int gate_sclk_mfc; + unsigned int gate_sclk_g3d; + unsigned char res49[0x4]; + unsigned int gate_sclk_lcd0; + unsigned int gate_sclk_isp; + unsigned int gate_sclk_maudio; + unsigned int gate_sclk_fsys; + unsigned char res50[0xc]; + unsigned int gate_sclk_peril; + unsigned char res51[0xcc]; + unsigned int gate_ip_cam; /* 0x1003_C920 */ + unsigned int gate_ip_tv; + unsigned int gate_ip_mfc; + unsigned int gate_ip_g3d; + unsigned char res52[0x4]; + unsigned int gate_ip_lcd0; + unsigned int gate_ip_isp; + unsigned char res53[0x4]; + unsigned int gate_ip_fsys; + unsigned char res54[0xc]; + unsigned int gate_ip_peril; + unsigned char res55[0x1c]; + unsigned int gate_block; + unsigned char res56[0x8c]; + unsigned int clkout_cmu_top; /* 0x1003_CA00 */ + unsigned int clkout_cmu_top_div_stat; + unsigned char res57[0x75f8]; + unsigned int apll_lock; /* 0x1004_4000 */ + unsigned char res58[0xfc]; + unsigned int apll_con0; /* 0x1004_4100 */ + unsigned int apll_con1; + unsigned int apll_con2; + unsigned char res59[0xf4]; + unsigned int src_cpu; + unsigned char res60[0x1fc]; + unsigned int mux_stat_cpu; + unsigned char res61[0xfc]; + unsigned int div_cpu0; + unsigned int div_cpu1; + unsigned char res62[0xf8]; + unsigned int div_stat_cpu0; + unsigned int div_stat_cpu1; + unsigned char res63[0x1f8]; + unsigned int gate_sclk_cpu; + unsigned char res64[0xfc]; + unsigned int gate_ip_cpu; + unsigned char res65[0xfc]; + unsigned int clkout_cmu_cpu; + unsigned int clkout_cmu_cpu_div_stat; + unsigned char res66[0x5f8]; + unsigned int armclk_stopctrl; /* 0x1004_5000 */ + unsigned int atclk_stopctrl; + unsigned int arm_ema_ctrl; + unsigned int arm_ema_status; + unsigned int parityfail_status; + unsigned int parityfail_clear; + unsigned char res67[0x8]; + unsigned int pwr_ctrl; + unsigned int pwr_ctrl2; + unsigned char res68[0xd8]; + unsigned int apll_con0_l8; + unsigned int apll_con0_l7; + unsigned int apll_con0_l6; + unsigned int apll_con0_l5; + unsigned int apll_con0_l4; + unsigned int apll_con0_l3; + unsigned int apll_con0_l2; + unsigned int apll_con0_l1; + unsigned int iem_control; + unsigned char res69[0xdc]; + unsigned int apll_con1_l8; + unsigned int apll_con1_l7; + unsigned int apll_con1_l6; + unsigned int apll_con1_l5; + unsigned int apll_con1_l4; + unsigned int apll_con1_l3; + unsigned int apll_con1_l2; + unsigned int apll_con1_l1; + unsigned char res70[0xe0]; + unsigned int div_iem_l8; + unsigned int div_iem_l7; + unsigned int div_iem_l6; + unsigned int div_iem_l5; + unsigned int div_iem_l4; + unsigned int div_iem_l3; + unsigned int div_iem_l2; + unsigned int div_iem_l1; + unsigned char res71[0xe0]; + unsigned int l2_status; + unsigned char res72[0xc]; + unsigned int cpu_status; + unsigned char res73[0xc]; + unsigned int ptm_status; + unsigned char res74[0x2edc]; + unsigned int div_isp0; + unsigned int div_isp1; + unsigned char res75[0xf8]; + unsigned int div_stat_isp0; + unsigned int div_stat_isp1; + unsigned char res76[0x2f8]; + unsigned int gate_bus_isp0; + unsigned int gate_bus_isp1; + unsigned int gate_bus_isp2; + unsigned int gate_bus_isp3; + unsigned char res77[0xf0]; + unsigned int gate_ip_isp0; + unsigned int gate_ip_isp1; + unsigned char res78[0xf8]; + unsigned int gate_sclk_isp0; + unsigned char res79[0xfc]; + unsigned int gate_cmu_isp; + unsigned int gate_cmu_isp_div_stat; + unsigned char res80[0xf8]; + unsigned int isp_spare0; + unsigned int isp_spare1; + unsigned int isp_spare2; + unsigned int isp_spare3; + unsigned char res81[0x4074f0]; + unsigned char res82[0x300]; /* 0x1450_0000 */ + unsigned int src_acp; + unsigned int src_mask_acp; + unsigned char res83[0xf8]; + unsigned int mux_stat_acp0; + unsigned int mux_stat_acp1; + unsigned char res84[0xf8]; + unsigned int div_acp0; + unsigned int div_acp1; + unsigned char res85[0xf8]; + unsigned int div_stat_acp0; + unsigned int div_stat_acp1; + unsigned char res86[0xf8]; + unsigned int gate_bus_acp0; + unsigned int gate_bus_acp1; + unsigned char res87[0xf8]; + unsigned int gate_sclk_acp; + unsigned char res88[0xfc]; + unsigned int gate_ip_acp0; + unsigned int gate_ip_acp1; + unsigned char res89[0xf8]; + unsigned int clkout_cmu_acp; + unsigned int clkout_cmu_acp_div_stat; + unsigned char res90[0x5f8]; + unsigned int dcgidx_map0; + unsigned int dcgidx_map1; + unsigned int dcgidx_map2; + unsigned char res91[0x14]; + unsigned int dcgperf_map0; + unsigned int dcgperf_map1; + unsigned char res92[0x18]; + unsigned int dvcidx_map; + unsigned char res93[0x1c]; + unsigned int freq_cpu; + unsigned int freq_dpm; + unsigned char res94[0x18]; + unsigned int dvsemclk_en; + unsigned int maxperf; + unsigned char res95[0xf78]; + unsigned int acp_spare0; + unsigned int acp_spare1; + unsigned int acp_spare2; + unsigned int acp_spare3; + unsigned int acp_spare4; + unsigned char res96[0xdfec]; + unsigned char res97[0x15fffd]; + unsigned char res98[0x8]; /* 0x105c_0000 */ + unsigned int mpll_lock; + unsigned char res99[0xfc]; + unsigned int mpll_con0; + unsigned int mpll_con1; + unsigned int mpll_con2; + unsigned char res100[0x4]; + unsigned int bpll_lock; + unsigned char res101[0xfc]; + unsigned int bpll_con0; + unsigned int bpll_con1; + unsigned int bpll_con2; + unsigned char res102[0xdc]; + unsigned int src_dmc; + unsigned char res103[0xfc]; + unsigned int mux_stat_dmc; + unsigned char res104[0xfc]; + unsigned int div_dyn_freq_scale; + unsigned int div_dmc1; + unsigned char res105[0xf8]; + unsigned int div_stat_dmc0; + unsigned char res106[0xfc]; + unsigned int gate_bus_dmc0; + unsigned int gate_bus_dmc1; + unsigned char res107[0xf8]; + unsigned int gate_sclk_dmc; + unsigned char res108[0xfc]; + unsigned int gate_ip_dmc0; + unsigned int gate_ip_dmc1; + unsigned char res109[0xf8]; + unsigned int clkout_cmu_dmc; + unsigned int clkout_cmu_dmc_div_stat; + unsigned char res110[0x688]; + unsigned int dmc_freq_ctrl; + unsigned int dmc_pause_ctrl; + unsigned int ddrphy_lock_ctrl; + unsigned char res111[0xf64]; + unsigned int semaphore0; + unsigned int semaphore1; + unsigned int semaphore2; + unsigned int cmu_dmc_spare0; + unsigned int cmu_dmc_spare1; +}; + +#else +struct exynos4_clock { + unsigned char res1[0x4200]; /* 0x1003_4200 */ unsigned int src_leftbus; unsigned char res2[0x1fc]; unsigned int mux_stat_leftbus; @@ -35,10 +777,10 @@ struct exynos4_clock { unsigned char res6[0x1fc]; unsigned int gate_ip_leftbus; unsigned char res7[0x1fc]; - unsigned int clkout_leftbus; + unsigned int clkout_leftbus; /* 0x1003_4A00 */ unsigned int clkout_leftbus_div_stat; unsigned char res8[0x37f8]; - unsigned int src_rightbus; + unsigned int src_rightbus; /* 0x1003_8200 */ unsigned char res9[0x1fc]; unsigned int mux_stat_rightbus; unsigned char res10[0xfc]; @@ -48,20 +790,20 @@ struct exynos4_clock { unsigned char res12[0x1fc]; unsigned int gate_ip_rightbus; unsigned char res13[0x1fc]; - unsigned int clkout_rightbus; + unsigned int clkout_rightbus; /* 0x1003_8A00 */ unsigned int clkout_rightbus_div_stat; unsigned char res14[0x3608]; - unsigned int epll_lock; + unsigned int epll_lock; /* 0x1003_C010 */ unsigned char res15[0xc]; unsigned int vpll_lock; unsigned char res16[0xec]; - unsigned int epll_con0; + unsigned int epll_con0; /* 0x1003_C110 */ unsigned int epll_con1; unsigned char res17[0x8]; - unsigned int vpll_con0; + unsigned int vpll_con0; /* 0x1003_C120 */ unsigned int vpll_con1; unsigned char res18[0xe8]; - unsigned int src_top0; + unsigned int src_top0; /* 0x1003_C210 */ unsigned int src_top1; unsigned char res19[0x8]; unsigned int src_cam; @@ -77,7 +819,7 @@ struct exynos4_clock { unsigned int src_peril0; unsigned int src_peril1; unsigned char res21[0xb8]; - unsigned int src_mask_top; + unsigned int src_mask_top; /* 0x1003_C310 */ unsigned char res22[0xc]; unsigned int src_mask_cam; unsigned int src_mask_tv; @@ -90,7 +832,7 @@ struct exynos4_clock { unsigned int src_mask_peril0; unsigned int src_mask_peril1; unsigned char res25[0xb8]; - unsigned int mux_stat_top; + unsigned int mux_stat_top; /* 0x1003_C410 */ unsigned char res26[0x14]; unsigned int mux_stat_mfc; unsigned int mux_stat_g3d; @@ -119,7 +861,7 @@ struct exynos4_clock { unsigned char res29[0x18]; unsigned int div2_ratio; unsigned char res30[0x8c]; - unsigned int div_stat_top; + unsigned int div_stat_top; /* 0x1003_C610 */ unsigned char res31[0xc]; unsigned int div_stat_cam; unsigned int div_stat_tv; @@ -142,7 +884,7 @@ struct exynos4_clock { unsigned char res32[0x18]; unsigned int div2_stat; unsigned char res33[0x29c]; - unsigned int gate_ip_cam; + unsigned int gate_ip_cam; /* 0x1003_C920 */ unsigned int gate_ip_tv; unsigned int gate_ip_mfc; unsigned int gate_ip_g3d; @@ -159,10 +901,17 @@ struct exynos4_clock { unsigned char res37[0xc]; unsigned int gate_block; unsigned char res38[0x8c]; - unsigned int clkout_cmu_top; + unsigned int clkout_cmu_top; /* 0x1003_CA00 */ unsigned int clkout_cmu_top_div_stat; +#ifdef CONFIG_EXYNOS4X12 + unsigned char res39[0x3700]; + unsigned int mpll_con0; /* 0x1004_0108 */ + unsigned int mpll_con1; /* 0x1004_010C */ + unsigned char res65[0xf0]; +#else unsigned char res39[0x37f8]; - unsigned int src_dmc; +#endif + unsigned int src_dmc; /* 0x1004_0200 */ unsigned char res40[0xfc]; unsigned int src_mask_dmc; unsigned char res41[0xfc]; @@ -179,7 +928,7 @@ struct exynos4_clock { unsigned int clkout_cmu_dmc; unsigned int clkout_cmu_dmc_div_stat; unsigned char res46[0x5f8]; - unsigned int dcgidx_map0; + unsigned int dcgidx_map0; /* 0x1004_1000 */ unsigned int dcgidx_map1; unsigned int dcgidx_map2; unsigned char res47[0x14]; @@ -194,15 +943,19 @@ struct exynos4_clock { unsigned int dvsemclk_en; unsigned int maxperf; unsigned char res51[0x2f78]; - unsigned int apll_lock; + unsigned int apll_lock; /* 0x1004_4000 */ unsigned char res52[0x4]; unsigned int mpll_lock; unsigned char res53[0xf4]; - unsigned int apll_con0; + unsigned int apll_con0; /* 0x1004_4100 */ unsigned int apll_con1; +#ifdef CONFIG_EXYNOS4X12 + unsigned char res54[0xf8]; +#else unsigned int mpll_con0; unsigned int mpll_con1; unsigned char res54[0xf0]; +#endif unsigned int src_cpu; unsigned char res55[0x1fc]; unsigned int mux_stat_cpu; @@ -216,7 +969,7 @@ struct exynos4_clock { unsigned int clkout_cmu_cpu; unsigned int clkout_cmu_cpu_div_stat; unsigned char res59[0x5f8]; - unsigned int armclk_stopctrl; + unsigned int armclk_stopctrl; /* 0x1004_5000 */ unsigned int atclk_stopctrl; unsigned char res60[0x8]; unsigned int parityfail_status; @@ -250,6 +1003,7 @@ struct exynos4_clock { unsigned int div_iem_l2; unsigned int div_iem_l1; }; +#endif struct exynos5_clock { unsigned int apll_lock; @@ -273,8 +1027,7 @@ struct exynos5_clock { unsigned int clkout_cmu_cpu_div_stat; unsigned char res8[0x5f8]; unsigned int armclk_stopctrl; - unsigned int atclk_stopctrl; - unsigned char res9[0x8]; + unsigned char res9[0xc]; unsigned int parityfail_status; unsigned int parityfail_clear; unsigned char res10[0x8]; @@ -323,12 +1076,15 @@ struct exynos5_clock { unsigned char res19[0xf8]; unsigned int div_core0; unsigned int div_core1; - unsigned char res20[0xf8]; + unsigned int div_sysrgt; + unsigned char res20[0xf4]; unsigned int div_stat_core0; unsigned int div_stat_core1; - unsigned char res21[0x2f8]; + unsigned int div_stat_sysrgt; + unsigned char res21[0x2f4]; unsigned int gate_ip_core; - unsigned char res22[0xfc]; + unsigned int gate_ip_sysrgt; + unsigned char res22[0xf8]; unsigned int clkout_cmu_core; unsigned int clkout_cmu_core_div_stat; unsigned char res23[0x5f8]; @@ -346,235 +1102,1336 @@ struct exynos5_clock { unsigned char res27[0x18]; unsigned int dvsemclk_en; unsigned int maxperf; - unsigned char res28[0x3478]; + unsigned char res28[0xf78]; + unsigned int c2c_config; + unsigned char res29[0x24fc]; unsigned int div_acp; - unsigned char res29[0xfc]; + unsigned char res30[0xfc]; unsigned int div_stat_acp; - unsigned char res30[0x1fc]; - unsigned int gate_ip_acp; unsigned char res31[0x1fc]; + unsigned int gate_ip_acp; + unsigned char res32[0xfc]; + unsigned int div_syslft; + unsigned char res33[0xc]; + unsigned int div_stat_syslft; + unsigned char res34[0x1c]; + unsigned int gate_ip_syslft; + unsigned char res35[0xcc]; unsigned int clkout_cmu_acp; unsigned int clkout_cmu_acp_div_stat; - unsigned char res32[0x38f8]; + unsigned char res36[0x8]; + unsigned int ufmc_config; + unsigned char res37[0x38ec]; unsigned int div_isp0; unsigned int div_isp1; unsigned int div_isp2; - unsigned char res33[0xf4]; + unsigned char res38[0xf4]; unsigned int div_stat_isp0; unsigned int div_stat_isp1; unsigned int div_stat_isp2; - unsigned char res34[0x3f4]; + unsigned char res39[0x3f4]; unsigned int gate_ip_isp0; unsigned int gate_ip_isp1; - unsigned char res35[0xf8]; + unsigned char res40[0xf8]; unsigned int gate_sclk_isp; - unsigned char res36[0xc]; + unsigned char res41[0xc]; unsigned int mcuisp_pwr_ctrl; - unsigned char res37[0xec]; + unsigned char res42[0xec]; unsigned int clkout_cmu_isp; unsigned int clkout_cmu_isp_div_stat; - unsigned char res38[0x3618]; + unsigned char res43[0x3618]; unsigned int cpll_lock; - unsigned char res39[0xc]; + unsigned char res44[0xc]; unsigned int epll_lock; - unsigned char res40[0xc]; + unsigned char res45[0xc]; unsigned int vpll_lock; - unsigned char res41[0xdc]; + unsigned char res46[0xc]; + unsigned int gpll_lock; + unsigned char res47[0xcc]; unsigned int cpll_con0; unsigned int cpll_con1; - unsigned char res42[0x8]; + unsigned char res48[0x8]; unsigned int epll_con0; unsigned int epll_con1; unsigned int epll_con2; - unsigned char res43[0x4]; + unsigned char res49[0x4]; unsigned int vpll_con0; unsigned int vpll_con1; unsigned int vpll_con2; - unsigned char res44[0xc4]; + unsigned char res50[0x4]; + unsigned int gpll_con0; + unsigned int gpll_con1; + unsigned char res51[0xb8]; unsigned int src_top0; unsigned int src_top1; unsigned int src_top2; unsigned int src_top3; unsigned int src_gscl; - unsigned int src_disp0_0; - unsigned int src_disp0_1; + unsigned char res52[0x8]; unsigned int src_disp1_0; - unsigned int src_disp1_1; - unsigned char res46[0xc]; + unsigned char res53[0x10]; unsigned int src_mau; unsigned int src_fsys; - unsigned char res47[0x8]; + unsigned int src_gen; + unsigned char res54[0x4]; unsigned int src_peric0; unsigned int src_peric1; - unsigned char res48[0x18]; + unsigned char res55[0x18]; unsigned int sclk_src_isp; - unsigned char res49[0x9c]; + unsigned char res56[0x9c]; unsigned int src_mask_top; - unsigned char res50[0xc]; + unsigned char res57[0xc]; unsigned int src_mask_gscl; - unsigned int src_mask_disp0_0; - unsigned int src_mask_disp0_1; + unsigned char res58[0x8]; unsigned int src_mask_disp1_0; - unsigned int src_mask_disp1_1; + unsigned char res59[0x4]; unsigned int src_mask_maudio; - unsigned char res52[0x8]; + unsigned char res60[0x8]; unsigned int src_mask_fsys; - unsigned char res53[0xc]; + unsigned int src_mask_gen; + unsigned char res61[0x8]; unsigned int src_mask_peric0; unsigned int src_mask_peric1; - unsigned char res54[0x18]; + unsigned char res62[0x18]; unsigned int src_mask_isp; - unsigned char res55[0x9c]; + unsigned char res63[0x9c]; unsigned int mux_stat_top0; unsigned int mux_stat_top1; unsigned int mux_stat_top2; unsigned int mux_stat_top3; - unsigned char res56[0xf0]; + unsigned char res64[0xf0]; unsigned int div_top0; unsigned int div_top1; - unsigned char res57[0x8]; + unsigned char res65[0x8]; unsigned int div_gscl; - unsigned int div_disp0_0; - unsigned int div_disp0_1; + unsigned char res66[0x8]; unsigned int div_disp1_0; - unsigned int div_disp1_1; - unsigned char res59[0x8]; + unsigned char res67[0xc]; unsigned int div_gen; - unsigned char res60[0x4]; + unsigned char res68[0x4]; unsigned int div_mau; unsigned int div_fsys0; unsigned int div_fsys1; unsigned int div_fsys2; - unsigned int div_fsys3; + unsigned char res69[0x4]; unsigned int div_peric0; unsigned int div_peric1; unsigned int div_peric2; unsigned int div_peric3; unsigned int div_peric4; unsigned int div_peric5; - unsigned char res61[0x10]; + unsigned char res70[0x10]; unsigned int sclk_div_isp; - unsigned char res62[0xc]; + unsigned char res71[0xc]; unsigned int div2_ratio0; unsigned int div2_ratio1; - unsigned char res63[0x8]; + unsigned char res72[0x8]; unsigned int div4_ratio; - unsigned char res64[0x6c]; + unsigned char res73[0x6c]; unsigned int div_stat_top0; unsigned int div_stat_top1; - unsigned char res65[0x8]; + unsigned char res74[0x8]; unsigned int div_stat_gscl; - unsigned int div_stat_disp0_0; - unsigned int div_stat_disp0_1; + unsigned char res75[0x8]; unsigned int div_stat_disp1_0; - unsigned int div_stat_disp1_1; - unsigned char res67[0x8]; + unsigned char res76[0xc]; unsigned int div_stat_gen; - unsigned char res68[0x4]; + unsigned char res77[0x4]; unsigned int div_stat_maudio; unsigned int div_stat_fsys0; unsigned int div_stat_fsys1; unsigned int div_stat_fsys2; - unsigned int div_stat_fsys3; + unsigned char res78[0x4]; unsigned int div_stat_peric0; unsigned int div_stat_peric1; unsigned int div_stat_peric2; unsigned int div_stat_peric3; unsigned int div_stat_peric4; unsigned int div_stat_peric5; - unsigned char res69[0x10]; + unsigned char res79[0x10]; unsigned int sclk_div_stat_isp; - unsigned char res70[0xc]; + unsigned char res80[0xc]; unsigned int div2_stat0; unsigned int div2_stat1; - unsigned char res71[0x8]; + unsigned char res81[0x8]; unsigned int div4_stat; - unsigned char res72[0x180]; - unsigned int gate_top_sclk_disp0; + unsigned char res82[0x184]; unsigned int gate_top_sclk_disp1; unsigned int gate_top_sclk_gen; - unsigned char res74[0xc]; + unsigned char res83[0xc]; unsigned int gate_top_sclk_mau; unsigned int gate_top_sclk_fsys; - unsigned char res75[0xc]; + unsigned char res84[0xc]; unsigned int gate_top_sclk_peric; - unsigned char res76[0x1c]; + unsigned char res85[0x1c]; unsigned int gate_top_sclk_isp; - unsigned char res77[0xac]; + unsigned char res86[0xac]; unsigned int gate_ip_gscl; - unsigned int gate_ip_disp0; + unsigned char res87[0x4]; unsigned int gate_ip_disp1; unsigned int gate_ip_mfc; unsigned int gate_ip_g3d; unsigned int gate_ip_gen; - unsigned char res79[0xc]; + unsigned char res88[0xc]; unsigned int gate_ip_fsys; - unsigned char res80[0x4]; - unsigned int gate_ip_gps; + unsigned char res89[0x8]; unsigned int gate_ip_peric; - unsigned char res81[0xc]; + unsigned char res90[0xc]; unsigned int gate_ip_peris; - unsigned char res82[0x1c]; + unsigned char res91[0x1c]; unsigned int gate_block; - unsigned char res83[0x7c]; + unsigned char res92[0x1c]; + unsigned int mcuiop_pwr_ctrl; + unsigned char res93[0x5c]; unsigned int clkout_cmu_top; unsigned int clkout_cmu_top_div_stat; - unsigned char res84[0x37f8]; + unsigned char res94[0x37f8]; unsigned int src_lex; - unsigned char res85[0x2fc]; + unsigned char res95[0x1fc]; + unsigned int mux_stat_lex; + unsigned char res96[0xfc]; unsigned int div_lex; - unsigned char res86[0xfc]; + unsigned char res97[0xfc]; unsigned int div_stat_lex; - unsigned char res87[0x1fc]; + unsigned char res98[0x1fc]; unsigned int gate_ip_lex; - unsigned char res88[0x1fc]; + unsigned char res99[0x1fc]; unsigned int clkout_cmu_lex; unsigned int clkout_cmu_lex_div_stat; - unsigned char res89[0x3af8]; + unsigned char res100[0x3af8]; unsigned int div_r0x; - unsigned char res90[0xfc]; + unsigned char res101[0xfc]; unsigned int div_stat_r0x; - unsigned char res91[0x1fc]; + unsigned char res102[0x1fc]; unsigned int gate_ip_r0x; - unsigned char res92[0x1fc]; + unsigned char res103[0x1fc]; unsigned int clkout_cmu_r0x; unsigned int clkout_cmu_r0x_div_stat; - unsigned char res94[0x3af8]; + unsigned char res104[0x3af8]; unsigned int div_r1x; - unsigned char res95[0xfc]; + unsigned char res105[0xfc]; unsigned int div_stat_r1x; - unsigned char res96[0x1fc]; + unsigned char res106[0x1fc]; unsigned int gate_ip_r1x; - unsigned char res97[0x1fc]; + unsigned char res107[0x1fc]; unsigned int clkout_cmu_r1x; unsigned int clkout_cmu_r1x_div_stat; - unsigned char res98[0x3608]; + unsigned char res108[0x3608]; unsigned int bpll_lock; - unsigned char res99[0xfc]; + unsigned char res109[0xfc]; unsigned int bpll_con0; unsigned int bpll_con1; - unsigned char res100[0xe8]; + unsigned char res110[0xe8]; unsigned int src_cdrex; - unsigned char res101[0x1fc]; + unsigned char res111[0x1fc]; unsigned int mux_stat_cdrex; - unsigned char res102[0xfc]; + unsigned char res112[0xfc]; unsigned int div_cdrex; - unsigned int div_cdrex2; - unsigned char res103[0xf8]; + unsigned char res113[0xfc]; unsigned int div_stat_cdrex; - unsigned char res104[0x2fc]; + unsigned char res114[0x2fc]; unsigned int gate_ip_cdrex; - unsigned char res105[0xc]; - unsigned int c2c_monitor; - unsigned int dmc_pwr_ctrl; - unsigned char res106[0x4]; + unsigned char res115[0x10]; + unsigned int dmc_freq_ctrl; + unsigned char res116[0x4]; unsigned int drex2_pause; - unsigned char res107[0xe0]; + unsigned char res117[0xe0]; unsigned int clkout_cmu_cdrex; unsigned int clkout_cmu_cdrex_div_stat; - unsigned char res108[0x8]; + unsigned char res118[0x8]; unsigned int lpddr3phy_ctrl; - unsigned char res109[0xf5f8]; + unsigned char res119[0xc]; + unsigned int lpddr3phy_con3; + unsigned int pll_div2_sel; + unsigned char res120[0xf5d8]; +}; + +struct exynos5410_clock { + unsigned int apll_lock; /* 0x1001_0000 */ + unsigned char res1[0xfc]; + unsigned int apll_con0; /* 0x1001_0100 */ + unsigned int apll_con1; /* 0x1001_0104 */ + unsigned char res2[0xf8]; + unsigned int src_cpu; /* 0x1001_0200 */ + unsigned char res3[0x2fc]; + unsigned int div_cpu0; /* 0x1001_0500 */ + unsigned int div_cpu1; /* 0x1001_0504 */ + unsigned char res4[0x4f8]; + unsigned int clkout_cmu_cpu; /* 0x1001_0A00 */ + unsigned char res5[0x35fc]; + unsigned int mpll_lock; /* 0x1001_4000 */ + unsigned char res6[0xfc]; + unsigned int mpll_con0; /* 0x1001_4100 */ + unsigned int mpll_con1; /* 0x1001_4104 */ + unsigned char res7[0xf8]; + unsigned int src_core0; /* 0x1001_4200 */ + unsigned int src_core1; /* 0x1001_4204 */ + unsigned char res8[0x2fc]; + unsigned int div_core1; /* 0x1001_4504 */ + unsigned char res9[0x4f8]; + unsigned int clkout_cmu_core; /* 0x1001_4A00 */ + unsigned char res10[0xb71c]; + unsigned int cpll_con0; /* 0x1002_0120 */ + unsigned int cpll_con1; /* 0x1002_0124 */ + unsigned int dpll_con0; /* 0x1002_0128 */ + unsigned int dpll_con1; /* 0x1002_012C */ + unsigned int epll_con0; /* 0x1002_0130 */ + unsigned int epll_con1; /* 0x1002_0134 */ + unsigned int epll_con2; /* 0x1002_0138 */ + unsigned char res11[0x4]; + unsigned int vpll_con0; /* 0x1002_0140 */ + unsigned int vpll_con1; /* 0x1002_0144 */ + unsigned int vpll_con2; /* 0x1002_0148 */ + unsigned char res12[0xc4]; + unsigned int src_top0; /* 0x1002_0210 */ + unsigned int src_top1; /* 0x1002_0214 */ + unsigned int src_top2; /* 0x1002_0218 */ + unsigned int src_top3; /* 0x1002_021C */ + unsigned char res13[0x20]; + unsigned int src_mau; /* 0x1002_0240 */ + unsigned int src_fsys; /* 0x1002_0244 */ + unsigned char res14[0x8]; + unsigned int src_peric0; /* 0x1002_0250 */ + unsigned int src_peric1; /* 0x1002_0254 */ + unsigned char res15[0x2b8]; + unsigned int div_top0; /* 0x1002_0510 */ + unsigned int div_top1; /* 0x1002_0514 */ + unsigned int div_top2; /* 0x1002_0518 */ + unsigned int div_top3; /* 0x1002_051C */ + unsigned char res16[0x28]; + unsigned int div_fsys0; /* 0x1002_0548 */ + unsigned int div_fsys1; /* 0x1002_054C */ + unsigned int div_fsys2; /* 0x1002_0550 */ + unsigned int div_fsys3; /* 0x1002_0554 */ + unsigned int div_peric0; /* 0x1002_0558 */ + unsigned char res17[0x44]; + unsigned int div4_ratio; /* 0x1002_05A0 */ + unsigned char res18[0x45c]; + unsigned int clkout_cmu_top; /* 0x1002_0A00 */ + unsigned char res19[0xf60c]; + unsigned int bpll_lock; /* 0x1003_0010 */ + unsigned char res20[0xfc]; + unsigned int bpll_con0; /* 0x1003_0110 */ + unsigned int bpll_con1; /* 0x1003_0114 */ + unsigned char res21[0xe8]; + unsigned int src_cdrex; /* 0x1003_0200 */ + unsigned char res22[0x1fc]; + unsigned int mux_stat_cdrex; /* 0x1003_0400 */ + unsigned char res23[0xfc]; + unsigned int div_cdrex0; /* 0x1003_0500 */ + unsigned int div_cdrex1; /* 0x1003_0504 */ + unsigned char res24[0x4f8]; + unsigned int clkout_cmu_cdrex; /* 0x1003_0A00 */ + unsigned char res25[0x75fc]; + unsigned int kpll_lock; /* 0x1003_8000 */ + unsigned char res26[0xfc]; + unsigned int kpll_con0; /* 0x1003_8100 */ + unsigned int kpll_con1; /* 0x1003_8104 */ + unsigned char res27[0xf8]; + unsigned int src_kfc; /* 0x1003_8200 */ + unsigned char res28[0x2fc]; + unsigned int div_kfc; /* 0x1003_8500 */ +}; + +struct exynos5260_clock_egl { + unsigned int egl_pll_lock; /* 0x1060_0000 */ + unsigned int egl_dpll_lock; + unsigned char res1[0xf8]; + unsigned int egl_pll_con0; + unsigned int egl_pll_con1; + unsigned char res2[0x4]; + unsigned int egl_pll_freq_det; + unsigned int egl_dpll_con0; + unsigned int egl_dpll_con1; + unsigned char res3[0x4]; + unsigned int egl_dpll_freq_det; + unsigned char res4[0xe0]; + unsigned int clk_mux_sel_egl; + unsigned char res5[0xfc]; + unsigned int clk_mux_enable_egl; + unsigned char res6[0xfc]; + unsigned int clk_mux_stat_egl; + unsigned char res7[0x1fc]; + unsigned int clk_div_egl; + unsigned int clk_div_egl_pll_freq_det; + unsigned char res8[0xf8]; + unsigned int clk_div_stat_egl; + unsigned int clk_div_stat_egl_pll_freq_det; + unsigned char res9[0xf8]; + unsigned int clk_en_aclk_egl; + unsigned char res10[0xfc]; + unsigned int clk_en_pclk_egl; + unsigned char res11[0xfc]; + unsigned int clk_en_sclk_egl; + unsigned char res12[0xfc]; + unsigned int clk_en_ip_egl; + unsigned char res13[0xfc]; + unsigned int clkout_cmu_egl; + unsigned int clkout_cmu_egl_div_stat; + unsigned char res14[0x3f8]; + unsigned int armclk_stopctrl; + unsigned char res15[0x4]; + unsigned int eagle_ema_ctrl; + unsigned int eagle_ema_status; + unsigned char res16[0x10]; + unsigned int pwr_ctrl; + unsigned int pwr_ctrl2; + unsigned int clkstop_ctrl; + unsigned char res17[0x54]; + unsigned int intr_spread_enable; + unsigned int intr_spread_use_standbywfi; + unsigned char res18[0xf74]; + unsigned int cmu_egl_spare0; + unsigned int cmu_egl_spare1; + unsigned int cmu_egl_spare2; + unsigned int cmu_egl_spare3; + unsigned int cmu_egl_spare4; /* 0x1060_2010 */ +}; + +struct exynos5260_clock_fsys { + unsigned char res1[0x200]; + unsigned int clk_mux_sel_fsys0; /* 0x122E_0200 */ + unsigned int clk_mux_sel_fsys1; + unsigned char res2[0xf8]; + unsigned int clk_mux_enable_fsys0; + unsigned int clk_mux_enable_fsys1; + unsigned char res3[0xf8]; + unsigned int clk_mux_stat_fsys0; + unsigned int clk_mux_stat_fsys1; + unsigned char res4[0xf8]; + unsigned int clk_mux_ignore_fsys0; + unsigned int clk_mux_ignore_fsys1; + unsigned char res5[0x2f8]; + unsigned int clk_en_aclk_fsys; + unsigned int clk_en_aclk_fsys_secure_rtic; + unsigned int clk_en_aclk_fsys_secure_smmu_rtic; + unsigned char res6[0xf4]; + unsigned int clk_en_pclk_fsys; + unsigned char res7[0xfc]; + unsigned int clk_en_sclk_fsys; + unsigned char res8[0xfc]; + unsigned int clk_en_ip_fsys; + unsigned int clk_en_ip_fsys_secure_rtic; + unsigned int clk_en_ip_fsys_secure_smmu_rtic; /* 0x122E_0B08 */ +}; + +struct exynos5260_clock_kfc { + unsigned int kfc_pll_lock; /* 0x1070_0000 */ + unsigned char res1[0xfc]; + unsigned int kfc_pll_con0; + unsigned int kfc_pll_con1; + unsigned char res2[0x4]; + unsigned int kfc_pll_freq_det; + unsigned char res3[0xf0]; + unsigned int clk_mux_sel_kfc0; + unsigned char res4[0x4]; + unsigned int clk_mux_sel_kfc2; + unsigned char res5[0xf4]; + unsigned int clk_mux_enable_kfc0; + unsigned char res6[0x4]; + unsigned int clk_mux_enable_kfc2; + unsigned char res7[0xf4]; + unsigned int clk_mux_stat_kfc0; + unsigned char res8[0x4]; + unsigned int clk_mux_stat_kfc2; + unsigned char res9[0x1f4]; + unsigned int clk_div_kfc; + unsigned int clk_div_kfc_pll_freq_det; + unsigned char res10[0xf8]; + unsigned int clk_div_stat_kfc; + unsigned int clk_div_stat_kfc_pll_freq_det; + unsigned char res11[0xf8]; + unsigned int clk_en_aclk_kfc; + unsigned char res12[0xfc]; + unsigned int clk_en_pclk_kfc; + unsigned char res13[0xfc]; + unsigned int clk_en_sclk_kfc; + unsigned char res14[0xfc]; + unsigned int clk_en_ip_kfc; + unsigned char res15[0xfc]; + unsigned int clkout_cmu_kfc; + unsigned int clkout_cmu_kfc_div_stat; + unsigned char res16[0x3f8]; + unsigned int armclk_stopctrl_kfc; + unsigned char res17[0x4]; + unsigned int arm_ema_ctrl; + unsigned int arm_ema_status; + unsigned char res18[0x10]; + unsigned int pwr_ctrl_kfc; + unsigned int pwr_ctrl2_kfc; + unsigned int clkstop_ctrl_kfc; + unsigned char res19[0x54]; + unsigned int intr_spread_enable_kfc; + unsigned int intr_spread_use_standbywfi_kfc; + unsigned int intr_spread_blocking_duration_kfc; + unsigned char res20[0xf74]; + unsigned int cmu_kfc_spare0; + unsigned int cmu_kfc_spare1; + unsigned int cmu_kfc_spare2; + unsigned int cmu_kfc_spare3; + unsigned int cmu_kfc_spare4; /* 0x1070_2010 */ +}; + +struct exynos5260_clock_mif { + unsigned int mem_pll_lock; /* 0x10CE_0000 */ + unsigned int bus_pll_lock; + unsigned int media_pll_lock; + unsigned char res1[0xf4]; + unsigned int mem_pll_con0; + unsigned int mem_pll_con1; + unsigned char res2[0x4]; + unsigned int mem_pll_freq_det; + unsigned int bus_pll_con0; + unsigned int bus_pll_con1; + unsigned char res3[0x4]; + unsigned int bus_pll_freq_det; + unsigned int media_pll_con0; + unsigned int media_pll_con1; + unsigned char res4[0x4]; + unsigned int media_pll_freq_det; + unsigned char res5[0xd0]; + unsigned int clk_mux_sel_mif; + unsigned char res6[0xfc]; + unsigned int clk_mux_enable_mif; + unsigned char res7[0xfc]; + unsigned int clk_mux_stat_mif; + unsigned char res8[0xfc]; + unsigned int clk_mux_ignore_mif; + unsigned char res9[0xfc]; + unsigned int clk_div_mif; + unsigned int clk_div_mif_pll_freq_det; + unsigned char res10[0xf8]; + unsigned int clk_div_stat_mif; + unsigned int clk_div_stat_mif_pll_freq_det; + unsigned char res11[0xf8]; + unsigned int clk_en_aclk_mif; + unsigned int clk_en_aclk_mif_secure_drex1_tz; + unsigned int clk_en_aclk_mif_secure_drex0_tz; + unsigned int clk_en_aclk_mif_secure_intmem; + unsigned char res12[0xf0]; + unsigned int clk_en_pclk_mif; + unsigned int clk_en_pclk_mif_secure_monocnt; + unsigned int clk_en_pclk_mif_secure_rtc_apbif; + unsigned int clk_en_pclk_mif_secure_drex1_tz; + unsigned int clk_en_pclk_mif_secure_drex0_tz; + unsigned char res13[0xec]; + unsigned int clk_en_sclk_mif; + unsigned char res14[0xfc]; + unsigned int clk_en_ip_mif; + unsigned int clk_en_ip_mif_secure_monocnt; + unsigned int clk_en_ip_mif_secure_rtc_apbif; + unsigned int clk_en_ip_mif_secure_drex1_tz; + unsigned int clk_en_ip_mif_secure_drex0_tz; + unsigned int clk_en_ip_mif_secure_intmem; + unsigned char res15[0xec]; + unsigned int clkout_cmu_mif_div_stat; + unsigned char res16[0x3f8]; + unsigned int drex_freq_ctrl; + unsigned int pause; + unsigned int ddrphy_lock_ctrl; + unsigned char res17[0xbaf4]; + unsigned int clkout_cmu_mif; /* 0x10CE_CB00 */ +}; + +struct exynos5260_clock_peri { + unsigned int clk_mux_sel_peri; /* 0x1020_0200 */ + unsigned int clk_mux_sel_peri1; + unsigned char res1[0xf8]; + unsigned int clk_mux_enable_peri; + unsigned int clk_mux_enable_peri1; + unsigned char res2[0xf8]; + unsigned int clk_mux_stat_peri; + unsigned int clk_mux_stat_peri1; + unsigned char res3[0xf8]; + unsigned int clk_mux_ignore_peri; + unsigned int clk_mux_ignore_peri1; + unsigned char res4[0xf8]; + unsigned int clk_div_peri; + unsigned char res5[0xfc]; + unsigned int clk_div_stat_peri; + unsigned char res6[0xfc]; + unsigned int clk_en_pclk_peri0; + unsigned int clk_en_pclk_peri1; + unsigned int clk_en_pclk_peri2; + unsigned int clk_en_pclk_peri3; + unsigned int clk_en_pclk_peri_secure_chipid; + unsigned int clk_en_pclk_peri_secure_provkey0; + unsigned int clk_en_pclk_peri_secure_provkey1; + unsigned int clk_en_pclk_peri_secure_seckey; + unsigned int clk_en_pclk_peri_secure_antirbkcnt; + unsigned int clk_en_pclk_peri_secure_top_rtc; + unsigned int clk_en_pclk_peri_secure_tzpc; + unsigned char res7[0x1d4]; + unsigned int clk_en_sclk_peri; + unsigned int clk_en_sclk_peri_secure_top_rtc; + unsigned char res8[0xf8]; + unsigned int clk_en_ip_peri0; + unsigned int clk_en_ip_peri1; + unsigned int clk_en_ip_peri2; + unsigned int clk_en_ip_peri_secure_chipid; + unsigned int clk_en_ip_peri_secure_provkey0; + unsigned int clk_en_ip_peri_secure_provkey1; + unsigned int clk_en_ip_peri_secure_seckey; + unsigned int clk_en_ip_peri_secure_antirbkcnt; + unsigned int clk_en_ip_peri_secure_top_rtc; + unsigned int clk_en_ip_peri_secure_tzpc; /* 0x1020_0B24 */ +}; + +struct exynos5260_clock_top { + unsigned int disp_pll_lock; /* 0x1001_0000 */ + unsigned int aud_pll_lock; + unsigned char res1[0xf8]; + unsigned int disp_pll_con0; + unsigned int disp_pll_con1; + unsigned int disp_pll_freq_det; + unsigned char res2[0x4]; + unsigned int aud_pll_con0; + unsigned int aud_pll_con1; + unsigned int aud_pll_con2; + unsigned int aud_pll_freq_det; + unsigned char res3[0xe0]; + unsigned int clk_mux_sel_top_pll0; + unsigned int clk_mux_sel_top_mfc; + unsigned int clk_mux_sel_top_g2d; + unsigned int clk_mux_sel_top_gscl; + unsigned char res4[0x4]; + unsigned int clk_mux_sel_top_isp10; + unsigned int clk_mux_sel_top_isp11; + unsigned int clk_mux_sel_top_disp0; + unsigned int clk_mux_sel_top_disp1; + unsigned int clk_mux_sel_top_bus; + unsigned int clk_mux_sel_top_peri0; + unsigned int clk_mux_sel_top_peri1; + unsigned int clk_mux_sel_top_fsys; + unsigned char res5[0xcc]; + unsigned int clk_mux_enable_top_pll0; + unsigned int clk_mux_enable_top_mfc; + unsigned int clk_mux_enable_top_g2d; + unsigned int clk_mux_enable_top_gscl; + unsigned char res6[0x4]; + unsigned int clk_mux_enable_top_isp10; + unsigned int clk_mux_enable_top_isp11; + unsigned int clk_mux_enable_top_disp0; + unsigned int clk_mux_enable_top_disp1; + unsigned int clk_mux_enable_top_bus; + unsigned int clk_mux_enable_top_peri0; + unsigned int clk_mux_enable_top_peri1; + unsigned int clk_mux_enable_top_fsys; + unsigned char res7[0xcc]; + unsigned int clk_mux_stat_top_pll0; + unsigned int clk_mux_stat_top_mfc; + unsigned int clk_mux_stat_top_g2d; + unsigned int clk_mux_stat_top_gscl; + unsigned char res8[0x4]; + unsigned int clk_mux_stat_top_isp10; + unsigned int clk_mux_stat_top_isp11; + unsigned int clk_mux_stat_top_disp0; + unsigned int clk_mux_stat_top_disp1; + unsigned int clk_mux_stat_top_bus; + unsigned int clk_mux_stat_top_peri0; + unsigned int clk_mux_stat_top_peri1; + unsigned int clk_mux_stat_top_fsys; + unsigned char res9[0xcc]; + unsigned int clk_mux_ignore_top_pll0; + unsigned int clk_mux_ignore_top_mfc; + unsigned int clk_mux_ignore_top_g2d; + unsigned int clk_mux_ignore_top_gscl; + unsigned char res10[0x4]; + unsigned int clk_mux_ignore_top_isp10; + unsigned int clk_mux_ignore_top_isp11; + unsigned int clk_mux_ignore_top_disp0; + unsigned int clk_mux_ignore_top_disp1; + unsigned int clk_mux_ignore_top_bus; + unsigned int clk_mux_ignore_top_peri0; + unsigned int clk_mux_ignore_top_peri1; + unsigned int clk_mux_ignore_top_fsys; + unsigned char res11[0xcc]; + unsigned int clk_div_top_g2d_mfc; + unsigned int clk_div_top_gscl_isp0; + unsigned int clk_div_top_isp10; + unsigned int clk_div_top_isp11; + unsigned int clk_div_top_disp; + unsigned int clk_div_top_bus; + unsigned int clk_div_top_peri0; + unsigned int clk_div_top_peri1; + unsigned int clk_div_top_peri2; + unsigned int clk_div_top_fsys0; + unsigned int clk_div_top_fsys1; + unsigned int clk_div_top_hpm; + unsigned int clk_div_top_pll_freq_det; + unsigned char res12[0xcc]; + unsigned int clk_div_stat_top_g2d_mfc; + unsigned int clk_div_stat_top_gscl_isp0; + unsigned int clk_div_stat_top_isp10; + unsigned int clk_div_stat_top_isp11; + unsigned int clk_div_stat_top_disp; + unsigned int clk_div_stat_top_bus; + unsigned int clk_div_stat_top_peri0; + unsigned int clk_div_stat_top_peri1; + unsigned int clk_div_stat_top_peri2; + unsigned int clk_div_stat_top_fsys0; + unsigned int clk_div_stat_top_fsys1; + unsigned int clk_div_stat_top_hpm; + unsigned int clk_div_stat_top_pll_freq_det; + unsigned char res13[0xcc]; + unsigned int clk_en_aclk_top; + unsigned char res14[0x1fc]; + unsigned int clk_en_sclk_top; + unsigned char res15[0xfc]; + unsigned int clk_en_ip_top; + unsigned char res16[0xfc]; + unsigned int clkout_cmu_top; + unsigned int clkout_cmu_top_div_stat; /* 0x1001_0C04 */ +}; + +/* EXYNOS5430 CMU */ +struct exynos5430_clock_egl { + unsigned int egl_pll_lock; /* 0x1180_0000 */ + unsigned int egl_dpll_lock; + unsigned char res1[0xf8]; + unsigned int egl_pll_con0; + unsigned int egl_pll_con1; + unsigned char res2[0x4]; + unsigned int egl_pll_freq_det; + unsigned int egl_dpll_con0; + unsigned int egl_dpll_con1; + unsigned int egl_dpll_con2; + unsigned int egl_dpll_freq_det; + unsigned char res3[0xe0]; + unsigned int clk_mux_sel_egl0; + unsigned int clk_mux_sel_egl1; + unsigned int clk_mux_sel_egl2; + unsigned char res4[0xf4]; + unsigned int clk_mux_enable_egl0; + unsigned int clk_mux_enable_egl1; + unsigned int clk_mux_enable_egl2; + unsigned char res5[0xf4]; + unsigned int clk_mux_stat_egl0; + unsigned int clk_mux_stat_egl1; + unsigned int clk_mux_stat_egl2; + unsigned char res6[0x1f4]; + unsigned int clk_div_egl0; + unsigned int clk_div_egl1; + unsigned int clk_div_egl_pll_freq_det; + unsigned char res7[0xf4]; + unsigned int clk_div_stat_egl0; + unsigned int clk_div_stat_egl1; + unsigned int clk_div_stat_egl_pll_freq_det; + unsigned char res8[0xf4]; + unsigned int clk_enable_aclk_egl; + unsigned char res9[0xfc]; + unsigned int clk_enable_pclk_egl; + unsigned char res10[0xfc]; + unsigned int clk_enable_sclk_egl; + unsigned char res11[0xfc]; + unsigned int clk_enable_ip_egl0; + unsigned int clk_enable_ip_egl1; + unsigned char res12[0xf8]; + unsigned int clkout_cmu_egl; + unsigned char res13[0x3fc]; + unsigned int armclk_stopctrl; + unsigned char res14[0x1c]; + unsigned int pwr_ctrl; + unsigned int pwr_ctrl2; + unsigned char res15[0x58]; + unsigned int intr_spread_enable; + unsigned int intr_spread_use_standbywfi; + unsigned int intr_spread_blocking_duration; /* 0x1180_1088 */ +}; + +struct exynos5430_clock_fsys { + unsigned char res1[0x200]; /* 0x156E_0000 */ + unsigned int clk_mux_sel_fsys0; + unsigned int clk_mux_sel_fsys1; + unsigned int clk_mux_sel_fsys2; + unsigned int clk_mux_sel_fsys3; + unsigned char res2[0xf0]; + unsigned int clk_mux_enable_fsys0; + unsigned int clk_mux_enable_fsys1; + unsigned int clk_mux_enable_fsys2; + unsigned int clk_mux_enable_fsys3; + unsigned int clk_mux_enable_fsys4; + unsigned char res3[0xec]; + unsigned int clk_mux_stat_fsys0; + unsigned int clk_mux_stat_fsys1; + unsigned int clk_mux_stat_fsys2; + unsigned int clk_mux_stat_fsys3; + unsigned int clk_mux_stat_fsys4; + unsigned char res4[0xec]; + unsigned int clk_mux_ignore_fsys2; + unsigned int clk_mux_ignore_fsys3; + unsigned char res5[0x2f8]; + unsigned int clk_enable_aclk_fsys0; + unsigned int clk_enable_aclk_fsys1; + unsigned char res6[0xf8]; + unsigned int clk_enable_pclk_fsys; + unsigned char res7[0xfc]; + unsigned int clk_enable_sclk_fsys; + unsigned char res8[0xfc]; + unsigned int clk_enable_ip_fsys0; + unsigned int clk_enable_ip_fsys1; /* 0x156E_0B04 */ +}; + +struct exynos5430_clock_kfc { + unsigned int kfc_pll_lock; /* 0x1190_0000 */ + unsigned char res1[0xfc]; + unsigned int kfc_pll_con0; + unsigned int kfc_pll_con1; + unsigned char res2[0x4]; + unsigned int kfc_pll_freq_det; + unsigned char res3[0xf0]; + unsigned int clk_mux_sel_kfc0; + unsigned int clk_mux_sel_kfc1; + unsigned int clk_mux_sel_kfc2; + unsigned char res5[0xf4]; + unsigned int clk_mux_enable_kfc0; + unsigned int clk_mux_enable_kfc1; + unsigned int clk_mux_enable_kfc2; + unsigned char res6[0xf4]; + unsigned int clk_mux_stat_kfc0; + unsigned int clk_mux_stat_kfc1; + unsigned int clk_mux_stat_kfc2; + unsigned char res7[0x1f4]; + unsigned int clk_div_kfc0; + unsigned int clk_div_kfc1; + unsigned int clk_div_kfc_pll_freq_det; + unsigned char res8[0xf4]; + unsigned int clk_div_stat_kfc0; + unsigned int clk_div_stat_kfc1; + unsigned int clk_div_stat_kfc_pll_freq_det; + unsigned char res9[0xf4]; + unsigned int clk_enable_aclk_kfc; + unsigned char res10[0xfc]; + unsigned int clk_enable_pclk_kfc; + unsigned char res11[0xfc]; + unsigned int clk_enable_sclk_kfc; + unsigned char res12[0xfc]; + unsigned int clk_enable_ip_kfc0; + unsigned int clk_enable_ip_kfc1; + unsigned char res13[0xf8]; + unsigned int clkout_cmu_kfc; + unsigned char res14[0x3fc]; + unsigned int armclk_stopctrl_kfc; + unsigned char res15[0x1c]; + unsigned int pwr_ctrl; + unsigned int pwr_ctrl2; + unsigned char res16[0x58]; + unsigned int intr_spread_enable_kfc; + unsigned int intr_spread_use_standbywfi_kfc; + unsigned int intr_spread_blocking_duration_kfc; /* 0x1190_1088 */ +}; + +struct exynos5430_clock_mif { + unsigned int mem_pll_lock; /* 0x105B_0000 */ + unsigned int bus_pll_lock; + unsigned int mfc_pll_lock; + unsigned int bus_dpll_lock; + unsigned char res1[0xf0]; + unsigned int bus_pll_con0; + unsigned int bus_pll_con1; + unsigned char res2[0x4]; + unsigned int bus_pll_freq_det; + unsigned int mem_pll_con0; + unsigned int mem_pll_con1; + unsigned char res3[0x4]; + unsigned int mem_pll_freq_det; + unsigned int mfc_pll_con0; + unsigned int mfc_pll_con1; + unsigned char res4[0x4]; + unsigned int mfc_pll_freq_det; + unsigned int bus_dpll_con0; + unsigned int bus_dpll_con1; + unsigned int bus_dpll_con2; + unsigned int bus_dpll_freq_det; + unsigned char res5[0xc0]; + unsigned int clk_mux_sel_mif0; + unsigned int clk_mux_sel_mif1; + unsigned int clk_mux_sel_mif2; + unsigned int clk_mux_sel_mif3; + unsigned int clk_mux_sel_mif4; + unsigned int clk_mux_sel_mif5; + unsigned char res6[0xe8]; + unsigned int clk_mux_enable_mif0; + unsigned int clk_mux_enable_mif1; + unsigned int clk_mux_enable_mif2; + unsigned int clk_mux_enable_mif3; + unsigned int clk_mux_enable_mif4; + unsigned int clk_mux_enable_mif5; + unsigned char res7[0xe8]; + unsigned int clk_mux_stat_mif0; + unsigned int clk_mux_stat_mif1; + unsigned int clk_mux_stat_mif2; + unsigned int clk_mux_stat_mif3; + unsigned int clk_mux_stat_mif4; + unsigned int clk_mux_stat_mif5; + unsigned char res8[0x1e8]; + unsigned int clk_div_mif0; + unsigned int clk_div_mif1; + unsigned int clk_div_mif2; + unsigned int clk_div_mif3; + unsigned int clk_div_mif4; + unsigned int clk_div_mif5; + unsigned int clk_div_mif_pll_freq_det; + unsigned char res9[0xe4]; + unsigned int clk_div_stat_mif0; + unsigned int clk_div_stat_mif1; + unsigned int clk_div_stat_mif2; + unsigned int clk_div_stat_mif3; + unsigned int clk_div_stat_mif4; + unsigned int clk_div_stat_mif5; + unsigned int clk_div_stat_mif_pll_freq_det; + unsigned char res10[0xe4]; + unsigned int clk_enable_aclk_mif0; + unsigned int clk_enable_aclk_mif1; + unsigned int clk_enable_aclk_mif2; + unsigned int clk_enable_aclk_mif3; + unsigned char res11[0xf0]; + unsigned int clk_enable_pclk_mif; + unsigned int clk_enable_pclk_mif_secure_drex0_tz; + unsigned int clk_enable_pclk_mif_secure_drex1_tz; + unsigned int clk_enable_pclk_mif_secure_monotonic_cnt; + unsigned int clk_enable_pclk_mif_secure_rtc; + unsigned char res12[0xec]; + unsigned int clk_enable_sclk_mif; + unsigned char res13[0xfc]; + unsigned int clk_enable_ip_mif0; + unsigned int clk_enable_ip_mif1; + unsigned int clk_enable_ip_mif2; + unsigned int clk_enable_ip_mif3; + unsigned int clk_enable_ip_mif_secure_drex0_tz; + unsigned int clk_enable_ip_mif_secure_drex1_tz; + unsigned int clk_enable_ip_mif_secure_monotonic_cnt; + unsigned int clk_enable_ip_mif_secure_rtc; + unsigned char res14[0xe4]; + unsigned int clkout_cmu_mif; + unsigned char res15[0x3f8]; + unsigned int drex_freq_ctrl0; + unsigned int drex_freq_ctrl1; + unsigned int pause; + unsigned int ddrphy_lock_ctrl; /* 0x105B_100C */ +}; + +struct exynos5430_clock_peric { + unsigned char res1[0x800]; /* 0x14C8_0000 */ + unsigned int clk_enable_aclk_peric; + unsigned char res2[0xfc]; + unsigned int clk_enable_pclk_peric; + unsigned char res3[0xfc]; + unsigned int clk_enable_sclk_peric; + unsigned char res4[0xfc]; + unsigned int clk_enable_ip_peric0; + unsigned int clk_enable_ip_peric1; +}; + +struct exynos5430_clock_peris { + unsigned char res1[0x800]; /* 0x1004_0000 */ + unsigned int clk_enable_aclk_peris; + unsigned char res2[0xfc]; + unsigned int clk_enable_pclk_peris; + unsigned int clk_enable_pclk_peris_secure_tzpc; + unsigned int clk_enable_pclk_peris_secure_seckey_apbif; + unsigned int clk_enable_pclk_peris_secure_chipid_apbif; + unsigned int clk_enable_pclk_peris_secure_toprtc; + unsigned int clk_enable_pclk_peris_secure_custom_efuse_apbif; + unsigned int clk_enable_pclk_peris_secure_antirbk_cnt_apbif; + unsigned char res3[0xe4]; + unsigned int clk_enable_sclk_peris; + unsigned int clk_enable_sclk_peris_secure_seckey; + unsigned int clk_enable_sclk_peris_secure_chipid; + unsigned int clk_enable_sclk_peris_secure_toprtc; + unsigned int clk_enable_sclk_peris_secure_custom_efuse_apbif; + unsigned int clk_enable_sclk_peris_secure_antirbk_cnt; + unsigned char res4[0xe8]; + unsigned int clk_enable_ip_peris0; + unsigned int clk_enable_ip_peris1; + unsigned int clk_enable_ip_peris_secure_tzpc; + unsigned int clk_enable_ip_peris_secure_seckey; + unsigned int clk_enable_ip_peris_secure_chipid; + unsigned int clk_enable_ip_peris_secure_toprtc; + unsigned int clk_enable_ip_peris_secure_custom_efuse; + unsigned int clk_enable_ip_peris_secure_antirbk_cnt; /* 0x1004_0B1C */ +}; + +struct exynos5430_clock_top { + unsigned int isp_pll_lock; /* 0x1003_0000 */ + unsigned int aud_pll_lock; + unsigned int aud_dpll_lock; + unsigned char res1[0xf4]; + unsigned int isp_pll_con0; + unsigned int isp_pll_con1; + unsigned int isp_pll_freq_det; + unsigned char res2[0x4]; + unsigned int aud_pll_con0; + unsigned int aud_pll_con1; + unsigned int aud_pll_con2; + unsigned int aud_pll_freq_det; + unsigned int aud_dpll_con0; + unsigned int aud_dpll_con1; + unsigned int aud_dpll_con2; + unsigned int aud_dpll_freq_det; + unsigned char res3[0xd0]; + unsigned int clk_mux_sel_top0; + unsigned int clk_mux_sel_top1; + unsigned int clk_mux_sel_top2; + unsigned int clk_mux_sel_top3; + unsigned int clk_mux_sel_top_mscl; + unsigned int clk_mux_sel_top_cam1; + unsigned int clk_mux_sel_top_disp; + unsigned char res4[0x4]; + unsigned int clk_mux_sel_top_fsys0; + unsigned int clk_mux_sel_top_fsys1; + unsigned int clk_mux_sel_top_peric0; + unsigned int clk_mux_sel_top_peric1; + unsigned char res5[0xd0]; + unsigned int clk_mux_enable_top_top0; + unsigned int clk_mux_enable_top_top1; + unsigned int clk_mux_enable_top_top2; + unsigned int clk_mux_enable_top_top3; + unsigned int clk_mux_enable_top_top_mscl; + unsigned int clk_mux_enable_top_top_cam1; + unsigned int clk_mux_enable_top_top_disp; + unsigned char res6[0x4]; + unsigned int clk_mux_enable_top_fsys0; + unsigned int clk_mux_enable_top_fsys1; + unsigned int clk_mux_enable_top_peric0; + unsigned int clk_mux_enable_top_peric1; + unsigned char res7[0xd0]; + unsigned int clk_mux_stat_top_top0; + unsigned int clk_mux_stat_top_top1; + unsigned int clk_mux_stat_top_top2; + unsigned int clk_mux_stat_top_top3; + unsigned int clk_mux_stat_top_top_mscl; + unsigned int clk_mux_stat_top_top_cam1; + unsigned char res8[0x8]; + unsigned int clk_mux_stat_top_fsys0; + unsigned int clk_mux_stat_top_fsys1; + unsigned int clk_mux_stat_top_peric0; + unsigned int clk_mux_stat_top_peric1; + unsigned char res9[0x1d0]; + unsigned int clk_div_top0; + unsigned int clk_div_top1; + unsigned int clk_div_top2; + unsigned int clk_div_top3; + unsigned char res10[0x8]; + unsigned int clk_div_top_mscl; + unsigned int clk_div_top_cam10; + unsigned int clk_div_top_cam11; + unsigned char res11[0x8]; + unsigned int clk_div_top_fsys0; + unsigned int clk_div_top_fsys1; + unsigned int clk_div_top_fsys2; + unsigned int clk_div_top_peric0; + unsigned int clk_div_top_peric1; + unsigned int clk_div_top_peric2; + unsigned int clk_div_top_peric3; + unsigned int clk_div_top_pll_freq_det; + unsigned char res12[0xb4]; + unsigned int clk_div_stat_top0; + unsigned int clk_div_stat_top1; + unsigned int clk_div_stat_top2; + unsigned int clk_div_stat_top3; + unsigned int clk_div_stat_top_mscl; + unsigned int clk_div_stat_top_cam10; + unsigned int clk_div_stat_top_cam11; + unsigned int clk_div_stat_top_fsys0; + unsigned int clk_div_stat_top_fsys1; + unsigned int clk_div_stat_top_fsys2; + unsigned int clk_div_stat_top_peric0; + unsigned int clk_div_stat_top_peric1; + unsigned int clk_div_stat_top_peric2; + unsigned int clk_div_stat_top_peric3; + unsigned int clk_div_stat_top_pll_freq_det; + unsigned char res13[0xc4]; + unsigned int clk_enable_aclk_top; + unsigned char res14[0x1fc]; + unsigned int clk_enable_sclk_top; + unsigned int clk_enable_sclk_top_mscl; + unsigned int clk_enable_sclk_top_cam1; + unsigned int clk_enable_sclk_top_disp; + unsigned int clk_enable_sclk_top_fsys; + unsigned int clk_enable_sclk_top_peric; + unsigned char res15[0xe8]; + unsigned int clk_enable_ip_top; + unsigned char res16[0xfc]; + unsigned int clkout_cmu_top; /* 0x1003_0C00 */ +}; + +struct exynos5430_clock_bus1 { + unsigned char res1[0x200]; /* 0x1480_0000 */ + unsigned int clk_mux_sel_bus1; + unsigned int clk_mux_enable_bus1; + unsigned int clk_mux_stat_bus1; + unsigned char res2[0x3f4]; + unsigned int clk_div_bus1; + unsigned char res3[0xfc]; + unsigned int clk_div_stat_bus1; + unsigned char res4[0xfc]; + unsigned int clk_enable_aclk_bus1; + unsigned char res5[0xfc]; + unsigned int clk_enable_pclk_bus1; + unsigned char res6[0x1fc]; + unsigned int clk_enable_ip_bus10; + unsigned int clk_enable_ip_bus11; /* 0x1480_0B04 */ +}; + +struct exynos5430_clock_bus2 { + unsigned char res1[0x200]; /* 0x1340_0000 */ + unsigned int clk_mux_sel_bus2; + unsigned int clk_mux_enable_bus2; + unsigned int clk_mux_stat_bus2; + unsigned char res2[0x3f4]; + unsigned int clk_div_bus2; + unsigned char res3[0xfc]; + unsigned int clk_div_stat_bus2; + unsigned char res4[0xfc]; + unsigned int clk_enable_aclk_bus2; + unsigned char res5[0xfc]; + unsigned int clk_enable_pclk_bus2; + unsigned char res6[0x1fc]; + unsigned int clk_enable_ip_bus20; + unsigned int clk_enable_ip_bus21; /* 0x1340_0B04 */ +}; + +struct exynos5430_clock_imem { + unsigned char res1[0x800]; /* 0x1106_0000 */ + unsigned int clk_enable_aclk_imem; + unsigned int clk_enable_aclk_imem_secure_int_mem; + unsigned int clk_enable_aclk_imem_secure_sss; + unsigned int clk_enable_aclk_imem_secure_slimsss; + unsigned int clk_enable_aclk_imem_secure_rtic; + unsigned int clk_enable_aclk_imem_secure_smmu_sss; + unsigned int clk_enable_aclk_imem_secure_smmu_slimsss; + unsigned int clk_enable_aclk_imem_secure_smmu_rtic; + unsigned char res2[0xe0]; + unsigned int clk_enable_pclk_imem; + unsigned int clk_enable_pclk_imem_secure_sss; + unsigned int clk_enable_pclk_imem_secure_slimsss; + unsigned int clk_enable_pclk_imem_secure_rtic; + unsigned int clk_enable_pclk_imem_secure_smmu_sss; + unsigned int clk_enable_pclk_imem_secure_smmu_slimsss; + unsigned int clk_enable_pclk_imem_secure_smmu_rtic; + unsigned char res3[0x1e4]; + unsigned int clk_enable_ip_imem0; + unsigned int clk_enable_ip_imem1; + unsigned int clk_enable_ip_imem_secure_int_mem; + unsigned int clk_enable_ip_imem_secure_sss; + unsigned int clk_enable_ip_imem_secure_slimsss; + unsigned int clk_enable_ip_imem_secure_rtic; + unsigned int clk_enable_ip_imem_secure_smmu_sss; + unsigned int clk_enable_ip_imem_secure_smmu_slimsss; + unsigned int clk_enable_ip_imem_secure_smmu_rtic; /* 0x1106_0B18 */ +}; + +struct exynos5430_clock_cpif { + unsigned int mphy_pll_lock; /* 0x13B9_0000 */ + unsigned char res1[0xfc]; + unsigned int mphy_pll_con0; + unsigned int mphy_pll_con1; + unsigned char res2[0x4]; + unsigned int mphy_pll_freq_det; + unsigned char res3[0xf0]; + unsigned int clk_mux_sel_cpif0; + unsigned int clk_mux_sel_cpif1; + unsigned int clk_mux_sel_cpif2; + unsigned char res4[0xf4]; + unsigned int clk_mux_enable_cpif0; + unsigned int clk_mux_enable_cpif1; + unsigned int clk_mux_enable_cpif2; + unsigned char res5[0xf4]; + unsigned int clk_mux_stat_cpif0; + unsigned int clk_mux_stat_cpif1; + unsigned int clk_mux_stat_cpif2; + unsigned char res6[0xf8]; + unsigned int clk_mux_ignore_cpif1; + unsigned char res7[0xf8]; + unsigned int clk_div_cpif; + unsigned char res8[0x4]; + unsigned int clk_div_cpif_pll_freq_det; + unsigned char res9[0xf4]; + unsigned int clk_div_stat_cpif; + unsigned char res10[0x4]; + unsigned int clk_div_stat_cpif_pll_freq_det; + unsigned char res11[0xf4]; + unsigned int clk_enable_aclk_cpif; + unsigned char res12[0xfc]; + unsigned int clk_enable_pclk_cpif; + unsigned char res13[0xfc]; + unsigned int clk_enable_sclk_cpif; + unsigned char res14[0xfc]; + unsigned int clk_enable_ip_cpif0; + unsigned int clk_enable_ip_cpif1; + unsigned char res15[0xf8]; + unsigned int clkout_cmu_cpif; /* 0x13B9_0C00 */ +}; + +struct exynos5412_clock { + unsigned int apll_lock; /* 0x1001_0000 */ + unsigned char res1[0xfc]; + unsigned int apll_con0; /* 0x1001_0100 */ + unsigned int apll_con1; /* 0x1001_0104 */ + unsigned char res2[0xf8]; + unsigned int src_cpu; /* 0x1001_0200 */ + unsigned char res3[0x2fc]; + unsigned int div_cpu0; /* 0x1001_0500 */ + unsigned int div_cpu1; /* 0x1001_0504 */ + unsigned char res4[0x4f8]; + unsigned int clkout_cmu_cpu; /* 0x1001_0A00 */ + unsigned char res5[0x37fc]; + unsigned int src_core0; /* 0x1001_4200 */ + unsigned int src_core1; /* 0x1001_4204 */ + unsigned char res6[0x2fc]; + unsigned int div_cperi1; /* 0x1001_4504 */ + unsigned char res7[0x4f8]; + unsigned int clkout_cmu_core; /* 0x1001_4A00 */ + unsigned char res8[0x3afc]; + unsigned int div_g2d; /* 0x1001_8500 */ + unsigned char res9[0x3DFC]; + unsigned int div_isp0; /* 0x1001_C300 */ + unsigned int div_isp1; /* 0x1001_C304 */ + unsigned int div_isp2; /* 0x1001_C308 */ + unsigned char res91[0x3D14]; + unsigned int cpll_lock; /* 0x1002_0020 */ + unsigned char res10[0xc]; + unsigned int dpll_lock; /* 0x1002_0030 */ + unsigned char res11[0xc]; + unsigned int epll_lock; /* 0x1002_0040 */ + unsigned char res12[0xc]; + unsigned int rpll_lock; /* 0x1002_0050 */ + unsigned char res13[0xc]; + unsigned int ipll_lock; /* 0x1002_0060 */ + unsigned char res14[0xc]; + unsigned int spll_lock; /* 0x1002_0070 */ + unsigned char res15[0xc]; + unsigned int vpll_lock; /* 0x1002_0080 */ + unsigned char res16[0xc]; + unsigned int mpll_lock; /* 0x1002_0090 */ + unsigned int tpll_lock; /* 0x1002_0094 */ + unsigned char res17[0x88]; + unsigned int cpll_con0; /* 0x1002_0120 */ + unsigned int cpll_con1; /* 0x1002_0124 */ + unsigned int dpll_con0; /* 0x1002_0128 */ + unsigned int dpll_con1; /* 0x1002_012C */ + unsigned int epll_con0; /* 0x1002_0130 */ + unsigned int epll_con1; /* 0x1002_0134 */ + unsigned int epll_con2; /* 0x1002_0138 */ + unsigned char res18[0x4]; + unsigned int rpll_con0; /* 0x1002_0140 */ + unsigned int rpll_con1; /* 0x1002_0144 */ + unsigned int rpll_con2; /* 0x1002_0148 */ + unsigned char res19[0x4]; + unsigned int ipll_con0; /* 0x1002_0150 */ + unsigned int ipll_con1; /* 0x1002_0154 */ + unsigned char res20[0x8]; + unsigned int spll_con0; /* 0x1002_0160 */ + unsigned int spll_con1; /* 0x1002_0164 */ + unsigned char res21[0x8]; + unsigned int vpll_con0; /* 0x1002_0170 */ + unsigned int vpll_con1; /* 0x1002_0174 */ + unsigned char res22[0x8]; + unsigned int mpll_con0; /* 0x1002_0180 */ + unsigned int mpll_con1; /* 0x1002_0184 */ + unsigned char res231[0x8]; + unsigned int tpll_con0; /* 0x1002_0190 */ + unsigned int tpll_con1; /* 0x1002_0194 */ + unsigned char res232[0x68]; + unsigned int src_top0; /* 0x1002_0200 */ + unsigned int src_top1; /* 0x1002_0204 */ + unsigned int src_top2; /* 0x1002_0208 */ + unsigned int src_top3; /* 0x1002_020C */ + unsigned int src_top4; /* 0x1002_0210 */ + unsigned int src_top5; /* 0x1002_0214 */ + unsigned int src_top6; /* 0x1002_0218 */ + unsigned int src_top7; /* 0x1002_021C */ + unsigned int src_top8; /* 0x1002_0220 */ + unsigned int src_top9; /* 0x1002_0224 */ + unsigned char res24[0x4]; + unsigned int src_disp10; /* 0x1002_022C */ + unsigned char res25[0x10]; + unsigned int src_mau; /* 0x1002_0240 */ + unsigned int src_fsys; /* 0x1002_0244 */ + unsigned char res26[0x8]; + unsigned int src_peric0; /* 0x1002_0250 */ + unsigned int src_peric1; /* 0x1002_0254 */ + unsigned char res27[0x18]; + unsigned int src_isp; /* 0x1002_0270 */ + unsigned char res28[0xC]; + unsigned int src_top10; /* 0x1002_0280 */ + unsigned int src_top11; /* 0x1002_0284 */ + unsigned int src_top12; /* 0x1002_0288 */ + unsigned char res29[0x274]; + unsigned int div_top0; /* 0x1002_0500 */ + unsigned int div_top1; /* 0x1002_0504 */ + unsigned int div_top2; /* 0x1002_0508 */ + unsigned int div_top3; /* 0x1002_050C */ + unsigned char res30[0x1C]; + unsigned int div_disp10; /* 0x1002_052C */ + unsigned char res31[0x14]; + unsigned int div_mau; /* 0x1002_0544 */ + unsigned int div_fsys0; /* 0x1002_0548 */ + unsigned int div_fsys1; /* 0x1002_054C */ + unsigned int div_fsys2; /* 0x1002_0550 */ + unsigned int div_fsys3; /* 0x1002_0554 */ + unsigned int div_peric0; /* 0x1002_0558 */ + unsigned int div_peric1; /* 0x1002_055C */ + unsigned int div_peric2; /* 0x1002_0560 */ + unsigned int div_peric3; /* 0x1002_0564 */ + unsigned int div_peric4; /* 0x1002_0568 */ + unsigned char res32[0x14]; + unsigned int div_s_isp0; /* 0x1002_0580 */ + unsigned int div_s_isp1; /* 0x1002_0584 */ + unsigned char res33[0x8]; + unsigned int div2_ratio0; /* 0x1002_0590 */ + unsigned char res34[0xc]; + unsigned int div4_ratio; /* 0x1002_05A0 */ + unsigned char res35[0x45c]; + unsigned int clkout_cmu_top; /* 0x1002_0A00 */ + unsigned char res36[0xfc]; + unsigned int wdrex0_pause; /* 0x1002_0B00 */ + unsigned int wdrex1_pause; /* 0x1002_0B04 */ + unsigned int wdrex2_pause; /* 0x1002_0B08 */ + unsigned int wdrex3_pause; /* 0x1002_0B0C */ + unsigned char res361[0xf500]; + unsigned int xpll_lock; /* 0x1003_0010 */ + unsigned char res37[0xfc]; + unsigned int xpll_con0; /* 0x1003_0110 */ + unsigned int xpll_con1; /* 0x1003_0114 */ + unsigned char res38[0xe8]; + unsigned int src_cdrex; /* 0x1003_0200 */ + unsigned char res39[0x1fc]; + unsigned int mux_stat_cdrex; /* 0x1003_0400 */ + unsigned char res40[0xfc]; + unsigned int div_cdrex0; /* 0x1003_0500 */ + unsigned int div_cdrex1; /* 0x1003_0504 */ + unsigned char res41[0x414]; + unsigned int pause; /* 0x1003_091C */ + unsigned char res412[0xe0]; + unsigned int clkout_cmu_cdrex; /* 0x1003_0A00 */ + unsigned char res42[0xc]; + unsigned int lpddr3phy_ctrl; /* 0x1003_0A10 */ + unsigned int lpddr3phy_con0; /* 0x1003_0A14 */ + unsigned int lpddr3phy_con1; /* 0x1003_0A18 */ + unsigned int lpddr3phy_con2; /* 0x1003_0A1C */ + unsigned int lpddr3phy_con3; /* 0x1003_0A20 */ + unsigned int lpddr3phy_con4; /* 0x1003_0A24 */ + unsigned int lpddr3phy_con5; /* 0x1003_0A28 */ + unsigned char res43[0x35E4]; + unsigned int bpll_lock; /* 0x1003_4010 */ + unsigned char res44[0xfc]; + unsigned int bpll_con0; /* 0x1003_4110 */ + unsigned int bpll_con1; /* 0x1003_4114 */ + unsigned char res45[0xe8]; + unsigned int src_cci; /* 0x1003_4200 */ + unsigned char res46[0x2fc]; + unsigned int div_cci0; /* 0x1003_4500 */ + unsigned char res461[0x3afc]; + unsigned int kpll_lock; /* 0x1003_8000 */ + unsigned char res47[0xfc]; + unsigned int kpll_con0; /* 0x1003_8100 */ + unsigned int kpll_con1; /* 0x1003_8104 */ + unsigned char res48[0xf8]; + unsigned int src_kfc; /* 0x1003_8200 */ + unsigned char res49[0x2fc]; + unsigned int div_kfc0; /* 0x1003_8500 */ }; #endif diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index 0c341d431..c6a156ecc 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -27,11 +27,19 @@ #define EXYNOS_CPU_NAME "Exynos" #define EXYNOS4_ADDR_BASE 0x10000000 +/* RAMDUMP */ +#define CONFIG_RAMDUMP_BASE (CONFIG_SYS_SDRAM_BASE + 0x6000000) +#define CONFIG_RAMDUMP_LOGBUF (CONFIG_RAMDUMP_BASE + 0x400000) +#define CONFIG_RAMDUMP_LOGSZ 0x200000 +#define CONFIG_RAMDUMP_SCRATCH (CONFIG_RAMDUMP_BASE + 0x10) +#define CONFIG_RAMDUMP_LASTBUF (CONFIG_RAMDUMP_BASE + 0x14) + /* EXYNOS4 */ #define EXYNOS4_GPIO_PART3_BASE 0x03860000 #define EXYNOS4_PRO_ID 0x10000000 #define EXYNOS4_SYSREG_BASE 0x10010000 #define EXYNOS4_POWER_BASE 0x10020000 +#define EXYNOS4_MCT_BASE 0x10050000 #define EXYNOS4_SWRESET 0x10020400 #define EXYNOS4_CLOCK_BASE 0x10030000 #define EXYNOS4_SYSTIMER_BASE 0x10050000 @@ -57,7 +65,11 @@ #define EXYNOS4_GPIO_PART4_BASE DEVICE_NOT_AVAILABLE /* EXYNOS5 */ +#if defined(CONFIG_CPU_EXYNOS5412) +#define EXYNOS5_GPIO_PART4_BASE 0x14010000 +#else #define EXYNOS5_GPIO_PART4_BASE 0x03860000 +#endif #define EXYNOS5_PRO_ID 0x10000000 #define EXYNOS5_CLOCK_BASE 0x10010000 #define EXYNOS5_POWER_BASE 0x10040000 @@ -66,9 +78,17 @@ #define EXYNOS5_WATCHDOG_BASE 0x101D0000 #define EXYNOS5_DMC_PHY0_BASE 0x10C00000 #define EXYNOS5_DMC_PHY1_BASE 0x10C10000 +#if defined(CONFIG_CPU_EXYNOS5412) +#define EXYNOS5_GPIO_PART3_BASE 0x14000000 +#else #define EXYNOS5_GPIO_PART3_BASE 0x10D10000 +#endif #define EXYNOS5_DMC_CTRL_BASE 0x10DD0000 +#if defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5412) +#define EXYNOS5_GPIO_PART1_BASE 0x13400000 +#else #define EXYNOS5_GPIO_PART1_BASE 0x11400000 +#endif #define EXYNOS5_MIPI_DSIM_BASE 0x11D00000 #define EXYNOS5_USB_HOST_EHCI_BASE 0x12110000 #define EXYNOS5_USBPHY_BASE 0x12130000 @@ -77,14 +97,111 @@ #define EXYNOS5_SROMC_BASE 0x12250000 #define EXYNOS5_UART_BASE 0x12C00000 #define EXYNOS5_PWMTIMER_BASE 0x12DD0000 +#if defined(CONFIG_CPU_EXYNOS5412) +#define EXYNOS5_GPIO_PART2_BASE 0x13410000 +#else #define EXYNOS5_GPIO_PART2_BASE 0x13400000 +#endif #define EXYNOS5_FIMD_BASE 0x14400000 #define EXYNOS5_ADC_BASE DEVICE_NOT_AVAILABLE #define EXYNOS5_MODEM_BASE DEVICE_NOT_AVAILABLE +/* EXYNOS5260 */ +#define EXYNOS5260_PRO_ID 0x10000000 +#define EXYNOS5260_CMU_TOP_BASE 0x10010000 +#define EXYNOS5260_MCT_BASE 0x100B0000 +#define EXYNOS5260_WATCHDOG_BASE 0x101D0000 +#define EXYNOS5260_CMU_PERI_BASE 0x10200000 +#define EXYNOS5260_SYSREG_BASE 0x10220000 +#define EXYNOS5260_CMU_EGL_BASE 0x10600000 +#define EXYNOS5260_CMU_KFC_BASE 0x10700000 +#define EXYNOS5260_LPDDR3PHY_0_BASE 0x10C00000 +#define EXYNOS5260_LPDDR3PHY_1_BASE 0x10C10000 +#define EXYNOS5260_DREXI_0_NS_BASE 0x10C20000 +#define EXYNOS5260_DREXI_1_NS_BASE 0x10C30000 +#define EXYNOS5260_DREXI_0_S_BASE 0x10C40000 +#define EXYNOS5260_DREXI_1_S_BASE 0x10C50000 +#define EXYNOS5260_CMU_MIF_BASE 0x10CE0000 +#define EXYNOS5260_POWER_BASE 0x10D50000 +#define EXYNOS5260_SWRESET 0x10D50400 +#define EXYNOS5260_GPIO_PART1_BASE 0x11600000 +#define EXYNOS5260_MMC_BASE 0x12140000 +#define EXYNOS5260_SROMC_BASE 0x12180000 +#define EXYNOS5260_GPIO_PART2_BASE 0x12290000 +#define EXYNOS5260_CMU_FSYS_BASE 0x122E0000 +#define EXYNOS5260_GPIO_PART3_BASE 0x128B0000 +#define EXYNOS5260_UART_BASE 0x12C00000 +#define EXYNOS5260_PWMTIMER_BASE 0x12D90000 +/* unnecessary definition */ +#define EXYNOS5260_ADC_BASE 0x0 +#define EXYNOS5260_CLOCK_BASE 0x0 +#define EXYNOS5260_FIMD_BASE 0x0 +#define EXYNOS5260_MIPI_DSIM_BASE 0x0 +#define EXYNOS5260_GPIO_PART4_BASE 0x0 +#define EXYNOS5260_MODEM_BASE 0x0 +#define EXYNOS5260_USBPHY_BASE 0x0 +#define EXYNOS5260_USB_HOST_EHCI_BASE 0x0 +#define EXYNOS5260_USBOTG_BASE 0x0 + +/* EXYNOS5430 */ +#define EXYNOS5430_PRO_ID 0x10000000 +#define EXYNOS5430_PMU_PERIS_BASE 0x10010000 +#define EXYNOS5430_CMU_TOP_BASE 0x10030000 +#define EXYNOS5430_CMU_PERIS_BASE 0x10040000 +#define EXYNOS5430_SYSREG_BASE 0x10050000 +#define EXYNOS5430_MCT_BASE 0x101C0000 +#define EXYNOS5430_WATCHDOG_BASE 0x101D0000 +#define EXYNOS5430_DREX0_BASE 0x10400000 +#define EXYNOS5430_DREX0_TZ_BASE 0x10410000 +#define EXYNOS5430_LPDDR3PHY_0_BASE 0x10420000 +#define EXYNOS5430_DREXI1_BASE 0x10440000 +#define EXYNOS5430_DREXI1_TZ_BASE 0x10450000 +#define EXYNOS5430_LPDDR3PHY_1_BASE 0x10460000 +#define EXYNOS5430_GPIO_ALIVE_BASE 0x10580000 +#define EXYNOS5430_CMU_MIF_BASE 0x105B0000 +#define EXYNOS5430_POWER_BASE 0x105C0000 +#define EXYNOS5430_SWRESET 0x105C0400 +#define EXYNOS5430_CMU_CPIF_BASE 0x10FC0000 +#define EXYNOS5430_GPIO_CPIF_BASE 0x10FE0000 +#define EXYNOS5430_CMU_IMEM_BASE 0x11060000 +#define EXYNOS5430_GPIO_AUD_BASE 0x114B0000 +#define EXYNOS5430_CMU_EGL_BASE 0x11800000 +#define EXYNOS5430_CMU_KFC_BASE 0x11900000 +#define EXYNOS5430_CMU_BUS2_BASE 0x13400000 +#define EXYNOS5430_CMU_BUS1_BASE 0x14800000 +#define EXYNOS5430_UART_BASE 0x14C10000 +#define EXYNOS5430_CMU_PERIC_BASE 0x14C80000 +#define EXYNOS5430_GPIO_PERIC_BASE 0x14CC0000 +#define EXYNOS5430_GPIO_NFC_BASE 0x14CD0000 +#define EXYNOS5430_GPIO_TOUCH_BASE 0x14CE0000 +#define EXYNOS5430_PWMTIMER_BASE 0x14DD0000 +#define EXYNOS5430_MMC_BASE 0x15540000 +#define EXYNOS5430_SROMC_BASE 0x15580000 +#define EXYNOS5430_GPIO_FSYS_BASE 0x15690000 +#define EXYNOS5430_CMU_FSYS_BASE 0x156E0000 + +/* unnecessary definition */ +#define EXYNOS5430_GPIO_PART1_BASE 0x0 +#define EXYNOS5430_GPIO_PART2_BASE 0x0 +#define EXYNOS5430_GPIO_PART3_BASE 0x0 +#define EXYNOS5430_ADC_BASE 0x0 +#define EXYNOS5430_CLOCK_BASE 0x0 +#define EXYNOS5430_FIMD_BASE 0x0 +#define EXYNOS5430_MIPI_DSIM_BASE 0x0 +#define EXYNOS5430_GPIO_PART4_BASE 0x0 +#define EXYNOS5430_MODEM_BASE 0x0 +#define EXYNOS5430_USBPHY_BASE 0x0 +#define EXYNOS5430_USB_HOST_EHCI_BASE 0x0 +#define EXYNOS5430_USBOTG_BASE 0x0 + +#define __REG(x) (*(unsigned int *)(x)) + #ifndef __ASSEMBLY__ #include <asm/io.h> +/* CHIP ID */ +extern unsigned int s5p_chip_id[2]; + /* CPU detection macros */ extern unsigned int s5p_cpu_id; extern unsigned int s5p_cpu_rev; @@ -94,56 +211,155 @@ static inline int s5p_get_cpu_rev(void) return s5p_cpu_rev; } -static inline void s5p_set_cpu_id(void) +static inline unsigned int s5p_get_cpu_id(void) { unsigned int pro_id = (readl(EXYNOS4_PRO_ID) & 0x00FFF000) >> 12; switch (pro_id) { case 0x200: /* Exynos4210 EVT0 */ - s5p_cpu_id = 0x4210; - s5p_cpu_rev = 0; - break; + return 0x4210; case 0x210: /* Exynos4210 EVT1 */ - s5p_cpu_id = 0x4210; - break; + return 0x4210; + case 0x220: + /* Exynos4212 */ + return 0x4212; + case 0x415: + /* Exynos4415 */ + return 0x4415; + case 0x260: + /* Exynos5260 */ + return 0x5260; case 0x412: - /* Exynos4412 */ - s5p_cpu_id = 0x4412; - break; + pro_id = (readl(EXYNOS4_PRO_ID) & 0x0FFFF000) >> 12; + if (pro_id == 0x4412) { + /* Exynos4412 */ + return 0x4412; + } else { + /* Exynos5412 */ + return 0x5412; + } case 0x520: /* Exynos5250 */ - s5p_cpu_id = 0x5250; - break; + return 0x5250; + case 0x410: + /* Exynos5410 */ + return 0x5410; + case 0x430: + /* Exynos5430 */ + return 0x5430; + case 0x472: + /* Exynos3250 */ + return 0x3250; } } +static inline void s5p_set_cpu_id(void) +{ + unsigned int rev_num = (readl(EXYNOS4_PRO_ID) & 0x000000F0) >> 4; + + s5p_cpu_id = s5p_get_cpu_id(); + + if(s5p_cpu_id == 0x4210) + s5p_cpu_rev = 0; + else + s5p_cpu_rev = rev_num; +} + static inline char *s5p_get_cpu_name(void) { return EXYNOS_CPU_NAME; } +#ifndef CONFIG_SPL_BUILD #define IS_SAMSUNG_TYPE(type, id) \ static inline int cpu_is_##type(void) \ { \ return (s5p_cpu_id >> 12) == id; \ } +#else +#define IS_SAMSUNG_TYPE(type, id) \ +static inline int cpu_is_##type(void) \ +{ \ + return (s5p_get_cpu_id() >> 12) == id; \ +} +#endif +#ifdef CONFIG_CPU_EXYNOS3250 +IS_SAMSUNG_TYPE(exynos4, 0x3) +#else IS_SAMSUNG_TYPE(exynos4, 0x4) +#endif + IS_SAMSUNG_TYPE(exynos5, 0x5) +#define IS_SAMSUNG_PKG_TYPE(type, inform) \ +static inline int exynos_pkg_is_##type(void) \ +{ \ + return ((readl(EXYNOS4_PRO_ID) & 0x00000F00) >> 8) == inform; \ +} + +IS_SAMSUNG_PKG_TYPE(pop, 0x2) + #define SAMSUNG_BASE(device, base) \ static inline unsigned int samsung_get_base_##device(void) \ { \ - if (cpu_is_exynos4()) \ + if (cpu_is_exynos4()) { \ return EXYNOS4_##base; \ - else if (cpu_is_exynos5()) \ - return EXYNOS5_##base; \ - else \ + } else if (cpu_is_exynos5()) { \ + if (s5p_get_cpu_id() == 0x5430) { \ + return EXYNOS5430_##base; \ + } else if (s5p_get_cpu_id() == 0x5260) { \ + return EXYNOS5260_##base; \ + } else { \ + return EXYNOS5_##base; \ + } \ + } else { \ return 0; \ + } \ } +#define EXYNOS5260_BASE(device, base) \ +static inline unsigned int samsung_get_base_##device(void) \ +{ \ + return EXYNOS5260_##base; \ +} + +#define EXYNOS5430_BASE(device, base) \ +static inline unsigned int exynos5430_get_base_##device(void) \ +{ \ + return EXYNOS5430_##base; \ +} + +/* EXYNOS5260, EXYNOS5430 */ +EXYNOS5260_BASE(clock_egl, CMU_EGL_BASE) +EXYNOS5260_BASE(clock_kfc, CMU_KFC_BASE) +EXYNOS5260_BASE(clock_mif, CMU_MIF_BASE) +EXYNOS5260_BASE(clock_top, CMU_TOP_BASE) +EXYNOS5260_BASE(clock_fsys, CMU_FSYS_BASE) + +/* EXYNOS5430 */ +EXYNOS5430_BASE(clock_egl, CMU_EGL_BASE) +EXYNOS5430_BASE(clock_kfc, CMU_KFC_BASE) +EXYNOS5430_BASE(clock_mif, CMU_MIF_BASE) +EXYNOS5430_BASE(clock_top, CMU_TOP_BASE) +EXYNOS5430_BASE(clock_fsys, CMU_FSYS_BASE) +EXYNOS5430_BASE(clock_bus1, CMU_BUS1_BASE) +EXYNOS5430_BASE(clock_bus2, CMU_BUS2_BASE) +EXYNOS5430_BASE(clock_peris, CMU_PERIS_BASE) +EXYNOS5430_BASE(clock_peric, CMU_PERIC_BASE) +EXYNOS5430_BASE(clock_cpif, CMU_CPIF_BASE) +EXYNOS5430_BASE(clock_imem, CMU_IMEM_BASE) +EXYNOS5430_BASE(gpio_alive, GPIO_ALIVE_BASE) +EXYNOS5430_BASE(gpio_cpif, GPIO_CPIF_BASE) +EXYNOS5430_BASE(gpio_aud, GPIO_AUD_BASE) +EXYNOS5430_BASE(gpio_peric, GPIO_PERIC_BASE) +EXYNOS5430_BASE(gpio_nfc, GPIO_NFC_BASE) +EXYNOS5430_BASE(gpio_touch, GPIO_TOUCH_BASE) +EXYNOS5430_BASE(gpio_fsys, GPIO_FSYS_BASE) + +/* EXYNOS4, EXYNOS5 */ SAMSUNG_BASE(adc, ADC_BASE) SAMSUNG_BASE(clock, CLOCK_BASE) SAMSUNG_BASE(sysreg, SYSREG_BASE) diff --git a/arch/arm/include/asm/arch-exynos/dmc.h b/arch/arm/include/asm/arch-exynos/dmc.h index bd52d16c9..862670727 100644 --- a/arch/arm/include/asm/arch-exynos/dmc.h +++ b/arch/arm/include/asm/arch-exynos/dmc.h @@ -122,7 +122,7 @@ struct exynos5_dmc { unsigned char res1[0xc]; unsigned int pwrdnconfig; unsigned int timingpzq; - unsigned int timingref; + unsigned int timingaref; unsigned int timingrow; unsigned int timingdata; unsigned int timingpower; @@ -168,40 +168,46 @@ struct exynos5_dmc { unsigned int ivcontrol; unsigned int wrtra_config; unsigned int rdlvl_config; - unsigned char res21[0x8]; + unsigned char res21[0x4]; + unsigned int brbrsvcontrol; unsigned int brbrsvconfig; unsigned int brbqosconfig; unsigned int membaseconfig0; unsigned int membaseconfig1; - unsigned char res22[0xc]; - unsigned int wrlvl_config; - unsigned char res23[0xc]; + unsigned char res22[0x1c]; unsigned int perevcontrol; unsigned int perev0config; unsigned int perev1config; unsigned int perev2config; unsigned int perev3config; - unsigned char res24[0xdebc]; + unsigned char res23[0xc]; + unsigned int ctrl_io_rdata_ch0; + unsigned int ctrl_io_rdata_ch1; + unsigned char res24[0x8]; + unsigned int cacal_config0; + unsigned int cacal_config1; + unsigned int cacal_status; + unsigned char res25[0xde94]; unsigned int pmnc_ppc_a; - unsigned char res25[0xc]; - unsigned int cntens_ppc_a; unsigned char res26[0xc]; - unsigned int cntenc_ppc_a; + unsigned int cntens_ppc_a; unsigned char res27[0xc]; - unsigned int intens_ppc_a; + unsigned int cntenc_ppc_a; unsigned char res28[0xc]; - unsigned int intenc_ppc_a; + unsigned int intens_ppc_a; unsigned char res29[0xc]; + unsigned int intenc_ppc_a; + unsigned char res30[0xc]; unsigned int flag_ppc_a; - unsigned char res30[0xac]; + unsigned char res31[0xac]; unsigned int ccnt_ppc_a; - unsigned char res31[0xc]; - unsigned int pmcnt0_ppc_a; unsigned char res32[0xc]; - unsigned int pmcnt1_ppc_a; + unsigned int pmcnt0_ppc_a; unsigned char res33[0xc]; - unsigned int pmcnt2_ppc_a; + unsigned int pmcnt1_ppc_a; unsigned char res34[0xc]; + unsigned int pmcnt2_ppc_a; + unsigned char res35[0xc]; unsigned int pmcnt3_ppc_a; }; @@ -211,11 +217,11 @@ struct exynos5_phy_control { unsigned int phy_con2; unsigned int phy_con3; unsigned int phy_con4; - unsigned char res1[4]; + unsigned int phy_con5; unsigned int phy_con6; - unsigned char res2[4]; + unsigned char res1[4]; unsigned int phy_con8; - unsigned int phy_con9; + unsigned char res2[4]; unsigned int phy_con10; unsigned char res3[4]; unsigned int phy_con12; @@ -237,19 +243,323 @@ struct exynos5_phy_control { unsigned int phy_con27; unsigned int phy_con28; unsigned int phy_con29; - unsigned int phy_con30; + unsigned char res5[4]; unsigned int phy_con31; unsigned int phy_con32; unsigned int phy_con33; unsigned int phy_con34; unsigned int phy_con35; - unsigned int phy_con36; + unsigned char res6[4]; unsigned int phy_con37; - unsigned int phy_con38; + unsigned char res7[4]; unsigned int phy_con39; unsigned int phy_con40; unsigned int phy_con41; unsigned int phy_con42; }; + +struct exynos5260_dmc { + unsigned int concontrol; /* 0x10Cx_0000 */ + unsigned int memcontrol; + unsigned int cgcontrol; + unsigned char res1[0x4]; + unsigned int directcmd; + unsigned int prechconfig0; + unsigned int phycontrol0; + unsigned int prechconfig1; + unsigned int timingrfcpb; + unsigned int timingzq; + unsigned int pwrdnconfig; + unsigned int timingpzq; + unsigned int timingaref; + unsigned int timingrow0; + unsigned int timingdata0; + unsigned int timingpower0; + unsigned int phystatus; + unsigned int etctiming; + unsigned int chipstatus; + unsigned char res2[0x8]; + unsigned int mrstatus; + unsigned char res3[0x8]; + unsigned int qoscontrol0; + unsigned char res4[0x4]; + unsigned int qoscontrol1; + unsigned char res5[0x4]; + unsigned int qoscontrol2; + unsigned char res6[0x4]; + unsigned int qoscontrol3; + unsigned char res7[0x4]; + unsigned int qoscontrol4; + unsigned char res8[0x4]; + unsigned int qoscontrol5; + unsigned char res9[0x4]; + unsigned int qoscontrol6; + unsigned char res10[0x4]; + unsigned int qoscontrol7; + unsigned char res11[0x4]; + unsigned int qoscontrol8; + unsigned char res12[0x4]; + unsigned int qoscontrol9; + unsigned char res13[0x4]; + unsigned int qoscontrol10; + unsigned char res14[0x4]; + unsigned int qoscontrol11; + unsigned char res15[0x4]; + unsigned int qoscontrol12; + unsigned char res16[0x4]; + unsigned int qoscontrol13; + unsigned char res17[0x4]; + unsigned int qoscontrol14; + unsigned char res18[0x4]; + unsigned int qoscontrol15; + unsigned char res19[0x4]; + unsigned int timing_set_sw; + unsigned int timingrow1; + unsigned int timingdata1; + unsigned int timingpower1; + unsigned char res20[0x4]; + unsigned int wrtra_config; + unsigned int rdlvl_config; + unsigned char res21[0x4]; + unsigned int brbrsvcontrol; + unsigned int brbrsvconfig; + unsigned int brbqosconfig; + unsigned char res22[0x14]; + unsigned int wrlvl_config0; + unsigned int wrlvl_config1; + unsigned int wrlvl_status; + unsigned char res23[0x4]; + unsigned int ppcclkcon; + unsigned int perev0config; + unsigned int perev1config; + unsigned int perev2config; + unsigned int perev3config; + unsigned char res24[0xc]; + unsigned int ctrl_io_rdata; + unsigned char res25[0xc]; + unsigned int cacal_config0; + unsigned int cacal_config1; + unsigned int cacal_status; + unsigned char res26[0x98]; + unsigned int emergent_config0; + unsigned int emergent_config1; + unsigned char res27[0x8]; + unsigned int bp_control0; + unsigned int bp_config0_r; + unsigned int bp_config0_w; + unsigned char res28[0x4]; + unsigned int bp_control1; + unsigned int bp_config1_r; + unsigned int bp_config1_w; + unsigned char res29[0xd4]; + unsigned int winconfig_odt_w; + unsigned char res30[0x4]; + unsigned int winconfig_ctrlread; + unsigned int winconfig_ctrlgate; + unsigned char res31[0xdcf0]; + unsigned int pmnc_ppc; + unsigned char res32[0xc]; + unsigned int cntens_ppc; + unsigned char res33[0xc]; + unsigned int cntenc_ppc; + unsigned char res34[0xc]; + unsigned int intens_ppc; + unsigned char res35[0xc]; + unsigned int intenc_ppc; + unsigned char res36[0xc]; + unsigned int flag_ppc; + unsigned char res37[0xac]; + unsigned int ccnt_ppc; + unsigned char res38[0xc]; + unsigned int pmcnt0_ppc; + unsigned char res39[0xc]; + unsigned int pmcnt1_ppc; + unsigned char res40[0xc]; + unsigned int pmcnt2_ppc; + unsigned char res41[0xc]; + unsigned int pmcnt3_ppc; /* 0x10Cx_E140 */ +}; + +struct exynos5260_phy_control { + unsigned int phy_con0; /* 0x10Cx_0000 */ + unsigned int phy_con1; + unsigned int phy_con2; + unsigned int phy_con3; + unsigned int phy_con4; + unsigned int phy_con5; + unsigned int phy_con6; + unsigned char res1[0x4]; + unsigned int phy_con8; + unsigned int phy_con9; + unsigned int phy_con10; + unsigned int phy_con11; + unsigned int phy_con12; + unsigned int phy_con13; + unsigned int phy_con14; + unsigned int phy_con15; + unsigned int phy_con16; + unsigned char res4[0x4]; + unsigned int phy_con17; + unsigned int phy_con18; + unsigned int phy_con19; + unsigned int phy_con20; + unsigned int phy_con21; + unsigned int phy_con22; + unsigned int phy_con23; + unsigned int phy_con24; + unsigned int phy_con25; + unsigned int phy_con26; + unsigned int phy_con27; + unsigned int phy_con28; + unsigned int phy_con29; + unsigned int phy_con30; + unsigned int phy_con31; + unsigned int phy_con32; + unsigned int phy_con33; + unsigned int phy_con34; + unsigned char res6[0x8]; + unsigned int phy_con37; + unsigned char res7[4]; + unsigned int phy_con39; + unsigned int phy_con40; + unsigned int phy_con41; + unsigned int phy_con42; /* 0x10Cx_00AC */ +}; + +struct exynos5430_dmc { + unsigned int concontrol; /* 0x104x_0000 */ + unsigned int memcontrol; + unsigned int cgcontrol; + unsigned char res1[0x4]; + unsigned int directcmd; + unsigned int prechconfig0; + unsigned int phycontrol0; + unsigned int prechconfig1; + unsigned int timingrfcpb; + unsigned int timingzq; + unsigned int pwrdnconfig; + unsigned char res2[0x4]; + unsigned int timingaref; + unsigned int timingrow0; + unsigned int timingdata0; + unsigned int timingpower0; + unsigned int phystatus; + unsigned int etctiming; + unsigned int chipstatus; + unsigned int rdfetch0; + unsigned int rdfetch1; + unsigned int mrstatus; + unsigned int termcontrol0; + unsigned int termcontrol1; + unsigned char res3[0x80]; + unsigned int timing_set_sw; + unsigned int timingrow1; + unsigned int timingdata1; + unsigned int timingpower1; + unsigned char res4[0x4]; + unsigned int wrtra_config; + unsigned int rdlvl_config; + unsigned char res5[0x24]; + unsigned int wrlvl_config0; + unsigned int wrlvl_config1; + unsigned int wrlvl_status; + unsigned char res6[0x4]; + unsigned int ppcclkcon; + unsigned int perev0config; + unsigned int perev1config; + unsigned int perev2config; + unsigned int perev3config; + unsigned char res7[0xc]; + unsigned int ctrl_io_rdata; + unsigned char res8[0xc]; + unsigned int cacal_config0; + unsigned int cacal_config1; + unsigned int cacal_status; + unsigned char res9[0x194]; + unsigned int winconfig_odt_w0; + unsigned int winconfig_odt_w1; + unsigned int winconfig_ctrlread; + unsigned int winconfig_ctrlgate; + unsigned int pipeline_config; + unsigned int all_init_indi; + unsigned char res10[0xdce8]; + unsigned int pmnc_ppc; + unsigned char res11[0xc]; + unsigned int cntens_ppc; + unsigned char res12[0xc]; + unsigned int cntenc_ppc; + unsigned char res13[0xc]; + unsigned int intens_ppc; + unsigned char res14[0xc]; + unsigned int intenc_ppc; + unsigned char res15[0xc]; + unsigned int flag_ppc; + unsigned char res37[0xac]; + unsigned int ccnt_ppc; + unsigned char res38[0xc]; + unsigned int pmcnt0_ppc; + unsigned char res39[0xc]; + unsigned int pmcnt1_ppc; + unsigned char res40[0xc]; + unsigned int pmcnt2_ppc; + unsigned char res41[0xc]; + unsigned int pmcnt3_ppc; /* 0x104x_E140 */ +}; + +struct exynos5430_phy_control { + unsigned int gnr_con0; /* 0x104x_0000 */ + unsigned int cal_con0; + unsigned int cal_con1; + unsigned int cal_con2; + unsigned int cal_con3; + unsigned int wlat_con0; + unsigned int lp_con0; + unsigned int gate_con0; + unsigned int offsetr_con0; + unsigned char res1[0xc]; + unsigned int offsetw_con0; + unsigned char res2[0xc]; + unsigned int offsetc_con0; + unsigned char res3[0x8]; + unsigned int shiftc_con0; + unsigned int offsetd_con0; + unsigned char res4[0x4]; + unsigned int lp_ddr_con0; + unsigned int lp_ddr_con1; + unsigned char res5[0x4]; + unsigned int lp_ddr_con3; + unsigned int lp_ddr_con4; + unsigned int wr_lvl_con0; + unsigned char res6[0x8]; + unsigned int wr_lvl_con3; + unsigned int ca_dskew_con0; + unsigned int ca_dskew_con1; + unsigned int ca_dskew_con2; + unsigned int ca_dskew_con3; + unsigned char res7[0x24]; + unsigned int mdll_con0; + unsigned int mdll_con1; + unsigned int dvfs_con0; + unsigned int dvfs_con1; + unsigned int zq_con0; + unsigned int zq_con1; + unsigned int zq_con2; + unsigned char res8[0x4]; + unsigned int t_rddata_con0; + unsigned char res9[0x8]; + unsigned int cal_wl_stat; + unsigned int cal_fail_stat0; + unsigned char res10[0x8]; + unsigned int cal_fail_stat3; + unsigned int cal_gt_vwmc0; + unsigned char res11[0x8]; + unsigned int cal_gt_cyc; + unsigned char res12[0x2b0]; + unsigned int cadq_map_con0; + unsigned int cadq_map_con1; + unsigned int cadq_map_con2; + unsigned int cadq_map_con3; + unsigned int cadq_map_con4; /* 0x10Cx_00AC */ +}; #endif #endif diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h index 7a9bb90a0..0469dfc5b 100644 --- a/arch/arm/include/asm/arch-exynos/gpio.h +++ b/arch/arm/include/asm/arch-exynos/gpio.h @@ -100,7 +100,9 @@ struct exynos5_gpio_part1 { struct s5p_gpio_bank y4; struct s5p_gpio_bank y5; struct s5p_gpio_bank y6; - struct s5p_gpio_bank res1[0x980]; + struct s5p_gpio_bank res1[0x3]; + struct s5p_gpio_bank c4; + struct s5p_gpio_bank res2[0x48]; struct s5p_gpio_bank x0; struct s5p_gpio_bank x1; struct s5p_gpio_bank x2; @@ -132,6 +134,178 @@ struct exynos5_gpio_part4 { struct s5p_gpio_bank z; }; +struct exynos3_gpio_part1 { + struct s5p_gpio_bank a0; + struct s5p_gpio_bank a1; + struct s5p_gpio_bank b; + struct s5p_gpio_bank c0; + struct s5p_gpio_bank c1; + struct s5p_gpio_bank d0; + struct s5p_gpio_bank d1; +}; +struct exynos3_gpio_part2 { + struct s5p_gpio_bank k0; + struct s5p_gpio_bank k1; + struct s5p_gpio_bank k2; + struct s5p_gpio_bank res1;//In fact MMC3 channel didn't use + struct s5p_gpio_bank l0; + struct s5p_gpio_bank res2[2]; + struct s5p_gpio_bank e0; + struct s5p_gpio_bank e1; + struct s5p_gpio_bank res3; + struct s5p_gpio_bank e2; + struct s5p_gpio_bank res4[0x6]; + struct s5p_gpio_bank M0; + struct s5p_gpio_bank M1; + struct s5p_gpio_bank M2; + struct s5p_gpio_bank M3; + struct s5p_gpio_bank M4; + struct s5p_gpio_bank res5[0x4a]; + struct s5p_gpio_bank x0; + struct s5p_gpio_bank x1; + struct s5p_gpio_bank x2; + struct s5p_gpio_bank x3; +}; + +struct exynos5412_gpio_part2 { + struct s5p_gpio_bank c0; + struct s5p_gpio_bank c1; + struct s5p_gpio_bank c2; + struct s5p_gpio_bank c3; + struct s5p_gpio_bank c4; + struct s5p_gpio_bank d1; +}; + +struct exynos5412_gpio_part3 { + struct s5p_gpio_bank h0; + struct s5p_gpio_bank y7; + struct s5p_gpio_bank f0; + struct s5p_gpio_bank e0; + struct s5p_gpio_bank e1; + struct s5p_gpio_bank f1; + struct s5p_gpio_bank g0; + struct s5p_gpio_bank g1; + struct s5p_gpio_bank g2; +}; + +struct exynos5412_gpio_part4 { + struct s5p_gpio_bank y0; + struct s5p_gpio_bank y1; + struct s5p_gpio_bank y5; + struct s5p_gpio_bank y6; + struct s5p_gpio_bank y2; + struct s5p_gpio_bank y3; + struct s5p_gpio_bank y4; + struct s5p_gpio_bank a0; + struct s5p_gpio_bank a1; + struct s5p_gpio_bank a2; + struct s5p_gpio_bank b0; + struct s5p_gpio_bank b1; + struct s5p_gpio_bank b2; + struct s5p_gpio_bank b3; + struct s5p_gpio_bank b4; +}; + +struct exynos5260_gpio_part1 { + struct s5p_gpio_bank a0; + struct s5p_gpio_bank a1; + struct s5p_gpio_bank a2; + struct s5p_gpio_bank b0; + struct s5p_gpio_bank b1; + struct s5p_gpio_bank b2; + struct s5p_gpio_bank b3; + struct s5p_gpio_bank b4; + struct s5p_gpio_bank b5; + struct s5p_gpio_bank d0; + struct s5p_gpio_bank d1; + struct s5p_gpio_bank d2; + struct s5p_gpio_bank e0; + struct s5p_gpio_bank e1; + struct s5p_gpio_bank f0; + struct s5p_gpio_bank f1; + struct s5p_gpio_bank k0; + unsigned char res1[0x9e0]; + struct s5p_gpio_bank x0; + struct s5p_gpio_bank x1; + struct s5p_gpio_bank x2; + struct s5p_gpio_bank x3; +}; + +struct exynos5260_gpio_part2 { + struct s5p_gpio_bank c0; + struct s5p_gpio_bank c1; + struct s5p_gpio_bank c2; + struct s5p_gpio_bank c3; + struct s5p_gpio_bank c4; +}; + +struct exynos5260_gpio_part3 { + struct s5p_gpio_bank z0; + struct s5p_gpio_bank z1; +}; + +/* exynos5430 */ +struct exynos5430_gpio_alive { + struct s5p_gpio_bank a0; + struct s5p_gpio_bank a1; + struct s5p_gpio_bank a2; + struct s5p_gpio_bank a3; +}; + +struct exynos5430_gpio_aud { + struct s5p_gpio_bank z0; + struct s5p_gpio_bank z1; +}; + +struct exynos5430_gpio_cpif { + struct s5p_gpio_bank v6; +}; + +struct exynos5430_gpio_fsys { + struct s5p_gpio_bank h1; + struct s5p_gpio_bank r4; + struct s5p_gpio_bank r0; + struct s5p_gpio_bank r1; + struct s5p_gpio_bank r2; + struct s5p_gpio_bank r3; +}; + +struct exynos5430_gpio_nfc { + struct s5p_gpio_bank j0; +}; + +struct exynos5430_gpio_peric { + struct s5p_gpio_bank v7; + struct s5p_gpio_bank b0; + struct s5p_gpio_bank c0; + struct s5p_gpio_bank c1; + struct s5p_gpio_bank c2; + struct s5p_gpio_bank c3; + struct s5p_gpio_bank g0; + struct s5p_gpio_bank d0; + struct s5p_gpio_bank d1; + struct s5p_gpio_bank d2; + struct s5p_gpio_bank d4; + struct s5p_gpio_bank d5; + struct s5p_gpio_bank d8; + struct s5p_gpio_bank d6; + struct s5p_gpio_bank d7; + struct s5p_gpio_bank f0; + struct s5p_gpio_bank f1; + struct s5p_gpio_bank f2; + struct s5p_gpio_bank f3; + struct s5p_gpio_bank f4; + struct s5p_gpio_bank f5; + unsigned char res1[0x3c]; + struct s5p_gpio_bank g1; + struct s5p_gpio_bank g2; + struct s5p_gpio_bank g3; +}; + +struct exynos5430_gpio_touch { + struct s5p_gpio_bank j1; +}; + /* functions */ void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg); void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en); @@ -160,6 +334,80 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode); - EXYNOS4_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \ * GPIO_PER_BANK) + pin) + EXYNOS4_GPIO_PART1_MAX) +#if defined(CONFIG_CPU_EXYNOS5260) +#define exynos5_gpio_part1_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5260_gpio_part1 *) \ + EXYNOS5260_GPIO_PART1_BASE)->bank)) \ + - EXYNOS5260_GPIO_PART1_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define EXYNOS5_GPIO_PART1_MAX ((sizeof(struct exynos5260_gpio_part1) \ + / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK) + +#define exynos5_gpio_part2_get_nr(bank, pin) \ + (((((((unsigned int) &(((struct exynos5260_gpio_part2 *) \ + EXYNOS5260_GPIO_PART2_BASE)->bank)) \ + - EXYNOS5260_GPIO_PART2_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + EXYNOS5260_GPIO_PART1_MAX) + +#define EXYNOS5_GPIO_PART2_MAX ((sizeof(struct exynos5_gpio_part2) \ + / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK) + +#define exynos5_gpio_part3_get_nr(bank, pin) \ + (((((((unsigned int) &(((struct exynos5260_gpio_part3 *) \ + EXYNOS5260_GPIO_PART3_BASE)->bank)) \ + - EXYNOS5260_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + EXYNOS5260_GPIO_PART2_MAX) + +#elif defined(CONFIG_CPU_EXYNOS5430) +#define exynos5_gpio_alive_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5430_gpio_alive *) \ + EXYNOS5430_GPIO_ALIVE_BASE)->bank)) \ + - EXYNOS5430_GPIO_ALIVE_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define exynos5_gpio_aud_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5430_gpio_aud *) \ + EXYNOS5430_GPIO_AUD_BASE)->bank)) \ + - EXYNOS5430_GPIO_AUD_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define exynos5_gpio_cpif_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5430_gpio_cpif *) \ + EXYNOS5430_GPIO_CPIF_BASE)->bank)) \ + - EXYNOS5430_GPIO_CPIF_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define exynos5_gpio_fsys_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5430_gpio_fsys *) \ + EXYNOS5430_GPIO_FSYS_BASE)->bank)) \ + - EXYNOS5430_GPIO_FSYS_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define exynos5_gpio_nfc_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5430_gpio_nfc *) \ + EXYNOS5430_GPIO_NFC_BASE)->bank)) \ + - EXYNOS5430_GPIO_NFC_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define exynos5_gpio_peric_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5430_gpio_peric *) \ + EXYNOS5430_GPIO_PERIC_BASE)->bank)) \ + - EXYNOS5430_GPIO_PERIC_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define exynos5_gpio_touch_get_nr(bank, pin) \ + ((((((unsigned int) &(((struct exynos5430_gpio_touch *) \ + EXYNOS5430_GPIO_TOUCH_BASE)->bank)) \ + - EXYNOS5430_GPIO_TOUCH_BASE) / sizeof(struct s5p_gpio_bank)) \ + * GPIO_PER_BANK) + pin) + +#define EXYNOS5430_GPIO_PERIC_MAX ((sizeof(struct exynos5430_gpio_peric) \ + / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK) + +#define EXYNOS5430_GPIO_FSYS_MAX ((sizeof(struct exynos5430_gpio_fsys) \ + / sizeof(struct s5p_gpio_bank)) * GPIO_PER_BANK) +#else /* CONFIG_CPU_EXYNOS5430 */ #define exynos5_gpio_part1_get_nr(bank, pin) \ ((((((unsigned int) &(((struct exynos5_gpio_part1 *) \ EXYNOS5_GPIO_PART1_BASE)->bank)) \ @@ -183,17 +431,33 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode); EXYNOS5_GPIO_PART3_BASE)->bank)) \ - EXYNOS5_GPIO_PART3_BASE) / sizeof(struct s5p_gpio_bank)) \ * GPIO_PER_BANK) + pin) + EXYNOS5_GPIO_PART2_MAX) +#endif /* CONFIG_CPU_EXYNOS5260 */ static inline unsigned int s5p_gpio_base(int nr) { if (cpu_is_exynos5()) { +#if defined(CONFIG_CPU_EXYNOS5430) + if (nr < EXYNOS5430_GPIO_PERIC_MAX) + return EXYNOS5430_GPIO_PERIC_BASE; + else if (nr < EXYNOS5430_GPIO_FSYS_MAX) + return EXYNOS5430_GPIO_FSYS_BASE; + else + return EXYNOS5430_GPIO_ALIVE_BASE; +#elif defined(CONFIG_CPU_EXYNOS5260) + if (nr < EXYNOS5_GPIO_PART1_MAX) + return EXYNOS5260_GPIO_PART1_BASE; + else if (nr < EXYNOS5_GPIO_PART2_MAX) + return EXYNOS5260_GPIO_PART2_BASE; + else + return EXYNOS5260_GPIO_PART3_BASE; +#else if (nr < EXYNOS5_GPIO_PART1_MAX) return EXYNOS5_GPIO_PART1_BASE; else if (nr < EXYNOS5_GPIO_PART2_MAX) return EXYNOS5_GPIO_PART2_BASE; else return EXYNOS5_GPIO_PART3_BASE; - +#endif /* CONFIG_CPU_EXYNOS5260 */ } else if (cpu_is_exynos4()) { if (nr < EXYNOS4_GPIO_PART1_MAX) return EXYNOS4_GPIO_PART1_BASE; diff --git a/arch/arm/include/asm/arch-exynos/mmc.h b/arch/arm/include/asm/arch-exynos/mmc.h index 0f701c901..eda44ea79 100644 --- a/arch/arm/include/asm/arch-exynos/mmc.h +++ b/arch/arm/include/asm/arch-exynos/mmc.h @@ -64,11 +64,20 @@ #define SDHCI_CTRL4_DRIVE_MASK(_x) ((_x) << 16) #define SDHCI_CTRL4_DRIVE_SHIFT (16) +#define MSHC_VERSION_MAIN_ID 0x5342 +#define MSHC_VERID 0x6C + int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks); static inline unsigned int s5p_mmc_init(int index, int bus_width) { unsigned int base = samsung_get_base_mmc() + (0x10000 * index); - return s5p_sdhci_init(base, 52000000, 400000, index); + unsigned int mshc_ver_main_id = readl(base + MSHC_VERID) >> 16; + + if(mshc_ver_main_id == MSHC_VERSION_MAIN_ID) + return s5p_mshc_init(base, index); + else + return s5p_sdhci_init(base, 52000000, 400000, index); + } #endif diff --git a/arch/arm/include/asm/arch-exynos/movi_partition.h b/arch/arm/include/asm/arch-exynos/movi_partition.h new file mode 100644 index 000000000..e475b08e1 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/movi_partition.h @@ -0,0 +1,115 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __MOVI_PARTITION_H__ +#define __MOVI_PARTITION_H__ + +#define eFUSE_SIZE (1 * 512) // 512 Byte eFuse, 512 Byte reserved + +#define MOVI_BLKSIZE (1<<9) /* 512 bytes */ + +/* partition information */ +#if defined(CONFIG_BL_MONITOR) +#define PART_SIZE_BL1 (15 * 1024) +#else +#define PART_SIZE_BL1 (8 * 1024) +#endif + +#define PART_SIZE_BL2 (16 * 1024) +#define PART_SIZE_UBOOT (328 * 1024) +#if defined(CONFIG_CPU_EXYNOS5260) || defined(CONFIG_CPU_EXYNOS3250) +#define PART_SIZE_KERNEL (8 * 1024 * 1024) +#elif defined(CONFIG_CPU_EXYNOS5430) || defined(CONFIG_CPU_EXYNOS5412) +#define PART_SIZE_KERNEL (5 * 1024 * 1024) +#else +#define PART_SIZE_KERNEL (4 * 1024 * 1024) +#endif +#define PART_SIZE_ROOTFS (26 * 1024 * 1024) +#if defined(CONFIG_EXYNOS4X12) || defined(CONFIG_CPU_EXYNOS5250) || defined(CONFIG_CPU_EXYNOS3250) +#define PART_SIZE_TZSW (156 * 1024) +#else +#define PART_SIZE_TZSW (256 * 1024) +#endif + +#if defined(CONFIG_BOOT_LOGO) +#define PART_SIZE_BOOT_LOGO (4 * 1024 * 1024) +#endif +#if defined(CONFIG_CHARGER_LOGO) +#define PART_SIZE_CHARGER_LOGO (4 * 1024 * 1024) +#endif + +#define MOVI_BL1_BLKCNT (PART_SIZE_BL1 / MOVI_BLKSIZE) +#define MOVI_BL2_BLKCNT (PART_SIZE_BL2 / MOVI_BLKSIZE) +#define MOVI_ENV_BLKCNT (CONFIG_ENV_SIZE / MOVI_BLKSIZE) /* 16KB */ +#define MOVI_UBOOT_BLKCNT (PART_SIZE_UBOOT / MOVI_BLKSIZE) /* 328KB */ +#define MOVI_ZIMAGE_BLKCNT (PART_SIZE_KERNEL / MOVI_BLKSIZE) /* 4MB */ +#define MOVI_ROOTFS_BLKCNT (PART_SIZE_ROOTFS / MOVI_BLKSIZE) /* 26MB */ +#define MOVI_TZSW_BLKCNT (PART_SIZE_TZSW / MOVI_BLKSIZE) /* 160KB */ +#if defined(CONFIG_CHARGER_LOGO) +#define MOVI_CHARGER_LOGO_BLKCNT (PART_SIZE_CHARGER_LOGO / MOVI_BLKSIZE) +#endif +#if defined(CONFIG_BOOT_LOGO) +#define MOVI_BOOT_LOGO_BLKCNT (PART_SIZE_BOOT_LOGO / MOVI_BLKSIZE) +#endif + +#define MOVI_UBOOT_POS ((eFUSE_SIZE / MOVI_BLKSIZE) + MOVI_BL1_BLKCNT + MOVI_BL2_BLKCNT) +#define MOVI_TZSW_POS ((eFUSE_SIZE / MOVI_BLKSIZE) + MOVI_BL1_BLKCNT \ + + MOVI_BL2_BLKCNT + MOVI_UBOOT_BLKCNT) +#define MOVI_ENV_POS (MOVI_TZSW_POS + MOVI_TZSW_BLKCNT) +#define CONFIG_ENV_OFFSET (MOVI_ENV_POS * MOVI_BLKSIZE) + +#ifndef __ASSEMBLY__ +#include <asm/io.h> + +/* + * + * start_blk: start block number for image + * used_blk: blocks occupied by image + * size: image size in bytes + * attribute: attributes of image + * 0x0: BL1 + * 0x1: u-boot parted (BL2) + * 0x2: u-boot + * 0x4: kernel + * 0x8: root file system + * 0x10: environment area + * 0x20: reserved + * description: description for image + * by scsuh + */ +typedef struct member { + uint start_blk; + uint used_blk; + uint size; + uint attribute; /* attribute of image */ + char description[16]; +} member_t; /* 32 bytes */ + +/* + * start_blk: start block number for raw area + * total_blk: total block number of card + * next_raw_area: add next raw_area structure + * description: description for raw_area + * image: several image that is controlled by raw_area structure + * by scsuh + */ +typedef struct raw_area { + uint start_blk; /* compare with PT on coherency test */ + uint total_blk; + uint next_raw_area; /* should be sector number */ + char description[16]; + member_t image[15]; +} raw_area_t; /* 512 bytes */ + +extern raw_area_t raw_area_control; +#endif +#endif /*__MOVI_PARTITION_H__*/ diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h index 5db25aa88..0aae2b031 100644 --- a/arch/arm/include/asm/arch-exynos/periph.h +++ b/arch/arm/include/asm/arch-exynos/periph.h @@ -39,6 +39,11 @@ enum periph_id { PERIPH_ID_UART1, PERIPH_ID_UART2, PERIPH_ID_UART3, + PERIPH_ID_INPUT_A0_3, + PERIPH_ID_INPUT_A2_0, + PERIPH_ID_INPUT_A2_1, + PERIPH_ID_INPUT_X0_0, + PERIPH_ID_INPUT_X2_0, PERIPH_ID_COUNT, PERIPH_ID_NONE = -1, diff --git a/arch/arm/include/asm/arch-exynos/pmic.h b/arch/arm/include/asm/arch-exynos/pmic.h new file mode 100644 index 000000000..1f8c5e83d --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/pmic.h @@ -0,0 +1,146 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __PMIC_H__ +#define __PMIC_H__ + +#ifdef CONFIG_CPU_EXYNOS5410 +#ifdef CONFIG_MACH_ASB5410 +#define GPD1CON *(volatile unsigned long *)(0x134000C0) +#define GPD1DAT *(volatile unsigned long *)(0x134000C4) +#define GPD1PUD *(volatile unsigned long *)(0x134000C8) +#else +#define GPD1CON *(volatile unsigned long *)(0x13400040) +#define GPD1DAT *(volatile unsigned long *)(0x13400044) +#define GPD1PUD *(volatile unsigned long *)(0x13400048) +#endif +#elif defined(CONFIG_CPU_EXYNOS5412) +#define GPD1CON *(volatile unsigned long *)(0x14010120) +#define GPD1DAT *(volatile unsigned long *)(0x14010124) +#define GPD1PUD *(volatile unsigned long *)(0x14010128) +#else +#define GPD1CON *(volatile unsigned long *)(0x114000C0) +#define GPD1DAT *(volatile unsigned long *)(0x114000C4) +#define GPD1PUD *(volatile unsigned long *)(0x114000C8) +#endif + +#ifdef CONFIG_SMDKC220 +#define GPA1CON *(volatile unsigned long *)(0x11400020) +#define GPA1DAT *(volatile unsigned long *)(0x11400024) +#define GPA1PUD *(volatile unsigned long *)(0x11400028) +#endif + +#ifdef CONFIG_MACH_UNIVERSAL5410 +#define IIC0_ESCL_Hi GPD1DAT |= (0x1<<3) +#define IIC0_ESCL_Lo GPD1DAT &= ~(0x1<<3) +#define IIC0_ESDA_Hi GPD1DAT |= (0x1<<2) +#define IIC0_ESDA_Lo GPD1DAT &= ~(0x1<<2) +#else +#define IIC0_ESCL_Hi GPD1DAT |= (0x1<<1) +#define IIC0_ESCL_Lo GPD1DAT &= ~(0x1<<1) +#define IIC0_ESDA_Hi GPD1DAT |= (0x1<<0) +#define IIC0_ESDA_Lo GPD1DAT &= ~(0x1<<0) +#endif + +#define IIC1_ESCL_Hi GPD1DAT |= (0x1<<3) +#define IIC1_ESCL_Lo GPD1DAT &= ~(0x1<<3) +#define IIC1_ESDA_Hi GPD1DAT |= (0x1<<2) +#define IIC1_ESDA_Lo GPD1DAT &= ~(0x1<<2) + +#ifdef CONFIG_SMDKC220 +#define IIC3_ESCL_Hi GPA1DAT |= (0x1<<3) +#define IIC3_ESCL_Lo GPA1DAT &= ~(0x1<<3) +#define IIC3_ESDA_Hi GPA1DAT |= (0x1<<2) +#define IIC3_ESDA_Lo GPA1DAT &= ~(0x1<<2) +#endif + +#ifdef CONFIG_MACH_UNIVERSAL5410 +#define IIC0_ESCL_INP GPD1CON &= ~(0xf<<12) +#define IIC0_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<12))|(0x1<<12) + +#define IIC0_ESDA_INP GPD1CON &= ~(0xf<<8) +#define IIC0_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<8))|(0x1<<8) +#else +#define IIC0_ESCL_INP GPD1CON &= ~(0xf<<4) +#define IIC0_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<4))|(0x1<<4) + +#define IIC0_ESDA_INP GPD1CON &= ~(0xf<<0) +#define IIC0_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<0))|(0x1<<0) +#endif + +#define IIC1_ESCL_INP GPD1CON &= ~(0xf<<12) +#define IIC1_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<12))|(0x1<<12) + +#define IIC1_ESDA_INP GPD1CON &= ~(0xf<<8) +#define IIC1_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<8))|(0x1<<8) + +#ifdef CONFIG_SMDKC220 +#define IIC3_ESCL_INP GPA1CON &= ~(0xf<<12) +#define IIC3_ESCL_OUTP GPA1CON = (GPA1CON & ~(0xf<<12))|(0x1<<12) + +#define IIC3_ESDA_INP GPA1CON &= ~(0xf<<8) +#define IIC3_ESDA_OUTP GPA1CON = (GPA1CON & ~(0xf<<8))|(0x1<<8) +#endif + +#define DELAY 100 + +#define MAX8952_ADDR 0xc0 // VDD_ARM - I2C0 +#define MAX8649_ADDR 0xc0 // VDD_INT - I2C1 +#define MAX8649A_ADDR 0xc4 // VDD_G3D - I2C0 +#define MAX8997_ADDR 0xCC // MAX8997 - I2C0 +#define MAX77686_ADDR 0x12 // MAX77686 - I2C0 +#define MAX77686_BUCK1OUT 0x11 +#define MAX77686_BUCK2TV_DVS1 0x14 +#define MAX77686_BUCK3TV_DVS1 0x1E +#define MAX77686_BUCK4TV_DVS1 0x28 +#define MAX77686_BUCK5OUT 0x31 +#define MAX8997_ID 0x00 +#define MAX8997_BUCK1TV_DVS 0x19 +#define MAX8997_BUCK2TV_DVS 0x22 +#define MAX8997_BUCK3TV_DVS 0x2B +#define MAX8997_BUCK4TV_DVS 0x2D +#define MAX8997_LDO10CTRL 0x44 +#define S5M8767_ADDR 0xCC // S5M8767 - I2C0 +extern void pmic8767_init(void); + +#define CALC_MAXIM_BUCK1245_VOLT(x) ( (x<650) ? 0 : ((x-650)/25) ) +#define CALC_MAXIM_BUCK37_VOLT(x) ( (x<750) ? 0 : ((x-750)/50) ) +#define CALC_MAXIM_ALL_LDO(x) ( (x<800) ? 0 : ((x-800)/50) ) +#define CALC_MAXIM77686_BUCK156789_VOLT(x) ( (x<750) ? 0 : ((x-750)/50) ) +#define CALC_MAXIM77686_BUCK234_VOLT(x) ( (x<600) ? 0 : ((x-600)/12.5) ) +#define CALC_MAXIM77686_LDO1267815_VOLT(x) ( (x<800) ? 0 : ((x-800)/25) ) +#define CALC_MAXIM77686_ALL_LDO_VOLT(x) ( (x<800) ? 0 : ((x-800)/50) ) + +#if defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5412) +#define VDD_BASE_VOLT 1.00 +#define VDD_BASE_VAL 0x40 +#define CONFIG_PM_CALC_VOLT(x) (VDD_BASE_VAL + ((x - VDD_BASE_VOLT) * 20 * 8)) + +#define ARM_EMA_CTRL_OFFSET 0x01008 +#define ARM_EMA_CTRL_KFC_OFFSET 0x29008 +#endif + +typedef enum +{ + PMIC_BUCK1=0, + PMIC_BUCK2, + PMIC_BUCK3, + PMIC_BUCK4, + PMIC_LDO14, + PMIC_LDO10, + PMIC_LDO21, +}PMIC_RegNum; + +extern void pmic_init(void); + +#endif /*__PMIC_H__*/ + diff --git a/arch/arm/include/asm/arch-exynos/pmu.h b/arch/arm/include/asm/arch-exynos/pmu.h new file mode 100644 index 000000000..51577497e --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/pmu.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <asm/arch/cpu.h> + +#ifndef __ASM_ARM_ARCH_PMU_H_ +#define __ASM_ARM_ARCH_PMU_H_ + +#define EXYNOS5430_POWER_WAKEUP_STAT (EXYNOS5430_POWER_BASE + 0x0600) +#define EXYNOS5430_POWER_GSCL_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4000) +#define EXYNOS5430_POWER_CAM0_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4020) +#define EXYNOS5430_POWER_MSCL_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4040) +#define EXYNOS5430_POWER_G3D_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4060) +#define EXYNOS5430_POWER_DISP_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4080) +#define EXYNOS5430_POWER_CAM1_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x40A0) +#define EXYNOS5430_POWER_AUD_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x40C0) +#define EXYNOS5430_POWER_FSYS_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x40E0) +#define EXYNOS5430_POWER_G2D_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4120) +#define EXYNOS5430_POWER_ISP_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4140) +#define EXYNOS5430_POWER_MFC0_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x4180) +#define EXYNOS5430_POWER_MFC1_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x41a0) +#define EXYNOS5430_POWER_HEVC_CONFIGURATION (EXYNOS5430_POWER_BASE + 0x41c0) + +#define WAKEUP_MASK 0x80000000 + +#endif diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index e5467e242..b9ec628da 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -847,6 +847,58 @@ struct exynos5_power { unsigned int cmu_reset_mau_option; unsigned char res163[0x24]; }; + +struct exynos5260_power { + unsigned int om_stat; + unsigned char res1[0x3fc]; + unsigned int sw_reset; + unsigned int rst_stat; + unsigned char res2[0x3f8]; + unsigned int inform0; + unsigned int inform1; + unsigned int inform2; + unsigned int inform3; + unsigned int sysip_dat0; + unsigned int sysip_dat1; + unsigned int sysip_dat2; + unsigned int sysip_dat3; + unsigned char res3[0xe0]; + unsigned int pmu_spare0; + unsigned int pmu_spare1; + unsigned int pmu_spare2; + unsigned int pmu_spare3; + unsigned char res4[0x70]; + unsigned int irom_data_reg0; + unsigned int irom_data_reg1; + unsigned int irom_data_reg2; + unsigned int irom_data_reg3; +}; + +struct exynos5430_power { + unsigned int om_stat; /* 0x105C_0000 */ + unsigned char res1[0x3fc]; + unsigned int swreset; + unsigned int rst_stat; + unsigned char res2[0x3f8]; + unsigned int inform0; + unsigned int inform1; + unsigned int inform2; + unsigned int inform3; + unsigned int sysip_dat0; + unsigned int sysip_dat1; + unsigned int sysip_dat2; + unsigned int sysip_dat3; + unsigned char res3[0xe0]; + unsigned int pmu_spare0; + unsigned int pmu_spare1; + unsigned int pmu_spare2; + unsigned int pmu_spare3; + unsigned char res4[0x70]; + unsigned int irom_data_reg0; + unsigned int irom_data_reg1; + unsigned int irom_data_reg2; + unsigned int irom_data_reg3; +}; #endif /* __ASSEMBLY__ */ void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable); diff --git a/arch/arm/include/asm/arch-exynos/smc.h b/arch/arm/include/asm/arch-exynos/smc.h new file mode 100644 index 000000000..51d713ba2 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/smc.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <config.h> +#include <asm/arch/movi_partition.h> +#include <asm/arch/cpu.h> + +#define SMC_CMD_LOAD_UBOOT (-230) +#define SMC_CMD_COLDBOOT (-231) +#define SMC_CMD_WARMBOOT (-232) +#define SMC_CMD_CHECK_SECOND_BOOT (-233) +#define SMC_CMD_EMMC_ENDBOOTOP (-234) +#define SMC_CMD_SDMMC_ENUMERATE (-235) +#define SMC_CMD_SET_SECURE_REG (-236) +#define SMC_CMD_READ_SECURE_REG (-237) +#define SMC_CMD_SET_SIGNATURE_SIZE (-238) + +#ifdef CONFIG_UBOOT_SECURE_BOOT +#define SMC_UBOOT_SIGNATURE_SIZE 256 +#else +#define SMC_UBOOT_SIGNATURE_SIZE 0 +#endif + +#ifdef CONFIG_TZSW_SECURE_BOOT +#define SMC_TZSW_SIGNATURE_SIZE 256 +#else +#define SMC_TZSW_SIGNATURE_SIZE 0 +#endif + +#define CONFIG_IMAGE_INFO_BASE (CONFIG_SYS_SDRAM_BASE) +#define CONFIG_PHY_UBOOT_BASE (CONFIG_SYS_TEXT_BASE) +#define SMC_SECURE_CONTEXT_BASE (CONFIG_PHY_IRAM_BASE + 0x4c00) +#if defined(CONFIG_CPU_EXYNOS5430) || defined(CONFIG_CPU_EXYNOS5260) || defined(CONFIG_CPU_EXYNOS3250) +#define CONFIG_PHY_TZSW_BASE (CONFIG_PHY_IRAM_BASE + 0xA000) +#elif defined(CONFIG_CPU_EXYNOS5412) +#define CONFIG_PHY_TZSW_BASE (CONFIG_PHY_IRAM_BASE + 0x10000) +#else +#define CONFIG_PHY_TZSW_BASE (CONFIG_PHY_IRAM_BASE + 0x8000) +#endif + +typedef struct sdmmc_dev { + /* for SDMMC */ + u32 image_pos; + u32 blkcnt; + u32 base_addr; +} sdmmc_t; + +typedef struct emmc_dev { + /* for eMMC */ + u32 blkcnt; + u32 base_addr; +} emmc_t; + +typedef struct sata_dev { + /* for SATA */ + u64 read_sector_of_hdd; + u32 trans_byte; + u32 *read_buffer; + u32 position_of_mem; +} sata_t; + +typedef struct sfmc_dev { + /* for SFMC */ + u32 cs; + u32 byte_offset; + u32 byte_size; + void *dest_addr; +} sfmc_t; + +typedef struct spi_sf_dev { + /* for SPI SERIAL FLASH */ + u32 flash_read_addr; + u32 read_size; + u8 *read_buff; +} spi_sf_t; + +typedef struct usb_dev { + /* for USB */ + u32 base_addr; + u32 *read_buffer; + u32 secure; +} usb_t; + +/* boot device */ +typedef union boot_device_u { + sdmmc_t sdmmc; + emmc_t emmc; + sata_t sata; + sfmc_t sfmc; + spi_sf_t spi_sf; + usb_t usb; +} boot_device_t; + +typedef struct ld_image_info { + /* for Signature */ + u32 image_base_addr; + u32 size; + u32 secure_context_base; + u32 signature_size; + boot_device_t bootdev; + +} image_info; + +typedef struct reg_val { + u32 addr; + u32 val; +} reg_val_t; + +typedef struct reg_arr { + reg_val_t set0; + reg_val_t set1; + reg_val_t set2; + reg_val_t set3; + reg_val_t set4; + reg_val_t set5; + reg_val_t set6; + reg_val_t set7; + reg_val_t set8; + reg_val_t set9; +} reg_arr_t; + +unsigned int load_uboot_image(u32 boot_device); +unsigned int coldboot(u32 boot_device); +void warmboot(void); +unsigned int find_second_boot(void); +void emmc_endbootop(void); +void set_secure_reg(u32 reg_val, u32 num); +unsigned int read_secure_reg(u32 addr); + + diff --git a/arch/arm/include/asm/arch-exynos/sysreg.h b/arch/arm/include/asm/arch-exynos/sysreg.h new file mode 100644 index 000000000..52052b8eb --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/sysreg.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __ASM_ARM_ARCH_SYSREG_H_ +#define __ASM_ARM_ARCH_SYSREG_H_ + +#ifndef __ASSEMBLY__ +struct exynos5_sysreg { + unsigned char res1[0x0214]; + unsigned int disp1blk_cfg; + unsigned int dispblk_cfg2; + unsigned int hdcp_e_fuse_mem_cfg; + unsigned int gsclblk_cfg0; + unsigned int gsclblk_cfg1; + unsigned char res2[0x4]; + unsigned int ispblk_cfg; + unsigned int usb20phy_cfg; + unsigned int i2c_cfg; + unsigned int mipi_dphy; + unsigned int dptx_phy; + unsigned int phyclk_sel; + unsigned int gsclblk_cfg2; + unsigned char res3[0xdffc]; +}; +#endif + +#endif diff --git a/arch/arm/include/asm/arch-exynos/usb.h b/arch/arm/include/asm/arch-exynos/usb.h new file mode 100644 index 000000000..5465769be --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/usb.h @@ -0,0 +1,139 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + + +#ifndef _EXYNOS_USB_H +#define _EXYNOS_USB_H + +/* + * SYSREG + */ +#define USB_CFG_OFFSET 0x230 +#define USB_CFG_REG (EXYNOS_SYSREG_BASE + USB_CFG_OFFSET) + +/* PHY CONTROL */ +#ifdef CONFIG_CPU_EXYNOS5250 +#define USB_DEVICE_PHY_CONTROL_OFFSET 0x0704 +#define USB_PHY_CONTROL_OFFSET 0x0708 +#else +#define USB_DEVICE_PHY_CONTROL_OFFSET 0x0704 +#define USB_DEVICE1_PHY_CONTROL_OFFSET 0x0708 +#define USB_PHY_CONTROL_OFFSET 0x070C +#endif + +#define USB_DEVICE_PHY_CONTROL (EXYNOS_POWER_BASE+USB_DEVICE_PHY_CONTROL_OFFSET) +#define USB_DEVICE1_PHY_CONTROL (EXYNOS_POWER_BASE+USB_DEVICE1_PHY_CONTROL_OFFSET) +#define USB_PHY_CONTROL (EXYNOS_POWER_BASE+USB_PHY_CONTROL_OFFSET) + +//========================== +// Global Registers (Gxxxx) +//========================== +// Global Common Registers +#define rGSBUSCFG0 (USBDEVICE3_LINK_BASE + 0xc100) +#define rGSBUSCFG1 (USBDEVICE3_LINK_BASE + 0xc104) +#define rGTXTHRCFG (USBDEVICE3_LINK_BASE + 0xc108) +#define rGRXTHRCFG (USBDEVICE3_LINK_BASE + 0xc10c) +#define rGCTL (USBDEVICE3_LINK_BASE + 0xc110) +#define rGEVTEN (USBDEVICE3_LINK_BASE + 0xc114) +#define rGSTS (USBDEVICE3_LINK_BASE + 0xc118) +#define rGSNPSID (USBDEVICE3_LINK_BASE + 0xc120) +#define rGGPIO (USBDEVICE3_LINK_BASE + 0xc124) +#define rGUID (USBDEVICE3_LINK_BASE + 0xc128) +#define rGUCTL (USBDEVICE3_LINK_BASE + 0xc12c) +#define rGBUSERRADDR_LO (USBDEVICE3_LINK_BASE + 0xc130) +#define rGBUSERRADDR_HI (USBDEVICE3_LINK_BASE + 0xc134) + +// Global Port to USB Instance Mapping Registers +#define rGPRTBIMAP_LO (USBDEVICE3_LINK_BASE + 0xc138) +#define rGPRTBIMAP_HI (USBDEVICE3_LINK_BASE + 0xc13c) +#define rGPRTBIMAP_HS_LO (USBDEVICE3_LINK_BASE + 0xc180) +#define rGPRTBIMAP_HS_HI (USBDEVICE3_LINK_BASE + 0xc184) +#define rGPRTBIMAP_FS_LO (USBDEVICE3_LINK_BASE + 0xc188) +#define rGPRTBIMAP_FS_HI (USBDEVICE3_LINK_BASE + 0xc18c) + +// Global Hardware Parameter Registers +#define rGHWPARAMS0 (USBDEVICE3_LINK_BASE + 0xc140) // 0x20204000 @c510 +#define rGHWPARAMS1 (USBDEVICE3_LINK_BASE + 0xc144) // 0x0060c93b @c510 +#define rGHWPARAMS2 (USBDEVICE3_LINK_BASE + 0xc148) // 0x12345678 @c510 +#define rGHWPARAMS3 (USBDEVICE3_LINK_BASE + 0xc14c) // 0x10420085 @c510 +#define rGHWPARAMS4 (USBDEVICE3_LINK_BASE + 0xc150) // 0x48820004 @c510 +#define rGHWPARAMS5 (USBDEVICE3_LINK_BASE + 0xc154) // 0x04204108 @c510 +#define rGHWPARAMS6 (USBDEVICE3_LINK_BASE + 0xc158) // 0x04008020 @c510 +#define rGHWPARAMS7 (USBDEVICE3_LINK_BASE + 0xc15c) // 0x018516fe @c510 +#define rGHWPARAMS8 (USBDEVICE3_LINK_BASE + 0xc600) // 0x00000386 @c510 + +// Global Debug Registers +#define rGDBGFIFOSPACE (USBDEVICE3_LINK_BASE + 0xc160) +#define rGDBGLTSSM (USBDEVICE3_LINK_BASE + 0xc164) +#define rGDBGLSPMUX (USBDEVICE3_LINK_BASE + 0xc170) +#define rGDBGLSP (USBDEVICE3_LINK_BASE + 0xc174) +#define rGDBGEPINFO0 (USBDEVICE3_LINK_BASE + 0xc178) +#define rGDBGEPINFO1 (USBDEVICE3_LINK_BASE + 0xc17c) + +// Global PHY Registers +#define rGUSB2PHYCFG (USBDEVICE3_LINK_BASE + 0xc200) +#define rGUSB2I2CCTL (USBDEVICE3_LINK_BASE + 0xc240) +#define rGUSB2PHYACC (USBDEVICE3_LINK_BASE + 0xc280) +#define rGUSB3PIPECTL (USBDEVICE3_LINK_BASE + 0xc2c0) + +// Global FIFO Size Registers (0 <= num <= 15 @510) +#define rGTXFIFOSIZ(num) ((USBDEVICE3_LINK_BASE + 0xc300) + 0x04*num) +#define rGRXFIFOSIZ0 (USBDEVICE3_LINK_BASE + 0xc380) + +// Global Event Buffer Registers (DWC_USB3_DEVICE_NUM_INT = 1 @C510, GHWPARAMS1[20:15]) +#define rGEVNTADR_LO0 (USBDEVICE3_LINK_BASE + 0xc400) +#define rGEVNTADR_HI0 (USBDEVICE3_LINK_BASE + 0xc404) +#define rGEVNTSIZ0 (USBDEVICE3_LINK_BASE + 0xc408) +#define rGEVNTCOUNT0 (USBDEVICE3_LINK_BASE + 0xc40c) + +//========================== +// Device Registers (Dxxxx) +//========================== +// Device Common Registers +#define rDCFG (USBDEVICE3_LINK_BASE + 0xc700) +#define rDCTL (USBDEVICE3_LINK_BASE + 0xc704) +#define rDEVTEN (USBDEVICE3_LINK_BASE + 0xc708) +#define rDSTS (USBDEVICE3_LINK_BASE + 0xc70c) +#define rDGCMDPAR (USBDEVICE3_LINK_BASE + 0xc710) +#define rDGCMD (USBDEVICE3_LINK_BASE + 0xc714) +#define rDALEPENA (USBDEVICE3_LINK_BASE + 0xc720) + +// Device Endpoint Registers (0 <= ep <= 15) +#define rDOEPCMDPAR2(ep) ((USBDEVICE3_LINK_BASE + 0xc800) + 0x20*ep) +#define rDOEPCMDPAR1(ep) ((USBDEVICE3_LINK_BASE + 0xc804) + 0x20*ep) +#define rDOEPCMDPAR0(ep) ((USBDEVICE3_LINK_BASE + 0xc808) + 0x20*ep) +#define rDOEPCMD(ep) ((USBDEVICE3_LINK_BASE + 0xc80c) + 0x20*ep) + +#define rDIEPCMDPAR2(ep) ((USBDEVICE3_LINK_BASE + 0xc810) + 0x20*ep) +#define rDIEPCMDPAR1(ep) ((USBDEVICE3_LINK_BASE + 0xc814) + 0x20*ep) +#define rDIEPCMDPAR0(ep) ((USBDEVICE3_LINK_BASE + 0xc818) + 0x20*ep) +#define rDIEPCMD(ep) ((USBDEVICE3_LINK_BASE + 0xc81c) + 0x20*ep) + +//========================== +// USB DEVICE PHY CONTROL REGISTERS +//========================== +#define EXYNOS_PHY_LINKSYSTEM (USBDEVICE3_PHYCTRL_BASE + 0x04) +#define EXYNOS_PHY_UTMI (USBDEVICE3_PHYCTRL_BASE + 0x08) +#define EXYNOS_PHY_PIPE (USBDEVICE3_PHYCTRL_BASE + 0x0C) +#define EXYNOS_PHY_CLKPWR (USBDEVICE3_PHYCTRL_BASE + 0x10) +#define EXYNOS_PHY_REG0 (USBDEVICE3_PHYCTRL_BASE + 0x14) +#define EXYNOS_PHY_REG1 (USBDEVICE3_PHYCTRL_BASE + 0x18) +#define EXYNOS_PHY_PARAM0 (USBDEVICE3_PHYCTRL_BASE + 0x1C) +#define EXYNOS_PHY_PARAM1 (USBDEVICE3_PHYCTRL_BASE + 0x20) +#define EXYNOS_PHY_TERM (USBDEVICE3_PHYCTRL_BASE + 0x24) +#define EXYNOS_PHY_TEST (USBDEVICE3_PHYCTRL_BASE + 0x28) +#define EXYNOS_PHY_ADP (USBDEVICE3_PHYCTRL_BASE + 0x2C) +#define EXYNOS_PHY_BATCHG (USBDEVICE3_PHYCTRL_BASE + 0x30) +#define EXYNOS_PHY_RESUME (USBDEVICE3_PHYCTRL_BASE + 0x34) +#define EXYNOS_PHY_LINK_PORT (USBDEVICE3_PHYCTRL_BASE + 0x44) + +#endif diff --git a/arch/arm/include/asm/arch-exynos/usb2.h b/arch/arm/include/asm/arch-exynos/usb2.h new file mode 100644 index 000000000..82e7b38d6 --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/usb2.h @@ -0,0 +1,396 @@ +/* + * Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + + +#ifndef _EXYNOS_USB2_H +#define _EXYNOS_USB2_H + +/* + * SYSREG + */ +#define USB_CFG_REG (EXYNOS_SYSREG_BASE + USB_CFG_OFFSET) +#if defined(CONFIG_CPU_EXYNOS5250) +#define USB_CFG_OFFSET 0x230 +#else +#define USB_CFG_OFFSET 0x21C +#endif + +/* USBD 2.0 SFR */ +#if defined(EXYNOS_USB_LINK_BASE) +#define USBOTG_LINK_BASE (EXYNOS_USB_LINK_BASE) +#else +#define USBOTG_LINK_BASE (0x12480000) //(0xEC000000) +#endif + +#if defined(EXYNOS_USB_LINK_BASE) +#define USBOTG_PHY_BASE (EXYNOS_USB_PHY_BASE) +#else +#define USBOTG_PHY_BASE (0x125B0000) //(0xEC100000) +#endif + +/* R/W OTG PHY Power Control Register */ +#define EXYNOS5_OTG_SYS (USBOTG_PHY_BASE + 0x038) + +#if defined(CONFIG_CPU_EXYNOS5250) +#define USB_PHY_CONTROL_OFFSET 0x0708 +#define USB_PHY_CONTROL (EXYNOS_POWER_BASE + USB_PHY_CONTROL_OFFSET) +#else +#define USB_PHY_CONTROL_OFFSET 0x0704 +#define USB_PHY_CONTROL (0x10020000 + USB_PHY_CONTROL_OFFSET) +#endif + +/* PENDING BIT */ +#define BIT_EINT0 (0x1) +#define BIT_EINT1 (0x1<<1) +#define BIT_EINT2 (0x1<<2) +#define BIT_EINT3 (0x1<<3) +#define BIT_EINT4_7 (0x1<<4) +#define BIT_EINT8_23 (0x1<<5) +#define BIT_BAT_FLT (0x1<<7) +#define BIT_TICK (0x1<<8) +#define BIT_WDT (0x1<<9) +#define BIT_TIMER0 (0x1<<10) +#define BIT_TIMER1 (0x1<<11) +#define BIT_TIMER2 (0x1<<12) +#define BIT_TIMER3 (0x1<<13) +#define BIT_TIMER4 (0x1<<14) +#define BIT_UART2 (0x1<<15) +#define BIT_LCD (0x1<<16) +#define BIT_DMA0 (0x1<<17) +#define BIT_DMA1 (0x1<<18) +#define BIT_DMA2 (0x1<<19) +#define BIT_DMA3 (0x1<<20) +#define BIT_SDI (0x1<<21) +#define BIT_SPI0 (0x1<<22) +#define BIT_UART1 (0x1<<23) +#define BIT_USBH (0x1<<26) +#define BIT_IIC (0x1<<27) +#define BIT_UART0 (0x1<<28) +#define BIT_SPI1 (0x1<<29) +#define BIT_RTC (0x1<<30) +#define BIT_ADC (0x1<<31) +#define BIT_ALLMSK (0xFFFFFFFF) + +/* + * USB2.0 HS OTG (Chapter 26) + */ + +#define S5P_OTG_PHYPWR (USBOTG_PHY_BASE + 0x000) /* R/W OTG PHY Power Control Register */ +#define S5P_OTG_PHYCLK (USBOTG_PHY_BASE + 0x004) /* R/W OTG PHY Clock Control Register */ +#define S5P_OTG_RSTCON (USBOTG_PHY_BASE + 0x008) /* R/W OTG Reset Control Register */ +#define S5P_OTG_PHYTUNE0 (USBOTG_PHY_BASE + 0x020) /* R/W OTG PHY0 Tuning Register */ +#define S5P_OTG_PHYTUNE1 (USBOTG_PHY_BASE + 0x024) /* R/W OTG PHY1 Tuning Register */ + +/* Core Global Register */ +#define S5P_OTG_GOTGCTL (USBOTG_LINK_BASE + 0x000) /* R/W OTG Control and Status Register */ +#define S5P_OTG_GOTGINT (USBOTG_LINK_BASE + 0x004) /* R/W OTG Interrupt Register */ +#define S5P_OTG_GAHBCFG (USBOTG_LINK_BASE + 0x008) /* R/W Core AHB Configuration Register */ +#define S5P_OTG_GUSBCFG (USBOTG_LINK_BASE + 0x00C) /* R/W Core USB Configuration Register */ +#define S5P_OTG_GRSTCTL (USBOTG_LINK_BASE + 0x010) /* R/W Core Reset Register */ +#define S5P_OTG_GINTSTS (USBOTG_LINK_BASE + 0x014) /* R/W Core Interrupt Register */ +#define S5P_OTG_GINTMSK (USBOTG_LINK_BASE + 0x018) /* R/W Core Interrupt Mask Register */ +#define S5P_OTG_GRXSTSR (USBOTG_LINK_BASE + 0x01C) /* R Receive Status Debug Read Register */ +#define S5P_OTG_GRXSTSP (USBOTG_LINK_BASE + 0x020) /* R Receive Status Read/Pop Register */ +#define S5P_OTG_GRXFSIZ (USBOTG_LINK_BASE + 0x024) /* R/W Receive FIFO Size Register */ +#define S5P_OTG_GNPTXFSIZ (USBOTG_LINK_BASE + 0x028) /* R/W Non-Periodic Transmit FIFO Size Register */ +#define S5P_OTG_GNPTXSTS (USBOTG_LINK_BASE + 0x02C) /* R Non-Periodic Transmit FIFO/Queue Status Register */ +#define S5P_OTG_HPTXFSIZ (USBOTG_LINK_BASE + 0x100) /* R/W Host Periodic Transmit FIFO Size Register */ +#define S5P_OTG_DPTXFSIZ1 (USBOTG_LINK_BASE + 0x104) /* R/W Device Periodic Transmit FIFO-1 Size Register */ +#define S5P_OTG_DPTXFSIZ2 (USBOTG_LINK_BASE + 0x108) /* R/W Device Periodic Transmit FIFO-2 Size Register */ +#define S5P_OTG_DPTXFSIZ3 (USBOTG_LINK_BASE + 0x10C) /* R/W Device Periodic Transmit FIFO-3 Size Register */ +#define S5P_OTG_DPTXFSIZ4 (USBOTG_LINK_BASE + 0x110) /* R/W Device Periodic Transmit FIFO-4 Size Register */ +#define S5P_OTG_DPTXFSIZ5 (USBOTG_LINK_BASE + 0x114) /* R/W Device Periodic Transmit FIFO-5 Size Register */ +#define S5P_OTG_DPTXFSIZ6 (USBOTG_LINK_BASE + 0x118) /* R/W Device Periodic Transmit FIFO-6 Size Register */ +#define S5P_OTG_DPTXFSIZ7 (USBOTG_LINK_BASE + 0x11C) /* R/W Device Periodic Transmit FIFO-7 Size Register */ +#define S5P_OTG_DPTXFSIZ8 (USBOTG_LINK_BASE + 0x120) /* R/W Device Periodic Transmit FIFO-8 Size Register */ +#define S5P_OTG_DPTXFSIZ9 (USBOTG_LINK_BASE + 0x124) /* R/W Device Periodic Transmit FIFO-9 Size Register */ +#define S5P_OTG_DPTXFSIZ10 (USBOTG_LINK_BASE + 0x128) /* R/W Device Periodic Transmit FIFO-10 Size Register */ +#define S5P_OTG_DPTXFSIZ11 (USBOTG_LINK_BASE + 0x12C) /* R/W Device Periodic Transmit FIFO-11 Size Register */ +#define S5P_OTG_DPTXFSIZ12 (USBOTG_LINK_BASE + 0x130) /* R/W Device Periodic Transmit FIFO-12 Size Register */ +#define S5P_OTG_DPTXFSIZ13 (USBOTG_LINK_BASE + 0x134) /* R/W Device Periodic Transmit FIFO-13 Size Register */ +#define S5P_OTG_DPTXFSIZ14 (USBOTG_LINK_BASE + 0x138) /* R/W Device Periodic Transmit FIFO-14 Size Register */ +#define S5P_OTG_DPTXFSIZ15 (USBOTG_LINK_BASE + 0x13C) /* R/W Device Periodic Transmit FIFO-15 Size Register */ + +/* Host Mode Register */ +/* Host Global Register */ +#define S5P_OTG_HCFG (USBOTG_LINK_BASE + 0x400) /* R/W Host Configuration Register */ +#define S5P_OTG_HFIR (USBOTG_LINK_BASE + 0x404) /* R/W Host Frame Interval Register */ +#define S5P_OTG_HFNUM (USBOTG_LINK_BASE + 0x408) /* R Host Frame Number/Frame Time Remaining Register */ + +#define S5P_OTG_HPTXSTS (USBOTG_LINK_BASE + 0x410) /* R Host Periodic Transmit FIFO/Queue Status Register */ +#define S5P_OTG_HAINT (USBOTG_LINK_BASE + 0x414) /* R Host All Channels Interrupt Register */ +#define S5P_OTG_HAINTMSK (USBOTG_LINK_BASE + 0x418) /* R/W Host All Channels Interrupt Mask Register */ + +/*Host Port Control and Status Register */ +#define S5P_OTG_HPRT (USBOTG_LINK_BASE + 0x440) /* R/W Host Port Control and Status Register */ + +/*Host Channel-Specific Register */ +#define S5P_OTG_HCCHAR0 (USBOTG_LINK_BASE + 0x500) /* R/W Host Channel 0 Characteristics Register */ +#define S5P_OTG_HCSPLT0 (USBOTG_LINK_BASE + 0x504) /* R/W Host Channel 0 Spilt Control Register */ +#define S5P_OTG_HCINT0 (USBOTG_LINK_BASE + 0x508) /* R/W Host Channel 0 Interrupt Register */ +#define S5P_OTG_HCINTMSK0 (USBOTG_LINK_BASE + 0x50C) /* R/W Host Channel 0 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ0 (USBOTG_LINK_BASE + 0x510) /* R/W Host Channel 0 Transfer Size Register */ +#define S5P_OTG_HCDMA0 (USBOTG_LINK_BASE + 0x514) /* R/W Host Channel 0 DMA Address Register */ +#define S5P_OTG_HCCHAR1 (USBOTG_LINK_BASE + 0x520) /* R/W Host Channel 1 Characteristics Register */ +#define S5P_OTG_HCSPLT1 (USBOTG_LINK_BASE + 0x524) /* R/W Host Channel 1 Spilt Control Register */ +#define S5P_OTG_HCINT1 (USBOTG_LINK_BASE + 0x528) /* R/W Host Channel 1 Interrupt Register */ +#define S5P_OTG_HCINTMSK1 (USBOTG_LINK_BASE + 0x52C) /* R/W Host Channel 1 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ1 (USBOTG_LINK_BASE + 0x530) /* R/W Host Channel 1 Transfer Size Register */ +#define S5P_OTG_HCDMA1 (USBOTG_LINK_BASE + 0x534) /* R/W Host Channel 1 DMA Address Register */ +#define S5P_OTG_HCCHAR2 (USBOTG_LINK_BASE + 0x540) /* R/W Host Channel 2 Characteristics Register */ +#define S5P_OTG_HCSPLT2 (USBOTG_LINK_BASE + 0x544) /* R/W Host Channel 2 Spilt Control Register */ +#define S5P_OTG_HCINT2 (USBOTG_LINK_BASE + 0x548) /* R/W Host Channel 2 Interrupt Register */ +#define S5P_OTG_HCINTMSK2 (USBOTG_LINK_BASE + 0x54C) /* R/W Host Channel 2 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ2 (USBOTG_LINK_BASE + 0x550) /* R/W Host Channel 2 Transfer Size Register */ +#define S5P_OTG_HCDMA2 (USBOTG_LINK_BASE + 0x554) /* R/W Host Channel 2 DMA Address Register */ +#define S5P_OTG_HCCHAR3 (USBOTG_LINK_BASE + 0x560) /* R/W Host Channel 3 Characteristics Register */ +#define S5P_OTG_HCSPLT3 (USBOTG_LINK_BASE + 0x564) /* R/W Host Channel 3 Spilt Control Register */ +#define S5P_OTG_HCINT3 (USBOTG_LINK_BASE + 0x568) /* R/W Host Channel 3 Interrupt Register */ +#define S5P_OTG_HCINTMSK3 (USBOTG_LINK_BASE + 0x56C) /* R/W Host Channel 3 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ3 (USBOTG_LINK_BASE + 0x570) /* R/W Host Channel 3 Transfer Size Register */ +#define S5P_OTG_HCDMA3 (USBOTG_LINK_BASE + 0x574) /* R/W Host Channel 3 DMA Address Register */ +#define S5P_OTG_HCCHAR4 (USBOTG_LINK_BASE + 0x580) /* R/W Host Channel 4 Characteristics Register */ +#define S5P_OTG_HCSPLT4 (USBOTG_LINK_BASE + 0x584) /* R/W Host Channel 4 Spilt Control Register */ +#define S5P_OTG_HCINT4 (USBOTG_LINK_BASE + 0x588) /* R/W Host Channel 4 Interrupt Register */ +#define S5P_OTG_HCINTMSK4 (USBOTG_LINK_BASE + 0x58C) /* R/W Host Channel 4 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ4 (USBOTG_LINK_BASE + 0x580) /* R/W Host Channel 4 Transfer Size Register */ +#define S5P_OTG_HCDMA4 (USBOTG_LINK_BASE + 0x584) /* R/W Host Channel 4 DMA Address Register */ +#define S5P_OTG_HCCHAR5 (USBOTG_LINK_BASE + 0x5A0) /* R/W Host Channel 5 Characteristics Register */ +#define S5P_OTG_HCSPLT5 (USBOTG_LINK_BASE + 0x5A4) /* R/W Host Channel 5 Spilt Control Register */ +#define S5P_OTG_HCINT5 (USBOTG_LINK_BASE + 0x5A8) /* R/W Host Channel 5 Interrupt Register */ +#define S5P_OTG_HCINTMSK5 (USBOTG_LINK_BASE + 0x5AC) /* R/W Host Channel 5 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ5 (USBOTG_LINK_BASE + 0x5B0) /* R/W Host Channel 5 Transfer Size Register */ +#define S5P_OTG_HCDMA5 (USBOTG_LINK_BASE + 0x5B4) /* R/W Host Channel 5 DMA Address Register */ +#define S5P_OTG_HCCHAR6 (USBOTG_LINK_BASE + 0x5C0) /* R/W Host Channel 6 Characteristics Register */ +#define S5P_OTG_HCSPLT6 (USBOTG_LINK_BASE + 0x5C4) /* R/W Host Channel 6 Spilt Control Register */ +#define S5P_OTG_HCINT6 (USBOTG_LINK_BASE + 0x5C8) /* R/W Host Channel 6 Interrupt Register */ +#define S5P_OTG_HCINTMSK6 (USBOTG_LINK_BASE + 0x5CC) /* R/W Host Channel 6 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ6 (USBOTG_LINK_BASE + 0x5D0) /* R/W Host Channel 6 Transfer Size Register */ +#define S5P_OTG_HCDMA6 (USBOTG_LINK_BASE + 0x5D4) /* R/W Host Channel 6 DMA Address Register */ +#define S5P_OTG_HCCHAR7 (USBOTG_LINK_BASE + 0x5E0) /* R/W Host Channel 7 Characteristics Register */ +#define S5P_OTG_HCSPLT7 (USBOTG_LINK_BASE + 0x5E4) /* R/W Host Channel 7 Spilt Control Register */ +#define S5P_OTG_HCINT7 (USBOTG_LINK_BASE + 0x5E8) /* R/W Host Channel 7 Interrupt Register */ +#define S5P_OTG_HCINTMSK7 (USBOTG_LINK_BASE + 0x5EC) /* R/W Host Channel 7 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ7 (USBOTG_LINK_BASE + 0x5F0) /* R/W Host Channel 7 Transfer Size Register */ +#define S5P_OTG_HCDMA7 (USBOTG_LINK_BASE + 0x5F4) /* R/W Host Channel 7 DMA Address Register */ +#define S5P_OTG_HCCHAR8 (USBOTG_LINK_BASE + 0x600) /* R/W Host Channel 8 Characteristics Register */ +#define S5P_OTG_HCSPLT8 (USBOTG_LINK_BASE + 0x604) /* R/W Host Channel 8 Spilt Control Register */ +#define S5P_OTG_HCINT8 (USBOTG_LINK_BASE + 0x608) /* R/W Host Channel 8 Interrupt Register */ +#define S5P_OTG_HCINTMSK8 (USBOTG_LINK_BASE + 0x60C) /* R/W Host Channel 8 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ8 (USBOTG_LINK_BASE + 0x610) /* R/W Host Channel 8 Transfer Size Register */ +#define S5P_OTG_HCDMA8 (USBOTG_LINK_BASE + 0x614) /* R/W Host Channel 8 DMA Address Register */ +#define S5P_OTG_HCCHAR9 (USBOTG_LINK_BASE + 0x620) /* R/W Host Channel 9 Characteristics Register */ +#define S5P_OTG_HCSPLT9 (USBOTG_LINK_BASE + 0x624) /* R/W Host Channel 9 Spilt Control Register */ +#define S5P_OTG_HCINT9 (USBOTG_LINK_BASE + 0x628) /* R/W Host Channel 9 Interrupt Register */ +#define S5P_OTG_HCINTMSK9 (USBOTG_LINK_BASE + 0x62C) /* R/W Host Channel 9 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ9 (USBOTG_LINK_BASE + 0x630) /* R/W Host Channel 9 Transfer Size Register */ +#define S5P_OTG_HCDMA9 (USBOTG_LINK_BASE + 0x634) /* R/W Host Channel 9 DMA Address Register */ +#define S5P_OTG_HCCHAR10 (USBOTG_LINK_BASE + 0x640) /* R/W Host Channel 10 Characteristics Register */ +#define S5P_OTG_HCSPLT10 (USBOTG_LINK_BASE + 0x644) /* R/W Host Channel 10 Spilt Control Register */ +#define S5P_OTG_HCINT10 (USBOTG_LINK_BASE + 0x648) /* R/W Host Channel 10 Interrupt Register */ +#define S5P_OTG_HCINTMSK10 (USBOTG_LINK_BASE + 0x64C) /* R/W Host Channel 10 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ10 (USBOTG_LINK_BASE + 0x650) /* R/W Host Channel 10 Transfer Size Register */ +#define S5P_OTG_HCDMA10 (USBOTG_LINK_BASE + 0x654) /* R/W Host Channel 10 DMA Address Register */ +#define S5P_OTG_HCCHAR11 (USBOTG_LINK_BASE + 0x660) /* R/W Host Channel 11 Characteristics Register */ +#define S5P_OTG_HCSPLT11 (USBOTG_LINK_BASE + 0x664) /* R/W Host Channel 11 Spilt Control Register */ +#define S5P_OTG_HCINT11 (USBOTG_LINK_BASE + 0x668) /* R/W Host Channel 11 Interrupt Register */ +#define S5P_OTG_HCINTMSK11 (USBOTG_LINK_BASE + 0x66C) /* R/W Host Channel 11 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ11 (USBOTG_LINK_BASE + 0x670) /* R/W Host Channel 11 Transfer Size Register */ +#define S5P_OTG_HCDMA11 (USBOTG_LINK_BASE + 0x674) /* R/W Host Channel 11 DMA Address Register */ +#define S5P_OTG_HCCHAR12 (USBOTG_LINK_BASE + 0x680) /* R/W Host Channel 12 Characteristics Register */ +#define S5P_OTG_HCSPLT12 (USBOTG_LINK_BASE + 0x684) /* R/W Host Channel 12 Spilt Control Register */ +#define S5P_OTG_HCINT12 (USBOTG_LINK_BASE + 0x688) /* R/W Host Channel 12 Interrupt Register */ +#define S5P_OTG_HCINTMSK12 (USBOTG_LINK_BASE + 0x68C) /* R/W Host Channel 12 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ12 (USBOTG_LINK_BASE + 0x690) /* R/W Host Channel 12 Transfer Size Register */ +#define S5P_OTG_HCDMA12 (USBOTG_LINK_BASE + 0x694) /* R/W Host Channel 12 DMA Address Register */ +#define S5P_OTG_HCCHAR13 (USBOTG_LINK_BASE + 0x6A0) /* R/W Host Channel 13 Characteristics Register */ +#define S5P_OTG_HCSPLT13 (USBOTG_LINK_BASE + 0x6A4) /* R/W Host Channel 13 Spilt Control Register */ +#define S5P_OTG_HCINT13 (USBOTG_LINK_BASE + 0x6A8) /* R/W Host Channel 13 Interrupt Register */ +#define S5P_OTG_HCINTMSK13 (USBOTG_LINK_BASE + 0x6AC) /* R/W Host Channel 13 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ13 (USBOTG_LINK_BASE + 0x6B0) /* R/W Host Channel 13 Transfer Size Register */ +#define S5P_OTG_HCDMA13 (USBOTG_LINK_BASE + 0x6B4) /* R/W Host Channel 13 DMA Address Register */ +#define S5P_OTG_HCCHAR14 (USBOTG_LINK_BASE + 0x6C0) /* R/W Host Channel 14 Characteristics Register */ +#define S5P_OTG_HCSPLT14 (USBOTG_LINK_BASE + 0x6C4) /* R/W Host Channel 14 Spilt Control Register */ +#define S5P_OTG_HCINT14 (USBOTG_LINK_BASE + 0x6C8) /* R/W Host Channel 14 Interrupt Register */ +#define S5P_OTG_HCINTMSK14 (USBOTG_LINK_BASE + 0x6CC) /* R/W Host Channel 14 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ14 (USBOTG_LINK_BASE + 0x6D0) /* R/W Host Channel 14 Transfer Size Register */ +#define S5P_OTG_HCDMA14 (USBOTG_LINK_BASE + 0x6D4) /* R/W Host Channel 14 DMA Address Register */ +#define S5P_OTG_HCCHAR15 (USBOTG_LINK_BASE + 0x6E0) /* R/W Host Channel 15 Characteristics Register */ +#define S5P_OTG_HCSPLT15 (USBOTG_LINK_BASE + 0x6E4) /* R/W Host Channel 15 Spilt Control Register */ +#define S5P_OTG_HCINT15 (USBOTG_LINK_BASE + 0x6E8) /* R/W Host Channel 15 Interrupt Register */ +#define S5P_OTG_HCINTMSK15 (USBOTG_LINK_BASE + 0x6EC) /* R/W Host Channel 15 Interrupt Mask Register */ +#define S5P_OTG_HCTSIZ15 (USBOTG_LINK_BASE + 0x6F0) /* R/W Host Channel 15 Transfer Size Register */ +#define S5P_OTG_HCDMA15 (USBOTG_LINK_BASE + 0x6F4) /* R/W Host Channel 15 DMA Address Register */ + +/* Device Global Register */ +#define S5P_OTG_DCFG (USBOTG_LINK_BASE + 0x800) /* R/W Device Configuration Register */ +#define S5P_OTG_DCTL (USBOTG_LINK_BASE + 0x804) /* R/W Device Control Register */ +#define S5P_OTG_DSTS (USBOTG_LINK_BASE + 0x808) /* R Device Status Register */ +#define S5P_OTG_DIEPMSK (USBOTG_LINK_BASE + 0x810) /* R/W Device IN Endpoint Common Interrupt Mask Register */ +#define S5P_OTG_DOEPMSK (USBOTG_LINK_BASE + 0x814) /* R/W Device OUT Endpoint Common Interrupt Mask Register */ +#define S5P_OTG_DAINT (USBOTG_LINK_BASE + 0x818) /* R Device ALL Endpoints Interrupt Register */ +#define S5P_OTG_DAINTMSK (USBOTG_LINK_BASE + 0x81C) /* R/W Device ALL Endpoints Interrupt Mask Register */ +#define S5P_OTG_DTKNQR1 (USBOTG_LINK_BASE + 0x820) /* R Device IN Token Sequence Learning Queue Read Register */ +#define S5P_OTG_DTKNQR2 (USBOTG_LINK_BASE + 0x824) /* R Device IN Token Sequence Learning Queue Read Register */ +#define S5P_OTG_DVBUSDIS (USBOTG_LINK_BASE + 0x828) /* R/W Device VBUS Discharge Time Register */ +#define S5P_OTG_DVBUSPULSE (USBOTG_LINK_BASE + 0x82C) /* R/W Device VBUS Pulsing Time Register */ +#define S5P_OTG_DTKNQR3 (USBOTG_LINK_BASE + 0x830) /* R Device IN Token Sequence Learning Queue Read Register */ +#define S5P_OTG_DTKNQR4 (USBOTG_LINK_BASE + 0x834) /* R Device IN Token Sequence Learning Queue Read Register */ + +/* Device Logical IN Endpo int-Specific Registers */ +#define S5P_OTG_DIEPCTL0 (USBOTG_LINK_BASE + 0x900) /* R/W Device Control IN Endpoint 0 Control Register */ +#define S5P_OTG_DIEPINT0 (USBOTG_LINK_BASE + 0x908) /* R/W Device IN Endpoint 0 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ0 (USBOTG_LINK_BASE + 0x910) /* R/W Device IN Endpoint 0 Transfer Size Register */ +#define S5P_OTG_DIEPDMA0 (USBOTG_LINK_BASE + 0x914) /* R/W Device IN Endpoint 0 DMA Address Register */ +#define S5P_OTG_DIEPCTL1 (USBOTG_LINK_BASE + 0x920) /* R/W Device Control IN Endpoint 1 Control Register */ +#define S5P_OTG_DIEPINT1 (USBOTG_LINK_BASE + 0x928) /* R/W Device IN Endpoint 1 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ1 (USBOTG_LINK_BASE + 0x930) /* R/W Device IN Endpoint 1 Transfer Size Register */ +#define S5P_OTG_DIEPDMA1 (USBOTG_LINK_BASE + 0x934) /* R/W Device IN Endpoint 1 DMA Address Register */ +#define S5P_OTG_DIEPCTL2 (USBOTG_LINK_BASE + 0x940) /* R/W Device Control IN Endpoint 2 Control Register */ +#define S5P_OTG_DIEPINT2 (USBOTG_LINK_BASE + 0x948) /* R/W Device IN Endpoint 2 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ2 (USBOTG_LINK_BASE + 0x950) /* R/W Device IN Endpoint 2 Transfer Size Register */ +#define S5P_OTG_DIEPDMA2 (USBOTG_LINK_BASE + 0x954) /* R/W Device IN Endpoint 2 DMA Address Register */ +#define S5P_OTG_DIEPCTL3 (USBOTG_LINK_BASE + 0x960) /* R/W Device Control IN Endpoint 3 Control Register */ +#define S5P_OTG_DIEPINT3 (USBOTG_LINK_BASE + 0x968) /* R/W Device IN Endpoint 3 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ3 (USBOTG_LINK_BASE + 0x970) /* R/W Device IN Endpoint 3 Transfer Size Register */ +#define S5P_OTG_DIEPDMA3 (USBOTG_LINK_BASE + 0x974) /* R/W Device IN Endpoint 3 DMA Address Register */ +#define S5P_OTG_DIEPCTL4 (USBOTG_LINK_BASE + 0x980) /* R/W Device Control IN Endpoint 0 Control Register */ +#define S5P_OTG_DIEPINT4 (USBOTG_LINK_BASE + 0x988) /* R/W Device IN Endpoint 4 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ4 (USBOTG_LINK_BASE + 0x990) /* R/W Device IN Endpoint 4 Transfer Size Register */ +#define S5P_OTG_DIEPDMA4 (USBOTG_LINK_BASE + 0x994) /* R/W Device IN Endpoint 4 DMA Address Register */ +#define S5P_OTG_DIEPCTL5 (USBOTG_LINK_BASE + 0x9A0) /* R/W Device Control IN Endpoint 5 Control Register */ +#define S5P_OTG_DIEPINT5 (USBOTG_LINK_BASE + 0x9A8) /* R/W Device IN Endpoint 5 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ5 (USBOTG_LINK_BASE + 0x9B0) /* R/W Device IN Endpoint 5 Transfer Size Register */ +#define S5P_OTG_DIEPDMA5 (USBOTG_LINK_BASE + 0x9B4) /* R/W Device IN Endpoint 5 DMA Address Register */ +#define S5P_OTG_DIEPCTL6 (USBOTG_LINK_BASE + 0x9C0) /* R/W Device Control IN Endpoint 6 Control Register */ +#define S5P_OTG_DIEPINT6 (USBOTG_LINK_BASE + 0x9C8) /* R/W Device IN Endpoint 6 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ6 (USBOTG_LINK_BASE + 0x9D0) /* R/W Device IN Endpoint 6 Transfer Size Register */ +#define S5P_OTG_DIEPDMA6 (USBOTG_LINK_BASE + 0x9D4) /* R/W Device IN Endpoint 6 DMA Address Register */ +#define S5P_OTG_DIEPCTL7 (USBOTG_LINK_BASE + 0x9E0) /* R/W Device Control IN Endpoint 7 Control Register */ +#define S5P_OTG_DIEPINT7 (USBOTG_LINK_BASE + 0x9E8) /* R/W Device IN Endpoint 7 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ7 (USBOTG_LINK_BASE + 0x9F0) /* R/W Device IN Endpoint 7 Transfer Size Register */ +#define S5P_OTG_DIEPDMA7 (USBOTG_LINK_BASE + 0x9F4) /* R/W Device IN Endpoint 7 DMA Address Register */ +#define S5P_OTG_DIEPCTL8 (USBOTG_LINK_BASE + 0xA00) /* R/W Device Control IN Endpoint 8 Control Register */ +#define S5P_OTG_DIEPINT8 (USBOTG_LINK_BASE + 0xA08) /* R/W Device IN Endpoint 8 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ8 (USBOTG_LINK_BASE + 0xA10) /* R/W Device IN Endpoint 8 Transfer Size Register */ +#define S5P_OTG_DIEPDMA8 (USBOTG_LINK_BASE + 0xA14) /* R/W Device IN Endpoint 8 DMA Address Register */ +#define S5P_OTG_DIEPCTL9 (USBOTG_LINK_BASE + 0xA20) /* R/W Device Control IN Endpoint 9 Control Register */ +#define S5P_OTG_DIEPINT9 (USBOTG_LINK_BASE + 0xA28) /* R/W Device IN Endpoint 9 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ9 (USBOTG_LINK_BASE + 0xA30) /* R/W Device IN Endpoint 9 Transfer Size Register */ +#define S5P_OTG_DIEPDMA9 (USBOTG_LINK_BASE + 0xA34) /* R/W Device IN Endpoint 9 DMA Address Register */ +#define S5P_OTG_DIEPCTL10 (USBOTG_LINK_BASE + 0xA40) /* R/W Device Control IN Endpoint 10 Control Register */ +#define S5P_OTG_DIEPINT10 (USBOTG_LINK_BASE + 0xA48) /* R/W Device IN Endpoint 10 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ10 (USBOTG_LINK_BASE + 0xA50) /* R/W Device IN Endpoint 10 Transfer Size Register */ +#define S5P_OTG_DIEPDMA10 (USBOTG_LINK_BASE + 0xA54) /* R/W Device IN Endpoint 10 DMA Address Register */ +#define S5P_OTG_DIEPCTL11 (USBOTG_LINK_BASE + 0xA60) /* R/W Device Control IN Endpoint 11 Control Register */ +#define S5P_OTG_DIEPINT11 (USBOTG_LINK_BASE + 0xA68) /* R/W Device IN Endpoint 11 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ11 (USBOTG_LINK_BASE + 0xA70) /* R/W Device IN Endpoint 11 Transfer Size Register */ +#define S5P_OTG_DIEPDMA11 (USBOTG_LINK_BASE + 0xA74) /* R/W Device IN Endpoint 11 DMA Address Register */ +#define S5P_OTG_DIEPCTL12 (USBOTG_LINK_BASE + 0xA80) /* R/W Device Control IN Endpoint 12 Control Register */ +#define S5P_OTG_DIEPINT12 (USBOTG_LINK_BASE + 0xA88) /* R/W Device IN Endpoint 12 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ12 (USBOTG_LINK_BASE + 0xA90) /* R/W Device IN Endpoint 12 Transfer Size Register */ +#define S5P_OTG_DIEPDMA12 (USBOTG_LINK_BASE + 0xA94) /* R/W Device IN Endpoint 12 DMA Address Register */ +#define S5P_OTG_DIEPCTL13 (USBOTG_LINK_BASE + 0xAA0) /* R/W Device Control IN Endpoint 13 Control Register */ +#define S5P_OTG_DIEPINT13 (USBOTG_LINK_BASE + 0xAA8) /* R/W Device IN Endpoint 13 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ13 (USBOTG_LINK_BASE + 0xAB0) /* R/W Device IN Endpoint 13 Transfer Size Register */ +#define S5P_OTG_DIEPDMA13 (USBOTG_LINK_BASE + 0xAB4) /* R/W Device IN Endpoint 13 DMA Address Register */ +#define S5P_OTG_DIEPCTL14 (USBOTG_LINK_BASE + 0xAC0) /* R/W Device Control IN Endpoint 14 Control Register */ +#define S5P_OTG_DIEPINT14 (USBOTG_LINK_BASE + 0xAC8) /* R/W Device IN Endpoint 14 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ14 (USBOTG_LINK_BASE + 0xAD0) /* R/W Device IN Endpoint 14 Transfer Size Register */ +#define S5P_OTG_DIEPDMA14 (USBOTG_LINK_BASE + 0xAD4) /* R/W Device IN Endpoint 14 DMA Address Register */ +#define S5P_OTG_DIEPCTL15 (USBOTG_LINK_BASE + 0xAE0) /* R/W Device Control IN Endpoint 15 Control Register */ +#define S5P_OTG_DIEPINT15 (USBOTG_LINK_BASE + 0xAE8) /* R/W Device IN Endpoint 15 Interrupt Register */ +#define S5P_OTG_DIEPTSIZ15 (USBOTG_LINK_BASE + 0xAF0) /* R/W Device IN Endpoint 15 Transfer Size Register */ +#define S5P_OTG_DIEPDMA15 (USBOTG_LINK_BASE + 0xAF4) /* R/W Device IN Endpoint 15 DMA Address Register */ + +/* Device Logical OUT Endpoint-Specific Register */ +#define S5P_OTG_DOEPCTL0 (USBOTG_LINK_BASE + 0xB00) /* R/W Device Control OUT Endpoint 0 Control Register */ +#define S5P_OTG_DOEPINT0 (USBOTG_LINK_BASE + 0xB08) /* R/W Device OUT Endpoint 0 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ0 (USBOTG_LINK_BASE + 0xB10) /* R/W Device OUT Endpoint 0 Transfer Size Register */ +#define S5P_OTG_DOEPDMA0 (USBOTG_LINK_BASE + 0xB14) /* R/W Device OUT Endpoint 0 DMA Address Register */ +#define S5P_OTG_DOEPCTL1 (USBOTG_LINK_BASE + 0xB20) /* R/W Device Control OUT Endpoint 1 Control Register */ +#define S5P_OTG_DOEPINT1 (USBOTG_LINK_BASE + 0xB28) /* R/W Device OUT Endpoint 1 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ1 (USBOTG_LINK_BASE + 0xB30) /* R/W Device OUT Endpoint 1 Transfer Size Register */ +#define S5P_OTG_DOEPDMA1 (USBOTG_LINK_BASE + 0xB34) /* R/W Device OUT Endpoint 1 DMA Address Register */ +#define S5P_OTG_DOEPCTL2 (USBOTG_LINK_BASE + 0xB40) /* R/W Device Control OUT Endpoint 2 Control Register */ +#define S5P_OTG_DOEPINT2 (USBOTG_LINK_BASE + 0xB48) /* R/W Device OUT Endpoint 2 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ2 (USBOTG_LINK_BASE + 0xB50) /* R/W Device OUT Endpoint 2 Transfer Size Register */ +#define S5P_OTG_DOEPDMA2 (USBOTG_LINK_BASE + 0xB54) /* R/W Device OUT Endpoint 2 DMA Address Register */ +#define S5P_OTG_DOEPCTL3 (USBOTG_LINK_BASE + 0xB60) /* R/W Device Control OUT Endpoint 3 Control Register */ +#define S5P_OTG_DOEPINT3 (USBOTG_LINK_BASE + 0xB68) /* R/W Device OUT Endpoint 3 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ3 (USBOTG_LINK_BASE + 0xB70) /* R/W Device OUT Endpoint 3 Transfer Size Register */ +#define S5P_OTG_DOEPDMA3 (USBOTG_LINK_BASE + 0xB74) /* R/W Device OUT Endpoint 3 DMA Address Register */ +#define S5P_OTG_DOEPCTL4 (USBOTG_LINK_BASE + 0xB80) /* R/W Device Control OUT Endpoint 4 Control Register */ +#define S5P_OTG_DOEPINT4 (USBOTG_LINK_BASE + 0xB88) /* R/W Device OUT Endpoint 4 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ4 (USBOTG_LINK_BASE + 0xB90) /* R/W Device OUT Endpoint 4 Transfer Size Register */ +#define S5P_OTG_DOEPDMA4 (USBOTG_LINK_BASE + 0xB94) /* R/W Device OUT Endpoint 4 DMA Address Register */ +#define S5P_OTG_DOEPCTL5 (USBOTG_LINK_BASE + 0xBA0) /* R/W Device Control OUT Endpoint 5 Control Register */ +#define S5P_OTG_DOEPINT5 (USBOTG_LINK_BASE + 0xBA8) /* R/W Device OUT Endpoint 5 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ5 (USBOTG_LINK_BASE + 0xBB0) /* R/W Device OUT Endpoint 5 Transfer Size Register */ +#define S5P_OTG_DOEPDMA5 (USBOTG_LINK_BASE + 0xBB4) /* R/W Device OUT Endpoint 5 DMA Address Register */ +#define S5P_OTG_DOEPCTL6 (USBOTG_LINK_BASE + 0xBC0) /* R/W Device Control OUT Endpoint 6 Control Register */ +#define S5P_OTG_DOEPINT6 (USBOTG_LINK_BASE + 0xBC8) /* R/W Device OUT Endpoint 6 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ6 (USBOTG_LINK_BASE + 0xBD0) /* R/W Device OUT Endpoint 6 Transfer Size Register */ +#define S5P_OTG_DOEPDMA6 (USBOTG_LINK_BASE + 0xBD4) /* R/W Device OUT Endpoint 6 DMA Address Register */ +#define S5P_OTG_DOEPCTL7 (USBOTG_LINK_BASE + 0xBE0) /* R/W Device Control OUT Endpoint 7 Control Register */ +#define S5P_OTG_DOEPINT7 (USBOTG_LINK_BASE + 0xBE8) /* R/W Device OUT Endpoint 7 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ7 (USBOTG_LINK_BASE + 0xBF0) /* R/W Device OUT Endpoint 7 Transfer Size Register */ +#define S5P_OTG_DOEPDMA7 (USBOTG_LINK_BASE + 0xBF4) /* R/W Device OUT Endpoint 7 DMA Address Register */ +#define S5P_OTG_DOEPCTL8 (USBOTG_LINK_BASE + 0xC00) /* R/W Device Control OUT Endpoint 8 Control Register */ +#define S5P_OTG_DOEPINT8 (USBOTG_LINK_BASE + 0xC08) /* R/W Device OUT Endpoint 8 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ8 (USBOTG_LINK_BASE + 0xC10) /* R/W Device OUT Endpoint 8 Transfer Size Register */ +#define S5P_OTG_DOEPDMA8 (USBOTG_LINK_BASE + 0xC14) /* R/W Device OUT Endpoint 8 DMA Address Register */ +#define S5P_OTG_DOEPCTL9 (USBOTG_LINK_BASE + 0xC20) /* R/W Device Control OUT Endpoint 9 Control Register */ +#define S5P_OTG_DOEPINT9 (USBOTG_LINK_BASE + 0xC28) /* R/W Device OUT Endpoint 9 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ9 (USBOTG_LINK_BASE + 0xC30) /* R/W Device OUT Endpoint 9 Transfer Size Register */ +#define S5P_OTG_DOEPDMA9 (USBOTG_LINK_BASE + 0xC34) /* R/W Device OUT Endpoint 9 DMA Address Register */ +#define S5P_OTG_DOEPCTL10 (USBOTG_LINK_BASE + 0xC40) /* R/W Device Control OUT Endpoint 10 Control Register */ +#define S5P_OTG_DOEPINT10 (USBOTG_LINK_BASE + 0xC48) /* R/W Device OUT Endpoint 10 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ10 (USBOTG_LINK_BASE + 0xC50) /* R/W Device OUT Endpoint 10 Transfer Size Register */ +#define S5P_OTG_DOEPDMA10 (USBOTG_LINK_BASE + 0xC54) /* R/W Device OUT Endpoint 10 DMA Address Register */ +#define S5P_OTG_DOEPCTL11 (USBOTG_LINK_BASE + 0xC60) /* R/W Device Control OUT Endpoint 11 Control Register */ +#define S5P_OTG_DOEPINT11 (USBOTG_LINK_BASE + 0xC68) /* R/W Device OUT Endpoint 11 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ11 (USBOTG_LINK_BASE + 0xC70) /* R/W Device OUT Endpoint 11 Transfer Size Register */ +#define S5P_OTG_DOEPDMA11 (USBOTG_LINK_BASE + 0xC74) /* R/W Device OUT Endpoint 11 DMA Address Register */ +#define S5P_OTG_DOEPCTL12 (USBOTG_LINK_BASE + 0xC80) /* R/W Device Control OUT Endpoint 12 Control Register */ +#define S5P_OTG_DOEPINT12 (USBOTG_LINK_BASE + 0xC88) /* R/W Device OUT Endpoint 12 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ12 (USBOTG_LINK_BASE + 0xC90) /* R/W Device OUT Endpoint 12 Transfer Size Register */ +#define S5P_OTG_DOEPDMA12 (USBOTG_LINK_BASE + 0xC94) /* R/W Device OUT Endpoint 12 DMA Address Register */ +#define S5P_OTG_DOEPCTL13 (USBOTG_LINK_BASE + 0xCA0) /* R/W Device Control OUT Endpoint 13 Control Register */ +#define S5P_OTG_DOEPINT13 (USBOTG_LINK_BASE + 0xCA8) /* R/W Device OUT Endpoint 13 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ13 (USBOTG_LINK_BASE + 0xCB0) /* R/W Device OUT Endpoint 13 Transfer Size Register */ +#define S5P_OTG_DOEPDMA13 (USBOTG_LINK_BASE + 0xCB4) /* R/W Device OUT Endpoint 13 DMA Address Register */ +#define S5P_OTG_DOEPCTL14 (USBOTG_LINK_BASE + 0xCC0) /* R/W Device Control OUT Endpoint 14 Control Register */ +#define S5P_OTG_DOEPINT14 (USBOTG_LINK_BASE + 0xCC8) /* R/W Device OUT Endpoint 14 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ14 (USBOTG_LINK_BASE + 0xCD0) /* R/W Device OUT Endpoint 14 Transfer Size Register */ +#define S5P_OTG_DOEPDMA14 (USBOTG_LINK_BASE + 0xCD4) /* R/W Device OUT Endpoint 14 DMA Address Register */ +#define S5P_OTG_DOEPCTL15 (USBOTG_LINK_BASE + 0xCE0) /* R/W Device Control OUT Endpoint 15 Control Register */ +#define S5P_OTG_OTG_DOEPINT15 (USBOTG_LINK_BASE + 0xCE8) /* R/W Device OUT Endpoint 15 Interrupt Register */ +#define S5P_OTG_DOEPTSIZ15 (USBOTG_LINK_BASE + 0xCF0) /* R/W Device OUT Endpoint 15 Transfer Size Register */ +#define S5P_OTG_DOEPDMA15 (USBOTG_LINK_BASE + 0xCF4) /* R/W Device OUT Endpoint 15 DMA Address Register */ + +/* Power and Clock Gating Register */ +#define S5P_OTG_PCGCCTL (USBOTG_LINK_BASE + 0xE00) /* R/W Power and Clock Gating Control Register */ + +/* Endpoint FIFO address */ +#define S5P_OTG_EP0_FIFO (USBOTG_LINK_BASE + 0x1000) + +/* USB Global Interrupt Status register(GINTSTS) setting value */ +#define GINTSTS_WkUpInt (1<<31) +#define GINTSTS_OEPInt (1<<19) +#define GINTSTS_IEPInt (1<<18) +#define GINTSTS_EnumDone (1<<13) +#define GINTSTS_USBRst (1<<12) +#define GINTSTS_USBSusp (1<<11) +#define GINTSTS_RXFLvl (1<<4) + +#endif diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h index 2d5c3bc37..ec2b7cf16 100644 --- a/arch/arm/include/asm/mach-types.h +++ b/arch/arm/include/asm/mach-types.h @@ -1104,7 +1104,16 @@ extern unsigned int __machine_arch_type; #define MACH_TYPE_THALES_ADC 3492 #define MACH_TYPE_UBISYS_P9D_EVP 3493 #define MACH_TYPE_ATDGP318 3494 +#define MACH_TYPE_ESPRESSO3250 4157 +#define MACH_TYPE_SMDK4212 3698 +#define MACH_TYPE_SMDK4412 3765 #define MACH_TYPE_OMAP5_SEVM 3777 +#define MACH_TYPE_SMDK5250 3825 +#define MACH_TYPE_XYREF5260 3901 +#define MACH_TYPE_XYREF4415 3900 +#define MACH_TYPE_SMDK5410 4151 +#define MACH_TYPE_SMDK5412 8002 +#define MACH_TYPE_XYREF5430 8003 #ifdef CONFIG_ARCH_EBSA110 # ifdef machine_arch_type diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index f1951e883..b13175966 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -245,8 +245,10 @@ init_fnc_t *init_sequence[] = { get_clocks, #endif env_init, /* initialize environment */ +#ifndef CONFIG_CPU_EXYNOS5410 init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ +#endif console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ #if defined(CONFIG_DISPLAY_CPUINFO) @@ -490,8 +492,10 @@ void board_init_r(gd_t *id, ulong dest_addr) set_cpu_clk_info(); /* Setup clock information */ #endif #ifdef CONFIG_SERIAL_MULTI +#ifndef CONFIG_CPU_EXYNOS5410 serial_initialize(); #endif +#endif debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 599547d2c..ae195ac8b 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -36,6 +36,12 @@ #include <asm/bootm.h> DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_CPU_EXYNOS5430 +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define GetBits(uAddr, uBaseBit, uMaskValue) \ + ((Inp32(uAddr)>>(uBaseBit))&(uMaskValue)) +#define GetPOPType() (GetBits(0x10000004, 4, 0x3)) +#endif #if defined(CONFIG_SETUP_MEMORY_TAGS) || \ defined(CONFIG_CMDLINE_TAG) || \ @@ -92,6 +98,16 @@ static int fixup_memory_node(void *blob) } #endif +#ifdef CONFIG_PREP_BOARDCONFIG_FOR_KERNEL +void __prep_boardconfig_for_kernel(void) +{ + +} + +void prep_boardconfig_for_kernel(void) + __attribute__((weak, alias("__prep_boardconfig_for_kernel"))); +#endif + static void announce_and_cleanup(void) { printf("\nStarting kernel ...\n\n"); @@ -99,6 +115,9 @@ static void announce_and_cleanup(void) #ifdef CONFIG_BOOTSTAGE_REPORT bootstage_report(); #endif +#ifdef CONFIG_PREP_BOARDCONFIG_FOR_KERNEL + prep_boardconfig_for_kernel(); +#endif #ifdef CONFIG_USB_DEVICE udc_disconnect(); @@ -130,8 +149,18 @@ static void setup_start_tag (bd_t *bd) static void setup_memory_tags(bd_t *bd) { int i; +#ifdef CONFIG_CPU_EXYNOS5430 + int nr_dram_banks; + if (GetPOPType() == 1) + nr_dram_banks = 12; + else + nr_dram_banks = 8; + + for (i = 0; i < nr_dram_banks; i++) { +#else for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { +#endif params->hdr.tag = ATAG_MEM; params->hdr.size = tag_size (tag_mem32); diff --git a/board/samsung/espresso3250/Makefile b/board/samsung/espresso3250/Makefile new file mode 100644 index 000000000..680e424c4 --- /dev/null +++ b/board/samsung/espresso3250/Makefile @@ -0,0 +1,69 @@ +# +# Copyright (C) 2012 Samsung Electronics +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +SOBJS := lowlevel_init.o + +COBJS := clock_init.o +COBJS += dmc_init.o +COBJS += pmic.o +COBJS += smc.o + +ifdef CONFIG_LCD +COBJS += display.o +else ifdef CONFIG_USE_LCD +COBJS += display.o +endif + +ifdef CONFIG_TZPC +COBJS += tzpc_init.o +endif + +ifndef CONFIG_SPL_BUILD +COBJS += espresso3250.o +endif + +ifdef CONFIG_SPL_BUILD +COBJS += mmc_boot.o +endif + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +ALL := $(obj).depend $(LIB) + +all: $(ALL) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/espresso3250/clock_init.c b/board/samsung/espresso3250/clock_init.c new file mode 100644 index 000000000..5b326cd44 --- /dev/null +++ b/board/samsung/espresso3250/clock_init.c @@ -0,0 +1,140 @@ +/* + * Clock setup for SMDK4270 board based on EXYNOS4 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include "setup.h" + +#include "smdk3250_val.h" + + +#define ASS_CLK_SRC (0x03810000) +#define ASS_CLK_DIV (0x03810004) +#define DIV_UNSTABLE (0x1) +#define DIV_DMCP_OFFSET (16) +#define MUX_G2D_ACP_SEL_OFFSET (28) +#define PLL_ENABLE (31) + +void system_clock_init(void) +{ + struct exynos4_clock *clk = (struct exynos4_clock *)EXYNOS4_CLOCK_BASE; + volatile unsigned int reg_val; + + /* + ** CPU Clock setting + */ + /* Set mux_cpu into fin MOUT_APLL = FIN*/ + writel((readl(&clk->src_cpu) & ~(1 << 0)), &clk->src_cpu); + + /* PLL LOCK */ + writel(APLL_LOCK_VAL, &clk->apll_lock); + + /* Set CMU_CPU, MUX & DIV */ + writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0); + writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); + + /* Set CMU_CPU MUX: CORE_CLK = MOUT_APLL */ + writel(0x01000000, &clk->src_cpu); + + /* Set APLL */ + writel(APLL_CON1_VAL, &clk->apll_con1); + writel(APLL_CON2_VAL, &clk->apll_con2); + writel(APLL_CON0_VAL, &clk->apll_con0); + + /* Enable APLL */ + reg_val = readl(&clk->apll_con0); + reg_val = (reg_val) | (1 << PLL_ENABLE); + writel(reg_val, &clk->apll_con0); + /* Wait PLL lock */ + while ((readl(&clk->apll_con0) & (1 << 29)) == 0); + + /* Turn On PLL Mout: MOUT_APLL = FOUT_APLL*/ + reg_val = readl(&clk->src_cpu); + reg_val = (reg_val) | (1 << 0); + writel(reg_val, &clk->src_cpu); + + /* Check mux_apll status */ + while(((readl(&clk->mux_stat_cpu)) & (1 << 2)) != 0); //wait MOUT_APLL stable + + /* + ** TOP Clock setting + */ + /* Set mux_mpll into fin: MOUTMPLL = FIN */ + writel(CLK_SRC_TOP1_VAL_0, &clk->src_top1); + + /* Check mux status */ + while(((readl(&clk->mux_stat_top1)) & (1 << 14)) != 0); //clk->mux_stat_top1.bit14 + + /*set top MUX & DIV*/ + writel(CLK_SRC_TOP0_VAL_0, &clk->src_top0); + writel(CLK_DIV_TOP_VAL, &clk->div_top); + + /* Set CMU_LEFTBUS, MUX & DIV */ + writel(CLK_SRC_LEFTBUS_VAL, &clk->src_leftbus); + writel(CLK_DIV_LEFTBUS_VAL, &clk->div_leftbus); + + /* Set CMU_RIGHTBUS, MUX & DIV */ + writel(CLK_SRC_RIGHTBUS_VAL, &clk->src_rightbus); + writel(CLK_DIV_RIGHTBUS_VAL, &clk->div_rightbus); + + writel(0x10000666, &clk->src_fsys); //src_MMC = sclk_MPLL + writel(0x00066666, &clk->src_peril0); //src_uart = sclk_MPLL + writel(0x00007777, &clk->div_peril0); + writel(0x0f000f00, &clk->div_fsys1); + writel(0x0f000f00, &clk->div_fsys2); + + /* Set MPLL */ + writel(MPLL_LOCK_VAL, &clk->mpll_lock); + writel(MPLL_CON1_VAL, &clk->mpll_con1); + writel(MPLL_CON2_VAL, &clk->mpll_con2); + writel(MPLL_CON0_VAL, &clk->mpll_con0); + /* Enable MPLL */ + reg_val = readl(&clk->mpll_con0); + reg_val = (reg_val) | (1 << PLL_ENABLE); + writel(reg_val, &clk->mpll_con0); + /* Wait PLL lock */ + while ((readl(&clk->mpll_con0) & (1 << 29)) == 0); + + /* Set VPLL */ + writel(VPLL_LOCK_VAL, &clk->vpll_lock); + writel(VPLL_CON1_VAL, &clk->vpll_con1); + writel(VPLL_CON2_VAL, &clk->vpll_con2); + writel(VPLL_CON0_VAL, &clk->vpll_con0); + /* Enable VPLL */ + reg_val = readl(&clk->vpll_con0); + reg_val = (reg_val) | (1 << PLL_ENABLE); + writel(reg_val, &clk->vpll_con0); + /* Wait PLL lock */ + while ((readl(&clk->vpll_con0) & (1 << 29)) == 0); + + /* Set mux_mpll into fin: MOUTMPLL = FOUT_MPLL ; MOUTUPLL = FOUT_UPLL */ + writel(CLK_SRC_TOP1_VAL_1, &clk->src_top1); + /* Check mux status */ + while(((readl(&clk->mux_stat_top1)) & (1 << 14)) != 0); //clk->mux_stat_top1.bit14: MPLL +} diff --git a/board/samsung/espresso3250/display.c b/board/samsung/espresso3250/display.c new file mode 100644 index 000000000..75ecc6899 --- /dev/null +++ b/board/samsung/espresso3250/display.c @@ -0,0 +1,412 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <lcd.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mipi_dsim.h> +#if defined(CONFIG_S6E8AX0) +#include "logo_588x95.h" +#elif defined(CONFIG_NT35510) +#include "logo_305x50.h" +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* For panel info */ +#if defined(CONFIG_S6E8AX0) +#define ESPRESSO3250_LCD_TYPE "s6e8aa0" +#define ESPRESSO3250_HBP 11 +#define ESPRESSO3250_HFP 11 +#define ESPRESSO3250_VBP 3 +#define ESPRESSO3250_VFP 3 +#define ESPRESSO3250_HSP 2 +#define ESPRESSO3250_VSW 2 +#define ESPRESSO3250_XRES 800 +#define ESPRESSO3250_YRES 1280 +#define ESPRESSO3250_VIRTUAL_X 800 +#define ESPRESSO3250_VIRTUAL_Y 1280 * 2 +#define ESPRESSO3250_WIDTH 71 +#define ESPRESSO3250_HEIGHT 114 +#define ESPRESSO3250_MAX_BPP 32 +#define ESPRESSO3250_DEFAULT_BPP 24 +#define ESPRESSO3250_DEFAULT_FREQ 60 + +#elif defined(CONFIG_NT35510) +#define ESPRESSO3250_LCD_TYPE "nt35510" +#define ESPRESSO3250_HBP 1 +#define ESPRESSO3250_HFP 1 +#define ESPRESSO3250_VBP 1 +#define ESPRESSO3250_VFP 1 +#define ESPRESSO3250_HSP 1 +#define ESPRESSO3250_VSW 1 +#define ESPRESSO3250_XRES 480 +#define ESPRESSO3250_YRES 800 +#define ESPRESSO3250_VIRTUAL_X 480 +#define ESPRESSO3250_VIRTUAL_Y 800 * 2 +#define ESPRESSO3250_WIDTH 56 +#define ESPRESSO3250_HEIGHT 94 +#define ESPRESSO3250_MAX_BPP 32 +#define ESPRESSO3250_DEFAULT_BPP 24 +#define ESPRESSO3250_DEFAULT_FREQ 60 + +#elif defined(CONFIG_SHIRI_LCD) +#define ESPRESSO3250_LCD_TYPE "shiri_mipi_lcd" +#define ESPRESSO3250_HBP 1 +#define ESPRESSO3250_HFP 1 +#define ESPRESSO3250_VBP 1 +#define ESPRESSO3250_VFP 1 +#define ESPRESSO3250_HSP 1 +#define ESPRESSO3250_VSW 1 +#define ESPRESSO3250_XRES 240 +#define ESPRESSO3250_YRES 240 +#define ESPRESSO3250_VIRTUAL_X 240 +#define ESPRESSO3250_VIRTUAL_Y 240 +#define ESPRESSO3250_WIDTH 27 +#define ESPRESSO3250_HEIGHT 27 +#define ESPRESSO3250_MAX_BPP 32 +#define ESPRESSO3250_DEFAULT_BPP 24 +#define ESPRESSO3250_DEFAULT_FREQ 60 + +#endif + +/* For dsim info */ +#if defined(CONFIG_S6E8AX0) +#define DSIM_DATA_LANE DSIM_DATA_LANE_4 +#define DSIM_PLL_OUT_DIV DSIM_PLL_OUT_DIV8 +#define DSIM_BURST_MODE DSIM_BURST +#define DSIM_P 2 +#define DSIM_M 50 +#define DSIM_S 0 +#define DSIM_ESC_CLK 20 * 1000000 /* escape clk : 20MHz */ + +#elif defined(CONFIG_NT35510) +#define DSIM_DATA_LANE DSIM_DATA_LANE_2 +#define DSIM_PLL_OUT_DIV DSIM_PLL_OUT_DIV8 +#define DSIM_BURST_MODE DSIM_BURST +#define DSIM_P 2 +#define DSIM_M 80 +#define DSIM_S 1 +#define DSIM_ESC_CLK 20 * 1000000 /* escape clk : 20MHz */ + +#elif defined(CONFIG_SHIRI_LCD) +#define DSIM_DATA_LANE DSIM_DATA_LANE_1 +#define DSIM_PLL_OUT_DIV DSIM_PLL_OUT_DIV8 +#define DSIM_BURST_MODE DSIM_BURST +#define DSIM_P 6 +#define DSIM_M 118 +#define DSIM_S 1 +#define DSIM_ESC_CLK 20 * 1000000 /* escape clk : 20MHz */ + +#endif + +#if defined(CONFIG_S6E8AX0) +static void lcd_reset(void) +{ + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* 1.8v Level Sequence: H->L->H */ + s5p_gpio_direction_output(&gpio2->x2, 4, 1); + udelay(10000); + s5p_gpio_direction_output(&gpio2->x2, 4, 0); + udelay(10000); + s5p_gpio_direction_output(&gpio2->x2, 4, 1); +} + +static int lcd_power(void) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* power1 GPX2-5 */ + s5p_gpio_direction_output(&gpio2->x2, 5, 0); + s5p_gpio_direction_output(&gpio2->x2, 5, 1); + /* power2 GPD0-0 */ + s5p_gpio_direction_output(&gpio1->d0, 0, 0); + s5p_gpio_direction_output(&gpio1->d0, 0, 1); + + return 0; +} + +static int mipi_power(void) +{ + /* + * MIPI power already enabled on smdk4270 board as default + * LDO7: VDD10 1.0v , LDO8: VDD18 1.8v + */ + return 0; +} + +static void get_logo_info(vidinfo_t *vid) +{ + vid->logo_width = 588; + vid->logo_height = 95; + vid->logo_addr = (ulong)gzip_bmp_logo; +} + +#elif defined(CONFIG_NT35510) +static void lcd_reset(void) +{ + struct exynos3_gpio_part1 *gpio1 = + (struct exynos3_gpio_part1 *)samsung_get_base_gpio_part1(); + + /* mipi-sel : gpc0[0] */ + s5p_gpio_direction_output(&gpio1->c0, 0, 0); + udelay(20000); + + /* reset : gpc0[1] */ + s5p_gpio_direction_output(&gpio1->c0, 1, 1); + udelay(20000); + s5p_gpio_direction_output(&gpio1->c0, 1, 0); + udelay(20000); + s5p_gpio_direction_output(&gpio1->c0, 1, 1); + +} + +static int lcd_power(void) +{ + struct exynos3_gpio_part1 *gpio1 = + (struct exynos3_gpio_part1 *)samsung_get_base_gpio_part1(); + + /* backlight GPD0-1 */ + s5p_gpio_direction_output(&gpio1->c0, 4, 0); + mdelay(1); + s5p_gpio_direction_output(&gpio1->c0, 4, 1); + + mdelay(150); + lcd_reset(); + mdelay(150); + + return 0; +} + +static int mipi_power(void) +{ + /* + * MIPI power already enabled on smdk4270 board as default + * LDO7: VDD10 1.0v , LDO8: VDD18 1.8v + */ + return 0; +} + +static void get_logo_info(vidinfo_t *vid) +{ + vid->logo_width = 305; + vid->logo_height = 50; + vid->logo_addr = (ulong)gzip_bmp_logo; +} + +#elif defined(CONFIG_SHIRI_LCD) +static void lcd_reset(void) +{ + struct exynos3_gpio_part2 *gpio2 = + (struct exynos3_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* reset : gpm0[4] */ + s5p_gpio_direction_output(&gpio2->M0, 4, 1); + udelay(20000); + s5p_gpio_direction_output(&gpio2->M0, 4, 0); + udelay(20000); + s5p_gpio_direction_output(&gpio2->M0, 4, 1); +} + +static int lcd_power(void) +{ + struct exynos3_gpio_part1 *gpio1 = + (struct exynos3_gpio_part1 *)samsung_get_base_gpio_part1(); + + lcd_reset(); + + return 0; +} + +extern int backlight_en(int en); +int backlight_en(int en) +{ + struct exynos3_gpio_part1 *gpio1 = + (struct exynos3_gpio_part1 *)samsung_get_base_gpio_part1(); + + /* backlight GPD0-0 */ + s5p_gpio_direction_output(&gpio1->d0, 0, 0); + if(en) + { + mdelay(50); + s5p_gpio_direction_output(&gpio1->d0, 0, 1); + } + + return 0; +} +static int mipi_power(void) +{ + /* + * MIPI power already enabled on smdk4270 board as default + * LDO7: VDD10 1.0v , LDO8: VDD18 1.8v + */ + return 0; +} + +extern void SWTrigger_for_te(void); +void SWTrigger_for_te(void) +{ + u32 val, i = 0; + + val = readl(0x11000c04); + val = ((val >> 4) & 1); + + while(!val && i <= 300) + { + val = readl(0x11000c04); + val = ((val >> 4) & 1); + i++; + mdelay(1); + } + exynos_set_trigger(); +} +#endif + +static struct mipi_dsim_config dsim_config = { + .e_interface = DSIM_COMMAND, + .e_pixel_format = DSIM_24BPP_888, + + .auto_flush = 0, + .eot_disable = 0, + .auto_vertical_cnt = 0, + + .hse = 0, + .hfp = 0, + .hbp = 0, + .hsa = 0, + + .e_no_data_lane = DSIM_DATA_LANE, + .e_byte_clk = DSIM_PLL_OUT_DIV, + .e_burst_mode = DSIM_BURST_MODE, + + .e_virtual_ch = DSIM_VIRTUAL_CH_0, + + .p = DSIM_P, + .m = DSIM_M, + .s = DSIM_S, + + .esc_clk = DSIM_ESC_CLK, /* escape clk : 20MHz */ + + /* stop state holding counter after bta change count 0 ~ 0xfff */ + .stop_holding_cnt = 0x0f, + /* bta timeout 0 ~ 0xff */ + .bta_timeout = 0xff, + /* lp rx timeout 0 ~ 0xffff */ + .rx_timeout = 0xffff, + /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */ + .pll_stable_time = 0x400, +}; + +static struct exynos_platform_mipi_dsim dsim_platform_data = { + .lcd_panel_info = NULL, + .dsim_config = &dsim_config, +}; + +static struct mipi_dsim_lcd_device mipi_lcd_device = { + .name = ESPRESSO3250_LCD_TYPE, + .id = -1, + .bus_id = 0, + .platform_data = (void *)&dsim_platform_data, +}; + +vidinfo_t panel_info = { + .vl_col = ESPRESSO3250_XRES, /* Number of columns (i.e. 640) */ + .vl_row = ESPRESSO3250_YRES, /* Number of rows (i.e. 480) */ + .vl_width = ESPRESSO3250_XRES, /* Width of display area in millimeters */ + .vl_height = ESPRESSO3250_YRES, /* Height of display area in millimeters */ + + /* LCD configuration register */ + .vl_freq = ESPRESSO3250_DEFAULT_FREQ, /* Frequency */ + .vl_clkp = CONFIG_SYS_LOW, /* Clock polarity */ + .vl_hsp = CONFIG_SYS_LOW, /* Horizontal Sync polarity */ + .vl_vsp = CONFIG_SYS_LOW, /* Vertical Sync polarity */ + .vl_dp = CONFIG_SYS_LOW, /* Data polarity */ + .vl_bpix = 5, /* Bits per pixel, 2^5 = 32 */ + + /* Horizontal control register. Timing from data sheet */ + .vl_hspw = ESPRESSO3250_HSP, /* Horizontal sync pulse width */ + .vl_hfpd = ESPRESSO3250_HFP, /* Wait before of line */ + .vl_hbpd = ESPRESSO3250_HBP, /* Wait end of line */ + + /* Vertical control register. */ + .vl_vspw = ESPRESSO3250_VSW, /* Vertical sync pulse width */ + .vl_vfpd = ESPRESSO3250_VFP, /* Wait before of frame */ + .vl_vbpd = ESPRESSO3250_VBP, /* Wait end of frame */ + .vl_cmd_allow_len = 0, /* Wait end of frame */ + + .cfg_gpio = NULL, + .backlight_on = NULL, + .lcd_power_on = NULL, /* lcd_power_on in mipi dsi driver */ + .reset_lcd = NULL, + .dual_lcd_enabled = 0, + + .win_id = 0, + .init_delay = 0, + .power_on_delay = 0, + .reset_delay = 0, + .interface_mode = FIMD_CPU_INTERFACE, + .mipi_enabled = 1, +}; + +#define HD_RESOLUTION 1 +void init_panel_info(vidinfo_t *vid) +{ + vid->logo_on = 0; + vid->resolution = HD_RESOLUTION; + vid->rgb_mode = MODE_RGB_P; +#ifdef CONFIG_TIZEN + get_tizen_logo_info(vid); +#elseif !defined(CONFIG_MACH_SHIRI) + get_logo_info(vid); +#endif + + strcpy(dsim_platform_data.lcd_panel_name, mipi_lcd_device.name); + dsim_platform_data.lcd_power = lcd_power; + dsim_platform_data.mipi_power = mipi_power; + dsim_platform_data.phy_enable = set_mipi_phy_ctrl; + dsim_platform_data.lcd_panel_info = (void *)vid; + exynos_mipi_dsi_register_lcd_device(&mipi_lcd_device); +#if defined(CONFIG_S6E8AX0) + s6e8ax0_init(); +#elif defined(CONFIG_NT35510) + nt35510_init(); +#elif defined(CONFIG_SHIRI_LCD) + shiri_mipi_lcd_init(); +#endif + exynos_set_dsim_platform_data(&dsim_platform_data); + +#if defined(CONFIG_S6E8AX0) + setenv("lcdinfo", "lcd=s6e8ax0"); +#elif defined(CONFIG_NT35510) + setenv("lcdinfo", "lcd=nt35510"); +#elif defined(CONFIG_SHIRI_LCD) + setenv("lcdinfo", "lcd=shiri_mipi_lcd"); +#endif + + puts("init_panel_info()..\n"); +} diff --git a/board/samsung/espresso3250/dmc.h b/board/samsung/espresso3250/dmc.h new file mode 100644 index 000000000..85a6f198c --- /dev/null +++ b/board/samsung/espresso3250/dmc.h @@ -0,0 +1,12 @@ +#ifndef _DMC_H_ +#define _DMC_H_ + +void InitDMC(u32 MemClk, RST_STAT eRstStat); + +typedef enum { + LPDDR3, + DDR3, + LPDDR2, +}Memory_Type; + +#endif /* _DMC_H_ */ diff --git a/board/samsung/espresso3250/dmc_init.c b/board/samsung/espresso3250/dmc_init.c new file mode 100644 index 000000000..7875a15e1 --- /dev/null +++ b/board/samsung/espresso3250/dmc_init.c @@ -0,0 +1,1730 @@ +/* + * Memory setup for SMDK3520 board based on S5P3520 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 <config.h> +#include <asm/io.h> +#include <asm/arch/dmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/smc.h> +#include "setup.h" + +#define LPDDR3 0 +#define DDR3 1 +#define LPDDR2 2 + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define SetBits(uAddr, uBaseBit, uMaskValue, uSetValue) \ + Outp32(uAddr, (Inp32(uAddr) & ~((uMaskValue)<<(uBaseBit))) \ + | (((uMaskValue)&(uSetValue))<<(uBaseBit))) + +#define PWMTIMER_BASE (0x139D0000) + +#define rTCFG0 (PWMTIMER_BASE+0x00) +#define rTCFG1 (PWMTIMER_BASE+0x04) +#define rTCON (PWMTIMER_BASE+0x08) +#define rTCNTB0 (PWMTIMER_BASE+0x0C) +#define rTCMPB0 (PWMTIMER_BASE+0x10) +#define rTCNTO0 (PWMTIMER_BASE+0x14) +#define rTINT_CSTAT (PWMTIMER_BASE+0x44) +#define dmcOutp32(a, d) Outp32(g_uBaseAddr+a, d) +#define dmcInp32(a) Inp32(g_uBaseAddr+a) + +#define PHY_BASE 0x106d0000 +#define DMC_BASE 0x105f0000 +#define TZASC_BASE 0x10600000 + +#define mem_type 0 //0=LPDDR3, 1=DDR3, 2 =LPDDR2 +#define mclk 400 + +#define pulldown_dq 0X0 +#define pulldown_dqs 0Xf + +#define mem_term_en 0X0 +#define phy_term_en 0X0 + +#define cs_num 0x1 + +#define cs0_base 0x40 //;;-ch0 base address(Physical 0x4000_0000) +#define cs1_base 0x60 //;;-ch1 base address(Physical 0x6000_0000) +//;&cs1_base=0x80 ;;-ch1 base address(Physical 0x8000_0000) ; for 16Gb +#define cs0_mask 0x7E0 //;;-ch0 mask address(chip size is 512MB, then chip_mask is 0x7E0) +//;&cs0_mask=0x7C0 ;;-ch0 mask address(chip size is 1GB, then chip_mask is 0x7C0); for 16Gb +#define cs1_mask 0x7E0 // ;;-ch1 mask address(chip size is 512MB, then chip_mask is 0x7E0) +//;&cs1_mask=0x7C0 ;;-ch1 mask address(chip size is 1GB, then chip_mask + + + +//static u32 g_uBaseAddr; +//static const u32 IROM_ARM_CLK = 1; + +/* CARMEN EVT1 +static void DMC_Delay(u32 uFreqMhz, u32 uMicroSec) +{ + volatile u32 uDelay; + volatile u32 uNop; + + for(uDelay = 0; uDelay < (uFreqMhz * uMicroSec); uDelay++) + { + uNop = uNop + 1; + uNop = Inp32(0x10600000+0x0048); + } +} +*/ + +static const u32 IROM_ARM_CLK = 1; + +static void StartTimer0(void) +{ + u32 uTimer=0; + u32 uTemp0,uTemp1; + u32 uEnInt=0; + u32 uDivider=0; + u32 uDzlen=0; + u32 uPrescaler=66; //- Silicon : uPrescaler=66 / FPGA : uPrescaler=24 + u32 uEnDz=0; + u32 uAutoreload=1; + u32 uEnInverter=0; + u32 uTCNTB=0xffffffff; + u32 uTCMPB=(u32)(0xffffffff/2); + + { + uTemp0 = Inp32(rTCFG1); // 1 changed into 0xf; dohyun kim 090211 + uTemp0 = (uTemp0 & (~ (0xf << 4*uTimer) )) | (uDivider<<4*uTimer); + // TCFG1 init. selected MUX 0~4, select 1/1~1/16 + + Outp32(rTCFG1,uTemp0); + + uTemp0 = Inp32(rTINT_CSTAT); + uTemp0 = (uTemp0 & (~(1<<uTimer)))|(uEnInt<<(uTimer)); + // selected timer disable, selected timer enable or diable. + Outp32(rTINT_CSTAT,uTemp0); + } + + { + uTemp0 = Inp32(rTCON); + uTemp0 = uTemp0 & (0xfffffffe); + Outp32(rTCON, uTemp0); // Timer0 stop + + uTemp0 = Inp32(rTCFG0); + uTemp0 = (uTemp0 & (~(0xff00ff))) | ((uPrescaler-1)<<0) |(uDzlen<<16); + // init. except prescaler 1 value, set the Prescaler 0 value, set the dead zone length. + Outp32(rTCFG0, uTemp0); + + Outp32(rTCNTB0, uTCNTB); + Outp32(rTCMPB0, uTCMPB); + + + uTemp1 = Inp32(rTCON); + uTemp1 = (uTemp1 & (~(0x1f))) |(uEnDz<<4)|(uAutoreload<<3)|(uEnInverter<<2)|(1<<1)|(0<<0); + // set all zero in the Tiemr 0 con., Deadzone En or dis, set autoload, set invert, manual uptate, timer stop + Outp32(rTCON, uTemp1); //timer0 manual update + uTemp1 = (uTemp1 & (~(0x1f))) |(uEnDz<<4)|(uAutoreload<<3)|(uEnInverter<<2)|(0<<1)|(1<<0); + // set all zero in the Tiemr 0 con., Deadzone En or dis, set autoload, set invert, manual uptate disable, timer start + Outp32(rTCON, uTemp1); // timer0 start + } +} + +static void PWM_stop(u32 uNum) +{ + u32 uTemp; + + uTemp = Inp32(rTCON); + + if(uNum == 0) + uTemp &= ~(0x1); + else + uTemp &= ~((0x10)<<(uNum*4)); + + Outp32(rTCON,uTemp); +} + +static u32 StopTimer0(void) +{ + u32 uVal = 0; + + PWM_stop(0); + + uVal = Inp32(rTCNTO0); + uVal = 0xffffffff - uVal; + + return uVal; +} + +#if 0 +void DMC_Delay(int msec) +{ + volatile u32 i; + for(;msec > 0; msec--); + for(i=0; i<1000; i++) ; +} +#else +void DMC_Delay(u32 usec) +{ + u32 uElapsedTime, uVal; + + StartTimer0(); + + while(1){ + uElapsedTime = Inp32(rTCNTO0); + uElapsedTime = 0xffffffff - uElapsedTime; + + if(uElapsedTime > usec){ + StopTimer0(); + break; + } + } +} +#endif + +void Check_MRStatus(u32 ch, u32 cs) +{ + u32 mr0; + u32 resp, temp; + u32 loop_cnt = 1000; + + #if 1 // Due to Pega W1 issue of MRR read , mrr_byte [26:25] bit of Memcontrol register must set 0x1 that MR Status Read location 0x1[15:8] + temp = Inp32(DMC_BASE+0x0004); + temp = temp | (0x1<<25); + Outp32(DMC_BASE+0x0004, temp); + #endif + + if(cs == 0) mr0=0x09000000; // Direct CMD 0x9=MRR(mode register reading), chip=0 + else mr0=0x09100000; // Direct CMD 0x9=MRR(mode register reading), chip=1 + + if(ch == 0){ + do{ + Outp32(DMC_BASE+0x0010, mr0); + resp=Inp32(DMC_BASE+0x0054)&0x1; + loop_cnt--; + + if(loop_cnt==0){ + DMC_Delay(10); //- Although DAI is not completed during polling it, end the loop when 10us delay is time over. + break; + } + }while(resp); + } + else{ + do{ + Outp32(DMC_BASE+0x0010, mr0); + resp=Inp32(DMC_BASE+0x0054)&0x1; + loop_cnt--; + + if(loop_cnt==0){ + DMC_Delay(10); //- Although DAI is not completed during polling it, end the loop when 10us delay is time over. + break; + } + }while(resp); + } + + return ; +} + +#define MPLL_USE_FOR_MIF +void set_mem_clock(u32 uMemClk) +{ + u32 uBits; + +#if defined(MPLL_USE_FOR_MIF) + //Turn Off MPLL + //MPLL(12) + uBits = (1 << 12) | (1 << 8) | (1 << 4); + Outp32(0x105C0300, Inp32(0x105C0300) & ~uBits); // rCLK_SRC_CORE + + if ((uMemClk==533)||(uMemClk==400)) + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/1:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (0 << 27) | (0 << 23) | (0 << 19) | (1 << 15) | (1 << 11) | (3<<0); + else if ((uMemClk==266)||(uMemClk==200)) + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/2:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (0 << 27) | (0 << 23) | (1 << 19) | (1 << 15) | (1 << 11) | (3<<0); + else if ((uMemClk==133)||(uMemClk==100)) + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/4:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (0 << 27) | (0 << 23) | (3 << 19) | (1 << 15) | (1 << 11) | (3<<0); + else if (uMemClk==50) + // DMC(1/2:27), DPHY(1/1:23), DMC_PRE(1/4:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (1 << 27) | (0 << 23) | (3 << 19) | (1 << 15) | (1 << 11) | (3<<0); + + // Set CMU_CORE_L, MUX & DIV + Outp32(0x105C0504, uBits); // rCLK_DIV_CORE_1 + + uBits = (1 << 12) | (0 << 10) | (0 << 8) | (0 << 4); // use MPLL_MIF source for DPHY,DMC + Outp32(0x105C0300, Inp32(0x105C0300) | uBits); // rCLK_SRC_CORE + while(Inp32(0x105c0400)&((1<<18)|(1<<14)|(1<<10)|(1<<6))); + + SetBits(0x10020024,0,0x1,0x0); //CP_CTRL CP_CTRL[0] (addr:x1002_0024) 1b0 + SetBits(0x105c0218,31,0x1,0x0); //BPLL disable - CMU + SetBits(0x10020074,31,0x1,0x0); //BPLL disable - alive +#else + //Turn Off BPLL + //BPLL(0:10) + uBits = (1 << 10); + Outp32(0x105C0300, Inp32(0x105C0300) & ~uBits); // rCLK_SRC_CORE + + // ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + if ((uMemClk==533)||(uMemClk==266)) + uBits = (1 << 31) | (533 << 16) | (6 << 8) | (2 << 0); // BPLL=1066MHz(4:328:1), for DREX PHY + else if ((uMemClk==400)||(uMemClk==200)||(uMemClk==133)||(uMemClk==100)||(uMemClk==50)) + uBits = (1 << 31) | (200 << 16) | (3 << 8) | (2 << 0); // BPLL= 800MHz(13:800:1), for DREX PHY + else + uBits = (1 << 31) | (200 << 16) | (3 << 8) | (2 << 0); // BPLL= 800MHz(13:800:1), for DREX PHY + + //Outp32(0x105C0218, uBits); // rBPLL_CON0 in CORE_L + //while ((Inp32(0x105C0218) & (1 << 29)) == 0); //Wait BPLL Core_l locked + + Outp32(0x10020074, uBits); // rBPLL_CON0 in ALIVE + while ((Inp32(0x10020074) & (1 << 29)) == 0); //Wait BPLL ALIVE locked + + + if ((uMemClk==533)||(uMemClk==400)) + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/1:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (0 << 27) | (0 << 23) | (0 << 19) | (1 << 15) | (1 << 11) | (3<<0); + else if ((uMemClk==266)||(uMemClk==200)) + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/2:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (0 << 27) | (0 << 23) | (1 << 19) | (1 << 15) | (1 << 11) | (3<<0); + else if (uMemClk==133) + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/4:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (0 << 27) | (0 << 23) | (2 << 19) | (1 << 15) | (1 << 11) | (3<<0); + else if (uMemClk==100) + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/4:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (0 << 27) | (0 << 23) | (3 << 19) | (1 << 15) | (1 << 11) | (3<<0); + else if (uMemClk==50) + // DMC(1/2:27), DPHY(1/1:23), DMC_PRE(1/4:19), COREP(1/2:15), CORED(1/2:11), AUDIOCODEC(1/16:0) + uBits = (1 << 27) | (0 << 23) | (3 << 19) | (1 << 15) | (1 << 11) | (3<<0); + + + // Set CMU_CORE_L, MUX & DIV + Outp32(0x105C0504, uBits); // rCLK_DIV_CORE_1 + + // BPLL(0:10) + uBits = (1 << 10); + Outp32(0x105C0300, Inp32(0x105C0300) | uBits); // rCLK_SRC_CORE +#endif // defined(MPLL_USE_FOR_MIF) +} + +void phy_mem_type(u32 mem_type_data) //0=LPDDR3, 1=DDR3, 2 =LPDDR2 +{ + u32 uBits, temp; + + if (mem_type_data==0) + uBits=0x1800; + else if (mem_type_data==1) + uBits=0x800; + else if (mem_type_data==2) + uBits=0x1000; + + temp = Inp32(PHY_BASE+0X0)&0xFFFFE7FF; + temp |= uBits; + + Outp32(PHY_BASE+0X0, temp); +} + +void pulldown_dq_dqs(u32 dq, u32 dqs) +{ + u32 temp; + + dq = dq&0xf; + dq = dq<<8; + dqs= dqs&0xf; + + temp = dq | dqs; + + Outp32(PHY_BASE+0X0038, temp); +} + +void phy_set_bl_rl_wl(u32 mem, u32 clk) //mem:0=LPDDR3, 1=DDR3, 2 =LPDDR2 +{ + u32 bl, rl, wl, temp; + + temp = 0; + if (mem==2) //lpddr2 + bl = 4; + else if (mem==0) + bl = 8; + + if ((clk==400)||(clk==266)||(clk==200)||(clk==133)||(clk==100)||(clk==50)) + { + rl=9; + wl=5; //In LPDDR3, the minimum wl is 5 + } + else if (clk==533) + { + rl=9; + wl=5; + } + + bl=bl&0x1f; + rl=rl&0x1f; + temp=temp|(bl<<8)|rl; + + Outp32(PHY_BASE+0X00ac, temp); + + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + wl=wl&0x1f; + wl=wl+1; + temp = Inp32(PHY_BASE+0X006c)&0xFFE0000F; + temp=temp|(wl<<16); + Outp32(PHY_BASE+0X006c, temp); +} + +#if 0 +void dram_init_cm1(void) +{ +#if defined(CONFIG_SMC_CMD) + reg_arr_t reg_arr; +#endif + u32 temp, uBits; + u32 i,j; + u32 mem_var,bl_var,pzq_val; + u32 row_param, data_param, power_param, rfcpb; + u32 port, cs, nop, mr63, mr10, mr1, mr2, mr3, pall; + + //;------------------------------------------------------------------------- + //;- Change CPU to 50Mhz + //;---------------------------------------------------------------------------- + // MPLL_USER(1:24), HPM(0:20), CPU(1:16), APLL(0:0) + uBits = (1 << 24) | (0 << 20) | (1 << 16) | (0 << 0); + Outp32(0x10044200, uBits); // rCLK_SRC_CPU ->mpll + + // CORE2(1/2:28), APLL(1/2:24), PCLK_DBG(1/8:20), ATB(1/4:16), COREM(1/2:4), CORE(1/4:0) + uBits = (1 << 28) | (1 << 24) | (7 << 20) | (3 << 16) | (1 << 4) | (3<< 0); + Outp32(0x10044500, uBits); // rCLK_DIV_CPU0 ARMCLK=400/2/4=50MHz + + // MPLL_USER(1:24), HPM(0:20), CPU(0:16), APLL(0:0) + uBits = (1 << 24) | (0 << 20) | (0 << 16) | (0 << 0); + Outp32(0x10044200, uBits); // rCLK_SRC_CPU->apll + + //while(1); //for debug + + //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + //;- CLK Pause enable + //GOSUB write 0x105C1094 0x1 "CLK Pause Enable" + //;--------------------------------------------------------------------- + //Outp32(0x105C1094, 0x1); + + //;----------------------------------------------- + //;- CA SWAP Setting..! + //;----------------------------------------------- + //GOSUB add_comment "CA SWAP Setting..!" + //GOSUB CA_swap_lpddr2 &PHY_BASE &DMC_BASE; + temp = Inp32(DMC_BASE+0X0000)&(~0x00000001)|(0x00000001); + Outp32(DMC_BASE+0X0000, temp); + + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + temp = Inp32(PHY_BASE+0X0064)&(~0x00000001)|(0x00000001); + Outp32(PHY_BASE+0X0064, temp); + + set_mem_clock(50); + + phy_mem_type(mem_type); //LPDDR2 + + pulldown_dq_dqs(pulldown_dq, pulldown_dqs); + + phy_set_bl_rl_wl(mem_type, mclk); + + //dmc_term(mem_term_en, phy_term_en); + + //--------------------------------------------------------------------------------- + //;- Set rd_fetch parameter + //;---------------------------------------------------------------------------- + //GOSUB dmc_rd_fetch &rd_fetch + //&rd_fetch=0x2 + temp = Inp32(DMC_BASE+0X0000); + temp = temp &0xFFFF8FFF; + temp = temp | ((0x2&0x7)<<12); //rd_fetch=0x2 + Outp32(DMC_BASE+0X0000, temp); + +//no need by weicong@2013.11.4 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //--------------------------------------------------------------------------------- + //- Assert the ConControl.dfi_init_start field then deassert + //---------------------------------------------------------------------------- + //GOSUB dfi_init_start 0x1 ;;- dfi_init_start + temp = Inp32(DMC_BASE+0X0000)|0x10000000; + temp= temp&0xFFFFFFDF; + Outp32(DMC_BASE+0X0000, temp); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //wait_status==1 + while(Inp32(0x105f0040)&0x00000008!=0x8); //wait dfi_init_complete + temp=temp&0xEFFFFFFF; + Outp32(DMC_BASE+0X0000, temp); + + //GOSUB fp_resync ;;- fp_resync + temp = Inp32(DMC_BASE+0X0018); + temp = temp |0x8; + Outp32(DMC_BASE+0X0018, temp); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + temp=temp&0xFFFFFFF7; + Outp32(DMC_BASE+0X0018, temp); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //;--------------------------------------------------------------------------------- + //;- Set the memory base register + //;---------------------------------------------------------------------------- + //(cs_num==0x1) + //GOSUB dmc_membase_cfg 0x0 &cs0_base &cs0_mask ;;- chip0 base + //&cs0_base=0x40 ;;-ch0 base address(Physical 0x4000_0000) + //&cs0_mask=0x7E0 ;;-ch0 mask address(chip size is 512MB, then chip_mask is 0x7E0) + i = cs0_base&0x7ff; + j = cs0_mask & 0x7ff; + temp = 0; + temp=temp|(i<<16); + temp=temp|j; +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F00; + reg_arr.set0.val = temp; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(TZASC_BASE+0X0F00, temp); +#endif + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //GOSUB dmc_membase_cfg 0x1 &cs1_base &cs1_mask ;;- chip1 base + //&cs1_base=0x60 ;;-ch1 base address(Physical 0x6000_0000) + //&cs1_mask=0x7E0 ;;-ch1 mask address(chip size is 512MB, then chip_mask is 0x7E0) + i = cs1_base&0x7ff; + j = cs1_mask & 0x7ff; + temp = 0; + temp=temp|(i<<16); + temp=temp|j; +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F04; + reg_arr.set0.val = temp; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(TZASC_BASE+0X0F04, temp); +#endif + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //;--------------------------------------------------------------------------------- + //;- Set the memory control register + //;---------------------------------------------------------------------------- + //GOSUB dmc_memcontrol &memory &cs_num &add_lat_pall &pzq_en ;;- memcontrol + //(cs_num==0x1) + //&add_lat_pall=0x1 ;;- Additional Latency for PALL in cclk cycle + // &pzq_en=0x0 ;;DDR3 periodic ZQ(ZQCS) enable + + if (mem_type==2) //lpddr2 + { + mem_var=0x5; + bl_var=0x2; + } + else if (mem_type==0) //lpddr3 + { + mem_var=0x7; + bl_var=0x3; + } + else if (mem_type==1) //ddr3 + { + mem_var=0x6; + bl_var=0x3; + } + + bl_var=bl_var&0x7; + mem_var=mem_var&0xF; + //pzq=pzq&0x1; + //&chip=&chip&0xF + //&add_pall=&add_pall&0xF + + temp=0; + temp=temp|0x00002000; + temp=temp|(0<<24); + temp=temp|(bl_var<<20); + temp=temp|(1<<16); + temp=temp|(mem_var<<8); + temp=temp|(1<<6); + Outp32(DMC_BASE+0X0004, temp); + +//no need by weicong@2013.11.4 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //;--------------------------------------------------------------------------------- + //;- Set the memory config register + //;---------------------------------------------------------------------------- + //GOSUB dmc_memconfig &cs_num &addr_map &col_len &row_len &bank_num ;;- memconfig + //cs_num=1 &addr_map=0x2 &col_len=0x3 &row_len=0x2 &bank_num=0x3 + // ENTRY &cs &map &col &row &ba + temp = 0; + temp=temp|(0x2<<12); + temp=temp|(0x3<<8); + temp=temp|(0x2<<4); + temp=temp|(0x3); +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F10; + reg_arr.set0.val = temp; + reg_arr.set1.addr = TZASC_BASE+0x0F14; + reg_arr.set1.val = temp; + + set_secure_reg((u32)®_arr, 2); +#else + Outp32(TZASC_BASE+0X0F10, temp); + Outp32(TZASC_BASE+0X0F14, temp); +#endif + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //;--------------------------------------------------------------------------------- + //;- Address mapping method setting + //;---------------------------------------------------------------------------- + //GOSUB map_dmc_memconfig &bank_lsb &rank_inter_en &bit_sel_en &bit_sel ;mapping method + //;;---------Address setting method----------------------------------------------- + //&bank_lsb=0x4 ;;choose the column width for the best performance. + //&rank_inter_en=0x0 ;;Rank Interleaved Address Mapping enable + //&bit_sel_en=0x1 ;;Enable Bit Selection for Randomized Interleaved Address enable + //&bit_sel=0x2 ;;0x0: bit position = [14:12] (if rank_inter_en is enabled, [15:12]), + //ENTRY &bank_lsb &rank_inter_en &bit_sel_en &bit_sel +#if defined(CONFIG_SMC_CMD) + temp = read_secure_reg(TZASC_BASE+0X0F10) & 0xFF80FFFF; +#else + temp = Inp32(TZASC_BASE+0X0F10)&0xFF80FFFF; +#endif + temp=temp|(0X4<<20); + temp=temp|(0<<19); + temp=temp|(0X1<<18); + temp=temp|(0X2<<16); +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F10; + reg_arr.set0.val = temp; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(TZASC_BASE+0X0F10, temp); +#endif + + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + +#if defined(CONFIG_SMC_CMD) + temp = read_secure_reg(TZASC_BASE+0X0F14) & 0xFF80FFFF; +#else + temp = Inp32(TZASC_BASE+0X0F14)&0xFF80FFFF; +#endif + temp=temp|(0X4<<20); + temp=temp|(0<<19); + temp=temp|(0X1<<18); + temp=temp|(0X2<<16); +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F14; + reg_arr.set0.val = temp; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(TZASC_BASE+0X0F14, temp); +#endif + +//no need by weicong@2013.11.4 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //;--------------------------------------------------------------------------------- + //;- Set auto refresh interval + //;---------------------------------------------------------------------------- + //GOSUB dmc_refresh_interval &t_refipb &t_refi + //;------ Set auto refresh interval-------------------------------- + //&t_refipb=0xc + //&t_refi=0x65 + temp=0; + temp=temp|(0XC<<16); + temp=temp|0X65; + //GOSUB set_dmc_config 0x0030 &temp "REFI=&t_refi" + //GOSUB write &DMC_BASE+&offset &var &str + Outp32(DMC_BASE+0X0030, temp); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + //;----------timing switch setting------------------------- + //GOSUB timing_set_con &timing_set_sw &timing_set_sw_con + //;----------timing switch setting------------------------- + //&timing_set_sw=0x0 ;0x0 = Use timing parameter set #0 + // ;0x1 = Use timing parameter set #1 + //&timing_set_sw_con=0x0 ;0x0 = Switching controlled by external port (port name is tim-ing_set_sw) + // ;0x1 = Switching controlled by SFR;;;;;;;;;;;;;;;;;;;;; + temp = (0x0<<4)|0x0; + //GOSUB write &DMC_BASE+0x00E0 &temp + Outp32(DMC_BASE+0X00E0, temp); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //;--------------------------------------------------------------------------------- + //;- Set timing_refpb, timing_row, timing_data, timing_power + //;---------------------------------------------------------------------------- + //GOSUB dmc_timing_parameter &mclk ;;- set timing parameter + //if (mclk==100) + // { + // rfcpb=(3<<8)|(3<<0); + // row_param=(7<<24)|(2<<20)|(2<<16)|(2<<12)|(4<<6)|(3<<0); + // data_param=(2<<28)|(2<<24)|(2<<20)|(3<<8)|(1<<4)|(6<<0); + // power_param=(4<<26)|(7<<16)|(2<<8)|(2<<4)|(5<<0); + + // } + //else if (mclk==133) + // { + // rfcpb=(4<<8)|(4<<0); + // row_param=(9<<24)|(2<<20)|(2<<16)|(2<<12)|(5<<6)|(3<<0); + // data_param=(2<<28)|(2<<24)|(2<<20)|(3<<8)|(1<<4)|(6<<0); + // power_param=(4<<26)|(10<<16)|(2<<8)|(2<<4)|(5<<0); + + // } + //else if (mclk==200) + // { + // rfcpb=(6<<8)|(6<<0); + // row_param=(13<<24)|(2<<20)|(3<<16)|(2<<12)|(7<<6)|(5<<0); + // data_param=(2<<28)|(2<<24)|(2<<20)|(3<<8)|(2<<4)|(6<<0); + // power_param=(5<<26)|(14<<16)|(2<<8)|(2<<4)|(5<<0); + + // } + //else if (mclk==266) + // { + // rfcpb=(8<<8)|(8<<0); + // row_param=(18<<24)|(2<<20)|(3<<16)|(3<<12)|(9<<6)|(6<<0); + // data_param=(2<<28)|(2<<24)|(2<<20)|(3<<8)|(2<<4)|(6<<0); + // power_param=(7<<26)|(19<<16)|(2<<8)|(2<<4)|(5<<0); + + // } + if (mclk==400) + { + rfcpb=(12<<8)|(12<<0); + row_param=(26<<24)|(2<<20)|(5<<16)|(4<<12)|(13<<6)|(9<<0); + data_param=(2<<28)|(3<<24)|(2<<20)|(3<<8)|(3<<4)|(6<<0); + power_param=(10<<26)|(28<<16)|(2<<8)|(3<<4)|(5<<0); + + } + else if (mclk==533) + { + rfcpb=(16<<8)|(16<<0); + row_param=(35<<24)|(3<<20)|(6<<16)|(5<<12)|(17<<6)|(12<<0); + data_param=(2<<28)|(4<<24)|(2<<20)|(4<<8)|(3<<4)|(8<<0); + power_param=(14<<26)|(38<<16)|(2<<8)|(4<<4)|(5<<0); + + } + //else if (mclk==50) + // { + // rfcpb=(2<<8)|(2<<0); + // row_param=(4<<24)|(2<<20)|(2<<16)|(2<<12)|(2<<6)|(2<<0); + // data_param=(2<<28)|(2<<24)|(2<<20)|(3<<8)|(1<<4)|(6<<0); + // power_param=(2<<26)|(4<<16)|(2<<8)|(2<<4)|(5<<0); + // } + //GOSUB write &DMC_BASE+0x0020 &rfcpb "DREX.TIMINGROW=&row_param" + //GOSUB write &DMC_BASE+0x0034 &row_param "DREX.TIMINGROW=&row_param" + //GOSUB write &DMC_BASE+0x0038 &data_param "DREX.TIMINGDATA=&data_param" + //GOSUB write &DMC_BASE+0x003C &power_param "DREX.TIMINGPOWER=&power_param" + //GOSUB write &DMC_BASE+0x00E4 &row_param "DREX.TIMINGROW=&row_param" + //GOSUB write &DMC_BASE+0x00E8 &data_param "DREX.TIMINGDATA=&data_param" + //GOSUB write &DMC_BASE+0x00EC &power_param "DREX.TIMINGPOWER=&power_param" + //GOSUB write &DMC_BASE+0x0044 0x00002270 "set the ETCTiming" ;ETCTiming + Outp32(DMC_BASE+0X0020, rfcpb); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + Outp32(DMC_BASE+0X0034, row_param); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + Outp32(DMC_BASE+0X0038, data_param); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + Outp32(DMC_BASE+0X003c, power_param); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + Outp32(DMC_BASE+0X00e4, row_param); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + Outp32(DMC_BASE+0X00e8, data_param); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + Outp32(DMC_BASE+0X00ec, power_param); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + Outp32(DMC_BASE+0X0044, 0x00002270); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //;--------------------------------------------------------------------------------- + //;- low frequency operation + //;---------------------------------------------------------------------------- + //GOSUB low_freq_op_mode + + //GOSUB set_offsetr 0x7F 0x7F 0x7F 0x7F ; + //ENTRY &dq3 &dq2 &dq1 &dq0 + temp = 0x7f|(0x7f<<8)|(0x7f<<16)|(0x7f<<24); + Outp32(PHY_BASE+0X0010, temp); + + //DMC_Delay(1000); //1ms + ////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 100); // wait 1ms // short delay by weicong@2013.11.4 + + //GOSUB set_offsetw 0x7F 0x7F 0x7F 0x7F ; + //ENTRY &dq3 &dq2 &dq1 &dq0 + temp = 0x7f|(0x7f<<8)|(0x7f<<16)|(0x7f<<24); + Outp32(PHY_BASE+0X0018, temp); + + //DMC_Delay(1000); //1ms + //DMC_Delay(IROM_ARM_CLK, 100); // wait 1ms // short delay by weicong@2013.11.4 + + //GOSUB set_offsetd 0x7F ; + //ENTRY &dll + temp = Inp32(PHY_BASE+0X0028)&0xFFFFFF00; + temp = temp | 0x7f; + Outp32(PHY_BASE+0X0028, temp); + + //DMC_Delay(1000); //1ms + ////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 100); // wait 1ms // short delay by weicong@2013.11.4 + + //GOSUB ca_deskew_code 0x60 ;;- if low freq. + //ENTRY &code + temp = ((0x60&0xf)<<28)|(0x60<<21)|(0x60<<14)|(0x60<<7)|0x60; + Outp32(PHY_BASE+0X0080, temp); + + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + temp = ((0x60&0x1)<<31)|(0x60<<24)|(0x60<<17)|(0x60<<10)|(0x60<<3)|(0x60>>4)&0x3; + Outp32(PHY_BASE+0X0084, temp); + + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + temp = (0x60>>1)&0x3f; + Outp32(PHY_BASE+0X0088, temp); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //GOSUB dll_off_forcing 0x7F ;- dll off and lock value force + //ENTRY &lock + i = 0x7f<<0x08; + temp = Inp32(PHY_BASE+0X0030)&0xFFFF80FF; + i = i | temp; + Outp32(PHY_BASE+0X0030, i); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + temp = Inp32(PHY_BASE+0X0030)&0xFFFFFFDF; + Outp32(PHY_BASE+0X0030, temp); + + //DMC_Delay(1000); //1ms +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 100); // wait 1ms // short delay by weicong@2013.11.4 + + //GOSUB fp_resync ;- fp_resync + temp = Inp32(DMC_BASE+0X0018)|0X8; + Outp32(DMC_BASE+0X0018, temp); +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + temp=temp&0xFFFFFFF7; + Outp32(DMC_BASE+0X0018, temp); + +////////////////////////////////20131106 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //;------------------------------------------------------------------------- + //;- Issue command to intial memory(DDR) + //;---------------------------------------------------------------------------- + //GOSUB mem_init &mclk &mem_ds ;;- memory init + //&mem_ds=0x1 ;To get the strong strength, set this value to the large value. + // ENTRY &clk &ds + //LOCAL &port &cs &nop &mr63 &mr10 &mr1 &mr2 &mr3 + port=0; + while (port<0x1) + { + nop=0x07000000; + mr63=0x00071C00; + mr10=0x00010BFC; + + if (mclk==400) + { + mr1=0x00000608; + mr2=0x00000810; + } + else if (mclk==533) + { + mr1=0x00000708; + mr2=0x00000818; + } + //else if (mclk==266) + // { + // mr1=0x00000508; + // mr2=0x00000810; + // } + //else if (mclk==200) + // { + // mr1=0x00000508; + // mr2=0x00000810; + // } + //else if (mclk==133) + // { + // mr1=0x00000508; + // mr2=0x00000810; + // } + //else if (mclk==100) + // { + // mr1=0x00000508; + // mr2=0x00000810; + // } + //else if (mclk==50) + // { + // mr1=0x00000508; + // mr2=0x00000810; + // } + + //;;- mr3 : I/O configuration + //if (mem_ds==0x1) + + mr3=0x00000C04; //; 34.3 + + if (port==1) + { + nop=nop|0x10000000; + mr63=mr63|0x10000000; + mr10=mr10|0x10000000; + mr1=mr1|0x10000000; + mr2=mr2|0x10000000; + mr3=mr3|0x10000000; + } + + cs=0; + while (cs<0x2) + { + if (cs==1) + { + nop=nop|0x100000; + mr63=mr63|0x100000; + mr10=mr10|0x100000; + mr1=mr1|0x100000; + mr2=mr2|0x100000; + mr3=mr3|0x100000; + } + + //GOSUB write &DMC_BASE+0x0010 &nop "port:&port, cs:&cs nop command" + //GOSUB waiting 1ms + Outp32(DMC_BASE+0X0010, nop); + //DMC_Delay(1000); //1ms + DMC_Delay(IROM_ARM_CLK, 200); // wait 1ms + + //print "send mr63 command &mr63" + //GOSUB write &DMC_BASE+0x0010 &mr63 "port:&port, cs:&cs mr63 command" + //GOSUB waiting 100ms + Outp32(DMC_BASE+0X0010, mr63); + //DMC_Delay(100000); //100ms + DMC_Delay(IROM_ARM_CLK, 1); // wait 100ms + + //print "send mr10 command &mr10" + //GOSUB write &DMC_BASE+0x0010 &mr10 "port:&port, cs:&cs mr10 command" + //GOSUB waiting 100ms + Outp32(DMC_BASE+0X0010, mr10); + //DMC_Delay(100000); //100ms + DMC_Delay(IROM_ARM_CLK, 1); // wait 100ms + + //print "send mr1 command &mr1" + //GOSUB write &DMC_BASE+0x0010 &mr1 "port:&port, cs:&cs mr1 command" + //GOSUB waiting 1ms + Outp32(DMC_BASE+0X0010, mr1); + //DMC_Delay(1000); //1ms + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1ms + + //print "send mr2 command &mr2" + //GOSUB write &DMC_BASE+0x0010 &mr2 "port:&port, cs:&cs mr2 command" + //GOSUB waiting 1ms + Outp32(DMC_BASE+0X0010, mr2); + //DMC_Delay(1000); //1ms + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1ms + + //print "send mr3 command &mr3" + //GOSUB write &DMC_BASE+0x0010 &mr3 "port:&port, cs:&cs mr3 command" + //GOSUB waiting 1ms + Outp32(DMC_BASE+0X0010, mr3); + //DMC_Delay(1000); //1ms + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 1000); // wait 1ms + + cs=cs+1; + } + port=port+1; + } + + //;------------------------------------------------------------------------- + //;- Set memory clock to normal frequency + //;---------------------------------------------------------------------------- + set_mem_clock(400); + + + //;------------------------------------------------------------------------- + //;- Change CORE_R frequency to 50Mhz + //;---------------------------------------------------------------------------- + // COREP(1/2:16), CORED(1/2:12), DMC(1/2:8), ACP_PCLK(1/2:4), ACP(1/4:0) + uBits = (1 << 16) | (1 << 12) | (1 << 8) | (1 << 4) | (3 << 0); + Outp32(0x10450500, uBits); // rCLK_DIV_CORE_R0 + + //;------------------------------------------------------------------------- + //;- Change CPU to 400Mhz + //;---------------------------------------------------------------------------- + // MPLL_USER(1:24), HPM(0:20), CPU(1:16), APLL(0:0) + uBits = (1 << 24) | (0 << 20) | (1 << 16) | (0 << 0); + Outp32(0x10044200, uBits); // rCLK_SRC_CPU ->mpll + + + // CORE2(1/1:28), APLL(1/2:24), PCLK_DBG(1/8:20), ATB(1/4:16), COREM(1/2:4), CORE(1/1:0) + uBits = (0 << 28) | (1 << 24) | (7 << 20) | (3 << 16) | (1 << 4) | (0<< 0); + Outp32(0x10044500, uBits); // rCLK_DIV_CPU0 ARMCLK=400/1/1=400MHz + + // MPLL_USER(1:24), HPM(0:20), CPU(0:16), APLL(0:0) + uBits = (1 << 24) | (0 << 20) | (0 << 16) | (0 << 0); + Outp32(0x10044200, uBits); // rCLK_SRC_CPU->apll + + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //;----------------------------------------------------------------------- + //;- Ch/CLK/CKE/CS/CA DDS Setting + //;----------------------------------------------------------------------- + //GOSUB set_dds &data_ds &clk_ds &cke_ds &cs_ds &ca_ds + //ENTRY &data_ds &clk_ds &cke_ds &cs_ds &ca_ds + //&clk_ds=0x6 + //&cke_ds=0x6 + //&cs_ds=0x6 + //&ca_ds=0x6 + //&data_ds=0x6 + temp = Inp32(PHY_BASE+0X00A0)&0xF0000000; + temp = temp |(0x7<<25)|(0x7<<22)|(0x7<<19)|(0x7<<16)|(0x7<<9)|(0x7<<6)|(0x7<<3)|0x7; + Outp32(PHY_BASE+0X00A0, temp); + + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //;-------------zq initial auto or one time-------------------------- + //&zq_cal_auto=0x0 + //;------------------------------------------------------------------------ + //;- ZQ_INIT/ZQ_DDS Setting. + //;------------------------------------------------------------------------ + //GOSUB zq_init &zq_ds &on_die_term ;;- zq init + //&zq_ds=0x6 + //;------------on die termination resistor------------------------- + //&on_die_term=0x0;;- 0x6, 0x5, 0x4 + //ENTRY &dds &term + temp = Inp32(PHY_BASE+0X0040)|0x08040000|0x00080000|(0x7<<24)|(0<<21); + Outp32(PHY_BASE+0X0040, temp); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + temp = temp| 0x04; + Outp32(PHY_BASE+0X0040, temp); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + temp = temp| 0x02; + Outp32(PHY_BASE+0X0040, temp); + + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + while(Inp32(PHY_BASE+0X0048)&0x00000001!=0x1); //"PHY0: wait for zq_done" + + temp = Inp32(PHY_BASE+0X0040)&0xFFFBFFFD; + Outp32(PHY_BASE+0X0040, temp); + + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //;--------------------------------------------------------------------------------- + //;- normal frequency operation + //;---------------------------------------------------------------------------- + //&default_set=0 + //GOSUB set_offsetr 0x08 0x08 0x08 0x08 ;; + //ENTRY &dq3 &dq2 &dq1 &dq0 + temp = 0x08|(0x08<<8)|(0x08<<16)|(0x08<<24); + Outp32(PHY_BASE+0X0010, temp); + + //DMC_Delay(1000); //1ms + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1ms // short delay by weicong@2013.11.4 + + //GOSUB set_offsetw 0x08 0x08 0x08 0x08 ; + //ENTRY &dq3 &dq2 &dq1 &dq0 + temp = 0x08|(0x08<<8)|(0x08<<16)|(0x08<<24); + Outp32(PHY_BASE+0X0018, temp); + + //DMC_Delay(1000); //1ms + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1ms // short delay by weicong@2013.11.4 + + //GOSUB set_offsetd 0x08 ; + //ENTRY &dll + temp = Inp32(PHY_BASE+0X0028)&0xFFFFFF00; + temp = temp | 0x08; + Outp32(PHY_BASE+0X0028, temp); + + //DMC_Delay(1000); //1ms + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1ms // short delay by weicong@2013.11.4 + + //GOSUB ca_deskew_code 0x0 ;;- if high freq. + //ENTRY &code + temp = ((0x0&0xf)<<28)|(0x0<<21)|(0x0<<14)|(0x6<<7)|0x0; + Outp32(PHY_BASE+0X0080, temp); + + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + temp = ((0x0&0x1)<<31)|(0x0<<24)|(0x0<<17)|(0x0<<10)|(0x0<<3)|(0x0>>4)&0x3; + Outp32(PHY_BASE+0X0084, temp); + + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + + temp = (0x0>>1)&0x3f; + Outp32(PHY_BASE+0X0088, temp); + + //no need by WZW@2013.11.6 DMC_Delay(IROM_ARM_CLK, 100); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + //GOSUB dll_on_start ;;- dll on & start + + temp = Inp32(PHY_BASE+0X0030)&0xFFFFFF9F; + Outp32(PHY_BASE+0X0030, temp); + + DMC_Delay(IROM_ARM_CLK, 1); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 // short delay by weicong@2013.11.4 + + temp = temp|0X20; + Outp32(PHY_BASE+0X0030, temp); + + //DMC_Delay(1000); //1ms + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1ms + //temp =temp&0xFFFFFFBF; + //Outp32(PHY_BASE+0X0030, temp); + temp =temp|0x40; + Outp32(PHY_BASE+0X0030, temp); + //DMC_Delay(1000); //1ms + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1ms + while(temp!=0x5) + { + i = Inp32(PHY_BASE+0X0034)&0xFFFFFF9F; + temp = i & 0x5; //Modified 20131101 + } + + //GOSUB fp_resync ;- fp_resync + temp = Inp32(DMC_BASE+0X0018)|0X8; + Outp32(DMC_BASE+0X0018, temp); +////////////////////////////////20131106 by wzw //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1m////////////////////////////////////added by WangCL 2013.11.01 + temp=temp&0xFFFFFFF7; + Outp32(DMC_BASE+0X0018, temp); + + //;--------------------------------------------------------------------------------- + //;- disable ctrl_atgate + //;---------------------------------------------------------------------------- + //GOSUB set_ctrl_at_gate 0x0 ;;- disable ctrl_atgate + temp = Inp32(PHY_BASE+0X0000)&0xFFFFFFBF; + Outp32(PHY_BASE+0X0000, temp); + + //;--------------------------------------------------------------------------------- + //;- Set auto refresh enable + //;---------------------------------------------------------------------------- + //GOSUB aref_en ;;- enable aref + temp = Inp32(DMC_BASE+0X0000)|0x20; + Outp32(DMC_BASE+0X0000, temp); + + //GOSUB send_precharge_all ;;- send precharge all command + port = 0; + while(port<0x1) + { + pall=0x01000000; + if (port==1) + { + pall=pall|0x10000000; + } + + cs=0; + while(cs<0x2) + { + if (cs==1) + { + pall=pall|0x100000; + } + + Outp32(DMC_BASE+0x0010, pall); + + //DMC_Delay(1000); //1ms + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1ms + + cs=cs+1; + } + + port=port+1; + } + + //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + //;- CLK Pause enable + //GOSUB write 0x105C1094 0x1 "CLK Pause Enable" + //;--------------------------------------------------------------------- + Outp32(0x105C1094, 0x1); +} +#endif + +void dram_init_w1(u32 nMEMCLK) +{ +#if defined(CONFIG_SMC_CMD) + reg_arr_t reg_arr; +#endif + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + u32 temp, uBits; + u32 i,j; + u32 mem_var,bl_var,pzq_val; + u32 row_param, data_param, power_param, rfcpb; + u32 port, cs, nop, mr63, mr10, mr1, mr2, mr3, pall; + u32 clk_ds, cke_ds, cs_ds, ca_ds, data_ds, zq_dds, zq_term; + volatile unsigned int eBootStat; + + eBootStat = readl(&pmu->inform1); + + //;----------------------------------------------- + //;- CA SWAP Setting..! + //;----------------------------------------------- +#if 0 + temp = Inp32(DMC_BASE+0X0000)&(~0x00000001)|(0x00000001); + Outp32(DMC_BASE+0X0000, temp); + + temp = Inp32(PHY_BASE+0X0064)&(~0x00000001)|(0x00000001); + Outp32(PHY_BASE+0X0064, temp); +#endif + + set_mem_clock(50); + + //;--------------------------------------------------------------------- + //;- Set the memory type for PHY register + //;---------------------------------------------------------------------- + phy_mem_type(LPDDR3); //LPDDR3 + + + //;--------------------------------------------------------------------- + //;- pulldown setting for DQ/DQS + //;---------------------------------------------------------------------- + pulldown_dq_dqs(pulldown_dq, pulldown_dqs); + + + //;------------------------------------------------------------------------- + //;- PHY Burst Length/Read, write latency setting + //;--------------------------------------------------------------------------- + phy_set_bl_rl_wl(LPDDR3, nMEMCLK); //mem:0=LPDDR3, 1=DDR3, 2 =LPDDR2 + + + //;------------------------------------------------------------------------------- + //;- dmc_term + //;------------------------------------------------------------------------------- + temp=Inp32(DMC_BASE+0x0018); + temp=temp&0xFFFF1FFF; + temp=temp|(0x5<<12); + Outp32(DMC_BASE+0x0018,temp); + + //--------------------------------------------------------------------------------- + //;- Set rd_fetch parameter + //;---------------------------------------------------------------------------- + //GOSUB dmc_rd_fetch &rd_fetch + //&rd_fetch=0x2 + temp = Inp32(DMC_BASE+0X0000); + temp = temp &0xFFFF8FFF; + temp = temp | ((0x2&0x7)<<12); //rd_fetch=0x2 + Outp32(DMC_BASE+0X0000, temp); + + //--------------------------------------------------------------------------------- + //- Assert the ConControl.dfi_init_start field then deassert + //---------------------------------------------------------------------------- + //GOSUB dfi_init_start 0x1 ;;- dfi_init_start + temp = Inp32(DMC_BASE+0X0000)|0x10000000; + temp= temp&0xFFFFFFDF; // Auto Refresh counter disable + Outp32(DMC_BASE+0X0000, temp); + + DMC_Delay(10); + while(Inp32(0x105f0040)&0x00000008!=0x8); //wait dfi_init_complete + temp=temp&0xEFFFFFFF; + Outp32(DMC_BASE+0X0000, temp); + + //GOSUB fp_resync ;;- fp_resync + temp = Inp32(DMC_BASE+0X0018); + temp = temp |0x8; + Outp32(DMC_BASE+0X0018, temp); + + temp=temp&0xFFFFFFF7; + Outp32(DMC_BASE+0X0018, temp); + + //;--------------------------------------------------------------------------------- + //;- Set the memory base register + //;---------------------------------------------------------------------------- + i = cs0_base&0x7ff; + j = cs0_mask & 0x7ff; + temp = 0; + temp=temp|(i<<16); + temp=temp|j; +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F00; + reg_arr.set0.val = temp; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(TZASC_BASE+0X0F00, temp); +#endif + + //;--------------------------------------------------------------------------------- + //;- Set the memory control register + //;---------------------------------------------------------------------------- + if (mem_type==2) //lpddr2 + { + mem_var=0x5; + bl_var=0x2; + } + else if (mem_type==0) //lpddr3 + { + mem_var=0x7; + bl_var=0x3; + } + else if (mem_type==1) //ddr3 + { + mem_var=0x6; + bl_var=0x3; + } + + bl_var=bl_var&0x7; + mem_var=mem_var&0xF; + //pzq=pzq&0x1; + //&chip=&chip&0xF + //&add_pall=&add_pall&0xF + + temp=0; + temp=temp|0x00002000; //mem_width + temp=temp|(0<<24); //pzq_en + temp=temp|(bl_var<<20); //if memory type is LPDDR3, bl is 8 + temp=temp|(0<<16); //num_chip, 0x0=1chip, 0x1=2chips + temp=temp|(mem_var<<8); // mem_tpye, 0x7=LPDDR3 + temp=temp|(0<<6); //add_lat_pall, 0x0=0cycle, 0x1=1cycle, 0x2=2cycle + Outp32(DMC_BASE+0X0004, temp); + + //;--------------------------------------------------------------------------------- + //;- Set the memory config register + //;---------------------------------------------------------------------------- + temp = 0; + temp=temp|(0x2<<12); //chip_map, 0x2 = Split column interleaved + temp=temp|(0x3<<8); //chip_col, 0x3 = 10bits + temp=temp|(0x2<<4); //chip_row, 0x2 = 14bits + temp=temp|(0x3); //chip_bank, 0x3 = 8banks +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F10; + reg_arr.set0.val = temp; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(TZASC_BASE+0X0F10, temp); +#endif + //Outp32(TZASC_BASE+0X0F14, temp); + + //;--------------------------------------------------------------------------------- + //;- Address mapping method setting + //;---------------------------------------------------------------------------- +#if defined(CONFIG_SMC_CMD) + temp = read_secure_reg(TZASC_BASE+0X0F10) & 0xFF80FFFF; +#else + temp = Inp32(TZASC_BASE+0X0F10)&0xFF80FFFF; +#endif + temp=temp|(0X4<<20); //bank_lsb, 0x4 = bit position [12](column low size = 4KB) + temp=temp|(0<<19); //rank_inter_en, + temp=temp|(0X1<<18); //bit_sel_en + temp=temp|(0X2<<16); //bit_sel, 0x2 = bit postion = [23:22](if rank_inter_en is enabled, [24:22]) +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_BASE+0x0F10; + reg_arr.set0.val = temp; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(TZASC_BASE+0X0F10, temp); +#endif + + //;--------------------------------------------------------------------------------- + //;- Set auto refresh interval + //;---------------------------------------------------------------------------- + temp=0; + temp=temp|(0XC<<16); // t_refipb = 0.4875us * 24MHz = 11.7 = C + temp=temp|0X5D; // t_refi = 3.9us * 24MHz = 93 = 0x5D + Outp32(DMC_BASE+0X0030, temp); + + + //;----------timing switch setting------------------------- + //GOSUB timing_set_con &timing_set_sw &timing_set_sw_con + //;----------timing switch setting------------------------- + temp = (0x0<<4)|0x0; + //GOSUB write &DMC_BASE+0x00E0 &temp + Outp32(DMC_BASE+0X00E0, temp); + SetBits(0x10020054,31,0x1,0x0); + + //;--------------------------------------------------------------------------------- + //;- Set timing_refpb, timing_row, timing_data, timing_power + //;---------------------------------------------------------------------------- + //GOSUB dmc_timing_parameter &mclk ;;- set timing parameter + if (nMEMCLK==400) + { + rfcpb=(12<<8)|(12<<0); + row_param=0x1A35538A; + data_param=0x23200539; + power_param=0x281C0225; + } + else if (nMEMCLK==533) + { + rfcpb=(16<<8)|(16<<0); + row_param=0x2347648D; + data_param=0x24200539; + power_param=0x38260225; + } + Outp32(DMC_BASE+0X0020, rfcpb); + Outp32(DMC_BASE+0X0034, row_param); + Outp32(DMC_BASE+0X0038, data_param); + Outp32(DMC_BASE+0X003c, power_param); + Outp32(DMC_BASE+0X00e4, row_param); + Outp32(DMC_BASE+0X00e8, data_param); + Outp32(DMC_BASE+0X00ec, power_param); + + //;--------------------------------------------------------------------------------- + //;- low frequency operation + //;---------------------------------------------------------------------------- + temp = 0x7f|(0x7f<<8)|(0x7f<<16)|(0x7f<<24); + Outp32(PHY_BASE+0X0010, temp); + + temp = 0x7f|(0x7f<<8)|(0x7f<<16)|(0x7f<<24); + Outp32(PHY_BASE+0X0018, temp); + + temp = Inp32(PHY_BASE+0X0028)&0xFFFFFF00; + temp = temp | 0x7f; + Outp32(PHY_BASE+0X0028, temp); + + temp = ((0x60&0xf)<<28)|(0x60<<21)|(0x60<<14)|(0x60<<7)|0x60; + Outp32(PHY_BASE+0X0080, temp); + + temp = ((0x60&0x1)<<31)|(0x60<<24)|(0x60<<17)|(0x60<<10)|(0x60<<3)|(0x60>>4)&0x3; + Outp32(PHY_BASE+0X0084, temp); + + temp = (0x60>>1)&0x3f; + Outp32(PHY_BASE+0X0088, temp); + + i = 0x7f<<0x08; + temp = Inp32(PHY_BASE+0X0030)&0xFFFF80FF; + i = i | temp; + Outp32(PHY_BASE+0X0030, i); + + temp = Inp32(PHY_BASE+0X0030)&0xFFFFFFDF; + Outp32(PHY_BASE+0X0030, temp); + + //GOSUB fp_resync ;- fp_resync + temp = Inp32(DMC_BASE+0X0018)|0X8; + Outp32(DMC_BASE+0X0018, temp); + temp=temp&0xFFFFFFF7; + Outp32(DMC_BASE+0X0018, temp); + + //;------------------------------------------------------------------------- + //;- Ch/CLK/CKE/CS/CA DDS Setting + //;---------------------------------------------------------------------------- + clk_ds=0x4&0x7; + cke_ds=0x4&0x7; + cs_ds=0x4&0x7; + ca_ds=0x4&0x7; + data_ds=0x4&0x7; + + temp = Inp32(PHY_BASE+0X00A0); // Read PHY_CON39 + temp=temp|(data_ds<<25)|(data_ds<<22)|(data_ds<<19)|(data_ds<<16)|(clk_ds<<9)|(cke_ds<<6)|(cs_ds<<3)|ca_ds; + Outp32( PHY_BASE+0x00A0, temp ); //- PHY0.CON39[11:0]=0xDB60DB6 + + //;------------------------------------------------------------------------ + //;- ZQ_INIT/ZQ_DDS Setting. + //;------------------------------------------------------------------------ + zq_dds=0x4&0x7; + zq_term=0x0&0x7; + temp = Inp32(PHY_BASE+0X0040); + temp=temp|0x08040000; + temp=temp|0x00080000; // if zq_term == 0, + temp=temp|(zq_dds<<24)|(zq_term<<21); + //Outp32( 0x106D0000+0x0040, 0xE0C0304 ); //- dds=0x6000000, term=0x0 + Outp32( PHY_BASE+0x0040, temp ); //- dds=0x6000000, term=0x0 + temp=temp|0x4; + //Outp32( 0x106D0000+0x0040, 0xE0C0304 ); //- long cal. + Outp32( PHY_BASE+0x0040, temp ); //- long cal. + temp=temp|0x2; + //Outp32( 0x106D0000+0x0040, 0xE0C0306 ); //- manual zq cal. start + Outp32( PHY_BASE+0x0040, temp ); //- manual zq cal. start + while( ( Inp32( PHY_BASE+0x0048 ) & 0x1 ) != 0x1 ); //- PHY0: wait for zq_done + + temp = Inp32(PHY_BASE+0X0040); + temp=temp&0xFFFBFFFD; //termination disable, clk_div_en disable,calibration manual start disble + Outp32( 0x106D0000+0x0040, temp ); //- ternination disable, clk div disable, manual calibration stop + + //;------------------------------------------------------------------------- + //;- Issue command to intial memory(DDR) + //;---------------------------------------------------------------------------- + if(eBootStat != S5P_CHECK_SLEEP) + { + port=0; + while (port<0x1) + { + nop=0x07000000; + mr63=0x00071C00; + mr10=0x00010BFC; // MR10, OP=0xFF "Calibration command after initialization" + + if (nMEMCLK==400) + { + mr1=0x0000060C; // nWR = tWR / tCK = 15ns / 2.5ns = 6, BL = 8 + mr2=0x0000081C; // RL = 9, WL = 5 because constraint of memory controller. + } + else if (nMEMCLK==533) + { + mr1=0x0000070C; + mr2=0x0000081C; + } + + mr3=0x00000C0C; //; 0xC04 : 34.3, 0xC0C=48 + + if (port==1) + { + nop=nop|0x10000000; + mr63=mr63|0x10000000; + mr10=mr10|0x10000000; + mr1=mr1|0x10000000; + mr2=mr2|0x10000000; + mr3=mr3|0x10000000; + } + + cs=0; + while (cs<0x2) + { + if (cs==1) + { + nop=nop|0x100000; + mr63=mr63|0x100000; + mr10=mr10|0x100000; + mr1=mr1|0x100000; + mr2=mr2|0x100000; + mr3=mr3|0x100000; + } + + Outp32(DMC_BASE+0X0010, nop); + DMC_Delay(200); + + Outp32(DMC_BASE+0X0010, mr63); + #if 0 + DMC_Delay(10); + #else + DMC_Delay(1); + Check_MRStatus(0,0); + #endif + + Outp32(DMC_BASE+0X0010, mr10); + //DMC_Delay(1); + + Outp32(DMC_BASE+0X0010, mr1); + Outp32(DMC_BASE+0X0010, mr2); + Outp32(DMC_BASE+0X0010, mr3); + cs=cs+1; + } + port=port+1; + } + } + else + { + Outp32(DMC_BASE+0X0010, 0x08000000); //- CH0, CS0. Self Refresh Exit Command for only sleep & wakeup + } + //;------------------------------------------------------------------------- + //;- Set memory clock to normal frequency + //;---------------------------------------------------------------------------- + set_mem_clock(nMEMCLK); + + //;--------------------------------------------------------------------------------- + //;- normal frequency operation + //;---------------------------------------------------------------------------- + temp = 0x08|(0x08<<8)|(0x08<<16)|(0x08<<24); + Outp32(PHY_BASE+0X0010, temp); + + //GOSUB set_offsetw 0x08 0x08 0x08 0x08 ; + //ENTRY &dq3 &dq2 &dq1 &dq0 + temp = 0x08|(0x08<<8)|(0x08<<16)|(0x08<<24); + Outp32(PHY_BASE+0X0018, temp); + + //GOSUB set_offsetd 0x08 ; + //ENTRY &dll + temp = Inp32(PHY_BASE+0X0028)&0xFFFFFF00; + temp = temp | 0x08; + Outp32(PHY_BASE+0X0028, temp); + + //GOSUB ca_deskew_code 0x0 ;;- if high freq. + //ENTRY &code + temp = ((0x0&0xf)<<28)|(0x0<<21)|(0x0<<14)|(0x0<<7)|0x0; + Outp32(PHY_BASE+0X0080, temp); + + temp = ((0x0&0x1)<<31)|(0x0<<24)|(0x0<<17)|(0x0<<10)|(0x0<<3)|(0x0>>4)&0x3; + Outp32(PHY_BASE+0X0084, temp); + + temp = (0x0>>1)&0x3f; + Outp32(PHY_BASE+0X0088, temp); + + //GOSUB dll_on_start ;;- dll on & start + + temp = Inp32(PHY_BASE+0X0030)&0xFFFFFF9F; + Outp32(PHY_BASE+0X0030, temp); + + temp = temp|0X20; + Outp32(PHY_BASE+0X0030, temp); + //DMC_Delay(IROM_ARM_CLK, 1000); // wait 1ms + + temp =temp|0x40; + Outp32(PHY_BASE+0X0030, temp); + //DMC_Delay(IROM_ARM_CLK, 2000); // wait 1ms + + while(temp!=0x5) + { + i = Inp32(PHY_BASE+0X0034); + temp = i & 0x5; + } + + //GOSUB fp_resync ;- fp_resync + temp = Inp32(DMC_BASE+0X0018)|0X8; + Outp32(DMC_BASE+0X0018, temp); + temp=temp&0xFFFFFFF7; + Outp32(DMC_BASE+0X0018, temp); + + //;--------------------------------------------------------------------------------- + //;- disable ctrl_atgate + //;---------------------------------------------------------------------------- + //GOSUB set_ctrl_at_gate 0x0 ;;- disable ctrl_atgate + temp = Inp32(PHY_BASE+0X0000)&0xFFFFFFBF; + Outp32(PHY_BASE+0X0000, temp); + + //;--------------------------------------------------------------------------------- + //;- Set timeout precharge + //;---------------------------------------------------------------------------- + temp = Inp32(DMC_BASE+0X0014); // read DREX.PrechConfig0 + temp=temp&0x0FFFFFFF; + temp=temp|(0xf<<28); // tp_en + Outp32(DMC_BASE+0X0014, temp); + + temp = Inp32(DMC_BASE+0X001C); // read DREX.PrechConfig1 + temp=temp&0x0; + temp=temp|0xffffffff; // tp_cnt + Outp32(DMC_BASE+0X001C, temp); + + //;------------------------------------------------------------------------------- + //;- dynamic_sref + //;------------------------------------------------------------------------------- + temp = Inp32(DMC_BASE+0X0004); + temp=temp&0xFFFFFFDF; + temp=temp|(0x1<<5); + Outp32(DMC_BASE+0X0004, temp); //"MemControl" + + //;------------------------------------------------------------------------------- + //;- dynamic_pwrdn + //;------------------------------------------------------------------------------- + temp = Inp32(DMC_BASE+0X0004); + temp=temp&0xFFFFFFF1; + temp=temp|(0x1<<1); + Outp32(DMC_BASE+0X0004, temp); //"MemControl" + + //;------------------------------------------------------------------------------- + //;- dmc_brb_control + //;- dmc_brb_config + //;------------------------------------------------------------------------------- + temp = (0x0<<7)|(0x0<<6)|(0x0<<5)|(0x0<<4)|(0x0<<3)|(0x0<<2)|(0x0<<1)|(0x0); + Outp32(DMC_BASE+0X0100, temp); //"DREX0 brbrsvcontrol"" + temp = (0x8<<28)|(0x8<<24)|(0x8<<20)|(0x8<<16)|(0x8<<12)|(0x8<<8)|(0x8<<4)|(0x8); + Outp32(DMC_BASE+0X0104, temp); //"DREX0 brbrsvconfig"" + + //;------------------------------------------------------------------------------- + //;- dynamic_clkstop + //;------------------------------------------------------------------------------- + temp = Inp32(DMC_BASE+0X0004); + temp=temp&0xFFFFFFFE; + temp=temp|0x0; + Outp32(DMC_BASE+0X0004, temp); //MemControl - dynamic_clkstop + + temp = Inp32(DMC_BASE+0X0008); + temp=temp&0xFFFFFFEF; + temp=temp|(0x1<<5); + Outp32(DMC_BASE+0X0008, temp); //"DMC.CGControl.tz_cg_en=&tz_cg_en" + + temp = Inp32(DMC_BASE+0X0008); + temp=temp&0xFFFFFFEF; + temp=temp|(0x1<<4); + Outp32(DMC_BASE+0X0008, temp); //"DMC.CGControl.phy_cg_en=&phy_cg_en" + + temp = Inp32(DMC_BASE+0X0008); + temp=temp&0xFFFFFFF7; + temp=temp|(0x1<<3); + Outp32(DMC_BASE+0X0008, temp); //"DMC.CGControl.mem_if_cg_en=&mem_if_cg_en" + + temp = Inp32(DMC_BASE+0X0008); + temp=temp&0xFFFFFFFB; + temp=temp|(0x1<<2); + Outp32(DMC_BASE+0X0008, temp); //"DMC.CGControl.scg_cg_en=&scg_cg_en" + + temp = Inp32(DMC_BASE+0X0008); + temp=temp&0xFFFFFFFD; + temp=temp|(0x1<<1); + Outp32(DMC_BASE+0X0008, temp); //"DMC.CGControl.busif_wr_cg_en=&busif_wr_cg_en" + + temp = Inp32(DMC_BASE+0X0008); + temp=temp&0xFFFFFFFE; + temp=temp|(0x1<<0); + Outp32(DMC_BASE+0X0008, temp); //"DMC0.CGControl.busif_rd_cg_en=&busif_rd_cg_en" + + //;------------------------------------------------------------------------------- + //;- dmc_io_pd + //;------------------------------------------------------------------------------- + temp = Inp32(DMC_BASE+0X0000); + temp=temp&0xFFFFFF3F; + temp=temp|(0x2<<6); // 0x2 = Automatic control for ctrl_pd in none read state, + Outp32(DMC_BASE+0X0000, temp); //"Set DREX0.ConControl.io_pd_con=&pd" + + //;--------------------------------------------------------------------------------- + //;- Set auto refresh enable + //;---------------------------------------------------------------------------- + //GOSUB aref_en ;;- enable aref + temp = Inp32(DMC_BASE+0X0000)|0x20; + Outp32(DMC_BASE+0X0000, temp); + + //;--------------------------------------------------------------------------------- + //;- Set update_mode enable + //;---------------------------------------------------------------------------- + temp = Inp32(DMC_BASE+0X0000)|0x8; //0x1 = MC initiated update/acknowledge mode + Outp32(DMC_BASE+0X0000, temp); + + //GOSUB send_precharge_all ;;- send precharge all command + port = 0; + while(port<0x1) + { + pall=0x01000000; + + if (port==1) + { + pall=pall|0x10000000; + } + + cs=0; + while(cs<0x2) + { + if (cs==1) + { + pall=pall|0x100000; + } + + Outp32(DMC_BASE+0x0010, pall); + + cs=cs+1; + } + + port=port+1; + } + //;--------------------------------------------------------------------- + //;- ctrl_ref set to resolve for bus hang issue + //;--------------------------------------------------------------------- + temp = Inp32(PHY_BASE+0X0030)|(0xf<<1); //0xf = 4'b1111: Once ctrl_locked and dfi_init_complete are asserted, those won't be deasserted until rst_n is asserted. + Outp32(PHY_BASE+0X0030, temp); + + //;--------------------------------------------------------------------- + //;- CLK Pause enable + //;--------------------------------------------------------------------- + Outp32(0x105C1094, 0x1); +} + +void mem_ctrl_init(void) +{ + u32 MemClk = 400; + dram_init_w1(MemClk); +} diff --git a/board/samsung/espresso3250/espresso3250.c b/board/samsung/espresso3250/espresso3250.c new file mode 100644 index 000000000..4fd72ef79 --- /dev/null +++ b/board/samsung/espresso3250/espresso3250.c @@ -0,0 +1,515 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/sromc.h> +#include <asm/arch/sysreg.h> +#include "pmic.h" + +#define DEBOUNCE_DELAY 10000 +#define OM_1stSDMMC_2ndUSB 0x2 + +DECLARE_GLOBAL_DATA_PTR; +unsigned int OmPin; + + +int board_init(void) +{ + u8 read_vol_arm; + u8 read_vol_int, read_vol_g3d; + u8 read_vol_mif, read_rtc_ctrl; + u8 read_buck; + u8 temp; + unsigned int reg; + + char bl1_version[9] = {0}; + + /* display BL1 version */ +#ifdef CONFIG_TRUSTZONE_ENABLE + printf("\nTrustZone Enabled BSP"); + strncpy(&bl1_version[0], (char *)(CONFIG_PHY_IRAM_NS_BASE + 0x810), 8); + printf("\nBL1 version: %s\n", &bl1_version[0]); +#endif + +#if defined(CONFIG_PM) +#if defined (CONFIG_PMIC_S5M8767A) +#if 0 + IIC0_ERead(S5M8767A_RD_ADDR, BUCK2_DVS, &read_vol_arm); + IIC0_ERead(S5M8767A_RD_ADDR, BUCK3_DVS, &read_vol_int); + IIC0_ERead(S5M8767A_RD_ADDR, BUCK4_DVS, &read_vol_g3d); + + printf("\nPMIC: 8767 + FAN3555\n "); + printf("MIF--FAN3555, fixed to: %dmV\t\n", 1100); + + //IIC0_ERead(S5M8767A_RD_ADDR, BUCK2_CTRL, &temp); + //printf("ARM---BUCK2, BUCK2_CTRL value: %d\t\n", temp); + printf("ARM---BUCK2: %dmV\t\n", RD_BUCK_VOLT((unsigned int)read_vol_arm)); + + //IIC0_ERead(S5M8767A_RD_ADDR, BUCK3_CTRL, &temp); + //printf("INT---BUCK3, BUCK3_CTRL value: %d\t\n", temp); + printf("INT---BUCK3: %dmV\t\n", RD_BUCK_VOLT((unsigned int)read_vol_int)); + + //IIC0_ERead(S5M8767A_RD_ADDR, BUCK4_CTRL, &temp); + //printf("G3D---BUCK4, BUCK4_CTRL value: %d\t\n", temp); + printf("G3D---BUCK4: %dmV\t\n", RD_BUCK_VOLT((unsigned int)read_vol_g3d)); +#endif +#endif +#if defined (CONFIG_PMIC_S2MPU02) + + IIC0_ERead(S2MPU02_RD_ADDR, BUCK1_CTRL2, &read_vol_mif); + IIC0_ERead(S2MPU02_RD_ADDR, BUCK2_CTRL2, &read_vol_arm); + IIC0_ERead(S2MPU02_RD_ADDR, BUCK3_CTRL2, &read_vol_int); + IIC0_ERead(S2MPU02_RD_ADDR, BUCK4_CTRL2, &read_vol_g3d); + printf("MIF: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_mif)); + printf("ARM: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_arm)); + printf("INT: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_int)); + printf("G3D: %dmV\t\n", RD_BUCK_VOLT((unsigned int)read_vol_g3d)); +#endif +#endif + + //gd->bd->bi_arch_number = MACH_TYPE_SMDK3250; + + gd->bd->bi_boot_params = (PHYS_SDRAM_1+0x100); + + OmPin = __REG(EXYNOS4_POWER_BASE + INFORM3_OFFSET); + #define SDMMC_DEV 0x4 + unsigned int om_status = readl(EXYNOS4_POWER_BASE + OM_STATUS_OFFSET); + if(om_status == SDMMC_DEV) { + OmPin = BOOT_EMMC_4_4; + } + + printf("\nChecking Boot Mode ..."); + if (OmPin == BOOT_ONENAND) { + printf(" OneNand\n"); + } else if (OmPin == BOOT_NAND) { + printf(" NAND\n"); + } else if (OmPin == BOOT_MMCSD) { + printf(" SDMMC\n"); + } else if (OmPin == BOOT_EMMC) { + printf(" EMMC4.3\n"); + } else if (OmPin == BOOT_EMMC_4_4) { + printf(" EMMC4.41\n"); + } else { + printf(" Please check OM_pin\n"); + } + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE) + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE) + + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, + PHYS_SDRAM_4_SIZE); + gd->bd->bi_dram[4].start = PHYS_SDRAM_5; + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5, + PHYS_SDRAM_5_SIZE); + gd->bd->bi_dram[5].start = PHYS_SDRAM_6; + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6, + PHYS_SDRAM_6_SIZE); + gd->bd->bi_dram[6].start = PHYS_SDRAM_7; + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7, + PHYS_SDRAM_7_SIZE); + gd->bd->bi_dram[7].start = PHYS_SDRAM_8; + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8, + PHYS_SDRAM_8_SIZE); +} + +int board_eth_init(bd_t *bis) +{ + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + + printf("\nBoard: ESPRESSO3250\n"); + + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + int err, OmPin; + + OmPin = readl(&pmu->inform3); + + err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); + if (err) { + debug("SDMMC2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); + if (err) { + debug("MSHC0 not configured\n"); + return err; + } + + if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) { +#ifdef USE_MMC0 + set_mmc_clk(PERIPH_ID_SDMMC0, 0); + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif +#ifdef USE_MMC2 + set_mmc_clk(PERIPH_ID_SDMMC2, 0); + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif + } + else { +#ifdef USE_MMC2 + set_mmc_clk(PERIPH_ID_SDMMC2, 0); + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif +#ifdef USE_MMC0 + set_mmc_clk(PERIPH_ID_SDMMC0, 0); + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif + } + + return err; +} +#endif + +static int board_uart_init(void) +{ + int err; + + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE); + if (err) { + debug("UART0 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE); + if (err) { + debug("UART1 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE); + if (err) { + debug("UART2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); + if (err) { + debug("UART3 not configured\n"); + return err; + } + + return 0; +} + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f(void) +{ + return board_uart_init(); +} +#endif + +#define SCAN_KEY_CNT 10 +unsigned int check_key(void) +{ + unsigned int scan_cnt = 0; + unsigned int cur_key_val = 0; + unsigned int old_key_val = 0; + unsigned int total_scan_cnt = 0; + int err; + struct exynos3_gpio_part2 *gpio2 = (struct exynos3_gpio_part2 *)samsung_get_base_gpio_part2(); + + unsigned int pwr, home, back; + + /* GPX1_6 : Back Key */ + s5p_gpio_direction_input(&gpio2->x1, 6); + s5p_gpio_set_pull(&gpio2->x1, 6, GPIO_PULL_UP); + + /* GPX2_7 : Power Key */ + s5p_gpio_direction_input(&gpio2->x2, 7); + s5p_gpio_set_pull(&gpio2->x2, 7, GPIO_PULL_UP); + + /* GPX0_3 : Home Key */ + s5p_gpio_direction_input(&gpio2->x0, 3); + s5p_gpio_set_pull(&gpio2->x0, 3, GPIO_PULL_UP); + + /* Fix me : Add the code to scan key */ + + mdelay(10); + + old_key_val = cur_key_val = s5p_gpio_get_value(&gpio2->x2, 7) << 2 | + s5p_gpio_get_value(&gpio2->x0, 3) << 1 | + s5p_gpio_get_value(&gpio2->x1, 6); + + while (1) { + if (total_scan_cnt >= SCAN_KEY_CNT) { + cur_key_val = 7; + break; + } + + mdelay(10); + + cur_key_val = s5p_gpio_get_value(&gpio2->x2, 7) << 2 | + s5p_gpio_get_value(&gpio2->x0, 3) << 1 | + s5p_gpio_get_value(&gpio2->x1, 6); + + if (cur_key_val == old_key_val) { + scan_cnt++; + } else { + scan_cnt = 0; + old_key_val = cur_key_val; + total_scan_cnt++; + } + + if (scan_cnt >= SCAN_KEY_CNT) { + break; + } + } + + return cur_key_val; +} + +#define RECOVERY_MENU_CNT 3 +char func_name[RECOVERY_MENU_CNT][30] = {"Reset", "Wipe", "Update"}; + +int menu_select(int i) +{ + switch(i) { + case 0: + setenv("bootcmd", "reset"); + break; + case 1: +#ifdef CONFIG_CMD_LCD + run_command("lcd 0", 0); + run_command("lcd 2", 0); +#endif +#ifdef CONFIG_CMD_LCDTEXT + run_command("lcdtext 0 30 \"Formatting ...\"", 0); +#endif + run_command(CONFIG_FACTORY_RESET_COMMAND, 0); + break; + case 2: + setenv("bootcmd", CONFIG_BOOTCOMMAND_VIA_SCRIPT); + break; + } + return 0; +} + +int menu_up(int i) +{ + int ret; + + if (i <= 0) + ret = RECOVERY_MENU_CNT - 1; + else + ret = i - 1; + + return ret; +} + +int menu_down(int i) +{ + int ret; + + if (i >= RECOVERY_MENU_CNT - 1) + ret = 0; + else + ret = i + 1; + + return ret; +} + +int recovery_mode(void) +{ + int i = 0, init = 1; + unsigned int cur_key_val = 0, old_key_val = 7, temp_key_val = 0; + +#ifdef CONFIG_CMD_LCD + run_command("lcd 0", 0); + run_command("lcd 2", 0); +#endif + while (1) { + temp_key_val = check_key(); + if (temp_key_val != 0x7 || init) { + init = 0; + old_key_val = cur_key_val; + cur_key_val = temp_key_val; +#ifdef CONFIG_CMD_LCD + run_command("lcd 2", 0); +#endif + switch(cur_key_val) { + case 0x3: // Power Key Pressed : Select + menu_select(i); + return 0; + case 0x5: // Home Key Pressed : Up + i = menu_up(i); + break; + case 0x6: // Back Key Pressed : Down + i = menu_down(i); + break; + } +#ifdef CONFIG_CMD_LCDTEXT + if (i == 0) + run_command("lcdtext 0 30 \"v Reset\"", 0); + else + run_command("lcdtext 0 30 \" Reset\"", 0); + + if (i == 1) + run_command("lcdtext \"v Wipe the partition\"", 0); + else + run_command("lcdtext \" Wipe the partition\"", 0); + + if (i == 2) + run_command("lcdtext \"v Update from SDcard\"", 0); + else + run_command("lcdtext \" Update from SDcard\"", 0); +#endif + printf("%s \n", func_name[i]); + } + } + return 0; +} + +int board_late_init(void) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + uint rst_stat; + unsigned int pressed_key = ~0; + unsigned om_status = readl(&pmu->om_stat) & 0x3f; + + rst_stat = readl(&pmu->rst_stat); + printf("rst_stat : 0x%x\n", rst_stat); + + pressed_key = check_key(); + switch(pressed_key) { + case 0x1: + if ((om_status >> 1) == OM_1stSDMMC_2ndUSB) { + printf("RecoveryMode from microSD \n"); +#ifdef CONFIG_CMD_LCD + run_command("lcd 0", 0); + run_command("lcd 2", 0); +#endif +#ifdef CONFIG_CMD_LCDTEXT + run_command("lcdtext \"Copying Bootloaders\"", 0); + run_command("lcdtext \" from microSD to eMMC...\"", 0); +#endif + run_command(CONFIG_RECOVERYCOMMAND_1st_SDMMC, 0); +#ifdef CONFIG_CMD_LCDTEXT + run_command("lcdtext \"Done...\"", 0); +#endif + mdelay(1000); + setenv("bootcmd", " "); + setenv("bootdelay", "0"); +#ifdef CONFIG_CMD_LCDTEXT + run_command("lcd 1", 0); +#endif + } else { + printf("Recovery Mode \n"); + setenv("bootdelay", "0"); + recovery_mode(); + } + break; + case 0x2: + printf("Download Mode \n"); +#ifdef CONFIG_CMD_LCD + run_command("lcd 0", 0); +#endif +#ifdef CONFIG_CMD_LCDTEXT + run_command("lcdtext \"Downlaod Mode\"", 0); +#endif + run_command("fastboot", 0); + break; + } + +#ifdef CONFIG_RECOVERY_MODE + u32 second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (second_boot_info == 1) { + printf("###Recovery Mode(SDMMC)###\n"); + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + setenv("bootcmd", CONFIG_RECOVERYCOMMAND_SDMMC); + } +#ifdef CONFIG_EXYNOS_DA + second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + if (second_boot_info == 2) { + printf("###USB Download### om:%d\n", readl(&pmu->inform3)); + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + writel(BOOT_EMMC_4_4, &pmu->inform3); + run_command(CFG_DNW_AUTO_CFG_PARTITION, 0); // make partition + setenv("bootcmd", "dnw v05"); + printf("###USB Download### om:%d\n", readl(&pmu->inform3)); + } +#endif +#endif + + if ((readl(&pmu->inform4)) == CONFIG_FACTORY_RESET_MODE) { + writel(0x0, &pmu->inform4); + setenv("bootcmd", CONFIG_FACTORY_RESET_BOOTCOMMAND); + } + +#ifdef CONFIG_RAMDUMP_MODE + /* check reset status for ramdump */ + if ((rst_stat & (WRESET | SYS_WDTRESET | ISP_ARM_WDTRESET)) + || (readl(CONFIG_RAMDUMP_SCRATCH) == CONFIG_RAMDUMP_MODE)) { + /* run fastboot */ + run_command("fastboot", 0); + } +#endif + return 0; +} diff --git a/board/samsung/espresso3250/lowlevel_init.S b/board/samsung/espresso3250/lowlevel_init.S new file mode 100644 index 000000000..fb66fbe79 --- /dev/null +++ b/board/samsung/espresso3250/lowlevel_init.S @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/arch/cpu.h> +#include "smdk3250_val.h" + +/* Multi Core Timer */ +#define G_TCON_OFFSET 0x0240 +#define GLOBAL_FRC_ENABLE 0x100 + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + + .globl lowlevel_init +lowlevel_init: + /* use iRAM stack in bl2 */ + ldr sp, =CONFIG_IRAM_STACK + stmdb r13!, {ip,lr} + + bl relocate_nscode + + /* check warm reset status */ + bl check_warm_reset + + /* check reset status */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + + /* AFTR wakeup reset */ + ldr r2, =S5P_CHECK_DIDLE + cmp r1, r2 + beq exit_wakeup + + /* LPA wakeup reset */ + ldr r2, =S5P_CHECK_LPA + cmp r1, r2 + beq exit_wakeup + + /* Sleep wakeup reset */ + ldr r2, =S5P_CHECK_SLEEP + cmp r1, r2 + beq wakeup_reset + + /* PS-HOLD high */ + ldr r0, =(EXYNOS4_POWER_BASE + PSHOLD_CONTROL_OFFSET) + ldr r1, [r0] + orr r1, r1, #0x100 + str r1, [r0] + + bl pmic_gpio_init + +#ifdef CONFIG_PM + bl pmic_enable_peric_dev + bl pmic_init +#endif + + bl read_om + + /* + * If U-boot is already running in RAM, no need to relocate U-Boot. + * Memory controller must be configured before relocating U-Boot + * in ram. + */ + ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ + bic r1, pc, r0 /* pc <- current addr of code */ + /* r1 <- unmasked bits of pc */ + ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ + bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ + cmp r1, r2 /* compare r1, r2 */ + beq after_copy /* r0 == r1 then skip sdram init */ + +#if defined(CONFIG_PM) + bl pmic_init +#endif + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +after_copy: + ldmia r13!, {ip,pc} + +wakeup_reset: + bl start_mct_frc + + bl read_om + + /* If eMMC booting */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +exit_wakeup: + b warmboot + +pmic_gpio_init: + /* Disable EINT GPIO Pull-up/down */ + ldr r0, =(0x11000C48) + mov r1, #0x0 + str r1, [r0] + + /* Set PMIC WRSTBI(GPE1_1) to Output */ + ldr r0, =(0x11000140) + ldr r1, [r0] + bic r2, r1, #0xF0 + and r1, r1, r2 + orr r1, r1, #0x10 + str r1, [r0] + + /* Set PMIC WRSTBI(GPE1_1) to High */ + ldr r0, =(0x11000144) + ldr r1, [r0] + orr r1, r1, #0x2 + str r1, [r0] + mov pc, lr + +read_om: + /* Read booting information */ + ldr r0, =EXYNOS4_POWER_BASE + ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC BOOT */ + cmp r2, #0x6 + moveq r3, #BOOT_EMMC + + /* eMMC 4.4 BOOT */ + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x28 + moveq r3, #BOOT_EMMC_5_0 + + /*add for silicon test, will be delete after silicon fix om option*/ + cmp r2, #0x0 + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x6 + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x20 + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x24 + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x26 + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x38 + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x3A + moveq r3, #BOOT_EMMC_5_0 + cmp r2, #0x3C + moveq r3, #BOOT_EMMC_5_0 + + ldr r0, =EXYNOS4_POWER_BASE + str r3, [r0, #INFORM3_OFFSET] + + mov pc, lr + +check_warm_reset: + /* check reset status */ + ldr r0, =(EXYNOS4_POWER_BASE + RST_STAT_OFFSET) + ldr r1, [r0] + and r1, r1, #WRESET + cmp r1, #WRESET @ check warm reset + /* clear reset_status */ + ldreq r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + moveq r1, #0x0 + streq r1, [r0] + + mov pc, lr + +start_mct_frc: + ldr r0, =(EXYNOS4_MCT_BASE + G_TCON_OFFSET) + ldr r1, [r0] + orr r1, r1, #GLOBAL_FRC_ENABLE + str r1, [r0] + + mov pc, lr + +/* + * Relocate code + */ +relocate_nscode: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + .word 0xF57FF04F @dsb sy + .word 0xF57FF06F @isb sy + + mov pc, lr + .ltorg + + /* + * CPU1, 2, 3 waits here until CPU0 wake it up. + * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory. + */ + nscode_base: + b 1f + nop @ for backward compatibility + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 + .word 0x0 @ REG4: RESERVED + _hotplug_addr: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6 + _c2_addr: + .word 0x0 @ REG7: REG_C2_ADDR + _cpu_state: + .word 0x1 @ CPU0_STATE : RESET + .word 0x2 @ CPU1_STATE : SECONDARY RESET + .word 0x2 @ CPU2_STATE : SECONDARY RESET + .word 0x2 @ CPU3_STATE : SECONDARY RESET + .word 0x0 @ RESERVED + .word 0x0 @ RESERVED + .word 0x0 @ RESERVED + .word 0x0 @ RESERVED + +#define RESET (1 << 0) +#define SECONDARY_RESET (1 << 1) +#define HOTPLUG (1 << 2) +#define C2_STATE (1 << 3) + + 1: + adr r0, _cpu_state + + mrc p15, 0, r7, c0, c0, 5 @ read MPIDR + and r7, r7, #0xf @ r7 = cpu id + + /* read the current cpu state */ + ldr r10, [r0, r7, lsl #2] + + ns_svc_entry: + tst r10, #C2_STATE + adrne r0, _c2_addr + bne wait_for_addr + + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + cmp r1, #0x0 + movne r1, #0x0 + strne r1, [r0] + ldrne r1, =(EXYNOS4_POWER_BASE + INFORM0_OFFSET) + ldrne pc, [r1] + + tst r10, #RESET + ldrne pc, =CONFIG_SYS_TEXT_BASE + + adr r0, _hotplug_addr + wait_for_addr: + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + wfe + b wait_for_addr + .ltorg + nscode_end: + diff --git a/board/samsung/espresso3250/mmc_boot.c b/board/samsung/espresso3250/mmc_boot.c new file mode 100644 index 000000000..28e867697 --- /dev/null +++ b/board/samsung/espresso3250/mmc_boot.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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<config.h> +#include <asm/arch/power.h> + + +#define FIRST_EMMC_SECOND_SDMMC_DEV_0 0x20 +#define FIRST_EMMC_SECOND_SDMMC_DEV_1 0x24 +#define FIRST_EMMC_SECOND_SDMMC_DEV_2 0x26 + +#define SIGNATURE_CHECK_FAIL -1 +#define SECOND_BOOT_MODE 0xFEED0002 +#define SPI_SDMMC_DEV 0x2C +#define SDMMC_SECOND_DEV 0x101 + +#define FIRST_SD_SECOND_USB_DEV 0b100 +#define FIRST_EMMC_SECOND_USB_DEV 0b110 + +/* +* Copy U-boot from mmc to RAM: +* COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains +* Pointer to API (Data transfer from mmc to ram) +*/ + +static int find_second_boot_dev(void) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + unsigned int om_status = readl(&pmu->om_stat) & 0x3e; + + if (om_status == SDMMC_SECOND_DEV) { + writel(0x1, CONFIG_SECONDARY_BOOT_INFORM_BASE); + return BOOT_SEC_DEV; + } else if ((om_status == FIRST_SD_SECOND_USB_DEV) || (om_status == FIRST_EMMC_SECOND_USB_DEV)) { + writel(0x2, CONFIG_SECONDARY_BOOT_INFORM_BASE); + return BOOT_USB; + } else + return -1; +} + +void copy_uboot_to_ram(unsigned int boot_dev) +{ + int ret = 0; + + switch (boot_dev) { + case BOOT_MMCSD: + case BOOT_SEC_DEV: + boot_dev = SDMMC_CH2; + break; + case BOOT_EMMC_4_4: + boot_dev = EMMC; + break; + case BOOT_USB: + boot_dev = USB; + break; + } + /* Load u-boot image to ram */ + ret = load_uboot_image(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) { + sdmmc_enumerate(); + if (find_second_boot_dev() == BOOT_SEC_DEV) + boot_dev = SDMMC_CH2; + ret = load_uboot_image(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) + while (1); + } + + /* Load tzsw image & U-Boot boot */ + ret = coldboot(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) { + sdmmc_enumerate(); + if (find_second_boot_dev() == BOOT_SEC_DEV) + boot_dev = SDMMC_CH2; + ret = coldboot(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) + while (1); + } +} + +void load_uboot(void) +{ + unsigned int om_status = readl(EXYNOS4_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + + /* TODO : find second boot function */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + copy_uboot_to_ram(boot_dev); +} + +void board_init_f(unsigned long bootflag) +{ + __attribute__((noreturn)) void (*uboot)(void); + load_uboot(); + + /* Jump to U-Boot image */ + /* + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); + */ + /* Never returns Here */ +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /* Function attribute is no-return */ + /* This Function never executes */ + while (1) + ; +} + +void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} diff --git a/board/samsung/espresso3250/pmic.c b/board/samsung/espresso3250/pmic.c new file mode 100644 index 000000000..75a5bd98c --- /dev/null +++ b/board/samsung/espresso3250/pmic.c @@ -0,0 +1,325 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include "pmic.h" +#include "smdk3250_val.h" + +void Delay(void) +{ + unsigned long i; + for(i=0;i<DELAY;i++); +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + IIC0_ESDA_INP; // Function <- Input + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPD1DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + ack = (ack>>0)&0x1; +// while(ack!=0); + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + IIC0_ESDA_OUTP; // Function <- Output + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + + IIC0_ESDA_INP; // Function <- Input (SDA) + + IIC0_SCLL_SDAL(); +} + +void IIC0_ESetport(void) +{ + GPD1PUD &= ~(0xf<<0); // Pull Up/Down Disable SCL, SDA + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + IIC0_ESCL_OUTP; // Function <- Output (SCL) + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + Delay(); +} + +void IIC0_EWrite (unsigned char ChipId, unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + +////////////////// write reg. data. ////////////////// + for(i = 8; i>0; i--) + { + if((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EEnd(); +} + +void IIC0_ERead (unsigned char ChipId, unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EHigh(); // read + + IIC0_EAck_write(); // ACK + +////////////////// read reg. data. ////////////////// + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for(i = 8; i>0; i--) + { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPD1DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + reg = (reg >> 0) & 0x1; + + data |= reg << (i-1); + } + + IIC0_EAck_read(); // ACK + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + +void pmic_init(void) +{ + unsigned char rtc_ctrl; + unsigned char wrstbi_ctrl; + + IIC0_ESetport(); + + /* enable low_jitter, CP, AP at RTC_BUF */ + IIC0_EWrite(S2MPS14_WR_ADDR, WRSTBI, 0x20); + IIC0_EWrite(S2MPS14_WR_ADDR, RTC_BUF, 0x17); + IIC0_EWrite(S2MPS14_WR_ADDR, BUCK2_OUT, + WR_BUCK_VOLT(CONFIG_ARM_VOLT) + VDD_BASE_OFFSET); +} + +void pmic_enable_peric_dev(void) +{ + unsigned char ldo_ctrl; + + IIC0_ESetport(); + + /* enable LDO18 : VCC_2.8V_PERI */ + IIC0_ERead(S2MPS14_WR_ADDR, 0x34, &ldo_ctrl); + ldo_ctrl |= (1 << 6); + IIC0_EWrite(S2MPS14_WR_ADDR, 0x34, ldo_ctrl); + + /* enable LDO23 : VCC_1.8V_PERI */ + IIC0_ERead(S2MPS14_WR_ADDR, 0x39, &ldo_ctrl); + ldo_ctrl |= (1 << 6); + IIC0_EWrite(S2MPS14_WR_ADDR, 0x39, ldo_ctrl); +} + +#ifdef CONFIG_USE_LCD +void pmic_turnon_vdd_lcd(void) +{ + unsigned char ldo_ctrl; + + IIC0_ESetport(); + + /* enable LDO16 : VCC_LCD_3.3V */ + IIC0_ERead(S2MPS14_WR_ADDR, 0x32, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS14_WR_ADDR, 0x32, ldo_ctrl); + + /* enable LDO19 : TSP_AVDD_1.8V */ + IIC0_ERead(S2MPS14_WR_ADDR, 0x35, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS14_WR_ADDR, 0x35, ldo_ctrl); +} + +void pmic_turnoff_vdd_lcd(void) +{ + unsigned char ldo_ctrl; + + IIC0_ESetport(); + + /* disable LDO16 : VCC_LCD_3.3V */ + IIC0_ERead(S2MPS14_WR_ADDR, 0x32, &ldo_ctrl); + ldo_ctrl &= ~OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS14_WR_ADDR, 0x32, ldo_ctrl); + + /* disable LDO19 : TSP_AVDD_1.8V */ + IIC0_ERead(S2MPS14_WR_ADDR, 0x35, &ldo_ctrl); + ldo_ctrl &= ~OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS14_WR_ADDR, 0x35, ldo_ctrl); +} +#endif diff --git a/board/samsung/espresso3250/pmic.h b/board/samsung/espresso3250/pmic.h new file mode 100644 index 000000000..1bf06fa70 --- /dev/null +++ b/board/samsung/espresso3250/pmic.h @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __PMIC_H__ +#define __PMIC_H__ + +#define GPD1CON *(volatile unsigned long *)(0x114000C0) +#define GPD1DAT *(volatile unsigned long *)(0x114000C4) +#define GPD1PUD *(volatile unsigned long *)(0x114000C8) + +#define IIC0_ESCL_Hi GPD1DAT |= (0x1<<1) +#define IIC0_ESCL_Lo GPD1DAT &= ~(0x1<<1) +#define IIC0_ESDA_Hi GPD1DAT |= (0x1<<0) +#define IIC0_ESDA_Lo GPD1DAT &= ~(0x1<<0) + +#define IIC1_ESCL_Hi GPD1DAT |= (0x1<<3) +#define IIC1_ESCL_Lo GPD1DAT &= ~(0x1<<3) +#define IIC1_ESDA_Hi GPD1DAT |= (0x1<<2) +#define IIC1_ESDA_Lo GPD1DAT &= ~(0x1<<2) + +#define IIC0_ESCL_INP GPD1CON &= ~(0xf<<4) +#define IIC0_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<4))|(0x1<<4) + +#define IIC0_ESDA_INP GPD1CON &= ~(0xf<<0) +#define IIC0_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<0))|(0x1<<0) + +#define DELAY 100 + +/* S2MPS14 slave address */ +#define S2MPS14_WR_ADDR 0xCC +#define S2MPS14_RD_ADDR 0xCD + +#define VDD_BASE_VOLT_BUCK1 65000 +#define VDD_VOLT_STEP_BUCK1 625 +#define MIN_VOLT_BUCK1 650 +#define MAX_RD_VAL_BUCK1 0xFC +#define RD_BUCK_VOLT_BUCK1(x) (((x > MAX_RD_VAL_BUCK1) ? 0 : \ + ((x * VDD_VOLT_STEP_BUCK1) + VDD_BASE_VOLT_BUCK1) / 100)) +#define WR_BUCK_VOLT_BUCK1(x) ((x < MIN_VOLT_BUCK1) ? 0 : \ + ((((x) * 100) - VDD_BASE_VOLT_BUCK1) / VDD_VOLT_STEP_BUCK1)) + +#define VDD_BASE_OFFSET 0x20 +#define VDD_BASE_VOLT 60000 +#define VDD_VOLT_STEP 625 +#define MIN_VOLT 600 +#define MAX_RD_VAL 0xA0 +#define RD_BUCK_VOLT(x) (((x > MAX_RD_VAL) ? 0 : \ + ((x * VDD_VOLT_STEP) + VDD_BASE_VOLT) / 100)) +#define WR_BUCK_VOLT(x) ((x < MIN_VOLT) ? 0 : \ + ((((x) * 100) - VDD_BASE_VOLT) / VDD_VOLT_STEP)) + +#define RTC_BUF 0x0C +#define WRSTBI 0x18 +#define LDO16_CTRL 0x32 +#define LDO18_CTRL 0x34 +#define LDO19_CTRL 0x35 +#define LDO23_CTRL 0x39 +#define BUCK2_OUT 0x1C + +/* LDO CTRL bit */ +#define OFF (0x0) +#define ON (0x1) +#define OUTPUT_OFF (~(3 << 6)) +#define OUTPUT_PWREN_ON (1 << 6) +#define OUTPUT_LOWPWR_MODE (2 << 6) +#define OUTPUT_NORMAL_MODE (3 << 6) + +/* + * RTC_BUF + */ +#define LOW_JITTER_EN (0x1 << 4) +#define CP_32KHZ_EN (0x1 << 1) +#define AP_32KHZ_EN (0x1 << 0) + +/* + * WRSTBI + */ +#define WRSTBI_EN (0x1 << 5) + +extern void pmic_init(void); +extern void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData); +extern void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData); + +#endif /*__PMIC_H__*/ + diff --git a/board/samsung/espresso3250/setup.h b/board/samsung/espresso3250/setup.h new file mode 100644 index 000000000..116937d8b --- /dev/null +++ b/board/samsung/espresso3250/setup.h @@ -0,0 +1,59 @@ +/* + * Machine Specific Values for SMDK4270 board based on EXYNOS4 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 _SMDK3250_SETUP_H +#define _SMDK3250_SETUP_H + +#include <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* TZPC : Register Offsets */ +#define TZPC0_BASE 0x10110000 +#define TZPC1_BASE 0x10120000 +#define TZPC2_BASE 0x10130000 +#define TZPC3_BASE 0x10140000 +#define TZPC4_BASE 0x10150000 +#define TZPC5_BASE 0x10160000 +#define TZPC6_BASE 0x10170000 + + +/* + * TZPC Register Value : + * R0SIZE: 0x0 : Size of secured ram + */ +#define R0SIZE 0x0 + +/* + * TZPC Decode Protection Register Value : + * DECPROTXSET: 0xFF : Set Decode region to non-secure + */ +#define DECPROTXSET 0xFF + +void sdelay(unsigned long); +void mem_ctrl_init(void); +void system_clock_init(void); +void system_top_clock_init(void); +extern unsigned int second_boot_info; +#endif diff --git a/board/samsung/espresso3250/smc.c b/board/samsung/espresso3250/smc.c new file mode 100644 index 000000000..63b7f9f2f --- /dev/null +++ b/board/samsung/espresso3250/smc.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <asm/arch/smc.h> + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + ".arch_extension sec\n" + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd, u32 arg) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + register u32 reg2 __asm__("r2") = arg; + + __asm__ volatile ( + ".arch_extension sec\n" + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2) + + ); + + return reg1; +} +#if 1 +#ifdef CONFIG_EXYNOS_DA +unsigned int bl2_mdelay(u32 mdelay) +{ + int i = 0; + int j = 0; + +#define DEF_CLK 800000000 + + for(i=0;i<mdelay*(DEF_CLK/1000);i++) + { + asm volatile("": : :"memory"); + j++; + } +} +#endif /* CONFIG_EXYNOS_DA */ +#endif +unsigned int load_uboot_image(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == USB) { + + info_image->bootdev.usb.read_buffer = CONFIG_PHY_IRAM_NS_BASE + 0x800; +#ifdef CONFIG_EXYNOS_DA + bl2_mdelay(500); +#endif + + } + + info_image->image_base_addr = CONFIG_PHY_UBOOT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_UBOOT_SIGNATURE_SIZE; + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, 0); +#else + if (boot_device == SDMMC_CH2) { + + u32 (*copy_uboot)(u32, u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + SDMMC_DEV_OFFSET); + + copy_uboot(MOVI_UBOOT_POS, + MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } else if (boot_device == EMMC) { + + u32 (*copy_uboot)(u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + EMMC_DEV_OFFSET ); + + copy_uboot(MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } + +#endif +} + +unsigned int coldboot(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == USB) { + + info_image->bootdev.usb.read_buffer = CONFIG_PHY_IRAM_BASE + 0xc00; +#ifdef CONFIG_EXYNOS_DA + bl2_mdelay(500); +#endif + + } + + info_image->image_base_addr = CONFIG_PHY_TZSW_BASE; + info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_TZSW_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_COLDBOOT, + boot_device, (u32)info_image, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*uboot)(void); + + /* Jump to U-Boot image */ + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); +#endif + /* Never returns Here */ +} + +void warmboot(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*wakeup_kernel)(void); + + /* Jump to kernel for wakeup */ + wakeup_kernel = (void *)readl(EXYNOS4_POWER_BASE + INFORM0_OFFSET); + (*wakeup_kernel)(); + /* Never returns Here */ +#endif +} + +unsigned int find_second_boot(void) +{ +#if defined(CONFIG_SMC_CMD) + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT, 0); +#else + return readl(IROM_FNPTR_BASE + SECCOND_BOOT_INFORM_OFFSET); +#endif +} + +void emmc_endbootop(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +#else + +#endif +} + +void sdmmc_enumerate(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_SDMMC_ENUMERATE, 0, 0, 0); +#else + +#endif +} + +void set_secure_reg(u32 reg_val, u32 num) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_SET_SECURE_REG, reg_val, num, 0); +#else + +#endif +} + +unsigned int read_secure_reg(u32 addr) +{ +#if defined(CONFIG_SMC_CMD) + return exynos_smc_read(SMC_CMD_READ_SECURE_REG, addr); +#else + /* Do nothing */ + return 0; +#endif +} diff --git a/board/samsung/espresso3250/smdk3250_val.h b/board/samsung/espresso3250/smdk3250_val.h new file mode 100644 index 000000000..6870f8fa9 --- /dev/null +++ b/board/samsung/espresso3250/smdk3250_val.h @@ -0,0 +1,700 @@ +#ifndef _VAL_SMDK3250_H +#define _VAL_SMDK3250_H + +#include <config.h> +#include <version.h> + +#if defined (CONFIG_SYS_FIN_26) +#define FIN 26000000 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define FIN 24000000 +#endif + +#if (CONFIG_ARM_CLK == 100) + #define CONFIG_CLK_ARM_100 + #define CONFIG_ARM_VOLT 850 +#elif (CONFIG_ARM_CLK == 200) + #define CONFIG_CLK_ARM_200 + #define CONFIG_ARM_VOLT 850 +#elif (CONFIG_ARM_CLK == 300) + #define CONFIG_CLK_ARM_300 + #define CONFIG_ARM_VOLT 925 +#elif (CONFIG_ARM_CLK == 400) + #define CONFIG_CLK_ARM_400 + #define CONFIG_ARM_VOLT 925 +#elif (CONFIG_ARM_CLK == 500) + #define CONFIG_CLK_ARM_500 + #define CONFIG_ARM_VOLT 1000 +#elif (CONFIG_ARM_CLK == 600) + #define CONFIG_CLK_ARM_600 + #define CONFIG_ARM_VOLT 1000 +#elif (CONFIG_ARM_CLK == 700) + #define CONFIG_CLK_ARM_700 + #define CONFIG_ARM_VOLT 1075 +#elif (CONFIG_ARM_CLK == 800) + #define CONFIG_CLK_ARM_800 + #define CONFIG_ARM_VOLT 1075 +#elif (CONFIG_ARM_CLK == 900) + #define CONFIG_CLK_ARM_900 + #define CONFIG_ARM_VOLT 1150 +#elif (CONFIG_ARM_CLK == 1000) + #define CONFIG_CLK_ARM_1000 + #define CONFIG_ARM_VOLT 1150 +#endif + +#define CONFIG_CLK_BPLL_800 +#define CONFIG_CLK_MPLL_800 +#define CONFIG_CLK_EPLL_200 +#define CONFIG_CLK_VPLL_266 +#define CONFIG_CLK_UPLL_50 + +/* +** APLL/MPLL/BPLL setting +*/ +#define PLL_LOCKTIME 0x1C20 +/* APLL_LOCK */ +#define APLL_LOCK_VAL (PLL_LOCKTIME) +/* MPLL_LOCK */ +#define MPLL_LOCK_VAL (PLL_LOCKTIME) +/* BPLL_LOCK */ +#define BPLL_LOCK_VAL (PLL_LOCKTIME) +/* EPLL_LOCK */ +#define EPLL_LOCK_VAL (PLL_LOCKTIME) +/* VPLL_LOCK */ +#define VPLL_LOCK_VAL (PLL_LOCKTIME) +/* UPLL_LOCK */ +#define UPLL_LOCK_VAL (PLL_LOCKTIME) + +#if defined(CONFIG_CLK_ARM_100) +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0xC8 +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x4 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_200) +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0xC8 +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x3 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_300) +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0x190 +#define APLL_PDIV 0x4 +#define APLL_SDIV 0x3 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_400) +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0xC8 +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x2 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_500) +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0xFA +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x2 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_600) +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0x190 +#define APLL_PDIV 0x4 +#define APLL_SDIV 0x2 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_700) +#if defined(CONFIG_SYS_FIN_26) +#define APLL_MDIV 0x2BC +#define APLL_PDIV 0xD +#define APLL_SDIV 0x1 +#endif +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0xAF +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x1 +#endif +#endif + + +#if defined(CONFIG_CLK_ARM_800) +#if defined(CONFIG_SYS_FIN_26) +#define APLL_MDIV 0x320 +#define APLL_PDIV 0xD +#define APLL_SDIV 0x1 +#endif +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0xC8 +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x1 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_900) +#if defined(CONFIG_SYS_FIN_24) +#define APLL_MDIV 0x12C +#define APLL_PDIV 0x4 +#define APLL_SDIV 0x1 +#endif +#endif + +#if defined(CONFIG_CLK_ARM_1000) +#if defined (CONFIG_SYS_FIN_26) +#define APLL_MDIV 0x3E8 +#define APLL_PDIV 0xD +#define APLL_SDIV 0x1 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define APLL_MDIV 0xFA +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x1 +#endif +#endif + +#if defined(CONFIG_CLK_BPLL_800) +#if defined (CONFIG_SYS_FIN_26) +#define BPLL_MDIV 0x320 +#define BPLL_PDIV 0xD +#define BPLL_SDIV 0x1 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define BPLL_MDIV 0xC8 +#define BPLL_PDIV 0x3 +#define BPLL_SDIV 0x1 +#endif +#endif + + +#if defined(CONFIG_CLK_BPLL_1066) +#if defined (CONFIG_SYS_FIN_26) +#define BPLL_MDIV 0x148 +#define BPLL_PDIV 0x4 +#define BPLL_SDIV 0x1 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define BPLL_MDIV 0x215 +#define BPLL_PDIV 0x6 +#define BPLL_SDIV 0x1 +#endif +#endif + +#if defined(CONFIG_CLK_BPLL_1333) +#if defined (CONFIG_SYS_FIN_26) +#define BPLL_MDIV 0x29B +#define BPLL_PDIV 0xD +#define BPLL_SDIV 0x0 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define BPLL_MDIV 0x29B +#define BPLL_PDIV 0x6 +#define BPLL_SDIV 0x1 +#endif +#endif + + +#if defined(CONFIG_CLK_MPLL_1600) +#if defined (CONFIG_SYS_FIN_26) +#define MPLL_MDIV 0x320 +#define MPLL_PDIV 0xD +#define MPLL_SDIV 0x0 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define MPLL_MDIV 0xC8 +#define MPLL_PDIV 0x3 +#define MPLL_SDIV 0x0 +#endif +#endif + +#if defined(CONFIG_CLK_MPLL_800) +#if defined (CONFIG_SYS_FIN_24) +#define MPLL_MDIV 0xC8 +#define MPLL_PDIV 0x3 +#define MPLL_SDIV 0x1 +#endif +#endif + +#if defined(CONFIG_CLK_UPLL_50) +#if defined (CONFIG_SYS_FIN_26) +#define UPLL_MDIV 0x320 +#define UPLL_PDIV 0xD +#define UPLL_SDIV 0x5 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define UPLL_MDIV 0xC8 +#define UPLL_PDIV 0x3 +#define UPLL_SDIV 0x5 +#endif +#endif + + +/* APLL_CON1 */ +#define APLL_CON1_VAL 0x00A0FC00 //reset value; AFC_ENB =0; AFC = 0x0; LOCK_EN =0 +#define APLL_CON2_VAL 0x00000020 //reset value: ICP =2; RSEL = 0; PBIAS_CTRL =0, PBIAS_CTRL_EN = 0 + +/* MPLL_CON1 */ +#define MPLL_CON1_VAL 0x00A0FC00 //reset value; AFC_ENB =0; AFC = 0x0; LOCK_EN =0 +#define MPLL_CON2_VAL 0x00000020 //reset value: ICP =2; RSEL = 0; PBIAS_CTRL =0, PBIAS_CTRL_EN = 0 + +/* BPLL_CON1 */ +#define BPLL_CON1_VAL 0x00A0FC00 //reset value; AFC_ENB =0; AFC = 0x0; LOCK_EN =0 +#define BPLL_CON2_VAL 0x00000020 //reset value: ICP =2; RSEL = 0; PBIAS_CTRL =0, PBIAS_CTRL_EN = 0 + +/* UPLL_CON1 */ +#define UPLL_CON1_VAL 0x00A0FC00 //reset value; AFC_ENB =0; AFC = 0x0; LOCK_EN =0 +#define UPLL_CON2_VAL 0x00000020 //reset value: ICP =2; RSEL = 0; PBIAS_CTRL =0, PBIAS_CTRL_EN = 0 + + +/* +** EPLL/VPLL setting +*/ +#if defined(CONFIG_CLK_EPLL_800) +#if defined (CONFIG_SYS_FIN_26) +#define EPLL_MDIV 0xB9 +#define EPLL_PDIV 0x3 +#define EPLL_SDIV 0x1 +#define EPLL_K 0x9D8A +#endif +#if defined (CONFIG_SYS_FIN_24) +#define EPLL_MDIV 0xC8 +#define EPLL_PDIV 0x3 +#define EPLL_SDIV 0x1 +#define EPLL_K 0x0 +#endif +#endif + +#if defined(CONFIG_CLK_EPLL_200) +#if defined (CONFIG_SYS_FIN_26) +#define EPLL_MDIV 0xB9 +#define EPLL_PDIV 0x3 +#define EPLL_SDIV 0x3 +#define EPLL_K 0x9D8A +#endif +#if defined (CONFIG_SYS_FIN_24) +#define EPLL_MDIV 0xC8 +#define EPLL_PDIV 0x3 +#define EPLL_SDIV 0x3 +#define EPLL_K 0x0 +#endif +#endif + + +#define EPLL_CON1_VAL ((0xC601<<16) | (EPLL_K)) +#define EPLL_CON2_VAL 0x18000000 @reset value + +#if defined(CONFIG_CLK_VPLL_335) +#if defined (CONFIG_SYS_FIN_26) +#define VPLL_MDIV 0x9B +#define VPLL_PDIV 0x3 +#define VPLL_SDIV 0x2 +#define VPLL_K 0x9D8A +#endif +#if defined (CONFIG_SYS_FIN_24) +#define VPLL_MDIV 0x70 +#define VPLL_PDIV 0x2 +#define VPLL_SDIV 0x2 +#define VPLL_K 0xAAAB +#endif +#endif + +#if defined(CONFIG_CLK_VPLL_266) +#if defined (CONFIG_SYS_FIN_24) +#define VPLL_MDIV 0x10A +#define VPLL_PDIV 0x3 +#define VPLL_SDIV 0x3 +#define VPLL_K 0x0 +#endif +#endif + +#define VPLL_CON1_VAL ((0xC601<<16) | (VPLL_K)) +#define VPLL_CON2_VAL 0x18000000 //reset value + +/********************************************************/ + +/* Set PLL */ +#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) + +#define APLL_CON0_VAL set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV) +#define MPLL_CON0_VAL set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV) +#define BPLL_CON0_VAL set_pll(BPLL_MDIV,BPLL_PDIV,BPLL_SDIV) +#define UPLL_CON0_VAL set_pll(UPLL_MDIV,UPLL_PDIV,UPLL_SDIV) +#define EPLL_CON0_VAL set_pll(EPLL_MDIV,EPLL_PDIV,EPLL_SDIV) +#define VPLL_CON0_VAL set_pll(VPLL_MDIV,VPLL_PDIV,VPLL_SDIV) + +/********************************************************/ +/* CPU Clock +/********************************************************/ +/* CLK_SRC_CPU */ +#define MUX_HPM_SEL_MOUTAPLL 0 +#define MUX_HPM_SEL_SCLKMPLL_USER_CPU 1 +#define MUX_CORE_SEL_MOUTAPLL 0 +#define MUX_CORE_SEL_SCLKMPLL_USER_CPU 1 + +/* 0 = FILPLL, 1 = MOUT */ +#define MUX_MPLL_USER_SEL_FINPLL 0 +#define MUX_MPLL_USER_SEL_SCLKMPLL 1 +#define MUX_APLL_SEL_FINPLL 0 +#define MUX_APLL_SEL_APLLFOUT 1 +#define CLK_SRC_CPU_VAL_FINPLL ((MUX_MPLL_USER_SEL_FINPLL << 24) \ + | (MUX_HPM_SEL_MOUTAPLL << 20) \ + | (MUX_CORE_SEL_MOUTAPLL <<16) \ + | (MUX_APLL_SEL_FINPLL)) +#define CLK_SRC_CPU_VAL_MOUTAPLL ((MUX_MPLL_USER_SEL_SCLKMPLL << 24) \ + | (MUX_HPM_SEL_MOUTAPLL << 20) \ + | (MUX_CORE_SEL_MOUTAPLL <<16) \ + | (MUX_APLL_SEL_APLLFOUT <<0)) +/* CLK_DIV_CPU0 */ +#define CORE2_RATIO 0x0 +#define APLL_RATIO 0x1 +#define PCLK_DBG_RATIO 0x7 +#define ATB_RATIO 0x3 +#define COREM_RATIO 0x1 +#define CORE_RATIO 0x0 +#define CLK_DIV_CPU0_VAL ( (CORE2_RATIO<<28) \ + |(APLL_RATIO << 24) \ + | (PCLK_DBG_RATIO << 20)\ + | (ATB_RATIO << 16) \ + | (COREM_RATIO << 4) \ + | (CORE_RATIO)) + +/* CLK_DIV_CPU1 */ +#define HPM_RATIO 0x0 +#define COPY_RATIO 0x2 +#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) | (COPY_RATIO)) + +/********************************************************/ +/* DMC Clock +/********************************************************/ +/* CLK_SRC_DMC */ +#define MUX_MPLL_USR_SEL_FINPLL 0 +#define MUX_MPLL_USR_SEL_MPLLFOUT 1 +#define MUX_BPLL_SEL_FINPLL 0 +#define MUX_BPLL_SEL_FOUTBPLL 1 +#define MUX_DMC_DPHY_SEL_MOUTMPLL 0 +#define MUX_DMC_DPHY_SEL_MOUTBPLL 1 +#define MUX_DMC_BUS_SEL_MOUTMPLL 0 +#define MUX_DMC_BUS_SEL_MOUTBPLL 1 +#define MUC_AUDIOCODEC_SEL_MPLL 0 +#define MUC_AUDIOCODEC_SEL_EPLL 1 +#define MUC_C2C_SEL_MPLL 0 +#define MUC_C2C_SEL_BPLL 1 +#define CLK_SRC_DMC_VAL_FINPLL ((MUX_MPLL_USR_SEL_MPLLFOUT << 12) \ + | (MUX_BPLL_SEL_FINPLL <<10) \ + | (MUX_DMC_DPHY_SEL_MOUTBPLL << 8) \ + | (MUX_DMC_BUS_SEL_MOUTBPLL<<4) \ + | (MUC_AUDIOCODEC_SEL_EPLL<<2) \ + | (MUC_C2C_SEL_MPLL<<0)) +#define CLK_SRC_DMC_VAL_FOUTBPLL ((MUX_MPLL_USR_SEL_MPLLFOUT << 12) \ + | (MUX_BPLL_SEL_FOUTBPLL <<10) \ + | (MUX_DMC_DPHY_SEL_MOUTBPLL << 8) \ + | (MUX_DMC_BUS_SEL_MOUTBPLL<<4) \ + | (MUC_AUDIOCODEC_SEL_EPLL<<2) \ + | (MUC_C2C_SEL_MPLL<<0)) + +/* CLK_DIV_DMC1 */ +#define BPLL_RATIO_PRE 0x1 +#define DMC_RATIO_SLEEP 0x3 +#define DMC_RATIO 0x1 +#define DPHY_RATIO 0x1 +#define DMC_RATIO_PRE 0x0 +#define DMCP_RATIO 0x1 +#define DMCD_RATIO 0x1 +#define AUDIOCODEC_RATIO 0xF +#define CLK_DIV_DMC1_VAL ( (DMC_RATIO << 27) \ + | (DPHY_RATIO << 23) \ + | (DMC_RATIO_PRE << 19) \ + | (DMCP_RATIO << 15) \ + | (DMCD_RATIO << 11) \ + | (AUDIOCODEC_RATIO)) +#define CLK_DIV_DMC1_VAL_SLEEP ((BPLL_RATIO_PRE << 30) \ + | (DMC_RATIO_SLEEP << 27) \ + | (DPHY_RATIO << 23) \ + | (DMC_RATIO_PRE << 19) \ + | (DMCP_RATIO << 15) \ + | (DMCD_RATIO << 11) \ + | (AUDIOCODEC_RATIO)) +#define CLK_DIV_DMC1_VAL_50M ((BPLL_RATIO_PRE << 30) \ + | (DMC_RATIO_SLEEP << 27) \ + | (DPHY_RATIO << 23) \ + | (DMC_RATIO_PRE << 19) \ + | (3 << 15) \ + | (DMCD_RATIO << 11) \ + | (AUDIOCODEC_RATIO)) + + +/********************************************************/ +/* ACP Clock +/********************************************************/ +/* CLK_SRC_ACP */ +#define MUX_G2D_ACP_SEL 0x0 +#define MUX_G2D_ACP_1_SEL 0x0 +#define MUX_G2D_ACP_0_SEL 0x0 +#define MUX_PWI_SEL 0x0 +#define MUX_MPLL_USER_ACP_SEL_FINPLL 0x0 +#define MUX_MPLL_USER_ACP_SEL_SCLKMPLL 0x1 +#define MUX_BPLL_USER_ACP_SEL_FINPLL 0x0 +#define MUX_BPLL_USER_ACP_SEL_SCLKBPLL 0x1 +#define MUX_DMC_BUS_ACP_SEL_SCLKMPLL_USER_ACP 0x0 +#define MUX_DMC_BUS_ACP_SEL_SCLKBPLL_USER_ACP 0x1 +#define CLK_SRC_ACP_VAL_0 0x00010000 +#define CLK_SRC_ACP_VAL_1 0x00012800 /*USER_ACP = Sclk*/ +/* CLK_DIV_ACP */ +#define ACP_DMC_PRE_RATIO 0x0 +#define ACP_DMCP_RATIO 0x1 +#define ACP_DMC_RATIO 0x1 +#define ACP_PCLK_RATIO 0x1 +#define ACP_RATIO 0x3 +#define CLK_DIV_ACP0_VAL ((ACP_DMC_PRE_RATIO << 16) \ + | (ACP_DMCP_RATIO << 12) \ + | (ACP_DMC_RATIO << 8) \ + | (ACP_PCLK_RATIO << 4) \ + | (ACP_RATIO << 12)) +#define ACP_PWI_RATIO 0x0 +#define ACP_G2D_RATIO 0x3 +#define CLK_DIV_ACP1_VAL ((ACP_PWI_RATIO << 5) \ + | (ACP_G2D_RATIO << 12)) +/********************************************************/ +/* TOP Clock +/********************************************************/ +/* CLK_SRC_TOP0 */ +#define MUX_EBI_SEL 0x0 /* 0 = DOUT200, 1 = DOUT160 */ +#define MUX_ACLK_266_SEL 0x0 /* 0 = SCLK_MPLL*/ +#define MUX_ACLK_160_SEL 0x0 /* 0 = SCLK_MPLL*/ +#define MUX_ACLK_100_SEL 0x0 /* 0 = SCLK_MPLL*/ +#define MUX_ACLK_200_SEL 0x0 /* 0 = SCLK_MPLL*/ +#define MUX_ACLK_266_1_SEL 0x0 /* 0 = SCLK_EPLL*/ +#define MUX_ACLK_266_0_SEL 0x0 /* 0 = SCLK_MPLL*/ +#define MUX_ACLK_266_SEL 0x0 /* 0 = ACLK_266_0*/ +#define MUX_VPLL_SEL 0x0 /* 0 = FIN*/ +#define MUX_EPLL_SEL 0x0 /* 0 = FIN*/ +#define MUX_EBI1_SEL 0x0 /* 0 = MOUTEBI*/ +#define CLK_SRC_TOP0_VAL_0 ((MUX_EBI_SEL << 28) \ + | (MUX_ACLK_200_SEL << 24) \ + | (MUX_ACLK_160_SEL << 20) \ + | (MUX_ACLK_100_SEL << 16) \ + | (MUX_ACLK_266_1_SEL << 14) \ + | (MUX_ACLK_266_0_SEL << 13) \ + | (MUX_ACLK_266_SEL << 12) \ + | (MUX_VPLL_SEL << 8) \ + | (MUX_EPLL_SEL << 4) \ + | (MUX_EBI1_SEL ) ) +#define CLK_SRC_TOP0_VAL_1 0x00000110 /*EPLL VPLL = Fout*/ + +/* CLK_SRC_TOP1 */ +#define MUX_UPLL_SEL_FIN 0x0 /*MOUT_UPLL = FIN*/ +#define MUX_UPLL_SEL_FOUTUPLL 0x1 /*MOUT_UPLL = FOUT_UPLL*/ +#define MUX_ACLK_400_MCUISP_SUB_SEL 0x1 /*= ACLK400_ISP*/ +#define MUX_ACLK_266_SUB_SEL 0x1 /*= ACLK266_ISP*/ +#define MUX_MPLL_SEL_FIN 0x0 /*MOUT_MPLL = FIN*/ +#define MUX_MPLL_SEL_FOUTMPLL 0x1 /*MOUT_MPLL = FOUT_MPLL*/ +#define MUX_ACLK_400_MCUISP_SEL 0x0 /*= SCLK_MPLL */ +#define MUX_VPLL_SRC_SEL 0x0 /*src = FIN*/ +#define CLK_SRC_TOP1_VAL_0 ((MUX_UPLL_SEL_FIN << 28) \ + | (MUX_ACLK_400_MCUISP_SUB_SEL << 24) \ + | (MUX_ACLK_266_SUB_SEL << 20) \ + | (MUX_MPLL_SEL_FIN << 12) \ + | (MUX_ACLK_400_MCUISP_SEL << 8) \ + | (MUX_VPLL_SRC_SEL ) ) +#define CLK_SRC_TOP1_VAL_1 ((MUX_UPLL_SEL_FIN << 28) \ + | (MUX_ACLK_400_MCUISP_SUB_SEL << 24) \ + | (MUX_ACLK_266_SUB_SEL << 20) \ + | (MUX_MPLL_SEL_FOUTMPLL << 12) \ + | (MUX_ACLK_400_MCUISP_SEL << 8) \ + | (MUX_VPLL_SRC_SEL ) ) + + +#define CLK_SRC_MFC_VAL 0x0 +#define CLK_SRC_G3D_VAL 0x0 +/* CLK_DIV_TOP */ +#define MPLL_RATIO_PRE 0x0 /*SCLK_MPLL = MOUTPLL/2*/ +#define ACLK_400_RATIO 0x1 +#define EBI_RATIO 0x0 +#define ACLK_200_RATIO 0x3 +#define ACLK_160_RATIO 0x4 +#define ACLK_100_RATIO 0x7 +#define ACLK_266_RATIO 0x2 +#define CLK_DIV_TOP_VAL ((MPLL_RATIO_PRE<<28)\ + | (ACLK_400_RATIO<<24)\ + | (EBI_RATIO << 16) \ + | (ACLK_200_RATIO << 12) \ + | (ACLK_160_RATIO << 8) \ + | (ACLK_100_RATIO << 4) \ + | (ACLK_266_RATIO)) +#define CLK_DIV_G3D_VAL 0x0 +#define CLK_DIV_MFC_VAL 0x0 +/********************************************************/ +/* LEFTBUS Clock +/********************************************************/ +/* CLK_SRC_LEFTBUS */ +#define MUX_MPLL_USER_L_SEL_SCLKMPLL 0x1 +#define MUX_MPLL_USER_L_SEL_FINPLL 0x0 +#define MUX_GDL_SEL 0x0 +#define CLK_SRC_LEFTBUS_VAL ((MUX_MPLL_USER_L_SEL_SCLKMPLL<<4) | (MUX_GDR_SEL)) + +/* CLK_DIV_LEFRBUS */ +#define GPL_RATIO 0x1 +#define GDL_RATIO 0x3 +#define CLK_DIV_LEFTBUS_VAL ((GPL_RATIO << 4) \ + | (GDL_RATIO)) +/********************************************************/ +/* RIGHT Clock +/********************************************************/ +/* CLK_SRC_RIGHTBUS */ +#define MUX_MPLL_USER_R_SEL 0x1 //select SLCK_MPLL +#define MUX_GDR_SEL 0x0 +#define CLK_SRC_RIGHTBUS_VAL ((MUX_MPLL_USER_R_SEL<<4) | (MUX_GDR_SEL)) + +/* CLK_DIV_RIGHTBUS */ +#define GPR_RATIO 0x1 +#define GDR_RATIO 0x3 +#define CLK_DIV_RIGHTBUS_VAL ((GPR_RATIO << 4) \ + | (GDR_RATIO)) + + +/* CLK_SRC_PERIL0 */ +#ifdef CONFIG_SMDK3250_FPGA_DEBUG +#define UART4_SEL 0 +#define UART3_SEL 0 +#define UART2_SEL 0 +#define UART1_SEL 0 +#define UART0_SEL 0 +#else +#if defined (CONFIG_SPL_BUILD) +#define UART4_SEL 0 +#define UART3_SEL 0 +#define UART2_SEL 0 +#define UART1_SEL 0 +#define UART0_SEL 0 +#else +#define UART4_SEL 6 +#define UART3_SEL 6 +#define UART2_SEL 6 +#define UART1_SEL 6 +#define UART0_SEL 6 +#endif +#endif +#define CLK_SRC_PERIL0_VAL ( (UART4_SEL << 16) \ + | (UART3_SEL << 12) \ + | (UART2_SEL<< 8) \ + | (UART1_SEL << 4) \ + | (UART0_SEL)) + + + + +/* CLK_DIV_PERIL0 */ +#ifdef CONFIG_SMDK3250_FPGA_DEBUG +#define UART4_RATIO 0 +#define UART3_RATIO 0 +#define UART2_RATIO 0 +#define UART1_RATIO 0 +#define UART0_RATIO 0 +#else +#if defined (CONFIG_SPL_BUILD) +#define UART4_RATIO 0x0 +#define UART3_RATIO 0x0 +#define UART2_RATIO 0x0 +#define UART1_RATIO 0x0 +#define UART0_RATIO 0x0 +#else +#define UART4_RATIO 0xF +#define UART3_RATIO 0xF +#define UART2_RATIO 0xF +#define UART1_RATIO 0xF +#define UART0_RATIO 0xF +#endif +#endif +#define CLK_DIV_PERIL0_VAL ( (UART4_RATIO << 16) \ + | (UART3_RATIO << 12) \ + | (UART2_RATIO << 8) \ + | (UART1_RATIO << 4) \ + | (UART0_RATIO)) + + + +/******************************************************************************* + * UART + ******************************************************************************/ +#define UART0_OFFSET 0x00000 +#define UART1_OFFSET 0x10000 +#define UART2_OFFSET 0x20000 +#define UART3_OFFSET 0x30000 + +#define EXYNOS3250_UART_BASE 0x13800000 + +#if defined(CONFIG_SERIAL0) +#define UART_CONSOLE_BASE (EXYNOS3250_UART_BASE + UART0_OFFSET) +#elif defined(CONFIG_SERIAL1) +#define UART_CONSOLE_BASE (EXYNOS3250_UART_BASE + UART1_OFFSET) +#elif defined(CONFIG_SERIAL2) +#define UART_CONSOLE_BASE (EXYNOS3250_UART_BASE + UART2_OFFSET) +#elif defined(CONFIG_SERIAL3) +#define UART_CONSOLE_BASE (EXYNOS3250_UART_BASE + UART3_OFFSET) +#else +#define UART_CONSOLE_BASE (EXYNOS3250_UART_BASE + UART0_OFFSET) +#endif + +#define ULCON_OFFSET 0x00 +#define UCON_OFFSET 0x04 +#define UFCON_OFFSET 0x08 +#define UMCON_OFFSET 0x0C +#define UTRSTAT_OFFSET 0x10 +#define UERSTAT_OFFSET 0x14 +#define UFSTAT_OFFSET 0x18 +#define UMSTAT_OFFSET 0x1C +#define UTXH_OFFSET 0x20 +#define URXH_OFFSET 0x24 +#define UBRDIV_OFFSET 0x28 +#define UDIVSLOT_OFFSET 0x2C +#define UINTP_OFFSET 0x30 +#define UINTSP_OFFSET 0x34 +#define UINTM_OFFSET 0x38 +#define UART_ERR_MASK 0xF + + +/* UART */ +#define MPLL_DEC (MPLL_MDIV * FIN / (MPLL_PDIV * 2^(MPLL_SDIV))) +#define SCLK_UART MPLL_DEC/ (UART1_RATIO+1) + +#if defined(CONFIG_SMDK3250_FPGA_DEBUG) +/* (SCLK_UART/(115200*16) -1) */ +#define UART_UBRDIV_VAL 0x5 /*115200 @ SCLK_UART = 12MHz*/ +/*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#define UART_UDIVSLOT_VAL 0x8 +#else +#if defined (CONFIG_SPL_BUILD) +#if defined (CONFIG_SYS_FIN_26) +#define UART_UBRDIV_VAL 0xD /*115200 @ SCLK_UART = 26MHz*/ +#define UART_UDIVSLOT_VAL 0x1 +#endif +#if defined (CONFIG_SYS_FIN_24) +#define UART_UBRDIV_VAL 0xC /*115200 @ SCLK_UART = 24MHz*/ +#define UART_UDIVSLOT_VAL 0x0 +#endif +#else +#if defined (CONFIG_CLK_MPLL_1600) +#define UART_UBRDIV_VAL 0x1A /*115200 @ SCLK_UART = 1600/2/16 = 50MHz*/ +#define UART_UDIVSLOT_VAL 0x2 +#endif +#endif +#endif + +#define PSHOLD_CONTROL_OFFSET 0x330C + + + +/******************************************************************************* + * End of smdk3250_val.h + ******************************************************************************/ +#endif + diff --git a/board/samsung/smdk4x12/Makefile b/board/samsung/smdk4x12/Makefile new file mode 100644 index 000000000..df0f46019 --- /dev/null +++ b/board/samsung/smdk4x12/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2012 Samsung Electronics +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +SOBJS := mem_init_smdk4x12.o +SOBJS += clock_init_smdk4x12.o +SOBJS += lowlevel_init.o +COBJS += smc.o +COBJS += pmic.o +ifndef CONFIG_SPL_BUILD +COBJS += smdk4x12.o +endif + +ifdef CONFIG_SPL_BUILD +COBJS += mmc_boot.o +endif + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +ALL := $(obj).depend $(LIB) + +ifdef CONFIG_SPL_BUILD +ALL += $(OBJTREE)/tools/mk$(BOARD)spl +endif + +all: $(ALL) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +ifdef CONFIG_SPL_BUILD +$(OBJTREE)/tools/mk$(BOARD)spl: tools/mk4x12_image.c + $(HOSTCC) tools/mk4x12_image.c -o $(OBJTREE)/tools/mk$(BOARD)spl +endif + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/smdk4x12/clock_init_smdk4x12.S b/board/samsung/smdk4x12/clock_init_smdk4x12.S new file mode 100644 index 000000000..a95845b43 --- /dev/null +++ b/board/samsung/smdk4x12/clock_init_smdk4x12.S @@ -0,0 +1,399 @@ +/* + * (C) Copyright 2012 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <config.h> + +#ifdef CONFIG_EXYNOS4412 +#include "smdk4412_val.h" +#else +#include "smdk4212_val.h" +#endif + +#define APB_DMC_0_BASE 0x10600000 +#define APB_DMC_1_BASE 0x10610000 + +#define DMC_CONCONTROL 0x00 +#define DMC_MEMCONTROL 0x04 +#define DMC_PHYCONTROL0 0x18 +#define DMC_PHYCONTROL1 0x1C +#define DMC_PHYSTATUS 0x40 + +/* + * CLOCK + */ +#define CLK_SRC_LEFTBUS_OFFSET 0x04200 +#define CLK_MUX_STAT_LEFTBUS_OFFSET 0x04400 +#define CLK_DIV_LEFTBUS_OFFSET 0x04500 + +#define CLK_SRC_RIGHTBUS_OFFSET 0x08200 +#define CLK_MUX_STAT_RIGHTBUS_OFFSET 0x08400 +#define CLK_DIV_RIGHTBUS_OFFSET 0x08500 + +#define EPLL_LOCK_OFFSET 0x0C010 +#define VPLL_LOCK_OFFSET 0x0C020 +#define EPLL_CON0_OFFSET 0x0C110 +#define EPLL_CON1_OFFSET 0x0C114 +#define EPLL_CON2_OFFSET 0x0C118 +#define VPLL_CON0_OFFSET 0x0C120 +#define VPLL_CON1_OFFSET 0x0C124 +#define VPLL_CON2_OFFSET 0x0C128 + +#define CLK_SRC_TOP0_OFFSET 0x0C210 +#define CLK_SRC_TOP1_OFFSET 0x0C214 +#define CLK_SRC_FSYS_OFFSET 0x0C240 +#define CLK_SRC_PERIL0_OFFSET 0x0C250 +#define CLK_MUX_STAT_TOP_OFFSET 0x0C410 +#define CLK_MUX_STAT_TOP1_OFFSET 0x0C414 +#define CLK_DIV_TOP_OFFSET 0x0C510 +#define CLK_DIV_FSYS1_OFFSET 0x0C544 +#define CLK_DIV_FSYS2_OFFSET 0x0C548 +#define CLK_DIV_FSYS3_OFFSET 0x0C54C +#define CLK_DIV_PERIL0_OFFSET 0x0C550 + +#define CLK_SRC_DMC_OFFSET 0x10200 +#define CLK_MUX_STAT_DMC_OFFSET 0x10400 +#define CLK_DIV_DMC0_OFFSET 0x10500 +#define CLK_DIV_DMC1_OFFSET 0x10504 + +#define CLK_GATE_IP_DMC_OFFSET 0x10900 +#define CLK_GATE_IP_PERIR_OFFSET 0x08960 + +#define APLL_LOCK_OFFSET 0x14000 +#define APLL_CON0_OFFSET 0x14100 +#define APLL_CON1_OFFSET 0x14104 + +#define MPLL_LOCK_OFFSET 0x10008 +#define MPLL_CON0_OFFSET 0x10108 +#define MPLL_CON1_OFFSET 0x1010C + +#define CLK_SRC_CPU_OFFSET 0x14200 +#define CLK_MUX_STAT_CPU_OFFSET 0x14400 +#define CLK_DIV_CPU0_OFFSET 0x14500 +#define CLK_DIV_CPU1_OFFSET 0x14504 + + +wait_mux_state: + ldr r1, [r0, r2] + cmp r1, r3 + bne wait_mux_state + mov pc, lr + +wait_pll_lock: + ldr r1, [r0, r2] + tst r1, #(1<<29) + beq wait_pll_lock + mov pc, lr + +wait_phy_state: + ldr r1, [r0, #DMC_PHYSTATUS] + tst r1, #(1<<2) + beq wait_phy_state + mov pc, lr + +#ifdef USE_2G_DRAM +check_2GB_DRAM: + ldr r6, =0x10000004 + ldr r5, [r6] + and r5, r5, #0x30 + cmp r5, #0x10 + mov pc, lr +#endif + +/* + * system_clock_init: Initialize core clock and bus clock. + * void system_clock_init(void) + */ +#define MEM_DLLl_ON + + .globl system_clock_init +system_clock_init: + push {lr} + + ldr r0, =EXYNOS4_CLOCK_BASE + +@ CMU_CPU MUX / DIV + ldr r1, =0x0 + ldr r2, =CLK_SRC_CPU_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_CPU_OFFSET + ldr r3, =0x01110001 + bl wait_mux_state + + ldr r1, =CLK_DIV_DMC0_VAL + ldr r2, =CLK_DIV_DMC0_OFFSET + str r1, [r0, r2] + ldr r1, =CLK_DIV_DMC1_VAL + ldr r2, =CLK_DIV_DMC1_OFFSET + str r1, [r0, r2] + +@ CMU_TOP MUX / DIV + ldr r1, =0x0 + ldr r2, =CLK_SRC_TOP0_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_TOP_OFFSET + ldr r3, =0x11111111 + bl wait_mux_state + + ldr r1, =0x0 + ldr r2, =CLK_SRC_TOP1_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_TOP1_OFFSET + ldr r3, =0x01111110 + bl wait_mux_state + + ldr r1, =CLK_DIV_TOP_VAL + ldr r2, =CLK_DIV_TOP_OFFSET + str r1, [r0, r2] + +@ CMU_LEFTBUS MUX / DIV + ldr r1, =0x10 + ldr r2, =CLK_SRC_LEFTBUS_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_LEFTBUS_OFFSET + ldr r3, =0x00000021 + bl wait_mux_state + + ldr r1, =CLK_DIV_LEFRBUS_VAL + ldr r2, =CLK_DIV_LEFTBUS_OFFSET + str r1, [r0, r2] + +@ CMU_RIGHTBUS MUX / DIV + ldr r1, =0x10 + ldr r2, =CLK_SRC_RIGHTBUS_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_RIGHTBUS_OFFSET + ldr r3, =0x00000021 + bl wait_mux_state + + ldr r1, =CLK_DIV_RIGHTBUS_VAL + ldr r2, =CLK_DIV_RIGHTBUS_OFFSET + str r1, [r0, r2] + +@ Set PLL locktime + ldr r1, =APLL_LOCK_VAL + ldr r2, =APLL_LOCK_OFFSET + str r1, [r0, r2] + + ldr r1, =MPLL_LOCK_VAL + ldr r2, =MPLL_LOCK_OFFSET + str r1, [r0, r2] + + ldr r1, =EPLL_LOCK_VAL + ldr r2, =EPLL_LOCK_OFFSET + str r1, [r0, r2] + + ldr r1, =VPLL_LOCK_VAL + ldr r2, =VPLL_LOCK_OFFSET + str r1, [r0, r2] + + ldr r1, =CLK_DIV_CPU0_VAL + ldr r2, =CLK_DIV_CPU0_OFFSET + str r1, [r0, r2] + ldr r1, =CLK_DIV_CPU1_VAL + ldr r2, =CLK_DIV_CPU1_OFFSET + str r1, [r0, r2] + +@ Set APLL + ldr r1, =APLL_CON1_VAL + ldr r2, =APLL_CON1_OFFSET + str r1, [r0, r2] + ldr r1, =APLL_CON0_VAL + ldr r2, =APLL_CON0_OFFSET + str r1, [r0, r2] + + /* check MPLL and if MPLL is not 400 Mhz skip MPLL resetting for C2C operation */ + ldr r2, =MPLL_CON0_OFFSET + ldr r1, [r0, r2] + ldr r3, =0xA0640301 + cmp r1, r3 + bne skip_mpll + +@ Set MPLL + ldr r1, =MPLL_CON1_VAL + ldr r2, =MPLL_CON1_OFFSET + str r1, [r0, r2] + ldr r1, =MPLL_CON0_VAL + ldr r2, =MPLL_CON0_OFFSET + str r1, [r0, r2] +skip_mpll: + +@ Set EPLL + ldr r1, =EPLL_CON2_VAL + ldr r2, =EPLL_CON2_OFFSET + str r1, [r0, r2] + ldr r1, =EPLL_CON1_VAL + ldr r2, =EPLL_CON1_OFFSET + str r1, [r0, r2] + ldr r1, =EPLL_CON0_VAL + ldr r2, =EPLL_CON0_OFFSET + str r1, [r0, r2] + +@ Set VPLL + ldr r1, =VPLL_CON2_VAL + ldr r2, =VPLL_CON2_OFFSET + str r1, [r0, r2] + ldr r1, =VPLL_CON1_VAL + ldr r2, =VPLL_CON1_OFFSET + str r1, [r0, r2] + ldr r1, =VPLL_CON0_VAL + ldr r2, =VPLL_CON0_OFFSET + str r1, [r0, r2] + + ldr r2, =APLL_CON0_OFFSET + bl wait_pll_lock + ldr r2, =MPLL_CON0_OFFSET + bl wait_pll_lock + ldr r2, =EPLL_CON0_OFFSET + bl wait_pll_lock + ldr r2, =VPLL_CON0_OFFSET + bl wait_pll_lock + + ldr r1, =0x01000001 + ldr r2, =CLK_SRC_CPU_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_CPU_OFFSET + ldr r3, =0x02110002 + bl wait_mux_state + + ldr r1, =0x00011000 + ldr r2, =CLK_SRC_DMC_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_DMC_OFFSET + ldr r3, =0x11102111 + bl wait_mux_state + + ldr r1, =0x00000110 + ldr r2, =CLK_SRC_TOP0_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_TOP_OFFSET + ldr r3, =0x11111221 + bl wait_mux_state + + /* skip MUX_ACLK_200_SUB_SEL, MUX_ACLK_400_MCUISP_SUB_SEL setting for CMU_SYSCLK_ISP function */ + ldr r1, =0x00011000 + ldr r2, =CLK_SRC_TOP1_OFFSET + str r1, [r0, r2] + + ldr r2, =CLK_MUX_STAT_TOP1_OFFSET + ldr r3, =0x01122110 + bl wait_mux_state + + ldr r0, =0x10000000 /* CHIP_ID_BASE */ + ldr r1, [r0] + lsr r1, r1, #8 + and r1, r1, #3 + cmp r1, #2 + bne SCP + + /* check C2C_CTRL enable bit */ + ldr r3, =EXYNOS4_POWER_BASE + ldr r1, [r3, #0x24] /* 0x24: C2C_CTRL_OFFSET */ + and r1, r1, #1 + cmp r1, #0 + bne SCP + +@ ConControl +#ifdef MEM_DLLl_ON + ldr r0, =APB_DMC_0_BASE + + ldr r1, =0x7F10100A + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + ldr r1, =0xE0000084 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + ldr r1, =0x7F10100B + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + bl wait_phy_state + + ldr r1, =0x0000008C + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + ldr r1, =0x00000084 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + bl wait_phy_state + + ldr r0, =APB_DMC_1_BASE + + ldr r1, =0x7F10100A + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + ldr r1, =0xE0000084 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + ldr r1, =0x7F10100B + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + bl wait_phy_state + + ldr r1, =0x0000008C + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + ldr r1, =0x00000084 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + bl wait_phy_state +#endif + + ldr r0, =APB_DMC_0_BASE + ldr r1, =0x0FFF30FA + ldr r2, =DMC_CONCONTROL + str r1, [r0, r2] + + ldr r0, =APB_DMC_1_BASE + ldr r1, =0x0FFF30FA + ldr r2, =DMC_CONCONTROL + str r1, [r0, r2] + + ldr r0, =APB_DMC_0_BASE +#ifdef USE_2G_DRAM + bl check_2GB_DRAM + ldreq r1, =0x00212533 + ldrne r1, =0x00202533 +#else + ldr r1, =0x00202533 +#endif + ldr r2, =DMC_MEMCONTROL + str r1, [r0, r2] + + ldr r0, =APB_DMC_1_BASE +#ifdef USE_2G_DRAM + bl check_2GB_DRAM + ldreq r1, =0x00212533 + ldrne r1, =0x00202533 +#else + ldr r1, =0x00202533 +#endif + ldr r2, =DMC_MEMCONTROL + str r1, [r0, r2] + +SCP: + pop {pc} + diff --git a/board/samsung/smdk4x12/lowlevel_init.S b/board/samsung/smdk4x12/lowlevel_init.S new file mode 100644 index 000000000..6ec3c3320 --- /dev/null +++ b/board/samsung/smdk4x12/lowlevel_init.S @@ -0,0 +1,338 @@ +/* + * Lowlevel setup for SMDKV310 board based on EXYNOS4210 + * + * Copyright (C) 2011 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +#ifdef CONFIG_EXYNOS4412 +#include "smdk4412_val.h" +#else +#include "smdk4212_val.h" +#endif + +/* + * Register usages: + * + * r5 has zero always + * r7 has GPIO part1 base 0x11400000 + * r6 has GPIO part2 base 0x11000000 + */ + +#define MEM_DLLl_ON + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + + .globl lowlevel_init +lowlevel_init: + /* use iROM stack in bl2 */ + ldr sp, =0x02060000 + stmdb r13!, {ip,lr} + + /* initialization for CMU_SYSCLK_ISP function */ + mov r1, #0 + ldr r0, =0x10021174 /* CMU_RESET_ISP_SYS_PWR_REG */ + str r1, [r0] + ldr r0, =0x100213B8 /* CMU_SYSCLK_ISP_SYS_PWR_REG */ + str r1, [r0] + + /* r5 has always zero */ + mov r5, #0 + ldr r7, =EXYNOS4_GPIO_PART1_BASE + ldr r6, =EXYNOS4_GPIO_PART2_BASE + + bl relocate_nscode + + /* check reset status */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + + /* Sleep wakeup reset */ + ldr r2, =S5P_CHECK_SLEEP + cmp r1, r2 + beq wakeup_reset + + /* PS-Hold high */ + ldr r0, =0x1002330c + ldr r1, [r0] + orr r1, r1, #0x300 + str r1, [r0] + + /* set CP reset to low */ + ldr r0, =0x11000C60 + ldr r1, [r0] + ldr r2, =0xFFFFFF0F + and r1, r1, r2 + orr r1, r1, #0x10 + str r1, [r0] + ldr r0, =0x11000C68 + ldr r1, [r0] + ldr r2, =0xFFFFFFF3 + and r1, r1, r2 + orr r1, r1, #0x4 + str r1, [r0] + ldr r0, =0x11000C64 + ldr r1, [r0] + ldr r2, =0xFFFFFFFD + and r1, r1, r2 + str r1, [r0] + + bl read_om + + /* + * If U-boot is already running in ram, no need to relocate U-Boot. + * Memory controller must be configured before relocating U-Boot + * in ram. + */ + ldr r0, =0x00ffffff /* r0 <- Mask Bits*/ + bic r1, pc, r0 /* pc <- current addr of code */ + /* r1 <- unmasked bits of pc */ + + ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ + bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ + cmp r1, r2 /* compare r1, r2 */ + beq 1f /* r0 == r1 then skip sdram init */ + /* and image loading */ + + bl pmic_init + + ldr r0, =0x10000000 /* CHIP_ID_BASE */ + ldr r1, [r0] + lsr r1, r1, #8 + and r1, r1, #3 + cmp r1, #2 + bne SCP + + /* Memory initialize */ + bl mem_ctrl_asm_init + + /* init system clock */ + bl system_clock_init + + b 1f + +SCP: + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_asm_init_ddr3 + +1: + /* for UART */ + bl uart_asm_init + + bl mmc_divider_change + + ldmia r13!, {ip,pc} + +wakeup_reset: + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + mov r1, #0x0 + str r1, [r0] + + bl read_om + + /* If eMMC booting */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + ldr r0, =0x10000000 /* CHIP_ID_BASE */ + ldr r1, [r0] + lsr r1, r1, #8 + and r1, r1, #3 + cmp r1, #2 + bne SCP_wake + + /* check C2C_CTRL enable bit */ + ldr r3, =EXYNOS4_POWER_BASE + ldr r1, [r3, #0x24] /* 0x24: C2C_CTRL_OFFSET */ + and r1, r1, #1 + cmp r1, #0 + bne skip_dmc + + /* Memory initialize */ + bl mem_ctrl_asm_init +skip_dmc: + /* init system clock */ + bl system_clock_init + + b exit_wakeup + +SCP_wake: + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_asm_init_ddr3 + + +exit_wakeup: + b warmboot + +read_om: + /* Read booting information */ + ldr r0, =(EXYNOS4_POWER_BASE + OM_STATUS_OFFSET) + ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC 4.4 BOOT */ + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x28 + moveq r3, #BOOT_EMMC_4_4 + + ldr r0, =(EXYNOS4_POWER_BASE + INFORM3_OFFSET) + str r3, [r0] + + mov pc, lr + +/* + * uart_asm_init: Initialize UART in asm mode, 115200bps fixed. + * void uart_asm_init(void) + */ + .globl uart_asm_init +uart_asm_init: + + /* setup UART0-UART3 GPIOs (part1) */ + mov r0, r7 + ldr r1, =0x22222222 + str r1, [r0, #0x00] @ EXYNOS4_GPIO_A0_OFFSET + ldr r1, =0x00222222 + str r1, [r0, #0x20] @ EXYNOS4_GPIO_A1_OFFSET + + ldr r0, =EXYNOS4_CLOCK_BASE + ldr r1, =CLK_SRC_PERIL0_VAL + ldr r2, =0x0C250 + str r1, [r0, r2] + ldr r1, =CLK_DIV_PERIL0_VAL + ldr r2, =0x0C550 + str r1, [r0, r2] + + ldr r0, =EXYNOS4_UART_BASE + add r0, r0, #EXYNOS4_DEFAULT_UART_OFFSET + + ldr r1, =0x3C5 + str r1, [r0, #0x4] + ldr r1, =0x111 + str r1, [r0, #0x8] + ldr r1, =0x3 + str r1, [r0, #0x0] + ldr r1, =0x35 + str r1, [r0, #0x28] + ldr r1, =0x4 + str r1, [r0, #0x2c] + + mov pc, lr + nop + nop + nop + +check_om_setting: + b check_om_setting + + +/* + * MPLL is Changed from 400MHz to 800MHz. + * So, MMC CH2, 4 divider need to change. + */ + +mmc_divider_change: + ldr r0, =EXYNOS4_CLOCK_BASE + ldr r2, =0x0C54C /* CLK_DIV_FSYS3_OFFSET */ + ldr r1, [r0, r2] + bic r1, r1, #(0xFF << 8) + bic r1, r1, #(0xF) + orr r1, r1, #(0x1 << 8) + orr r1, r1, #0x7 + str r1, [r0, r2] + ldr r2, =0x0C548 /* CLK_DIV_FSYS2_OFFSET */ + ldr r1, [r0, r2] + orr r1, r1, #0xf + str r1, [r0, r2] + + mov pc, lr + +/* + * Relocate codes for secondary core to non-secure iRAM + */ +relocate_nscode: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + dsb + isb + + mov pc, lr + + + .align 4 +nscode_base: + adr r0, _ns_reg5 + b 1f + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 + .word 0x0 @ REG4 +_ns_reg5: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6: REG_DIRECTGO_FLAG + .word 0x0 @ REG7: REG_DIRECTGO_ADDR + .word 0x0 @ REG8 + .word 0x0 @ REG9 + + nop + nop + +1: +#if defined(CONFIG_EXYNOS4412) + mrc p15, 0, r1, c0, c0, 5 @ MPIDR + and r1, r1, #0x3 + add r0, r0, r1, lsl #0x2 +#endif +cpu1_wait: + .word 0xE320F002 @ wfe instruction + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + b cpu1_wait + nop +nscode_end: diff --git a/board/samsung/smdk4x12/mem_init_smdk4x12.S b/board/samsung/smdk4x12/mem_init_smdk4x12.S new file mode 100644 index 000000000..e06a31438 --- /dev/null +++ b/board/samsung/smdk4x12/mem_init_smdk4x12.S @@ -0,0 +1,755 @@ +/* + * (C) Copyright 2012 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <config.h> + +#if defined(USE_512MB_DRAM) +#define IV_SIZE 0x1E +#else +#define IV_SIZE 0x7 +#endif + +#define APB_DMC_0_BASE 0x10600000 +#define APB_DMC_1_BASE 0x10610000 + +#define DMC_CONCONTROL 0x00 +#define DMC_MEMCONTROL 0x04 +#define DMC_MEMCONFIG0 0x08 +#define DMC_MEMCONFIG1 0x0C +#define DMC_DIRECTCMD 0x10 +#define DMC_PRECHCONFIG 0x14 +#define DMC_PHYCONTROL0 0x18 +#define DMC_PHYCONTROL1 0x1C +#define DMC_PHYCONTROL2 0x20 +#define DMC_PWRDNCONFIG 0x28 +#define DMC_TIMINGAREF 0x30 +#define DMC_TIMINGROW 0x34 +#define DMC_TIMINGDATA 0x38 +#define DMC_TIMINGPOWER 0x3C +#define DMC_PHYSTATUS 0x40 +#define DMC_PHYZQCONTROL 0x44 +#define DMC_CHIP0STATUS 0x48 +#define DMC_CHIP1STATUS 0x4C +#define DMC_AREFSTATUS 0x50 +#define DMC_MRSTATUS 0x54 +#define DMC_PHYTEST0 0x58 +#define DMC_PHYTEST1 0x5C +#define DMC_QOSCONTROL0 0x60 +#define DMC_QOSCONFIG0 0x64 +#define DMC_QOSCONTROL1 0x68 +#define DMC_QOSCONFIG1 0x6C +#define DMC_QOSCONTROL2 0x70 +#define DMC_QOSCONFIG2 0x74 +#define DMC_QOSCONTROL3 0x78 +#define DMC_QOSCONFIG3 0x7C +#define DMC_QOSCONTROL4 0x80 +#define DMC_QOSCONFIG4 0x84 +#define DMC_QOSCONTROL5 0x88 +#define DMC_QOSCONFIG5 0x8C +#define DMC_QOSCONTROL6 0x90 +#define DMC_QOSCONFIG6 0x94 +#define DMC_QOSCONTROL7 0x98 +#define DMC_QOSCONFIG7 0x9C +#define DMC_QOSCONTROL8 0xA0 +#define DMC_QOSCONFIG8 0xA4 +#define DMC_QOSCONTROL9 0xA8 +#define DMC_QOSCONFIG9 0xAC +#define DMC_QOSCONTROL10 0xB0 +#define DMC_QOSCONFIG10 0xB4 +#define DMC_QOSCONTROL11 0xB8 +#define DMC_QOSCONFIG11 0xBC +#define DMC_QOSCONTROL12 0xC0 +#define DMC_QOSCONFIG12 0xC4 +#define DMC_QOSCONTROL13 0xC8 +#define DMC_QOSCONFIG13 0xCC +#define DMC_QOSCONTROL14 0xD0 +#define DMC_QOSCONFIG14 0xD4 +#define DMC_QOSCONTROL15 0xD8 +#define DMC_QOSCONFIG15 0xDC +#define DMC_IVCONTROL 0xF0 + +/* + * MIU + */ +#define MIU_BASE 0x10600000 +#define MIU_INTLV_CONFIG 0x400 +#define MIU_INTLV_START_ADDR 0x808 +#define MIU_MAPPING_UPDATE 0x800 +#define MIU_INTLV_END_ADDR 0x810 + +#define MIU_SINGLE_MAPPING0_START_ADDR 0x818 +#define MIU_SINGLE_MAPPING0_END_ADDR 0x820 +#define MIU_SINGLE_MAPPING1_START_ADDR 0x828 +#define MIU_SINGLE_MAPPING1_END_ADDR 0x830 + + +wait_phy_state: + ldr r1, [r0, #DMC_PHYSTATUS] + tst r1, #(1<<2) + beq wait_phy_state + mov pc, lr + +dmc_delay: + push {lr} +1: subs r2, r2, #1 + bne 1b + pop {pc} + + .globl mem_ctrl_asm_init +mem_ctrl_asm_init: + push {lr} + + /* CLK_DIV_DMC0 on iROM DMC=50MHz for Init DMC */ + ldr r0, =0x10030000 + ldr r1, =0x00117713 + ldr r2, =0x10500 /* CLK_DIV_DMC0_OFFSET */ + str r1, [r0, r2] + +/*****************************************************************/ +/*DREX0***********************************************************/ +/*****************************************************************/ + + ldr r0, =APB_DMC_0_BASE + +#ifdef USE_512MB_DRAM + ldr r1, =0xE3855503 + str r1, [r0, #DMC_PHYZQCONTROL] +#else + ldr r1, =0xE3855403 + str r1, [r0, #DMC_PHYZQCONTROL] +#endif + + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x7110100A + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x00000084 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x0000008C + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x00000084 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x0000008C + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x00000084 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x0FFF30CA + str r1, [r0, #DMC_CONCONTROL] + +#ifdef USE_2G_DRAM + ldr r1, =0x00212500 +#else + ldr r1, =0x00202500 +#endif + str r1, [r0, #DMC_MEMCONTROL] + + ldr r1, =0x40C01323 + str r1, [r0, #DMC_MEMCONFIG0] + +#ifdef USE_2G_DRAM + ldr r1, =0x80C01323 + str r1, [r0, #DMC_MEMCONFIG1] +#endif + + ldr r1, =(0x80000000 | IV_SIZE) + str r1, [r0, #DMC_IVCONTROL] + + ldr r1, =0x64000000 + str r1, [r0, #DMC_PRECHCONFIG] + + ldr r1, =0x9C4000FF + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x0000005D + str r1, [r0, #DMC_TIMINGAREF] @TimingAref + +#if defined(CONFIG_CLK_BUS_DMC_200_400) + ldr r1, =0x34498691 + str r1, [r0, #DMC_TIMINGROW] @TimingRow + ldr r1, =0x36330306 + str r1, [r0, #DMC_TIMINGDATA] @TimingData + ldr r1, =0x50380365 + str r1, [r0, #DMC_TIMINGPOWER] @TimingPower +#elif defined(CONFIG_CLK_BUS_DMC_220_440) + ldr r1, =0x3A5A8713 + str r1, [r0, #DMC_TIMINGROW] @TimingRow + ldr r1, =0x47400407 + str r1, [r0, #DMC_TIMINGDATA] @TimingData + ldr r1, =0x583E0475 + str r1, [r0, #DMC_TIMINGPOWER] @TimingPower +#endif + + /* minimum wait time is 100 nano seconds */ + /* 0x64: wait 250 nano seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x64 + bl dmc_delay + + ldr r1, =0x07000000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 200 micro seconds */ + /* 0x19000: wait 250 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x19000 + bl dmc_delay + + ldr r1, =0x00071C00 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 20 micro seconds */ + /* 0x2700: wait 25 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x2700 + bl dmc_delay + + ldr r1, =0x00010BFC + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 1 micro seconds */ + /* 0x3f0: wait 2.5 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x3f0 + bl dmc_delay + +#if defined(CONFIG_CLK_BUS_DMC_200_400) + ldr r1, =0x00000608 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00000810 + str r1, [r0, #DMC_DIRECTCMD] +#elif defined(CONFIG_CLK_BUS_DMC_220_440) + ldr r1, =0x00000808 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00000814 + str r1, [r0, #DMC_DIRECTCMD] +#endif + ldr r1, =0x00000C08 + str r1, [r0, #DMC_DIRECTCMD] + +#ifdef USE_2G_DRAM + mov r2, #0x64 + bl dmc_delay + + ldr r1, =0x07100000 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x19000 + bl dmc_delay + + ldr r1, =0x00171C00 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x2700 + bl dmc_delay + + ldr r1, =0x00110BFC + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + +#if defined(CONFIG_CLK_BUS_DMC_200_400) + ldr r1, =0x00100608 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00100810 + str r1, [r0, #DMC_DIRECTCMD] +#elif defined(CONFIG_CLK_BUS_DMC_220_440) + ldr r1, =0x00100808 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00100814 + str r1, [r0, #DMC_DIRECTCMD] +#endif + ldr r1, =0x00100C08 + str r1, [r0, #DMC_DIRECTCMD] +#endif + +/*****************************************************************/ +/*DREX1***********************************************************/ +/*****************************************************************/ + ldr r0, =APB_DMC_1_BASE + +#ifdef USE_512MB_DRAM + ldr r1, =0xE3855503 + str r1, [r0, #DMC_PHYZQCONTROL] +#else + ldr r1, =0xE3855403 + str r1, [r0, #DMC_PHYZQCONTROL] +#endif + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x7110100A + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x00000084 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x0000008C + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x00000084 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x0000008C + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x00000084 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x0FFF30CA + str r1, [r0, #DMC_CONCONTROL] + +#ifdef USE_2G_DRAM + ldr r1, =0x00212500 +#else + ldr r1, =0x00202500 +#endif + str r1, [r0, #DMC_MEMCONTROL] + + ldr r1, =0x40C01323 + str r1, [r0, #DMC_MEMCONFIG0] + +#ifdef USE_2G_DRAM + ldr r1, =0x80C01323 + str r1, [r0, #DMC_MEMCONFIG1] +#endif + ldr r1, =(0x80000000 | IV_SIZE) + str r1, [r0, #DMC_IVCONTROL] + + ldr r1, =0x64000000 + str r1, [r0, #DMC_PRECHCONFIG] + + ldr r1, =0x9C4000FF + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x0000005D + str r1, [r0, #DMC_TIMINGAREF] @TimingAref + +#if defined(CONFIG_CLK_BUS_DMC_200_400) + ldr r1, =0x34498691 + str r1, [r0, #DMC_TIMINGROW] @TimingRow + ldr r1, =0x36330306 + str r1, [r0, #DMC_TIMINGDATA] @TimingData + ldr r1, =0x50380365 + str r1, [r0, #DMC_TIMINGPOWER] @TimingPower +#elif defined(CONFIG_CLK_BUS_DMC_220_440) + ldr r1, =0x3A5A8713 + str r1, [r0, #DMC_TIMINGROW] @TimingRow + ldr r1, =0x47400407 + str r1, [r0, #DMC_TIMINGDATA] @TimingData + ldr r1, =0x583E0475 + str r1, [r0, #DMC_TIMINGPOWER] @TimingPower +#endif + + /* minimum wait time is 100 nano seconds */ + /* 0x64: wait 250 nano seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x64 + bl dmc_delay + + ldr r1, =0x07000000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 200 micro seconds */ + /* 0x19000: wait 250 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x19000 + bl dmc_delay + + ldr r1, =0x00071C00 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 20 micro seconds */ + /* 0x2700: wait 25 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x2700 + bl dmc_delay + + ldr r1, =0x00010BFC + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 1 micro seconds */ + /* 0x3f0: wait 2.5 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x3f0 + bl dmc_delay + +#if defined(CONFIG_CLK_BUS_DMC_200_400) + ldr r1, =0x00000608 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00000810 + str r1, [r0, #DMC_DIRECTCMD] +#elif defined(CONFIG_CLK_BUS_DMC_220_440) + ldr r1, =0x00000808 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00000814 + str r1, [r0, #DMC_DIRECTCMD] +#endif + ldr r1, =0x00000C08 + str r1, [r0, #DMC_DIRECTCMD] + +#ifdef USE_2G_DRAM + mov r2, #0x64 + bl dmc_delay + + ldr r1, =0x07100000 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x19000 + bl dmc_delay + + ldr r1, =0x00171C00 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x2700 + bl dmc_delay + + ldr r1, =0x00110BFC + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + +#if defined(CONFIG_CLK_BUS_DMC_200_400) + ldr r1, =0x00100608 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00100810 + str r1, [r0, #DMC_DIRECTCMD] +#elif defined(CONFIG_CLK_BUS_DMC_220_440) + ldr r1, =0x00100808 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00100814 + str r1, [r0, #DMC_DIRECTCMD] +#endif + ldr r1, =0x00100C08 + str r1, [r0, #DMC_DIRECTCMD] +#endif + + pop {pc} + + .globl mem_ctrl_asm_init_ddr3 +mem_ctrl_asm_init_ddr3: + push {lr} + +/*****************************************************************/ +/*DREX0***********************************************************/ +/*****************************************************************/ + + ldr r0, =APB_DMC_0_BASE + + ldr r1, =0x0 + str r1, [r0, #DMC_PHYCONTROL2] + + ldr r1, =0x0 + str r1, [r0, #0x24] + + ldr r1, =0xE3855503 + str r1, [r0, #DMC_PHYZQCONTROL] + + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x7110100A + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x20000086 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x2000008E + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x20000086 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x2000008E + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x20000086 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x0FFF30CA + str r1, [r0, #DMC_CONCONTROL] + + ldr r1, =0x00302600 + str r1, [r0, #DMC_MEMCONTROL] + + ldr r1, =0x40C01323 + str r1, [r0, #DMC_MEMCONFIG0] + + ldr r1, =(0x80000000 | IV_SIZE) + str r1, [r0, #DMC_IVCONTROL] + + ldr r1, =0x64000000 + str r1, [r0, #DMC_PRECHCONFIG] + + ldr r1, =0x9C4000FF + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x000000BB + str r1, [r0, #DMC_TIMINGAREF] @TimingAref + + ldr r1, =0x4046654F + str r1, [r0, #DMC_TIMINGROW] @TimingRow + ldr r1, =0x46400506 + str r1, [r0, #DMC_TIMINGDATA] @TimingData + ldr r1, =0x52000A3C + str r1, [r0, #DMC_TIMINGPOWER] @TimingPower + + /* minimum wait time is 100 nano seconds */ + /* 0x64: wait 250 nano seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x64 + bl dmc_delay + + ldr r1, =0x07000000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 200 micro seconds */ + /* 0x19000: wait 250 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x19000 + bl dmc_delay + + ldr r1, =0x00020000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 20 micro seconds */ + /* 0x2700: wait 25 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x2700 + bl dmc_delay + + ldr r1, =0x00030000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 1 micro seconds */ + /* 0x3f0: wait 2.5 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x3f0 + bl dmc_delay + + ldr r1, =0x00010000 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00000100 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + + ldr r1, =0x00000420 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + + ldr r1, =0x0A000000 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + +/*****************************************************************/ +/*DREX1***********************************************************/ +/*****************************************************************/ + ldr r0, =APB_DMC_1_BASE + + ldr r1, =0x0 + str r1, [r0, #DMC_PHYCONTROL2] + + ldr r1, =0x0 + str r1, [r0, #0x24] + + ldr r1, =0xE3855503 + str r1, [r0, #DMC_PHYZQCONTROL] + + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x7110100A + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x20000086 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x71101008 + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x2000008E + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x20000086 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x2000008E + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x20000086 + str r1, [r0, #DMC_PHYCONTROL1] + + ldr r1, =0x0FFF30CA + str r1, [r0, #DMC_CONCONTROL] + + ldr r1, =0x00302600 + str r1, [r0, #DMC_MEMCONTROL] + + ldr r1, =0x40C01323 + str r1, [r0, #DMC_MEMCONFIG0] + + ldr r1, =(0x80000000 | IV_SIZE) + str r1, [r0, #DMC_IVCONTROL] + + ldr r1, =0x64000000 + str r1, [r0, #DMC_PRECHCONFIG] + + ldr r1, =0x9C4000FF + str r1, [r0, #DMC_PHYCONTROL0] + + ldr r1, =0x000000BB + str r1, [r0, #DMC_TIMINGAREF] @TimingAref + + ldr r1, =0x4046654F + str r1, [r0, #DMC_TIMINGROW] @TimingRow + ldr r1, =0x46400506 + str r1, [r0, #DMC_TIMINGDATA] @TimingData + ldr r1, =0x52000A3C + str r1, [r0, #DMC_TIMINGPOWER] @TimingPower + + /* minimum wait time is 100 nano seconds */ + /* 0x64: wait 250 nano seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x64 + bl dmc_delay + + ldr r1, =0x07000000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 200 micro seconds */ + /* 0x19000: wait 250 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x19000 + bl dmc_delay + + ldr r1, =0x00020000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 20 micro seconds */ + /* 0x2700: wait 25 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x2700 + bl dmc_delay + + ldr r1, =0x00030000 + str r1, [r0, #DMC_DIRECTCMD] + + /* minimum wait time is 1 micro seconds */ + /* 0x3f0: wait 2.5 micro seconds at ARMCLK 1.5 Ghz */ + mov r2, #0x3f0 + bl dmc_delay + + ldr r1, =0x00010000 + str r1, [r0, #DMC_DIRECTCMD] + ldr r1, =0x00000100 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + + ldr r1, =0x00000420 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + + ldr r1, =0x0A000000 + str r1, [r0, #DMC_DIRECTCMD] + + mov r2, #0x3f0 + bl dmc_delay + + + ldr r0, =APB_DMC_0_BASE + + ldr r1, =0x7110100A + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + ldr r1, =0x20000086 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + ldr r1, =0x7110100B + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + bl wait_phy_state + + ldr r1, =0x2000008E + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + ldr r1, =0x20000086 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + bl wait_phy_state + + ldr r0, =APB_DMC_1_BASE + + ldr r1, =0x7110100A + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + ldr r1, =0x20000086 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + ldr r1, =0x7110100B + ldr r2, =DMC_PHYCONTROL0 + str r1, [r0, r2] + + bl wait_phy_state + + ldr r1, =0x2000008E + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + ldr r1, =0x20000086 + ldr r2, =DMC_PHYCONTROL1 + str r1, [r0, r2] + + bl wait_phy_state + + ldr r0, =APB_DMC_0_BASE + ldr r2, =DMC_CONCONTROL + ldr r1, [r0, r2] + orr r1, r1, #(1 << 5) + str r1, [r0, r2] + + ldr r0, =APB_DMC_1_BASE + ldr r2, =DMC_CONCONTROL + ldr r1, [r0, r2] + orr r1, r1, #(1 << 5) + str r1, [r0, r2] + + ldr r0, =APB_DMC_0_BASE + ldr r2, =DMC_MEMCONTROL + ldr r1, [r0, r2] + orr r1, r1, #((1 << 4) | (1 << 1) | (1 << 0)) + str r1, [r0, r2] + + ldr r0, =APB_DMC_1_BASE + ldr r2, =DMC_MEMCONTROL + ldr r1, [r0, r2] + orr r1, r1, #((1 << 4) | (1 << 1) | (1 << 0)) + str r1, [r0, r2] + + pop {pc} + diff --git a/board/samsung/smdk4x12/mmc_boot.c b/board/samsung/smdk4x12/mmc_boot.c new file mode 100644 index 000000000..b5c235ed0 --- /dev/null +++ b/board/samsung/smdk4x12/mmc_boot.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * 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<config.h> + +#define SDMMC_SECOND_DEV 0x28 /* 1st_dev: eMMC, 2nd_dev: SD/MMC */ +#define SECOND_BOOT_MODE 0xFEED0002 +#define UBOOT 0x1 +#define TZSW 0x2 +#define SIGNATURE_CHECK_FAIL -1 + +/* find boot device for secondary booting */ +static int find_second_boot_dev(void) +{ + unsigned int om_status = readl(EXYNOS4_POWER_BASE + OM_STATUS_OFFSET); + + om_status &= 0x3E; + + writel(0x1, CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (om_status == SDMMC_SECOND_DEV) + return BOOT_SEC_DEV; + else + return -1; +} + +static unsigned int device(unsigned int dev) +{ + if ((dev == BOOT_MMCSD) || (dev == BOOT_SEC_DEV)) + return SDMMC_CH2; + else if (dev == BOOT_EMMC_4_4) + return EMMC_4_4; + else + while(1); +} + +static int ld_image_from_2nd_dev(int image) +{ + int ret = 0; + unsigned int boot_dev = 0; + + boot_dev = find_second_boot_dev(); + + /* sdmmc enumerate */ + if (device(boot_dev) == SDMMC_CH2) + sdmmc_enumerate(); + + switch (image) { + + case UBOOT: + /* load uboot from 2nd dev */ + ret = load_uboot_image(device(boot_dev)); + break; + case TZSW: + /* load uboot from 2nd dev */ + ret = coldboot(device(boot_dev)); + break; + defalut: + ret = SIGNATURE_CHECK_FAIL; + break; + } + + if (ret == SIGNATURE_CHECK_FAIL) + while(1); + + return boot_dev; +} + +void load_uboot(void) +{ + unsigned int om_status = readl(EXYNOS4_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + int ret = 0; + + /* verify recovery boot mode */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + /* Load u-boot image to ram */ + ret = load_uboot_image(device(boot_dev)); + if (ret == SIGNATURE_CHECK_FAIL) + boot_dev = ld_image_from_2nd_dev(UBOOT); + + /* Load tzsw image & U-Boot boot */ + ret = coldboot(device(boot_dev)); + if (ret == SIGNATURE_CHECK_FAIL) + ld_image_from_2nd_dev(TZSW); + +} + +void board_init_f(unsigned long bootflag) +{ + __attribute__((noreturn)) void (*uboot)(void); + + /* Jump to U-Boot image */ + load_uboot(); + /* Never returns Here */ +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /*Function attribute is no-return*/ + /*This Function never executes*/ + while (1) + ; +} + +void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) +{ +} diff --git a/board/samsung/smdk4x12/pmic.c b/board/samsung/smdk4x12/pmic.c new file mode 100644 index 000000000..4da5fa44e --- /dev/null +++ b/board/samsung/smdk4x12/pmic.c @@ -0,0 +1,726 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include "pmic.h" + +void Delay(void) +{ + unsigned long i; + for(i=0;i<DELAY;i++); +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC1_SCLH_SDAH(void) +{ + IIC1_ESCL_Hi; + IIC1_ESDA_Hi; + Delay(); +} + +void IIC1_SCLH_SDAL(void) +{ + IIC1_ESCL_Hi; + IIC1_ESDA_Lo; + Delay(); +} + +void IIC1_SCLL_SDAH(void) +{ + IIC1_ESCL_Lo; + IIC1_ESDA_Hi; + Delay(); +} + +void IIC1_SCLL_SDAL(void) +{ + IIC1_ESCL_Lo; + IIC1_ESDA_Lo; + Delay(); +} + +void IIC3_SCLH_SDAH(void) +{ + IIC3_ESCL_Hi; + IIC3_ESDA_Hi; + Delay(); +} + +void IIC3_SCLH_SDAL(void) +{ + IIC3_ESCL_Hi; + IIC3_ESDA_Lo; + Delay(); +} + +void IIC3_SCLL_SDAH(void) +{ + IIC3_ESCL_Lo; + IIC3_ESDA_Hi; + Delay(); +} + +void IIC3_SCLL_SDAL(void) +{ + IIC3_ESCL_Lo; + IIC3_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC1_ELow(void) +{ + IIC1_SCLL_SDAL(); + IIC1_SCLH_SDAL(); + IIC1_SCLH_SDAL(); + IIC1_SCLL_SDAL(); +} + +void IIC1_EHigh(void) +{ + IIC1_SCLL_SDAH(); + IIC1_SCLH_SDAH(); + IIC1_SCLH_SDAH(); + IIC1_SCLL_SDAH(); +} + +void IIC3_ELow(void) +{ + IIC3_SCLL_SDAL(); + IIC3_SCLH_SDAL(); + IIC3_SCLH_SDAL(); + IIC3_SCLL_SDAL(); +} + +void IIC3_EHigh(void) +{ + IIC3_SCLL_SDAH(); + IIC3_SCLH_SDAH(); + IIC3_SCLH_SDAH(); + IIC3_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + IIC0_ESDA_INP; // Function <- Input + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPD1DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + ack = (ack>>0)&0x1; +// while(ack!=0); + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + IIC0_ESDA_OUTP; // Function <- Output + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + //IIC0_ESDA_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + + IIC0_ESDA_INP; // Function <- Input (SDA) + + IIC0_SCLL_SDAL(); +} + +void IIC1_EStart(void) +{ + IIC1_SCLH_SDAH(); + IIC1_SCLH_SDAL(); + Delay(); + IIC1_SCLL_SDAL(); +} + +void IIC1_EEnd(void) +{ + IIC1_SCLL_SDAL(); + IIC1_SCLH_SDAL(); + Delay(); + IIC1_SCLH_SDAH(); +} + +void IIC1_EAck(void) +{ + unsigned long ack; + + IIC1_ESDA_INP; // Function <- Input + + IIC1_ESCL_Lo; + Delay(); + IIC1_ESCL_Hi; + Delay(); + ack = GPD1DAT; + IIC1_ESCL_Hi; + Delay(); + IIC1_ESCL_Hi; + Delay(); + + IIC1_ESDA_OUTP; // Function <- Output (SDA) + + ack = (ack>>2)&0x1; +// while(ack!=0); + + IIC1_SCLL_SDAL(); +} + +void IIC3_EStart(void) +{ + IIC3_SCLH_SDAH(); + IIC3_SCLH_SDAL(); + Delay(); + IIC3_SCLL_SDAL(); +} + +void IIC3_EEnd(void) +{ + IIC3_SCLL_SDAL(); + IIC3_SCLH_SDAL(); + Delay(); + IIC3_SCLH_SDAH(); +} + +void IIC3_EAck(void) +{ + unsigned long ack; + + IIC3_ESDA_INP; // Function <- Input + + IIC3_ESCL_Lo; + Delay(); + IIC3_ESCL_Hi; + Delay(); + ack = GPA1DAT; + IIC3_ESCL_Hi; + Delay(); + IIC3_ESCL_Hi; + Delay(); + + IIC3_ESDA_OUTP; // Function <- Output (SDA) + + ack = (ack>>2)&0x1; +// while(ack!=0); + + IIC3_SCLL_SDAL(); +} + + +void IIC0_ESetport(void) +{ + GPD1PUD &= ~(0xf<<0); // Pull Up/Down Disable SCL, SDA + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + IIC0_ESCL_OUTP; // Function <- Output (SCL) + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + Delay(); +} + +void IIC1_ESetport(void) +{ + GPD1PUD &= ~(0xf<<4); // Pull Up/Down Disable SCL, SDA + + IIC1_ESCL_Hi; + IIC1_ESDA_Hi; + + IIC1_ESCL_OUTP; // Function <- Output (SCL) + IIC1_ESDA_OUTP; // Function <- Output (SDA) + + Delay(); +} + +void IIC3_ESetport(void) +{ + GPA1PUD &= ~(0xf<<4); // Pull Up/Down Disable SCL, SDA + + IIC3_ESCL_Hi; + IIC3_ESDA_Hi; + + IIC3_ESCL_OUTP; // Function <- Output (SCL) + IIC3_ESDA_OUTP; // Function <- Output (SDA) + + Delay(); +} + +void IIC0_EWrite (unsigned char ChipId, unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + +////////////////// write reg. data. ////////////////// + for(i = 8; i>0; i--) + { + if((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EEnd(); +} + +void IIC0_ERead (unsigned char ChipId, unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EHigh(); // read + + IIC0_EAck_write(); // ACK + +////////////////// read reg. data. ////////////////// + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for(i = 8; i>0; i--) + { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPD1DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + reg = (reg >> 0) & 0x1; + data |= reg << (i-1); + } + + IIC0_EAck_read(); // ACK + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + + +void IIC1_EWrite (unsigned char ChipId, unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC1_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC1_EHigh(); + else + IIC1_ELow(); + } + + IIC1_ELow(); // write 'W' + + IIC1_EAck(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC1_EHigh(); + else + IIC1_ELow(); + } + + IIC1_EAck(); // ACK + +////////////////// write reg. data. ////////////////// + for(i = 8; i>0; i--) + { + if((IicData >> (i-1)) & 0x0001) + IIC1_EHigh(); + else + IIC1_ELow(); + } + + IIC1_EAck(); // ACK + + IIC1_EEnd(); +} + +void IIC3_EWrite (unsigned char ChipId, unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC3_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC3_EHigh(); + else + IIC3_ELow(); + } + + IIC3_ELow(); // write 'W' + + IIC3_EAck(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC3_EHigh(); + else + IIC3_ELow(); + } + + IIC3_EAck(); // ACK + +////////////////// write reg. data. ////////////////// + for(i = 8; i>0; i--) + { + if((IicData >> (i-1)) & 0x0001) + IIC3_EHigh(); + else + IIC3_ELow(); + } + + IIC3_EAck(); // ACK + + IIC3_EEnd(); +} + + +void I2C_MAX8997_VolSetting(PMIC_RegNum eRegNum, u8 ucVolLevel, u8 ucEnable) +{ + u8 reg_addr, reg_bitpos, reg_bitmask, vol_level; + u8 read_data; + + reg_bitpos = 0; + reg_bitmask = 0x3F; + if(eRegNum == 0) + { + reg_addr = 0x19; + } + else if(eRegNum == 1) + { + reg_addr = 0x22; + } + else if(eRegNum == 2) + { + reg_addr = 0x2B; + } + else if(eRegNum == 3) + { + reg_addr = 0x2D; + } + else if(eRegNum == 4) + { + reg_addr = 0x48; + } + else if(eRegNum == 5) + { + reg_addr = 0x44; + } + else + while(1); + + vol_level = ucVolLevel®_bitmask; + + IIC0_ERead(MAX8997_ADDR, reg_addr, &read_data); + + read_data = (read_data & (~(reg_bitmask<<reg_bitpos))) | (vol_level<<reg_bitpos); + + IIC0_EWrite(MAX8997_ADDR, reg_addr, read_data); + + I2C_MAX8997_EnableReg(eRegNum, ucEnable); +} + +void I2C_MAX8997_EnableReg(PMIC_RegNum eRegNum, u8 ucEnable) +{ + u8 reg_addr, reg_bitpos; + u8 read_data; + + reg_bitpos = 0; + if(eRegNum == 0) + { + reg_addr = 0x18; + } + else if(eRegNum == 1) + { + reg_addr = 0x21; + } + else if(eRegNum == 2) + { + reg_addr = 0x2A; + } + else if(eRegNum == 3) + { + reg_addr = 0x2C; + } + else if(eRegNum == 4) + { + reg_addr = 0x48; + reg_bitpos = 0x6; + } + else if(eRegNum == 5) + { + reg_addr = 0x44; + reg_bitpos = 0x6; + } + + else + while(1); + + IIC0_ERead(MAX8997_ADDR, reg_addr, &read_data); + + read_data = (read_data & (~(1<<reg_bitpos))) | (ucEnable<<reg_bitpos); + + IIC0_EWrite(MAX8997_ADDR, reg_addr, read_data); +} + +#define CALC_S5M8767_BUCK234_VOLT(x) ( (x<600) ? 0 : ((x-600)/6.25) ) +#define CALC_S5M8767_BUCK156_VOLT(x) ( (x<650) ? 0 : ((x-650)/6.25) ) + +void I2C_S5M8767_VolSetting(PMIC_RegNum eRegNum, unsigned char ucVolLevel, unsigned char ucEnable) +{ + unsigned char reg_addr, reg_bitpos, reg_bitmask, vol_level; + + reg_bitpos = 0; + reg_bitmask = 0xFF; + if(eRegNum == 0) + { + reg_addr = 0x33; + } + else if(eRegNum == 1) + { + reg_addr = 0x35; + } + else if(eRegNum == 2) + { + reg_addr = 0x3E; + } + else if(eRegNum == 3) + { + reg_addr = 0x47; + } + else if(eRegNum == 4) + { + reg_addr = 0x50; + } + else + while(1); + + vol_level = ucVolLevel®_bitmask; + IIC0_EWrite(S5M8767_ADDR, reg_addr, vol_level); +} + + +void pmic_init(void) +{ + float vdd_arm, vdd_int, vdd_g3d; + float vdd_mif; + float vdd_ldo14; + + u8 read_data; + + vdd_arm = CONFIG_PM_VDD_ARM; + vdd_int = CONFIG_PM_VDD_INT; + vdd_g3d = CONFIG_PM_VDD_G3D; + vdd_mif = CONFIG_PM_VDD_MIF; + vdd_ldo14 = CONFIG_PM_VDD_LDO14; + + IIC0_ESetport(); + IIC3_ESetport(); + + /* read ID */ + IIC0_ERead(MAX8997_ADDR, 0, &read_data); + if (read_data == 0x77) { + I2C_MAX8997_VolSetting(PMIC_BUCK1, CALC_MAXIM_BUCK1245_VOLT(vdd_arm * 1000), 1); + I2C_MAX8997_VolSetting(PMIC_BUCK2, CALC_MAXIM_BUCK1245_VOLT(vdd_int * 1000), 1); + I2C_MAX8997_VolSetting(PMIC_BUCK3, CALC_MAXIM_BUCK37_VOLT(vdd_g3d * 1000), 1); + + /* LDO14 config */ + I2C_MAX8997_VolSetting(PMIC_LDO14, CALC_MAXIM_ALL_LDO(vdd_ldo14 * 1000), 3); + + /* VDD_MIF, mode 1 register */ + IIC3_EWrite(MAX8952_ADDR, 0x01, 0x80 | (((unsigned char)(vdd_mif * 100))-77)); + } else if((0 <= read_data) && (read_data <= 0x5)) { + I2C_S5M8767_VolSetting(PMIC_BUCK1, CALC_S5M8767_BUCK156_VOLT(vdd_mif * 1000), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK2, CALC_S5M8767_BUCK234_VOLT(vdd_arm * 1000), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK3, CALC_S5M8767_BUCK234_VOLT(vdd_int * 1000), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK4, CALC_S5M8767_BUCK234_VOLT(vdd_g3d * 1000), 1); + + IIC0_EWrite(S5M8767_ADDR, 0x5A, 0x58); + } else { + /* set DVS1,2,3 as 0 by GPL0 */ + *((volatile unsigned int *)0x110000c0) = 0x11111111; + *((volatile unsigned int *)0x110000c4) = 0x7; + *((volatile unsigned int *)0x110000c4) = 0x0; + *((volatile unsigned int *)0x110000c4) = 0x7; + *((volatile unsigned int *)0x110000c4) = 0x0; + *((volatile unsigned int *)0x110000c0) = 0x0; + + /* VDD_MIF */ + IIC0_EWrite(MAX77686_ADDR, 0x11, CALC_MAXIM77686_BUCK156789_VOLT(vdd_mif * 1000)); + /* VDD_ARM */ + IIC0_EWrite(MAX77686_ADDR, 0x14, CALC_MAXIM77686_BUCK234_VOLT(vdd_arm * 1000)); + /* VDD_INT */ + IIC0_EWrite(MAX77686_ADDR, 0x1E, CALC_MAXIM77686_BUCK234_VOLT(vdd_int * 1000)); + /* VDD_G3D */ + IIC0_EWrite(MAX77686_ADDR, 0x28, CALC_MAXIM77686_BUCK234_VOLT(vdd_g3d * 1000)); + } + + GPA1PUD |= (0x5<<4); // restore reset value: Pull Up/Down Enable SCL, SDA +} diff --git a/board/samsung/smdk4x12/pmic.h b/board/samsung/smdk4x12/pmic.h new file mode 100644 index 000000000..bfa7aeda5 --- /dev/null +++ b/board/samsung/smdk4x12/pmic.h @@ -0,0 +1,115 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __PMIC_H__ +#define __PMIC_H__ + +#define GPD1CON *(volatile unsigned long *)(0x114000C0) +#define GPD1DAT *(volatile unsigned long *)(0x114000C4) +#define GPD1PUD *(volatile unsigned long *)(0x114000C8) +#ifdef CONFIG_EXYNOS4X12 +#define GPA1CON *(volatile unsigned long *)(0x11400020) +#define GPA1DAT *(volatile unsigned long *)(0x11400024) +#define GPA1PUD *(volatile unsigned long *)(0x11400028) +#endif + +#ifdef CONFIG_INVERSE_PMIC_I2C +#define IIC0_ESCL_Hi GPD1DAT |= (0x1<<0) +#define IIC0_ESCL_Lo GPD1DAT &= ~(0x1<<0) +#define IIC0_ESDA_Hi GPD1DAT |= (0x1<<1) +#define IIC0_ESDA_Lo GPD1DAT &= ~(0x1<<1) +#else +#define IIC0_ESCL_Hi GPD1DAT |= (0x1<<1) +#define IIC0_ESCL_Lo GPD1DAT &= ~(0x1<<1) +#define IIC0_ESDA_Hi GPD1DAT |= (0x1<<0) +#define IIC0_ESDA_Lo GPD1DAT &= ~(0x1<<0) +#endif + +#define IIC1_ESCL_Hi GPD1DAT |= (0x1<<3) +#define IIC1_ESCL_Lo GPD1DAT &= ~(0x1<<3) +#define IIC1_ESDA_Hi GPD1DAT |= (0x1<<2) +#define IIC1_ESDA_Lo GPD1DAT &= ~(0x1<<2) + +#ifdef CONFIG_EXYNOS4X12 +#define IIC3_ESCL_Hi GPA1DAT |= (0x1<<3) +#define IIC3_ESCL_Lo GPA1DAT &= ~(0x1<<3) +#define IIC3_ESDA_Hi GPA1DAT |= (0x1<<2) +#define IIC3_ESDA_Lo GPA1DAT &= ~(0x1<<2) +#endif + +#ifdef CONFIG_INVERSE_PMIC_I2C +#define IIC0_ESCL_INP GPD1CON &= ~(0xf<<0) +#define IIC0_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<0))|(0x1<<0) + +#define IIC0_ESDA_INP GPD1CON &= ~(0xf<<4) +#define IIC0_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<4))|(0x1<<4) +#else +#define IIC0_ESCL_INP GPD1CON &= ~(0xf<<4) +#define IIC0_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<4))|(0x1<<4) + +#define IIC0_ESDA_INP GPD1CON &= ~(0xf<<0) +#define IIC0_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<0))|(0x1<<0) +#endif + +#define IIC1_ESCL_INP GPD1CON &= ~(0xf<<12) +#define IIC1_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<12))|(0x1<<12) + +#define IIC1_ESDA_INP GPD1CON &= ~(0xf<<8) +#define IIC1_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<8))|(0x1<<8) + +#ifdef CONFIG_EXYNOS4X12 +#define IIC3_ESCL_INP GPA1CON &= ~(0xf<<12) +#define IIC3_ESCL_OUTP GPA1CON = (GPA1CON & ~(0xf<<12))|(0x1<<12) + +#define IIC3_ESDA_INP GPA1CON &= ~(0xf<<8) +#define IIC3_ESDA_OUTP GPA1CON = (GPA1CON & ~(0xf<<8))|(0x1<<8) +#endif + +#define DELAY 100 + +#define MAX8952_ADDR 0xc0 // VDD_ARM - I2C0 +#define MAX8649_ADDR 0xc0 // VDD_INT - I2C1 +#define MAX8649A_ADDR 0xc4 // VDD_G3D - I2C0 +#define MAX8997_ADDR 0xCC // MAX8997 - I2C0 +#define MAX77686_ADDR 0x12 // MAX77686 - I2C0 +#define MAX8997_ID 0x00 +#define MAX8997_BUCK1TV_DVS 0x19 +#define MAX8997_BUCK2TV_DVS 0x22 +#define MAX8997_BUCK3TV_DVS 0x2B +#define MAX8997_BUCK4TV_DVS 0x2D +#define MAX8997_LDO10CTRL 0x44 +#define S5M8767_ADDR 0xCC // S5M8767 - I2C0 +extern void pmic8767_init(void); + +#define CALC_MAXIM_BUCK1245_VOLT(x) ( (x<650) ? 0 : ((x-650)/25) ) +#define CALC_MAXIM_BUCK37_VOLT(x) ( (x<750) ? 0 : ((x-750)/50) ) +#define CALC_MAXIM_ALL_LDO(x) ( (x<800) ? 0 : ((x-800)/50) ) +#define CALC_MAXIM77686_BUCK156789_VOLT(x) ( (x<750) ? 0 : ((x-750)/50) ) +#define CALC_MAXIM77686_BUCK234_VOLT(x) ( (x<600) ? 0 : ((x-600)/12.5) ) +#define CALC_MAXIM77686_LDO1267815_VOLT(x) ( (x<800) ? 0 : ((x-800)/25) ) +#define CALC_MAXIM77686_ALL_LDO_VOLT(x) ( (x<800) ? 0 : ((x-800)/50) ) + +typedef enum +{ + PMIC_BUCK1=0, + PMIC_BUCK2, + PMIC_BUCK3, + PMIC_BUCK4, + PMIC_LDO14, + PMIC_LDO10, + PMIC_LDO21, +}PMIC_RegNum; + +extern void pmic_init(void); + +#endif /*__PMIC_H__*/ + diff --git a/board/samsung/smdk4x12/smc.c b/board/samsung/smdk4x12/smc.c new file mode 100644 index 000000000..fe3c1ed57 --- /dev/null +++ b/board/samsung/smdk4x12/smc.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <asm/arch/smc.h> + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1) + + ); + + return reg1; +} + + +unsigned int load_uboot_image(u32 boot_device) +{ + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_SYS_TEXT_BASE; + + } else if (boot_device == EMMC || boot_device == EMMC_4_4) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_SYS_TEXT_BASE; + + } + + info_image->image_base_addr = CONFIG_SYS_TEXT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_UBOOT_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, 0); +} + +unsigned int coldboot(u32 boot_device) +{ + image_info *info_image; + int i; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC || boot_device == EMMC_4_4) { + + i = 100; /* for EMMC 4.4 */ + while(i--); + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } + + info_image->image_base_addr = CONFIG_PHY_TZSW_BASE; + info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_TZSW_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_COLDBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, CONFIG_SYS_TEXT_BASE); +} + +void warmboot(void) +{ + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, (EXYNOS4_POWER_BASE + INFORM0_OFFSET)); +} + +unsigned int find_second_boot(void) +{ + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT); +} + +void emmc_endbootop(void) +{ + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +} + +void sdmmc_enumerate(void) +{ + exynos_smc(SMC_CMD_SDMMC_ENUMERATE, 0, 0, 0); +} diff --git a/board/samsung/smdk4x12/smdk4212_val.h b/board/samsung/smdk4x12/smdk4212_val.h new file mode 100644 index 000000000..a8e1322bb --- /dev/null +++ b/board/samsung/smdk4x12/smdk4212_val.h @@ -0,0 +1,299 @@ +/* + * (C) Copyright 2012 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef _VAL_SMDK4212_H +#define _VAL_SMDK4212_H + +#include <config.h> +#include <asm/arch/cpu.h> + +#define CORE2_RATIO 0x0 +#define PCLK_DBG_RATIO 0x1 +#define PERIPH_RATIO 0x0 +#define CORE_RATIO 0x0 +#define HPM_RATIO 0x0 + +/* ARM_CLOCK_800Mhz */ +#if defined(CONFIG_CLK_ARM_800_APLL_800) +#define APLL_MDIV 0x64 +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x0 + +/* CLK_DIV_CPU0 */ +#define APLL_RATIO 0x1 +#define ATB_RATIO 0x3 +#define COREM1_RATIO 0x5 +#define COREM0_RATIO 0x2 + +/* CLK_DIV_CPU1 */ +#define CORES_RATIO 0x3 +#define COPY_RATIO 0x3 + +/* ARM_CLOCK_1Ghz */ +#elif defined(CONFIG_CLK_ARM_1000_APLL_1000) +#define APLL_MDIV 0x7D +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x0 + +/* CLK_DIV_CPU0 */ +#ifdef CONFIG_EXYNOS4412_EVT2 +#define APLL_RATIO 0x4 +#else +#define APLL_RATIO 0x1 +#endif +#define ATB_RATIO 0x4 +#define COREM1_RATIO 0x5 +#define COREM0_RATIO 0x2 + +/* CLK_DIV_CPU1 */ +#define CORES_RATIO 0x4 +#define COPY_RATIO 0x4 + +/* ARM_CLOCK_1.5Ghz */ +#elif defined(CONFIG_CLK_ARM_1500_APLL_1500) +#define APLL_MDIV 0xFA +#define APLL_PDIV 0x4 +#define APLL_SDIV 0x0 + +#define APLL_RATIO 0x2 +#define ATB_RATIO 0x6 +#define COREM1_RATIO 0x7 +#define COREM0_RATIO 0x3 + +/* CLK_DIV_CPU1 */ +#define CORES_RATIO 0x7 +#define COPY_RATIO 0x6 + +#endif + +#define CLK_DIV_CPU0_VAL ((CORE2_RATIO << 28) \ + | (APLL_RATIO << 24) \ + | (PCLK_DBG_RATIO << 20)\ + | (ATB_RATIO << 16) \ + | (PERIPH_RATIO <<12) \ + | (COREM1_RATIO << 8) \ + | (COREM0_RATIO << 4) \ + | (CORE_RATIO)) + +#define CLK_DIV_CPU1_VAL ((CORES_RATIO << 8) \ + | (HPM_RATIO << 4) \ + | (COPY_RATIO)) + +#if defined(CONFIG_CLK_BUS_DMC_200_400) +#define MPLL_MDIV 0x64 +#define MPLL_PDIV 0x3 +#define MPLL_SDIV 0x0 +#elif defined(CONFIG_CLK_BUS_DMC_220_440) +#define MPLL_MDIV 0x6E +#define MPLL_PDIV 0x3 +#define MPLL_SDIV 0x0 +#endif + + +/* APLL_CON1 */ +#define APLL_CON1_VAL (0x00203800) + +/* MPLL_CON1 */ +#define MPLL_CON1_VAL (0x00203800) + +#define EPLL_MDIV 0x40 +#define EPLL_PDIV 0x2 +#define EPLL_SDIV 0x3 + +#define EPLL_CON1_VAL 0x66010000 +#define EPLL_CON2_VAL 0x00000080 + +#define VPLL_MDIV 0xAF +#define VPLL_PDIV 0x3 +#define VPLL_SDIV 0x2 + +#define VPLL_CON1_VAL 0x66010000 +#define VPLL_CON2_VAL 0x00000080 + + +/* Set PLL */ +#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) + +#define APLL_CON0_VAL set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV) +#define MPLL_CON0_VAL set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV) +#define EPLL_CON0_VAL set_pll(EPLL_MDIV,EPLL_PDIV,EPLL_SDIV) +#define VPLL_CON0_VAL set_pll(VPLL_MDIV,VPLL_PDIV,VPLL_SDIV) + +/* APLL_LOCK */ +#define APLL_LOCK_VAL (APLL_PDIV * 270) +/* MPLL_LOCK */ +#define MPLL_LOCK_VAL (MPLL_PDIV * 270) +/* EPLL_LOCK */ +#define EPLL_LOCK_VAL (EPLL_PDIV * 3000) +/* VPLL_LOCK */ +#define VPLL_LOCK_VAL (VPLL_PDIV * 3000) + + +#if defined(MIF_DVFS_LEVEL1) +/* CLK_DIV_DMC0 */ +#define DMCP_RATIO 0x1 +#define DMCD_RATIO 0x1 +#define DMC_RATIO 0x2 +#define DPHY_RATIO 0x1 +#define ACP_PCLK_RATIO 0x1 +#define ACP_RATIO 0x4 + +#define CLK_DIV_DMC0_VAL ((DMCP_RATIO << 20) \ + | (DMCD_RATIO << 16) \ + | (DMC_RATIO << 12) \ + | (DPHY_RATIO << 8) \ + | (ACP_PCLK_RATIO << 4) \ + | (ACP_RATIO)) + +/* CLK_DIV_DMC1 */ +#define DPM_RATIO 0x1 +#define DVSEM_RATIO 0x1 +#define C2C_ACLK_RATIO 0x1 +#define PWI_RATIO 0xF +#define C2C_RATIO 0x2 +#define G2D_ACP_RATIO 0x4 + +#define CLK_DIV_DMC1_VAL ((DPM_RATIO << 24) \ + | (DVSEM_RATIO << 16) \ + | (C2C_ACLK_RATIO << 12)\ + | (PWI_RATIO << 8) \ + | (C2C_RATIO << 4) \ + | (G2D_ACP_RATIO)) + +#else +/* CLK_DIV_DMC0 */ +#define DMCP_RATIO 0x1 +#define DMCD_RATIO 0x1 +#define DMC_RATIO 0x1 +#define DPHY_RATIO 0x1 +#define ACP_PCLK_RATIO 0x1 +#define ACP_RATIO 0x3 + +#define CLK_DIV_DMC0_VAL ((DMCP_RATIO << 20) \ + | (DMCD_RATIO << 16) \ + | (DMC_RATIO << 12) \ + | (DPHY_RATIO << 8) \ + | (ACP_PCLK_RATIO << 4) \ + | (ACP_RATIO)) + +/* CLK_DIV_DMC1 */ +#define DPM_RATIO 0x1 +#define DVSEM_RATIO 0x1 +#define C2C_ACLK_RATIO 0x1 +#define PWI_RATIO 0xF +#define C2C_RATIO 0x1 +#define G2D_ACP_RATIO 0x3 + +#define CLK_DIV_DMC1_VAL ((DPM_RATIO << 24) \ + | (DVSEM_RATIO << 16) \ + | (C2C_ACLK_RATIO << 12)\ + | (PWI_RATIO << 8) \ + | (C2C_RATIO << 4) \ + | (G2D_ACP_RATIO)) +#endif +/* CLK_DIV_TOP */ +#define ACLK_400_MCUISP_RATIO 0x1 +#define ACLK_266_GPS_RATIO 0x2 +#define ONENAND_RATIO 0x1 +#define ACLK_133_RATIO 0x5 +#define ACLK_160_RATIO 0x4 +#define ACLK_100_RATIO 0x7 +#define ACLK_200_RATIO 0x4 + +#define CLK_DIV_TOP_VAL ((ACLK_400_MCUISP_RATIO << 24) \ + | (ACLK_266_GPS_RATIO << 20) \ + | (ONENAND_RATIO << 16) \ + | (ACLK_133_RATIO << 12) \ + | (ACLK_160_RATIO << 8) \ + | (ACLK_100_RATIO << 4) \ + | (ACLK_200_RATIO)) + +/* CLK_DIV_LEFRBUS */ +#define GPL_RATIO 0x1 +#define GDL_RATIO 0x3 +#define CLK_DIV_LEFRBUS_VAL ((GPL_RATIO << 4) \ + | (GDL_RATIO)) + +/* CLK_DIV_RIGHTBUS */ +#define GPR_RATIO 0x1 +#define GDR_RATIO 0x3 +#define CLK_DIV_RIGHTBUS_VAL ((GPR_RATIO << 4) \ + | (GDR_RATIO)) + + +/* CLK_SRC_PERIL0 */ +#define PWM_SEL 0 +#define UART5_SEL 6 +#define UART4_SEL 6 +#define UART3_SEL 6 +#define UART2_SEL 6 +#define UART1_SEL 6 +#define UART0_SEL 6 +#define CLK_SRC_PERIL0_VAL ((PWM_SEL << 24)\ + | (UART5_SEL << 20) \ + | (UART4_SEL << 16) \ + | (UART3_SEL << 12) \ + | (UART2_SEL<< 8) \ + | (UART1_SEL << 4) \ + | (UART0_SEL)) + +/* CLK_DIV_PERIL0 */ +#if defined(CONFIG_CLK_BUS_DMC_165_330) +#define UART5_RATIO 7 +#define UART4_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 +#elif defined(CONFIG_CLK_BUS_DMC_200_400) +#define UART5_RATIO 7 +#define UART4_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 +#elif defined(CONFIG_CLK_BUS_DMC_220_440) +#define UART5_RATIO 7 +#define UART4_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 +#endif + +#define CLK_DIV_PERIL0_VAL ((UART5_RATIO << 20) \ + | (UART4_RATIO << 16) \ + | (UART3_RATIO << 12) \ + | (UART2_RATIO << 8) \ + | (UART1_RATIO << 4) \ + | (UART0_RATIO)) + + +#define MPLL_DEC (MPLL_MDIV * MPLL_MDIV / (MPLL_PDIV * 2^(MPLL_SDIV-1))) + + +#define SCLK_UART MPLL_DEC / (UART1_RATIO+1) + +#if defined(CONFIG_CLK_BUS_DMC_165_330) +#define UART_UBRDIV_VAL 0x2B/* (SCLK_UART/(115200*16) -1) */ +#define UART_UDIVSLOT_VAL 0xC /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#elif defined(CONFIG_CLK_BUS_DMC_200_400) +#define UART_UBRDIV_VAL 0x35 /* (SCLK_UART/(115200*16) -1) */ +#define UART_UDIVSLOT_VAL 0x4 /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#elif defined(CONFIG_CLK_BUS_DMC_220_440) +#define UART_UBRDIV_VAL 0x3A /* (SCLK_UART/(115200*16) -1) */ +#define UART_UDIVSLOT_VAL 0xB /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#endif + + +#endif + diff --git a/board/samsung/smdk4x12/smdk4412_val.h b/board/samsung/smdk4x12/smdk4412_val.h new file mode 100644 index 000000000..64d9cfd22 --- /dev/null +++ b/board/samsung/smdk4x12/smdk4412_val.h @@ -0,0 +1,267 @@ +/* + * (C) Copyright 2012 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef _VAL_SMDK4412_H +#define _VAL_SMDK4412_H + +#include <config.h> +#include <asm/arch/cpu.h> + +#define CORE2_RATIO 0x0 +#define PCLK_DBG_RATIO 0x1 +#define PERIPH_RATIO 0x0 +#define CORE_RATIO 0x0 +#define HPM_RATIO 0x0 + +/* ARM_CLOCK_800Mhz */ +#if defined(CONFIG_CLK_ARM_800_APLL_800) +#define APLL_MDIV 0x64 +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x0 + +/* CLK_DIV_CPU0 */ +#define APLL_RATIO 0x1 +#define ATB_RATIO 0x3 +#define COREM1_RATIO 0x5 +#define COREM0_RATIO 0x2 + +/* CLK_DIV_CPU1 */ +#define CORES_RATIO 0x3 +#define COPY_RATIO 0x3 + +/* ARM_CLOCK_1Ghz */ +#elif defined(CONFIG_CLK_ARM_1000_APLL_1000) +#define APLL_MDIV 0x7D +#define APLL_PDIV 0x3 +#define APLL_SDIV 0x0 + +/* CLK_DIV_CPU0 */ +#ifdef CONFIG_EXYNOS4412_EVT2 +#define APLL_RATIO 0x4 +#else +#define APLL_RATIO 0x1 +#endif +#define ATB_RATIO 0x4 +#define COREM1_RATIO 0x5 +#define COREM0_RATIO 0x2 + +/* CLK_DIV_CPU1 */ +#define CORES_RATIO 0x4 +#define COPY_RATIO 0x4 + +/* ARM_CLOCK_1.5Ghz */ +#elif defined(CONFIG_CLK_ARM_1500_APLL_1500) +#define APLL_MDIV 0xFA +#define APLL_PDIV 0x4 +#define APLL_SDIV 0x0 + +#define APLL_RATIO 0x2 +#define ATB_RATIO 0x6 +#define COREM1_RATIO 0x7 +#define COREM0_RATIO 0x3 + +/* CLK_DIV_CPU1 */ +#define CORES_RATIO 0x7 +#define COPY_RATIO 0x6 + +#endif + +#define CLK_DIV_CPU0_VAL ((CORE2_RATIO << 28) \ + | (APLL_RATIO << 24) \ + | (PCLK_DBG_RATIO << 20)\ + | (ATB_RATIO << 16) \ + | (PERIPH_RATIO <<12) \ + | (COREM1_RATIO << 8) \ + | (COREM0_RATIO << 4) \ + | (CORE_RATIO)) + +#define CLK_DIV_CPU1_VAL ((CORES_RATIO << 8) \ + | (HPM_RATIO << 4) \ + | (COPY_RATIO)) + +#if defined(CONFIG_CLK_BUS_DMC_200_400) +#define MPLL_MDIV 0x64 +#define MPLL_PDIV 0x3 +#define MPLL_SDIV 0x0 +#elif defined(CONFIG_CLK_BUS_DMC_220_440) +#define MPLL_MDIV 0x6E +#define MPLL_PDIV 0x3 +#define MPLL_SDIV 0x0 +#endif + + +/* APLL_CON1 */ +#define APLL_CON1_VAL (0x00203800) + +/* MPLL_CON1 */ +#define MPLL_CON1_VAL (0x00203800) + +#define EPLL_MDIV 0x40 +#define EPLL_PDIV 0x2 +#define EPLL_SDIV 0x3 + +#define EPLL_CON1_VAL 0x66010000 +#define EPLL_CON2_VAL 0x00000080 + +#define VPLL_MDIV 0xAF +#define VPLL_PDIV 0x3 +#define VPLL_SDIV 0x2 + +#define VPLL_CON1_VAL 0x66010000 +#define VPLL_CON2_VAL 0x00000080 + + +/* Set PLL */ +#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) + +#define APLL_CON0_VAL set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV) +#define MPLL_CON0_VAL set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV) +#define EPLL_CON0_VAL set_pll(EPLL_MDIV,EPLL_PDIV,EPLL_SDIV) +#define VPLL_CON0_VAL set_pll(VPLL_MDIV,VPLL_PDIV,VPLL_SDIV) + +/* APLL_LOCK */ +#define APLL_LOCK_VAL (APLL_PDIV * 270) +/* MPLL_LOCK */ +#define MPLL_LOCK_VAL (MPLL_PDIV * 270) +/* EPLL_LOCK */ +#define EPLL_LOCK_VAL (EPLL_PDIV * 3000) +/* VPLL_LOCK */ +#define VPLL_LOCK_VAL (VPLL_PDIV * 3000) + + +/* CLK_DIV_DMC0 */ +#define DMCP_RATIO 0x1 +#define DMCD_RATIO 0x1 +#define DMC_RATIO 0x1 +#define DPHY_RATIO 0x1 +#define ACP_PCLK_RATIO 0x1 +#define ACP_RATIO 0x3 + +#define CLK_DIV_DMC0_VAL ((DMCP_RATIO << 20) \ + | (DMCD_RATIO << 16) \ + | (DMC_RATIO << 12) \ + | (DPHY_RATIO << 8) \ + | (ACP_PCLK_RATIO << 4) \ + | (ACP_RATIO)) + +/* CLK_DIV_DMC1 */ +#define DPM_RATIO 0x1 +#define DVSEM_RATIO 0x1 +#define C2C_ACLK_RATIO 0x1 +#define PWI_RATIO 0xF +#define C2C_RATIO 0x1 +#define G2D_ACP_RATIO 0x3 + +#define CLK_DIV_DMC1_VAL ((DPM_RATIO << 24) \ + | (DVSEM_RATIO << 16) \ + | (C2C_ACLK_RATIO << 12)\ + | (PWI_RATIO << 8) \ + | (C2C_RATIO << 4) \ + | (G2D_ACP_RATIO)) + +/* CLK_DIV_TOP */ +#define ACLK_400_MCUISP_RATIO 0x1 +#define ACLK_266_GPS_RATIO 0x2 +#define ONENAND_RATIO 0x1 +#define ACLK_133_RATIO 0x5 +#define ACLK_160_RATIO 0x4 +#define ACLK_100_RATIO 0x7 +#define ACLK_200_RATIO 0x4 + +#define CLK_DIV_TOP_VAL ((ACLK_400_MCUISP_RATIO << 24) \ + | (ACLK_266_GPS_RATIO << 20) \ + | (ONENAND_RATIO << 16) \ + | (ACLK_133_RATIO << 12) \ + | (ACLK_160_RATIO << 8) \ + | (ACLK_100_RATIO << 4) \ + | (ACLK_200_RATIO)) + +/* CLK_DIV_LEFRBUS */ +#define GPL_RATIO 0x1 +#define GDL_RATIO 0x3 +#define CLK_DIV_LEFRBUS_VAL ((GPL_RATIO << 4) \ + | (GDL_RATIO)) + +/* CLK_DIV_RIGHTBUS */ +#define GPR_RATIO 0x1 +#define GDR_RATIO 0x3 +#define CLK_DIV_RIGHTBUS_VAL ((GPR_RATIO << 4) \ + | (GDR_RATIO)) + + +/* CLK_SRC_PERIL0 */ +#define PWM_SEL 0 +#define UART5_SEL 6 +#define UART4_SEL 6 +#define UART3_SEL 6 +#define UART2_SEL 6 +#define UART1_SEL 6 +#define UART0_SEL 6 +#define CLK_SRC_PERIL0_VAL ((PWM_SEL << 24)\ + | (UART5_SEL << 20) \ + | (UART4_SEL << 16) \ + | (UART3_SEL << 12) \ + | (UART2_SEL<< 8) \ + | (UART1_SEL << 4) \ + | (UART0_SEL)) + +/* CLK_DIV_PERIL0 */ +#if defined(CONFIG_CLK_BUS_DMC_165_330) +#define UART5_RATIO 7 +#define UART4_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 +#elif defined(CONFIG_CLK_BUS_DMC_200_400) +#define UART5_RATIO 7 +#define UART4_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 +#elif defined(CONFIG_CLK_BUS_DMC_220_440) +#define UART5_RATIO 7 +#define UART4_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 +#endif + +#define CLK_DIV_PERIL0_VAL ((UART5_RATIO << 20) \ + | (UART4_RATIO << 16) \ + | (UART3_RATIO << 12) \ + | (UART2_RATIO << 8) \ + | (UART1_RATIO << 4) \ + | (UART0_RATIO)) + + +#define MPLL_DEC (MPLL_MDIV * MPLL_MDIV / (MPLL_PDIV * 2^(MPLL_SDIV-1))) + + +#define SCLK_UART MPLL_DEC / (UART1_RATIO+1) + +#if defined(CONFIG_CLK_BUS_DMC_165_330) +#define UART_UBRDIV_VAL 0x2B/* (SCLK_UART/(115200*16) -1) */ +#define UART_UDIVSLOT_VAL 0xC /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#elif defined(CONFIG_CLK_BUS_DMC_200_400) +#define UART_UBRDIV_VAL 0x35 /* (SCLK_UART/(115200*16) -1) */ +#define UART_UDIVSLOT_VAL 0x4 /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#elif defined(CONFIG_CLK_BUS_DMC_220_440) +#define UART_UBRDIV_VAL 0x3A /* (SCLK_UART/(115200*16) -1) */ +#define UART_UDIVSLOT_VAL 0xB /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#endif + + +#endif + diff --git a/board/samsung/smdk4x12/smdk4x12.c b/board/samsung/smdk4x12/smdk4x12.c new file mode 100644 index 000000000..7e0a78b90 --- /dev/null +++ b/board/samsung/smdk4x12/smdk4x12.c @@ -0,0 +1,325 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * 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 <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/mmc.h> +#include <asm/arch/sromc.h> +#include <asm/arch/clk.h> + +DECLARE_GLOBAL_DATA_PTR; +struct exynos4_gpio_part1 *gpio1; +struct exynos4_gpio_part2 *gpio2; + +static void smc9115_pre_init(void) +{ + u32 smc_bw_conf, smc_bc_conf; + + /* gpio configuration GPK0CON */ + s5p_gpio_cfg_pin(&gpio2->y0, CONFIG_ENV_SROM_BANK, GPIO_FUNC(2)); + + /* Ethernet needs bus width of 16 bits */ + smc_bw_conf = SROMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK); + smc_bc_conf = SROMC_BC_TACS(0x0F) | SROMC_BC_TCOS(0x0F) + | SROMC_BC_TACC(0x0F) | SROMC_BC_TCOH(0x0F) + | SROMC_BC_TAH(0x0F) | SROMC_BC_TACP(0x0F) + | SROMC_BC_PMC(0x0F); + + /* Select and configure the SROMC bank */ + s5p_config_sromc(CONFIG_ENV_SROM_BANK, smc_bw_conf, smc_bc_conf); +} + +int board_init(void) +{ + u8 read_id; + u8 read_vol_arm = 0x0; + u8 read_vol_int = 0x0; + u8 read_vol_g3d = 0x0; + u8 read_vol_mif = 0x0; + + int OmPin = readl(EXYNOS4_POWER_BASE + INFORM3_OFFSET); + + gpio1 = (struct exynos4_gpio_part1 *) EXYNOS4_GPIO_PART1_BASE; + gpio2 = (struct exynos4_gpio_part2 *) EXYNOS4_GPIO_PART2_BASE; + + IIC0_ERead(0xcc, 0, &read_id); + if (read_id == 0x77) { + IIC0_ERead(0xcc, 0x19, &read_vol_arm); + IIC0_ERead(0xcc, 0x22, &read_vol_int); + IIC0_ERead(0xcc, 0x2B, &read_vol_g3d); + //IIC0_ERead(0xcc, 0x2D, &read_vol_mif); + } else if ((0 <= read_id) && (read_id <= 0x5)) { + IIC0_ERead(0xcc, 0x33, &read_vol_mif); + IIC0_ERead(0xcc, 0x35, &read_vol_arm); + IIC0_ERead(0xcc, 0x3E, &read_vol_int); + IIC0_ERead(0xcc, 0x47, &read_vol_g3d); + } else { + IIC0_ERead(0x12, 0x11, &read_vol_mif); + IIC0_ERead(0x12, 0x14, &read_vol_arm); + IIC0_ERead(0x12, 0x1E, &read_vol_int); + IIC0_ERead(0x12, 0x28, &read_vol_g3d); + } + + printf("vol_arm: %X\n", read_vol_arm); + printf("vol_int: %X\n", read_vol_int); + printf("vol_g3d: %X\n", read_vol_g3d); + printf("vol_mif: %X\n", read_vol_mif); + + smc9115_pre_init(); + + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); + + printf("\nChecking Boot Mode ..."); + switch (OmPin) { + case BOOT_ONENAND: + printf(" OneNand\n"); + break; + case BOOT_NAND: + printf(" NAND\n"); + break; + case BOOT_MMCSD: + printf(" SDMMC\n"); + break; + case BOOT_EMMC: + printf(" EMMC4.3\n"); + break; + case BOOT_EMMC_4_4: + printf(" EMMC4.41\n"); + break; + default: + break; + } + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE); + +#ifndef USE_512MB_DRAM + gd->ram_size += get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE); +#ifdef USE_2G_DRAM + gd->ram_size += get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_5_SIZE) + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_6_SIZE) + + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE); +#endif +#endif + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, \ + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, \ + PHYS_SDRAM_2_SIZE); +#ifndef USE_512MB_DRAM + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, \ + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, \ + PHYS_SDRAM_4_SIZE); +#ifdef USE_2G_DRAM + gd->bd->bi_dram[4].start = PHYS_SDRAM_5; + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5, \ + PHYS_SDRAM_5_SIZE); + gd->bd->bi_dram[5].start = PHYS_SDRAM_6; + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6, \ + PHYS_SDRAM_6_SIZE); + gd->bd->bi_dram[6].start = PHYS_SDRAM_7; + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7, \ + PHYS_SDRAM_7_SIZE); + gd->bd->bi_dram[7].start = PHYS_SDRAM_8; + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8, \ + PHYS_SDRAM_8_SIZE); +#endif +#endif +} + +int board_eth_init(bd_t *bis) +{ + int rc = 0; +#ifdef CONFIG_SMC911X + rc = smc911x_initialize(0, CONFIG_SMC911X_BASE); +#endif + return rc; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ +#ifdef CONFIG_EXYNOS4412 + printf("\nBoard: SMDK4412\n"); +#else + printf("\nBoard: SMDK4212\n"); +#endif + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + int i, err, OmPin; + u32 clock; + + OmPin = readl(EXYNOS4_POWER_BASE + INFORM3_OFFSET); + + /* + * MMC2 SD card GPIO: + * + * GPK2[0] SD_2_CLK(2) + * GPK2[1] SD_2_CMD(2) + * GPK2[2] SD_2_CDn + * GPK2[3:6] SD_2_DATA[0:3](2) + */ + for (i = 0; i < 7; i++) { + /* GPK2[0:6] special function 2 */ + s5p_gpio_cfg_pin(&gpio2->k2, i, GPIO_FUNC(0x2)); + + /* GPK2[0:6] drv 4x */ + s5p_gpio_set_drv(&gpio2->k2, i, GPIO_DRV_4X); + + /* GPK2[0:1] pull disable */ + if (i == 0 || i == 1) { + s5p_gpio_set_pull(&gpio2->k2, i, GPIO_PULL_NONE); + continue; + } + + /* GPK2[2:6] pull up */ + s5p_gpio_set_pull(&gpio2->k2, i, GPIO_PULL_UP); + } + + /* + * MMC4 MSHC GPIO: + * + * GPK0[0] SD_4_CLK + * GPK0[1] SD_4_CMD + * GPK0[2] SD_4_CDn + * GPK0[3:6] SD_4_DATA[0:3] + * GPK1[3:6] SD_4_DATA[4:7] + */ + for (i = 0; i < 7; i++) { + /* GPK0[0:6] special function 3 */ + s5p_gpio_cfg_pin(&gpio2->k0, i, GPIO_FUNC(0x3)); + + /* GPK0[0:6] drv 4x */ + s5p_gpio_set_drv(&gpio2->k0, i, GPIO_DRV_4X); + + /* GPK0[0:1] pull disable */ + if (i == 0 || i == 1) { + s5p_gpio_set_pull(&gpio2->k0, i, GPIO_PULL_NONE); + continue; + } + + /* GPK0[2:6] pull up */ + s5p_gpio_set_pull(&gpio2->k0, i, GPIO_PULL_UP); + } + + for (i = 3; i < 7; i++) { + /* GPK1[3:6] special function 3 */ + s5p_gpio_cfg_pin(&gpio2->k1, i, GPIO_FUNC(0x4)); + + /* GPK1[3:6] drv 4x */ + s5p_gpio_set_drv(&gpio2->k1, i, GPIO_DRV_4X); + + /* GPK1[3:6] pull up */ + s5p_gpio_set_pull(&gpio2->k1, i, GPIO_PULL_UP); + } + + /* Drive Strength */ + writel(0x00010001, 0x1255009C); + + clock = get_pll_clk(MPLL)/1000000; + for(i=0 ; i<=0xf; i++) + { + if((clock /(i+1)) <= 400) { + set_mmc_clk(4, i); + break; + } + } + + switch (OmPin) { + case BOOT_EMMC_4_4: + err = s5p_mmc_init(4, 8); + if (err) + printf("MSHC Channel 4 init failed!!!\n"); + err = s5p_mmc_init(2, 4); + if (err) + printf("SDHC Channel 2 init failed!!!\n"); + + break; + default: + err = s5p_mmc_init(2, 4); + if (err) + printf("MSHC Channel 2 init failed!!!\n"); + err = s5p_mmc_init(4, 8); + if (err) + printf("SDHC Channel 4 init failed!!!\n"); + + break; + } + +} +#endif + +int board_late_init(void) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *) samsung_get_base_gpio_part2(); + int second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + int err; + + err = exynos_pinmux_config(PERIPH_ID_INPUT_X0_0, PINMUX_FLAG_NONE); + if (err) { + debug("GPX0_0 INPUT not configured\n"); + return err; + } + + udelay(10); + if ((s5p_gpio_get_value(&gpio2->x0, 0) == 0) || second_boot_info == 1) { + printf("###Recovery Boot Mode###\n"); + setenv("bootcmd", CONFIG_RECOVERYCOMMAND); + /* clear secondary boot inform */ + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + } + + if ((readl(&pmu->inform4)) == CONFIG_FACTORY_RESET_MODE) { + writel(0x0, &pmu->inform4); + setenv("bootcmd", CONFIG_FACTORY_RESET_BOOTCOMMAND); + } + + return 0; +} diff --git a/board/samsung/smdk4x12/tools/mk4x12_image.c b/board/samsung/smdk4x12/tools/mk4x12_image.c new file mode 100644 index 000000000..1a51913f5 --- /dev/null +++ b/board/samsung/smdk4x12/tools/mk4x12_image.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/stat.h> + +#define CHECKSUM_OFFSET (14*1024-4) +#define BUFSIZE (16*1024) +#define FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP \ + | S_IWGRP | S_IROTH | S_IWOTH) +/* +* Requirement: +* IROM code reads first 14K bytes from boot device. +* It then calculates the checksum of 14K-4 bytes and compare with data at +* 14K-4 offset. +* +* This function takes two filenames: +* IN "u-boot-spl.bin" and +* OUT "u-boot-mmc-spl.bin" as filenames. +* It reads the "u-boot-spl.bin" in 16K buffer. +* It calculates checksum of 14K-4 Bytes and stores at 14K-4 offset in buffer. +* It writes the buffer to "u-boot-mmc-spl.bin" file. +*/ + +int main(int argc, char **argv) +{ + int i, len; + unsigned char buffer[BUFSIZE] = {0}; + int ifd, ofd; + unsigned int checksum = 0, count; + + if (argc != 3) { + printf(" %d Wrong number of arguments\n", argc); + exit(EXIT_FAILURE); + } + + ifd = open(argv[1], O_RDONLY); + if (ifd < 0) { + fprintf(stderr, "%s: Can't open %s: %s\n", + argv[0], argv[1], strerror(errno)); + exit(EXIT_FAILURE); + } + + ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM); + if (ifd < 0) { + fprintf(stderr, "%s: Can't open %s: %s\n", + argv[0], argv[2], strerror(errno)); + if (ifd) + close(ifd); + exit(EXIT_FAILURE); + } + + len = lseek(ifd, 0, SEEK_END); + lseek(ifd, 0, SEEK_SET); + + count = (len < CHECKSUM_OFFSET) ? len : CHECKSUM_OFFSET; + + if (read(ifd, buffer, count) != count) { + fprintf(stderr, "%s: Can't read %s: %s\n", + argv[0], argv[1], strerror(errno)); + + if (ifd) + close(ifd); + if (ofd) + close(ofd); + + exit(EXIT_FAILURE); + } + + for (i = 0, checksum = 0; i < CHECKSUM_OFFSET; i++) + checksum += buffer[i]; + + memcpy(&buffer[CHECKSUM_OFFSET], &checksum, sizeof(checksum)); + + if (write(ofd, buffer, BUFSIZE) != BUFSIZE) { + fprintf(stderr, "%s: Can't write %s: %s\n", + argv[0], argv[2], strerror(errno)); + + if (ifd) + close(ifd); + if (ofd) + close(ofd); + + exit(EXIT_FAILURE); + } + + if (ifd) + close(ifd); + if (ofd) + close(ofd); + + return EXIT_SUCCESS; +} diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 226db1f1f..0c0828c15 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -29,6 +29,8 @@ SOBJS := lowlevel_init.o COBJS := clock_init.o COBJS += dmc_init.o COBJS += tzpc_init.o +COBJS += pmic.o +COBJS += smc.o ifndef CONFIG_SPL_BUILD COBJS += smdk5250.o diff --git a/board/samsung/smdk5250/board_rev.h b/board/samsung/smdk5250/board_rev.h new file mode 100644 index 000000000..38b92edcf --- /dev/null +++ b/board/samsung/smdk5250/board_rev.h @@ -0,0 +1,45 @@ +/* + * (C) Copyright 2012 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +/* ADC SFR BASE ADDRESS */ +#define FIMC_IS_ADC_BASE 0x13150000 +#define MTCADC_PHY_CONTROL (EXYNOS5_POWER_BASE + 0x071C) + +/* ADC CONTROL */ +#define ADCCON 0x00 +#define ADCDAT0 0x0C +#define ADCMUX 0x1C + +#define ADCCON_SELMUX(x) (((x)&0xF)<<0) +#define ADCCON_MUXMASK (0x7<<3) +#define ADCCON_STDBM (1<<2) +#define ADCCON_ENABLE_START (1<<0) +#define ADCCON_STARTMASK (0x3<<0) +#define ADCCON_PRSCEN (1<<14) +#define ADCCLRINT 0x18 + +/* BOART REVISION INFORMATION */ +#define SMDK5250_REV_0_0_ADC_VALUE 0 +#define SMDK5250_REV_0_2_ADC_VALUE 500 + +#define SMDK5250_REV_0_0 0x0 +#define SMDK5250_REV_0_1 0x1 +#define SMDK5250_REV_0_2 0x2 +#define SMDK5250_REV_MASK 0xf + +/* BOART REVISION INFORMATION */ +#define SMDK5250_REGULATOR_MAX77686 0x0 +#define SMDK5250_REGULATOR_MAX8997 0x1 +#define SMDK5250_REGULATOR_S5M8767 0x2 +#define SMDK5250_REGULATOR_SHIFT 16 +#define SMDK5250_REGULATOR_MASK 0xf + diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c index 305842d2f..717936323 100644 --- a/board/samsung/smdk5250/clock_init.c +++ b/board/samsung/smdk5250/clock_init.c @@ -26,6 +26,7 @@ #include <version.h> #include <asm/io.h> #include <asm/arch/clock.h> +#include <asm/arch/power.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> #include "setup.h" @@ -33,109 +34,26 @@ void system_clock_init() { struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; /* * MUX_APLL_SEL[0]: FINPLL = 0 * MUX_CPU_SEL[6]: MOUTAPLL = 0 * MUX_HPM_SEL[20]: MOUTAPLL = 0 */ - writel(0x0, &clk->src_cpu); + writel(readl(&clk->src_cpu) & ~(0x1), &clk->src_cpu); - /* MUX_MPLL_SEL[8]: FINPLL = 0 */ - writel(0x0, &clk->src_core1); + /* MUX_MPLL_SEL[8]: 0*/ + writel(readl(&clk->src_core1) & ~(0x100), &clk->src_core1); /* * VPLLSRC_SEL[0]: FINPLL = 0 - * MUX_{CPLL[8]}|{EPLL[12]}|{VPLL[16]}_SEL: FINPLL = 0 + * MUX_{CPLL[8]}|{EPLL[12]}|{VPLL[16]|{GPLL[28]}_SEL: FINPLL = 0 */ - writel(0x0, &clk->src_top2); + writel(readl(&clk->src_top2) & ~(0x10011100), &clk->src_top2); - /* MUX_BPLL_SEL[0]: FINPLL = 0 */ - writel(0x0, &clk->src_cdrex); - - /* MUX_ACLK_* Clock Selection */ - writel(CLK_SRC_TOP0_VAL, &clk->src_top0); - - /* MUX_ACLK_* Clock Selection */ - writel(CLK_SRC_TOP1_VAL, &clk->src_top1); - - /* MUX_ACLK_* Clock Selection */ - writel(CLK_SRC_TOP3_VAL, &clk->src_top3); - - /* MUX_PWI_SEL[19:16]: SCLKMPLL = 6 */ - writel(CLK_SRC_CORE0_VAL, &clk->src_core0); - - /* MUX_ATCLK_LEX[0]: ACLK_200 = 0 */ - writel(CLK_SRC_LEX_VAL, &clk->src_lex); - - /* UART [0-5]: SCLKMPLL = 6 */ - writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); - - /* Set Clock Ratios */ - writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0); - - /* Set COPY and HPM Ratio */ - writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); - - /* CORED_RATIO, COREP_RATIO */ - writel(CLK_DIV_CORE0_VAL, &clk->div_core0); - - /* PWI_RATIO[11:8], DVSEM_RATIO[22:16], DPM_RATIO[24:20] */ - writel(CLK_DIV_CORE1_VAL, &clk->div_core1); - - /* ACLK_*_RATIO */ - writel(CLK_DIV_TOP0_VAL, &clk->div_top0); - - /* ACLK_*_RATIO */ - writel(CLK_DIV_TOP1_VAL, &clk->div_top1); - - /* CDREX Ratio */ - writel(CLK_DIV_CDREX_INIT_VAL, &clk->div_cdrex); - - /* MCLK_EFPHY_RATIO[3:0] */ - writel(CLK_DIV_CDREX2_VAL, &clk->div_cdrex2); - - /* {PCLK[4:6]|ATCLK[10:8]}_RATIO */ - writel(CLK_DIV_LEX_VAL, &clk->div_lex); - - /* PCLK_R0X_RATIO[3:0] */ - writel(CLK_DIV_R0X_VAL, &clk->div_r0x); - - /* PCLK_R1X_RATIO[3:0] */ - writel(CLK_DIV_R1X_VAL, &clk->div_r1x); - - /* SATA[24]: SCLKMPLL=0, MMC[0-4]: SCLKMPLL = 6 */ - writel(CLK_SRC_FSYS_VAL, &clk->src_fsys); - - /* UART[0-4] */ - writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0); - - /* PWM_RATIO[3:0] */ - writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3); - - /* SATA_RATIO, USB_DRD_RATIO */ - writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); - - /* MMC[0-1] */ - writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1); - - /* MMC[2-3] */ - writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2); - - /* MMC[4] */ - writel(CLK_DIV_FSYS3_VAL, &clk->div_fsys3); - - /* ACLK|PLCK_ACP_RATIO */ - writel(CLK_DIV_ACP_VAL, &clk->div_acp); - - /* ISPDIV0_RATIO, ISPDIV1_RATIO */ - writel(CLK_DIV_ISP0_VAL, &clk->div_isp0); - - /* MCUISPDIV0_RATIO, MCUISPDIV1_RATIO */ - writel(CLK_DIV_ISP1_VAL, &clk->div_isp1); - - /* MPWMDIV_RATIO */ - writel(CLK_DIV_ISP2_VAL, &clk->div_isp2); + /* MUX_BPLL_SEL[0]: 0 */ + writel(readl(&clk->src_cdrex) & ~(0x1), &clk->src_cdrex); /* PLL locktime */ writel(APLL_LOCK_VAL, &clk->apll_lock); @@ -146,12 +64,30 @@ void system_clock_init() writel(CPLL_LOCK_VAL, &clk->cpll_lock); + writel(GPLL_LOCK_VAL, &clk->gpll_lock); + writel(EPLL_LOCK_VAL, &clk->epll_lock); writel(VPLL_LOCK_VAL, &clk->vpll_lock); sdelay(0x10000); + /* Set BPLL, MPLL fixed Divider 2 */ + writel(0x0, &clk->pll_div2_sel); + + /* + * MUX_APLL_SEL[0]: FINPLL = 0 + * MUX_CPU_SEL[6]: MOUTAPLL = 0 + * MUX_HPM_SEL[20]: MOUTAPLL = 0 + */ + writel(0x00100000, &clk->src_cpu); + + /* Set Clock Ratios */ + writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0); + + /* Set COPY and HPM Ratio */ + writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); + /* Set APLL */ writel(APLL_CON1_VAL, &clk->apll_con1); writel(APLL_CON0_VAL, &clk->apll_con0); @@ -170,6 +106,11 @@ void system_clock_init() writel(CPLL_CON0_VAL, &clk->cpll_con0); sdelay(0x30000); + /* Set CPLL */ + writel(GPLL_CON1_VAL, &clk->gpll_con1); + writel(GPLL_CON0_VAL, &clk->gpll_con0); + sdelay(0x30000); + /* Set EPLL */ writel(EPLL_CON2_VAL, &clk->epll_con2); writel(EPLL_CON1_VAL, &clk->epll_con1); @@ -182,21 +123,105 @@ void system_clock_init() writel(VPLL_CON0_VAL, &clk->vpll_con0); sdelay(0x30000); - /* Set MPLL */ - /* After Initiallising th PLL select the sources accordingly */ - /* MUX_APLL_SEL[0]: MOUTAPLLFOUT = 1 */ - writel(CLK_SRC_CPU_VAL, &clk->src_cpu); + /* MUX_PWI_SEL[19:16]: XXTI = 0 */ + writel(CLK_SRC_CORE0_VAL, &clk->src_core0); - /* MUX_MPLL_SEL[8]: MOUTMPLLFOUT = 1 */ - writel(CLK_SRC_CORE1_VAL, &clk->src_core1); + /* CORED_RATIO, COREP_RATIO */ + writel(CLK_DIV_CORE0_VAL, &clk->div_core0); + + /* PWI_RATIO[11:8], DVSEM_RATIO[22:16], DPM_RATIO[24:20] */ + writel(CLK_DIV_CORE1_VAL, &clk->div_core1); + + /* + * ACLK_C2C_200_RATIO[10:8] + * C2C_CLK_400_RATIO[6:4] + * ACLK_R1BX_RATIO[2:0] + */ + writel(CLK_DIV_SYSRGT_VAL, &clk->div_sysrgt); + + /* ACLK|PLCK_ACP_RATIO */ + writel(CLK_DIV_ACP_VAL, &clk->div_acp); + + /* + * EFCLK_SYSLFT_RATIO[11:8] + * PCLK_SYSLFT_RATIO[6:4] + * ACLK_SYSLFT_RATIO[2:0] + */ + writel(CLK_DIV_SYSLFT_VAL, &clk->div_syslft); + + /* MUX_ACLK_* Clock Selection */ + writel(CLK_SRC_TOP0_VAL, &clk->src_top0); + + /* MUX_ACLK_* Clock Selection */ + writel(CLK_SRC_TOP1_VAL, &clk->src_top1); + + /* MUX_ACLK_* Clock Selection */ + writel(0x01100000, &clk->src_top2); + + /* MUX_ACLK_* Clock Selection */ + writel(CLK_SRC_TOP3_VAL, &clk->src_top3); + + /* ACLK_*_RATIO */ + writel(CLK_DIV_TOP0_VAL, &clk->div_top0); + + /* ACLK_*_RATIO */ + writel(CLK_DIV_TOP1_VAL, &clk->div_top1); + + /* MUX_ATCLK_LEX[0]: ACLK_200 = 0 */ + writel(readl(&clk->src_lex) | CLK_SRC_LEX_VAL, &clk->src_lex); - /* MUX_BPLL_SEL[0]: FOUTBPLL = 1*/ + /* {PCLK[4:6]|ATCLK[10:8]}_RATIO */ + writel(CLK_DIV_LEX_VAL, &clk->div_lex); + + /* PCLK_R0X_RATIO[3:0] */ + writel(CLK_DIV_R0X_VAL, &clk->div_r0x); + + /* PCLK_R1X_RATIO[3:0] */ + writel(CLK_DIV_R1X_VAL, &clk->div_r1x); + + /* MUX_BPLL_SEL[0]: FINPLL = 0*/ writel(CLK_SRC_CDREX_INIT_VAL, &clk->src_cdrex); + /* CDREX Ratio */ + writel(CLK_DIV_CDREX_INIT_VAL, &clk->div_cdrex); + + /* After Initiallising th PLL select the sources accordingly */ + /* MUX_APLL_SEL[0]: MOUTAPLLFOUT = 1 */ + writel(readl(&clk->src_cpu) | CLK_SRC_CPU_VAL, &clk->src_cpu); + /* * VPLLSRC_SEL[0]: FINPLL = 0 * MUX_{CPLL[8]}|{EPLL[12]}|{VPLL[16]}_SEL: MOUT{CPLL|EPLL|VPLL} = 1 * MUX_{MPLL[20]}|{BPLL[24]}_USER_SEL: FOUT{MPLL|BPLL} = 1 */ - writel(CLK_SRC_TOP2_VAL, &clk->src_top2); + writel(readl(&clk->src_top2) | CLK_SRC_TOP2_VAL, &clk->src_top2); + + /* MUX_MPLL_SEL[8]: MOUTMPLLFOUT = 1 */ + writel(readl(&clk->src_core1) | CLK_SRC_CORE1_VAL, &clk->src_core1); + + /* Set Clock Ratios */ + /* SATA[24]: SCLKMPLL=0, MMC[0-4]: SCLKMPLL = 6 */ + writel(CLK_SRC_FSYS_VAL, &clk->src_fsys); + + /* SATA_RATIO, USB_DRD_RATIO */ + writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); + + /* UART [0-5]: SCLKMPLL = 6 */ + writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); + + /* UART[0-4] */ + writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0); + + /* disable CLKOUT_CMU */ + writel(0x0, &clk->clkout_cmu_cpu); + writel(0x0, &clk->clkout_cmu_core); + writel(0x0, &clk->clkout_cmu_acp); + writel(0x0, &clk->clkout_cmu_top); + writel(0x0, &clk->clkout_cmu_lex); + writel(0x0, &clk->clkout_cmu_r0x); + writel(0x0, &clk->clkout_cmu_r1x); + writel(0x0, &clk->clkout_cmu_cdrex); + writel(0x0, &pmu->fsys_arm_configuration); + writel(0x0, &pmu->sata_phy_control); + } diff --git a/board/samsung/smdk5250/dmc_init.c b/board/samsung/smdk5250/dmc_init.c index 788107465..f9bdd58c5 100644 --- a/board/samsung/smdk5250/dmc_init.c +++ b/board/samsung/smdk5250/dmc_init.c @@ -26,437 +26,1061 @@ #include <asm/io.h> #include <asm/arch/dmc.h> #include <asm/arch/clock.h> +#include <asm/arch/power.h> #include <asm/arch/cpu.h> #include "setup.h" -/* APLL : 1GHz */ -/* MCLK_CDREX: MCLK_CDREX_533*/ -/* LPDDR support: LPDDR2 */ -static void reset_phy_ctrl(void); -static void config_zq(struct exynos5_phy_control *, - struct exynos5_phy_control *); -static void update_reset_dll(struct exynos5_dmc *); -static void config_cdrex(void); -static void config_mrs(struct exynos5_dmc *); -static void sec_sdram_phy_init(struct exynos5_dmc *); -static void config_prech(struct exynos5_dmc *); -static void config_rdlvl(struct exynos5_dmc *, - struct exynos5_phy_control *, - struct exynos5_phy_control *); -static void config_memory(struct exynos5_dmc *); - -static void config_offsets(unsigned int, - struct exynos5_phy_control *, - struct exynos5_phy_control *); - -static void reset_phy_ctrl(void) +#define CONFIG_DMC_CALIBRATION +#undef CONFIG_DMC_CA_CALIBRATION +#define CONFIG_ODTOFF_GATELEVELINGON +#define CONFIG_DMC_BRB +#undef CONFIG_WR_DQ_CAL + +#define DDR_R1_FBM_BASE 0x10c30000 +#define DDR_R0_FBM_BASE 0x10dc0000 +#define FBM_MODESEL0 0x0 +#define FBM_THRESHOLDSEL0 0x40 + + +static void set_memclk(void) { struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + volatile u32 ubits; - writel(PHY_RESET_VAL, &clk->lpddr3phy_ctrl); - sdelay(0x10000); -} + /* MEM Clock = 800 MHz */ + + /* CLK_SRC_CDREX */ + /* MCLK_DPHY(0:8), MCLK_CDREX(0:4), BPLL(0:0) */ + ubits = (0 << 8) | (0 << 4) | (1 << 0); + writel(ubits, &clk->src_cdrex); -static void config_zq(struct exynos5_phy_control *phy0_ctrl, - struct exynos5_phy_control *phy1_ctrl) -{ - unsigned long val = 0; /* - * ZQ Calibration: - * Select Driver Strength, - * long calibration for manual calibration + * CLK_DIV_CDREX + * MCLK_DPHY = 800 / 1 = 800 + * MCLK_CDREX = 800 / 1 = 800 + * ACLK_CDREX = MCLK_CDREX / 2 = 400 + * PCLK_CDREX = 800 / 1 / 6 = 133 + * MCLK_CDREX2(1/1:28), ACLK_SFRTZASCP(1/2:24), MCLK_DPHY(1/1:20), + * MCLK_CDREX(1/1:16), PCLK_CDREX(1/6:4), ACLK_CDREX(1/2:0) */ - val = PHY_CON16_RESET_VAL; - SET_ZQ_MODE_DDS_VAL(val); - SET_ZQ_MODE_TERM_VAL(val); - val |= ZQ_CLK_DIV_EN; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); - - /* Disable termination */ - val |= ZQ_MODE_NOTERM; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); - - /* ZQ_MANUAL_START: Enable */ - val |= ZQ_MANUAL_STR; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); - sdelay(0x10000); + ubits = (0 << 28) | (1 << 24) | (0 << 20) | (0 << 16) | (5 << 4) | (1 << 0); + writel(ubits, &clk->div_cdrex); - /* ZQ_MANUAL_START: Disable */ - val &= ~ZQ_MANUAL_STR; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); -} + /* CLK_SRC_CORE1 */ + /* MPLL(0:8) : FINPLL=0 */ + ubits = (1 << 8); + writel(readl(&clk->src_core1) & ~ubits, &clk->src_core1); -static void update_reset_dll(struct exynos5_dmc *dmc) -{ - unsigned long val; - /* - * Update DLL Information: - * Force DLL Resyncronization - */ - val = readl(&dmc->phycontrol0); - val |= FP_RSYNC; - writel(val, &dmc->phycontrol0); - - /* Reset Force DLL Resyncronization */ - val = readl(&dmc->phycontrol0); - val &= ~FP_RSYNC; - writel(val, &dmc->phycontrol0); -} + /* Setting MPLL [P,M,S] */ + /* set MPLL_CONT1 */ + ubits = (1 << 21) | (3 << 12) | (8 << 8); + writel(ubits, &clk->mpll_con1); -static void config_mrs(struct exynos5_dmc *dmc) -{ - unsigned long channel, chip, mask = 0, val; - - for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) { - SET_CMD_CHANNEL(mask, channel); - for (chip = 0; chip < CONFIG_CHIPS_PER_CHANNEL; chip++) { - /* - * NOP CMD: - * Assert and hold CKE to logic high level - */ - SET_CMD_CHIP(mask, chip); - val = DIRECT_CMD_NOP | mask; - writel(val, &dmc->directcmd); - sdelay(0x10000); - - /* EMRS, MRS Cmds(Mode Reg Settings) Using Direct Cmd */ - val = DIRECT_CMD_MRS1 | mask; - writel(val, &dmc->directcmd); - sdelay(0x10000); - - val = DIRECT_CMD_MRS2 | mask; - writel(val, &dmc->directcmd); - sdelay(0x10000); - - /* MCLK_CDREX_533 */ - val = DIRECT_CMD_MRS3 | mask; - writel(val, &dmc->directcmd); - sdelay(0x10000); - - val = DIRECT_CMD_MRS4 | mask; - writel(val, &dmc->directcmd); - sdelay(0x10000); - } - } -} + /* set MPLL_CON0 : MPLL=1600Mhz*/ + /* ENABLE(1), MDIV(200), PDIV(3), SDIV(0) */ + ubits = (1 << 31) | (200 << 16) | (3 << 8) | (0 << 0); + writel(ubits, &clk->mpll_con0); -static void config_prech(struct exynos5_dmc *dmc) -{ - unsigned long channel, chip, mask = 0, val; - - for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) { - SET_CMD_CHANNEL(mask, channel); - for (chip = 0; chip < CONFIG_CHIPS_PER_CHANNEL; chip++) { - SET_CMD_CHIP(mask, chip); - /* PALL (all banks precharge) CMD */ - val = DIRECT_CMD_PALL | mask; - writel(val, &dmc->directcmd); - sdelay(0x10000); - } - } -} + /* check mpll locking status */ + while ((readl(&clk->mpll_con0) & (1 << 29)) == 0); -static void sec_sdram_phy_init(struct exynos5_dmc *dmc) -{ - unsigned long val; - val = readl(&dmc->concontrol); - val |= DFI_INIT_START; - writel(val, &dmc->concontrol); - sdelay(0x10000); + /* CLK_SRC_CORE1 */ + /* MPLL(0:8) : MOUT_MPLLOUT=1 */ + ubits = (1 << 8); + writel(ubits, &clk->src_core1); - val = readl(&dmc->concontrol); - val &= ~DFI_INIT_START; - writel(val, &dmc->concontrol); } - -static void config_offsets(unsigned int state, - struct exynos5_phy_control *phy0_ctrl, - struct exynos5_phy_control *phy1_ctrl) +static void dmc_zqinit(u8 dq, u8 ck, u8 cke, u8 cs, u8 ca) { - unsigned long val; - /* Set Offsets to read DQS */ - val = (state == SET) ? SET_DQS_OFFSET_VAL : RESET_DQS_OFFSET_VAL; - writel(val, &phy0_ctrl->phy_con4); - writel(val, &phy1_ctrl->phy_con4); - - /* Set Offsets to read DQ */ - val = (state == SET) ? SET_DQ_OFFSET_VAL : RESET_DQ_OFFSET_VAL; - writel(val, &phy0_ctrl->phy_con6); - writel(val, &phy1_ctrl->phy_con6); - - /* Debug Offset */ - val = (state == SET) ? SET_DEBUG_OFFSET_VAL : RESET_DEBUG_OFFSET_VAL; - writel(val, &phy0_ctrl->phy_con10); - writel(val, &phy1_ctrl->phy_con10); -} + u32 temp; + u32 zqbase; + int ch; -static void config_cdrex(void) -{ - struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; - writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex); - writel(CLK_SRC_CDREX_VAL, &clk->src_cdrex); - sdelay(0x30000); -} + for (ch = 0; ch < 2; ch++) { -static void config_ctrl_dll_on(unsigned int state, - unsigned int ctrl_force_val, - struct exynos5_phy_control *phy0_ctrl, - struct exynos5_phy_control *phy1_ctrl) -{ - unsigned long val; - val = readl(&phy0_ctrl->phy_con12); - CONFIG_CTRL_DLL_ON(val, state); - SET_CTRL_FORCE_VAL(val, ctrl_force_val); - writel(val, &phy0_ctrl->phy_con12); - - val = readl(&phy1_ctrl->phy_con12); - CONFIG_CTRL_DLL_ON(val, state); - SET_CTRL_FORCE_VAL(val, ctrl_force_val); - writel(val, &phy1_ctrl->phy_con12); -} + zqbase = 0x10c00000 + (0x10000 * ch); -static void config_ctrl_start(unsigned int state, - struct exynos5_phy_control *phy0_ctrl, - struct exynos5_phy_control *phy1_ctrl) -{ - unsigned long val; - val = readl(&phy0_ctrl->phy_con12); - CONFIG_CTRL_START(val, state); - writel(val, &phy0_ctrl->phy_con12); - - val = readl(&phy1_ctrl->phy_con12); - CONFIG_CTRL_START(val, state); - writel(val, &phy1_ctrl->phy_con12); -} + temp = readl(zqbase + 0x40); + temp &= 0xF8FBFFF1; + temp |= ((dq & 0x7) << 24); + temp |= ((1<< 18) | (1 << 2)); -#if defined(CONFIG_RD_LVL) -static void config_rdlvl(struct exynos5_dmc *dmc, - struct exynos5_phy_control *phy0_ctrl, - struct exynos5_phy_control *phy1_ctrl) -{ - unsigned long val; + writel(temp, zqbase + 0x40); - /* Disable CTRL_DLL_ON and set ctrl_force */ - config_ctrl_dll_on(RESET, 0x2D, phy0_ctrl, phy1_ctrl); + temp |= (1 << 1); - /* - * Set ctrl_gateadj, ctrl_readadj - * ctrl_gateduradj, rdlvl_pass_adj - * rdlvl_rddataPadj - */ - val = SET_RDLVL_RDDATAPADJ; - writel(val, &phy0_ctrl->phy_con1); - writel(val, &phy1_ctrl->phy_con1); - - /* LPDDR2 Address */ - writel(LPDDR2_ADDR, &phy0_ctrl->phy_con22); - writel(LPDDR2_ADDR, &phy1_ctrl->phy_con22); - - /* Enable Byte Read Leveling set ctrl_ddr_mode */ - val = readl(&phy0_ctrl->phy_con0); - val |= BYTE_RDLVL_EN; - writel(val, &phy0_ctrl->phy_con0); - val = readl(&phy1_ctrl->phy_con0); - val |= BYTE_RDLVL_EN; - writel(val, &phy1_ctrl->phy_con0); - - /* rdlvl_en: Use levelling offset instead ctrl_shiftc */ - val = PHY_CON2_RESET_VAL | RDLVL_EN; - writel(val, &phy0_ctrl->phy_con2); - writel(val, &phy1_ctrl->phy_con2); - sdelay(0x10000); + writel(temp, zqbase + 0x40); - /* Enable Data Eye Training */ - val = readl(&dmc->rdlvl_config); - val |= CTRL_RDLVL_DATA_EN; - writel(val, &dmc->rdlvl_config); - sdelay(0x10000); + while((readl(zqbase + 0x48) & 0x5) != 0x1); - /* Disable Data Eye Training */ - val = readl(&dmc->rdlvl_config); - val &= ~CTRL_RDLVL_DATA_EN; - writel(val, &dmc->rdlvl_config); + temp = readl(zqbase + 0x40); - /* RdDeSkew_clear: Clear */ - val = readl(&phy0_ctrl->phy_con2); - val |= RDDSKEW_CLEAR; - writel(val, &phy0_ctrl->phy_con2); - val = readl(&phy1_ctrl->phy_con2); - val |= RDDSKEW_CLEAR; - writel(val, &phy1_ctrl->phy_con2); + temp &= ~(1 << 18); - /* Enable CTRL_DLL_ON */ - config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl); + writel(temp, zqbase + 0x40); - update_reset_dll(dmc); - sdelay(0x10000); + temp = ((ck & 0x7) << 9) | ((cke & 0x7) << 6) | + ((cs & 0x7) << 3) | (ca & 0x7); - /* ctrl_atgte: ctrl_gate_p*, ctrl_read_p* generated by PHY */ - val = readl(&phy0_ctrl->phy_con0); - val &= ~CTRL_ATGATE; - writel(val, &phy0_ctrl->phy_con0); - val = readl(&phy1_ctrl->phy_con0); - val &= ~CTRL_ATGATE; - writel(val, &phy1_ctrl->phy_con0); + writel(temp, zqbase + 0xA0); + } } -#endif -static void config_memory(struct exynos5_dmc *dmc) +static void dmc_catraining(int ch) { - /* - * Memory Configuration Chip 0 - * Address Mapping: Interleaved - * Number of Column address Bits: 10 bits - * Number of Rows Address Bits: 14 - * Number of Banks: 8 - */ - writel(DMC_MEMCONFIG0_VAL, &dmc->memconfig0); + struct exynos5_dmc *dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; + unsigned char code; + int find_vmw; + unsigned int phybase; + unsigned int iord_offset; + unsigned int temp, mr41, mr48, vwml, vwmr, vwmc; + unsigned int lock; + unsigned int resp_mr41, resp_mr48; + + phybase = EXYNOS5_DMC_PHY0_BASE+(0x10000 * ch); + iord_offset = 0x150 + (0x4 * ch); + + temp = readl(phybase + 0x0000); + temp |= (1 << 16); + writel(temp, phybase + 0x0000); + + temp = readl(phybase + 0x0008); + temp |= (1 << 23); + writel(temp, phybase + 0x0008); + + code = 0x8; + find_vmw = 0; + vwml = vwmr = vwmc = 0; + + if (exynos_pkg_is_pop()) { + resp_mr41 = 0x5555; + resp_mr48 = 0x0101; + } else { + if ( ch == 0 ) { + resp_mr41 = 0x69C5; + resp_mr48 = 0x4040; + } else { + resp_mr41 = 0xD14E; + resp_mr48 = 0x8008; + } + } - /* - * Memory Configuration Chip 1 - * Address Mapping: Interleaved - * Number of Column address Bits: 10 bits - * Number of Rows Address Bits: 14 - * Number of Banks: 8 - */ - writel(DMC_MEMCONFIG1_VAL, &dmc->memconfig1); + while (1) { + + /* code update */ + temp = readl(phybase + 0x0028); + temp &= 0xFFFFFF00; + temp |= code; + writel(temp, phybase + 0x0028); + + /* resync */ + temp = readl(phybase + 0x0028); + temp &= 0xFEFFFFFF; + writel(temp, phybase + 0x0028); + temp |= 0x01000000; + writel(temp, phybase + 0x0028); + temp &= 0xFEFFFFFF; + writel(temp, phybase + 0x0028); + + if (ch == 0) { + /* Send MRW: MA=0x29 OP=0xA4, 0x50690 */ + writel(0x50690, &dmc->directcmd); + } else { + /* Send MRW: MA=0x29 OP=0xA4, 0x10050690 */ + writel(0x10050690, &dmc->directcmd); + } - /* - * Chip0: AXI - * AXI Base Address: 0x40000000 - * AXI Base Address Mask: 0x780 - */ - writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0); + /* Set DMC.CACAL_CONFIG0.deassert_cke=1 */ + writel(0x3FF011, &dmc->cacal_config0); + /* Set DMC.CACAL_CONFIG1.cacal_csn=1 */ + writel(0x1, &dmc->cacal_config1); + sdelay(0x100); + + mr41 = readl(EXYNOS5_DMC_CTRL_BASE + iord_offset); + mr41 &= 0xFFFF; + + /* Set DMC.CACAL_CONFIG0.deassert_cke=0 */ + writel(0x3FF010, &dmc->cacal_config0); + sdelay(0x100); + + if (ch == 0) { + /* Send MRW: MA=0x30 OP=0xC0, 0x60300 */ + writel(0x60300, &dmc->directcmd); + } else { + /* Send MRW: MA=0x30 OP=0xC0, 0x10060300 */ + writel(0x10060300, &dmc->directcmd); + } - /* - * Chip1: AXI - * AXI Base Address: 0x80000000 - * AXI Base Address Mask: 0x780 - */ - writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1); + /* Set DMC.CACAL_CONFIG0.deassert_cke=1 */ + writel(0x3FF011, &dmc->cacal_config0); + /* Set DMC.CACAL_CONFIG1.cacal_csn=1 */ + writel(0x1, &dmc->cacal_config1); + sdelay(0x100); + + mr48 = readl(EXYNOS5_DMC_CTRL_BASE + iord_offset ); + + if (exynos_pkg_is_pop()) { + mr48 &= 0x0303; + } else { + if (ch == 0) + mr48 &= 0xC060; + else + mr48 &= 0x8418; + } + + /* Set DMC.CACAL_CONFIG0.deassert_cke=0 */ + writel(0x3FF010, &dmc->cacal_config0); + sdelay(0x100); + + if ((find_vmw == 0) && (mr41 == resp_mr41) + && (mr48 == resp_mr48)) { + find_vmw = 0x1; + vwml = code; + } + + if ((find_vmw == 1) && ((mr41 != resp_mr41) + || (mr48 != resp_mr48))) { + find_vmw = 0x3; + vwmr = code - 1; + + if( ch == 0 ) { + /* Send MRW: MA=0x2A OP=0xA8, 0x50AA0 */ + writel(0x50AA0, &dmc->directcmd); + } else { + /* Send MRW: MA=0x2A OP=0xA8, 0x10050AA0 */ + writel(0x10050AA0, &dmc->directcmd); + } + break; + } + + code++; + + if (code == 255) + while(1); + } + + vwmc = (vwml + vwmr) / 2; + + { + unsigned int lock_force; + unsigned int temp = 0; + + lock_force = (readl( phybase + 0x30 ) >> 8) & 0x7F; + + temp = ((vwml & 0xFF) << 16) | + ((vwmr & 0xFF) << 8) | + ((vwmc & 0xFF)); + + if(ch == 0) + writel(temp, 0x10040818); + else + writel(temp, 0x1004081C); + } + /* code update */ + temp = readl(phybase + 0x0028); + temp &= 0xFFFFFF00; + temp |= vwmc; + writel(temp, phybase + 0x0028); + + /* resync */ + temp = readl(phybase + 0x0028); + temp &= 0xFEFFFFFF; + writel(temp, phybase + 0x0028); + temp |= 0x01000000; + writel(temp, phybase + 0x0028); + temp &= 0xFEFFFFFF; + writel(temp, phybase + 0x0028); + + temp = readl(phybase+0x0000); + temp &= 0xFFFEFFFF; + writel(temp, phybase + 0x0000); + + /* vmwc convert to offsetd value. */ + lock = readl(phybase + 0x0034); + lock &= 0x1FF00; + lock >>= 8; + + if( (lock & 0x3) == 0x3 ) + lock++; + + code = vwmc - (lock >> 2); + + temp = readl(phybase + 0x0028); + temp &= 0xFFFFFF00; + temp |= code; + writel(temp, phybase + 0x0028); + + temp = readl(phybase + 0x0008); + temp &= 0xFF7FFFFF; + writel(temp, phybase + 0x0008); } -void mem_ctrl_init() +#if defined(CONFIG_LPDDR3) +static void mem_ctrl_init_lpddr3() { struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; struct exynos5_dmc *dmc; - unsigned long val; + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + unsigned int lock, temp; phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE; phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE; dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; - /* Reset PHY Controllor: PHY_RESET[0] */ - reset_phy_ctrl(); - - /*set Read Latancy and Burst Length for PHY0 and PHY1 */ - writel(PHY_CON42_VAL, &phy0_ctrl->phy_con42); - writel(PHY_CON42_VAL, &phy1_ctrl->phy_con42); - - /* ZQ Cofiguration */ - config_zq(phy0_ctrl, phy1_ctrl); + /* Step2. the right value to PHY_CON0.ctrl_ddr_mode */ + /* PHY.CON0[12:11].ctrl_ddr_mode=LPDDR3 */ + writel(0x17021A40, &phy0_ctrl->phy_con0); + writel(0x17021A40, &phy1_ctrl->phy_con0); + + /* Step3. Enable CA swap when POP is used */ + /* PHY.CON0.ctrl_atgate=0x0 */ + writel(0x17021A00, &phy0_ctrl->phy_con0); + writel(0x17021A00, &phy1_ctrl->phy_con0); + + if (exynos_pkg_is_pop()) { + /* LPDDR3PHY_CON3[31]=1. */ + writel(0x80000000, &clk->lpddr3phy_con3); + /* PHY.CON24=1. */ + writel(0x1, &phy0_ctrl->phy_con24); + writel(0x1, &phy1_ctrl->phy_con24); + } else { + /* LPDDR3PHY_CON3[31]=0. */ + writel(0x0, &clk->lpddr3phy_con3); + /* PHY.CON24=0. */ + writel(0x0, &phy0_ctrl->phy_con24); + writel(0x0, &phy1_ctrl->phy_con24); + } - /* Operation Mode : LPDDR2 */ - val = PHY_CON0_RESET_VAL; - SET_CTRL_DDR_MODE(val, DDR_MODE_LPDDR2); - writel(val, &phy0_ctrl->phy_con0); - writel(val, &phy1_ctrl->phy_con0); + /* Step4. Set PHY for DQS pull-down mode */ + /* PHY.CON14.ctrl_pulld_dq=0x0, ctrl_pulld_dqs=0x0F */ + writel(0x0F, &phy0_ctrl->phy_con14); + writel(0x0F, &phy1_ctrl->phy_con14); + + /* Step5. Set PHY_CON42.ctrl_bstlen and PHY_CON42.ctrl_rdlat */ + /* PHY.CON42.ctrl_bstlen[12:8]=0x8, ctrl_rdlat[4:0]=0x0C */ + writel(0x80C, &phy0_ctrl->phy_con42); + writel(0x80C, &phy1_ctrl->phy_con42); + + /* PHY.CON26.T_wrdata_en[20:16]=0x7 */ + writel(0x7107F, &phy0_ctrl->phy_con26); + writel(0x7107F, &phy1_ctrl->phy_con26); + + /* Set PHY.PHY_CON0.ctrl_read_disable=0x0 */ + /* Set PHY.PHY_CON16.zq_term */ + writel(0x17021A00, &phy0_ctrl->phy_con0); + writel(0x8080304, &phy0_ctrl->phy_con16); + writel(0x17021A00, &phy1_ctrl->phy_con0); + writel(0x8080304, &phy1_ctrl->phy_con16); + //- Set 0x1003_0B00[0]=0x1 + writel(0x1, 0x10030B00); + + /* Step6. ZQ calibration */ + if (exynos_pkg_is_pop()) { + /* Set PHY0.CON16.zq_mode_dds=0x6000000 */ + writel(0xE0C0304, &phy0_ctrl->phy_con16); + /* Set PHY0.CON16.zq_manual_mode=1 */ + writel(0xE0C0304, &phy0_ctrl->phy_con16); + /* Set PHY0.CON16.zq_manual_str */ + writel(0xE0C0306, &phy0_ctrl->phy_con16); + /* Wait for PHY0.CON17.zq_done */ + while((readl(&phy0_ctrl->phy_con17) & 0x1) != 0x1); + /* Set PHY0.CON16.zq_clk_en=0 */ + writel(0xE080304, &phy0_ctrl->phy_con16); + + /* Set PHY1.CON16.zq_mode_dds=0x6000000 */ + writel(0xE0C0304, &phy1_ctrl->phy_con16); + /* Set PHY1.CON16.zq_manual_mode=1 */ + writel(0xE0C0304, &phy1_ctrl->phy_con16); + /* Set PHY1.CON16.zq_manual_str */ + writel(0xE0C0306, &phy1_ctrl->phy_con16); + /* Wait for PHY1.CON17.zq_done */ + while((readl(&phy1_ctrl->phy_con17) & 0x1) != 0x1); + /* Set PHY1.CON16.zq_clk_en=0 */ + writel(0xE080304, &phy1_ctrl->phy_con16); + + /* PHY0.CON39[11:0]=0xDB6 */ + writel(0xDB6, &phy0_ctrl->phy_con39); + writel(0xDB6, &phy1_ctrl->phy_con39); + } else { + dmc_zqinit(0x4, 0x4, 0x4, 0x4, 0x4); + } - /* DQS, DQ: Signal, for LPDDR2: Always Set */ - val = CTRL_PULLD_DQ | CTRL_PULLD_DQS; - writel(val, &phy0_ctrl->phy_con14); - writel(val, &phy1_ctrl->phy_con14); + /* + * Step7. Set CONCONTROL. + * At this moment, assert the dfi_init_start field to high. + */ + /* DMC.CONCOTROL.rdfetch=0x2 */ + writel(0xFFF2100, &dmc->concontrol); + /* DMC.CONCOTROL : assert dfi_init_start */ + writel(0x1FFF2100, &dmc->concontrol); + sdelay(0x10000); //- wait 100ms + /* DMC.CONCOTROL : deassert dfi_init_start */ + writel(0xFFF2100, &dmc->concontrol); - /* Init SEC SDRAM PHY */ - sec_sdram_phy_init(dmc); - sdelay(0x10000); + /* phase 2 : setting controller register */ - update_reset_dll(dmc); + /* + * Step8. set memcontrol. + * at this moment, switch off all low power feature. + */ + writel(0x312700, &dmc->memcontrol); + + /* Step9. set the membaseconfig0 register. */ + /* if there are two external memory chips set the membasecon1 reg.*/ + /* chipbase0=0x40, mask=0x7c0 */ + writel(0x4007c0, &dmc->membaseconfig0); + /* chipbase1=0x80, mask=0x7c0 */ + writel(0x8007c0, &dmc->membaseconfig1); + /* set memconfig0,1 */ + writel(0x1323, &dmc->memconfig0); + writel(0x1323, &dmc->memconfig1); + + /* Step10. Set the PRECHCONFIG register */ + /* DMC.PRECHCONFIG[15:0]=(0x0|0x0) */ + writel(0xFF000000, &dmc->prechconfig); /* - * Dynamic Clock: Always Running - * Memory Burst length: 4 - * Number of chips: 2 - * Memory Bus width: 32 bit - * Memory Type: LPDDR2-S4 - * Additional Latancy for PLL: 1 Cycle + * Step11. + * Set the TIMINGAREF, TIMINGROW, TIMINGDATA,TIMINGPOWER registers + * according to memory AC parameters. */ - writel(DMC_MEMCONTROL_VAL, &dmc->memcontrol); + /* DMC.ivcontrol.iv_size=0x7 */ + writel(0x7, &dmc->ivcontrol); + /* DMC.TIMINGAREF.tREFI=0x5D */ + writel(0x5D, &dmc->timingaref); + /* DMC.TIMINGROW=0x34498692 */ + writel(0x34498692, &dmc->timingrow); + /* DMC.TIMINGDATA=0x3630560C */ + writel(0x3630560C, &dmc->timingdata); + /* DMC.TIMINGPOWER=0x50380336 */ + writel(0x50380336, &dmc->timingpower); + writel(0x312700, &dmc->memcontrol); - config_memory(dmc); + /* + * Step12. + * Set the QOSCONTROL0~15 and BRBQOSCONFIG register + * if Qos Scheme is required. + */ + /* QOS#0~14.=0xFFF, QOS#15=0x0 */ + writel(0xFFF, &dmc->qoscontrol0); + writel(0xFFF, &dmc->qoscontrol1); + writel(0xFFF, &dmc->qoscontrol2); + writel(0xFFF, &dmc->qoscontrol3); + writel(0xFFF, &dmc->qoscontrol4); + writel(0xFFF, &dmc->qoscontrol5); + writel(0xFFF, &dmc->qoscontrol6); + writel(0xFFF, &dmc->qoscontrol7); + writel(0xFFF, &dmc->qoscontrol8); + writel(0xFFF, &dmc->qoscontrol9); + writel(0xFFF, &dmc->qoscontrol10); + writel(0xFFF, &dmc->qoscontrol11); + writel(0xFFF, &dmc->qoscontrol12); + writel(0xFFF, &dmc->qoscontrol13); + writel(0xFFF, &dmc->qoscontrol14); + writel(0x0, &dmc->qoscontrol15); - /* Precharge Configuration */ - writel(DMC_PRECHCONFIG_VAL, &dmc->prechconfig); + /* + * Step13. Set the PHY_CON4.ctrl_offsetr0~3 + * and PHY_CON6.ctrl_offsetw0~3 to 0x7F. + */ + /* READ SDLL : offsetr=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F */ + writel(0x7F7F7F7F, &phy0_ctrl->phy_con4); + writel(0x7F7F7F7F, &phy1_ctrl->phy_con4); + /* WRTIE SDLL : offsetr=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F */ + writel(0x7F7F7F7F, &phy0_ctrl->phy_con6); + writel(0x7F7F7F7F, &phy1_ctrl->phy_con6); + + /* Step14. Set the PHY_CON10.ctrl_offsetd value to 0x7F. */ + writel(0x7F, &phy0_ctrl->phy_con10); + writel(0x7F, &phy1_ctrl->phy_con10); + + /* Step15. Set the PHY_CON12.ctrl_force value to 0x7F.*/ + writel(0x10107F70, &phy0_ctrl->phy_con12); + writel(0x10107F70, &phy1_ctrl->phy_con12); + + /* Step16. Set the PHY_CON12.ctrl_dll_on value to low.*/ + writel(0x10107F50, &phy0_ctrl->phy_con12); + writel(0x10107F50, &phy1_ctrl->phy_con12); + + /* Step17. Wait for 10 PCLK cycles. */ + sdelay(0x100); + + /* Step18. Update the DLL information. */ + /* fp_resync=1 */ + writel(0x8, &dmc->phycontrol0); + /* fp_resync=0 */ + writel(0x0, &dmc->phycontrol0); - /* Power Down mode Configuration */ - writel(DMC_PWRDNCONFIG_VAL, &dmc->pwrdnconfig); + /* + * PHASE 3 : Memory Initialization + */ + /* Step19. ~ 26. nop, mr63, mr10, mr1, mr2, mr3 command */ + /* port:0x0, cs:0x0 */ + writel(0x7000000, &dmc->directcmd); + sdelay(0x100); + writel(0x71C00, &dmc->directcmd); + sdelay(0x100); + writel(0x10BFC, &dmc->directcmd); + sdelay(0x100); + writel(0x50C, &dmc->directcmd); + sdelay(0x100); + writel(0x868, &dmc->directcmd); + sdelay(0x100); + writel(0xC04, &dmc->directcmd); + sdelay(0x100); + /* port:0x0, cs:0x1 */ + writel(0x7100000, &dmc->directcmd); + sdelay(0x100); + writel(0x171C00, &dmc->directcmd); + sdelay(0x100); + writel(0x110BFC, &dmc->directcmd); + sdelay(0x100); + writel(0x10050C, &dmc->directcmd); + sdelay(0x100); + writel(0x100868, &dmc->directcmd); + sdelay(0x100); + writel(0x100C04, &dmc->directcmd); + sdelay(0x100); + /* port:0x1, cs:0x0 */ + writel(0x17000000, &dmc->directcmd); + sdelay(0x100); + writel(0x10071C00, &dmc->directcmd); + sdelay(0x100); + writel(0x10010BFC, &dmc->directcmd); + sdelay(0x100); + writel(0x1000050C, &dmc->directcmd); + sdelay(0x100); + writel(0x10000868, &dmc->directcmd); + sdelay(0x100); + writel(0x10000C04, &dmc->directcmd); + sdelay(0x100); + /* port:0x1, cs:0x1 */ + writel(0x17100000, &dmc->directcmd); + sdelay(0x100); + writel(0x10171C00, &dmc->directcmd); + sdelay(0x100); + writel(0x10110BFC, &dmc->directcmd); + sdelay(0x100); + writel(0x1010050C, &dmc->directcmd); + sdelay(0x100); + writel(0x10100868, &dmc->directcmd); + sdelay(0x100); + writel(0x10100C04, &dmc->directcmd); + sdelay(0x100); + + /* Step.27 Return to the memory operating frequency.*/ + set_memclk(); - /* Periodic Refrese Interval */ - writel(DMC_TIMINGREF_VAL, &dmc->timingref); + /* + * Step.28 + * Set the PHY_CON4.ctrl_offsetr0~3 & PHY_CON6.ctrl_offsetw0~3 to 0x8. + */ + /* READ SDLL : offsetr=0:0x08, 1:0x08, 2:0x08, 3:0x08 */ + writel(0x8080808, &phy0_ctrl->phy_con4); + writel(0x8080808, &phy1_ctrl->phy_con4); + /* WRTIE SDLL : offsetw=0:0x08, 1:0x08, 2:0x08, 3:0x08 */ + writel(0x8080808, &phy0_ctrl->phy_con6); + writel(0x8080808, &phy1_ctrl->phy_con6); + /* Step29. Set the PHY_CON104.ctrl_offsetd value to 0x8. */ + writel(0x8, &phy0_ctrl->phy_con10); + writel(0x8, &phy1_ctrl->phy_con10); + + /* Step30. ~ 34. */ + /* PHY0_CON12.ctrl_dll_on[5] = 1*/ + writel(0x10107F70, &phy0_ctrl->phy_con12); + sdelay(0x100); + /* PHY0_CON12.ctrl_dll_on[6] = 0*/ + writel(0x10107F30, &phy0_ctrl->phy_con12); + /* PHY0_CON12.ctrl_dll_on[6] = 1*/ + writel(0x10107F70, &phy0_ctrl->phy_con12); + sdelay(0x100); + + /* PHY1_CON12.ctrl_dll_on[5] = 1*/ + writel(0x10107F70, &phy1_ctrl->phy_con12); + sdelay(0x100); + /* PHY1_CON12.ctrl_dll_on[6] = 0*/ + writel(0x10107F30, &phy1_ctrl->phy_con12); + /* PHY1_CON12.ctrl_dll_on[6] = 1*/ + writel(0x10107F70, &phy1_ctrl->phy_con12); + sdelay(0x100); + + /* Step35. ~ 36. */ + /* DMC.CONCOTROL : assert dfi_init_start */ + writel(0x1FFF2100, &dmc->concontrol); + /* Wait for DMC.dfi_init_complete_ch0/1 */ + while((readl(&dmc->phystatus) & 0xC) != 0xC); + /* DMC.CONCOTROL : deassert dfi_init_start */ + writel(0xFFF2100, &dmc->concontrol); + + /* Step37. Update the DLL information. */ + /* fp_resync=1 */ + writel(0x8, &dmc->phycontrol0); + /* fp_resync=0 */ + writel(0x0, &dmc->phycontrol0); + +#if defined(CONFIG_DMC_CALIBRATION) + /* 38) Do leveing and calibration */ + /* 39) Perform these steps */ /* - * TimingRow, TimingData, TimingPower Setting: - * Values as per Memory AC Parameters + * a. Update PHYCON12.ctrl_force with + * by using PHY_CON13.ctrl_lock_value[9:2] */ - writel(DMC_TIMINGROW_VAL, &dmc->timingrow); + lock = (readl(&phy0_ctrl->phy_con13) >> 8) & 0xFF; + if((lock & 0x3) == 0x3) { + lock++; + } - writel(DMC_TIMINGDATA_VAL, &dmc->timingdata); + temp = readl(&phy0_ctrl->phy_con12) & 0xFFFF80FF; + temp |= ((lock >> 2) << 8); + writel(temp, &phy0_ctrl->phy_con12); - writel(DMC_TIMINGPOWER_VAL, &dmc->timingpower); + lock = (readl(&phy1_ctrl->phy_con13) >> 8) & 0xFF; + if((lock & 0x3) == 0x3) { + lock++; + } - /* Memory Channel Inteleaving Size: 128 Bytes */ - writel(CONFIG_IV_SIZE, &dmc->ivcontrol); + temp = readl(&phy1_ctrl->phy_con12) & 0xFFFF80FF; + temp |= ((lock >> 2) << 8); + writel(temp, &phy1_ctrl->phy_con12); + + /* b. Enable PHY_CON0.ctrl_atgate */ + writel(0x17021A40, &phy0_ctrl->phy_con0); + writel(0x17021A40, &phy1_ctrl->phy_con0); + + /* d. Enable PHY_CON0.p0_cmd_en */ + writel(0x17025A40, &phy0_ctrl->phy_con0); + writel(0x17025A40, &phy1_ctrl->phy_con0); + + /* e. Enable PHY_CON2.InitDeskewEn */ + writel(0x10044, &phy0_ctrl->phy_con2); + writel(0x10044, &phy1_ctrl->phy_con2); + + /* f. Enable PHY_CON0.byte_rdlvl_en */ + writel(0x17027A40, &phy0_ctrl->phy_con0); + writel(0x17027A40, &phy1_ctrl->phy_con0); + + /* c. Disable PHY_CON12.ctrl_dll_on */ + temp = readl(&phy0_ctrl->phy_con12) & 0xFFFFFFDF; + writel(temp, &phy0_ctrl->phy_con12); + temp = readl(&phy1_ctrl->phy_con12) & 0xFFFFFFDF; + writel(temp, &phy1_ctrl->phy_con12); + sdelay(0x100); + + /* CA Training. */ +#if defined(CONFIG_DMC_CA_CALIBRATION) + dmc_catraining(0); + dmc_catraining(1); +#endif - /* Set DQS, DQ and DEBUG offsets */ - config_offsets(SET, phy0_ctrl, phy1_ctrl); + if (exynos_pkg_is_pop()) { + unsigned int cal_error = 0; + unsigned int cal_count = 0; + + /* Read DQ Calibration. */ + /* Set PHY0.CON1.rdlvl_rddata_adj */ + writel(0x92F00FF, &phy0_ctrl->phy_con1); + writel(0x92F00FF, &phy1_ctrl->phy_con1); + /* PHY0.CON22.lpddr2_addr=0x041 */ + writel(0x00000041, &phy0_ctrl->phy_con22); + writel(0x00000041, &phy1_ctrl->phy_con22); + /* Set PHY0.CON2.rdlvl_en */ + writel( 0x2010044, &phy0_ctrl->phy_con2); + writel( 0x2010044, &phy1_ctrl->phy_con2); + /* DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=1 */ + writel(0x2, &dmc->rdlvl_config); + /* Wait DMC.rdlvl_complete_ch0/1 */ + while((readl(&dmc->phystatus) & 0xC000) != 0xC000) { + if (cal_count++ > 10) { + cal_error = 1; + break; + } else + sdelay(100); + } + /* Set DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=0 */ + writel(0x0, &dmc->rdlvl_config); - /* Disable CTRL_DLL_ON and set ctrl_force */ - config_ctrl_dll_on(RESET, 0x7F, phy0_ctrl, phy1_ctrl); - sdelay(0x10000); + writel(0xC, &phy0_ctrl->phy_con5); + cal_error |= readl(&phy0_ctrl->phy_con21); - update_reset_dll(dmc); + writel(0xC, &phy1_ctrl->phy_con5); + cal_error |= readl(&phy1_ctrl->phy_con21); - /* Config MRS(Mode Register Settingg) */ - config_mrs(dmc); + writel(0x0, &phy0_ctrl->phy_con5); + writel(0x0, &phy1_ctrl->phy_con5); - config_cdrex(); + if (cal_error) { + /* clear PHYx.CON2.rdlvl_en */ + writel(readl(&phy0_ctrl->phy_con2) & ~(1<<25), &phy0_ctrl->phy_con2); + writel(readl(&phy1_ctrl->phy_con2) & ~(1<<25), &phy1_ctrl->phy_con2); + } + /* Write DQ Calibration. */ +#if defined(CONFIG_WR_DQ_CAL) + /* Wait for DMC.chip_busy_state CH0 */ + while((readl(&dmc->chipstatus_ch0) & 0x3) != 0x0); + while((readl(&dmc->chipstatus_ch1) & 0x3) != 0x0); + /* DMC.WRTRACONFIG */ + writel(0x1, &dmc->wrtra_config); + /* Read leveling control */ + writel(0x204, &phy0_ctrl->phy_con22); + writel(0x204, &phy1_ctrl->phy_con22); + /* Set "rdlvl_rddata_adj" to 0x0001 or 0x0100 in PHY_CON1*/ + writel(0x92F00FF, &phy0_ctrl->phy_con1); + writel(0x92F00FF, &phy1_ctrl->phy_con1); + /* PHY_CON2 */ + writel(0x6010044, &phy0_ctrl->phy_con2); + writel(0x6010044, &phy1_ctrl->phy_con2); + writel(0xE010044, &phy0_ctrl->phy_con2); + writel(0xE010044, &phy1_ctrl->phy_con2); + /* Wait DMC.rdlvl_complete_ch0/1 */ + while((readl(&dmc->phystatus) & 0xC000) != 0xC000); + writel(0x6010044, &phy0_ctrl->phy_con2); + writel(0x6010044, &phy1_ctrl->phy_con2); + + writel(0xC, &phy0_ctrl->phy_con5); + while(readl(&phy0_ctrl->phy_con21) != 0); + + writel(0xC, &phy1_ctrl->phy_con5); + while(readl(&phy1_ctrl->phy_con21) != 0); + + writel(0x0, &phy0_ctrl->phy_con5); + writel(0x0, &phy1_ctrl->phy_con5); +#endif + } - /* Reset DQS DQ and DEBUG offsets */ - config_offsets(RESET, phy0_ctrl, phy1_ctrl); + /* Step43. Enable PHY_CON12.ctrl_dll_on */ + temp = readl(&phy0_ctrl->phy_con12) | 0x20; + writel(temp, &phy0_ctrl->phy_con12); - /* Enable CTRL_DLL_ON */ - config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl); + temp = readl(&phy1_ctrl->phy_con12) | 0x20; + writel(temp, &phy1_ctrl->phy_con12); - /* Stop DLL Locking */ - config_ctrl_start(RESET, phy0_ctrl, phy1_ctrl); - sdelay(0x10000); + /* Step44. Disable PHY_CON.ctrl_atgate when POP is used */ + if (exynos_pkg_is_pop()) { + /* PHY_CON0.ctrl_atgate=0x0 */ + writel(0x17027A00, &phy0_ctrl->phy_con0); + writel(0x17027A00, &phy1_ctrl->phy_con0); + } + /* Set PHY_CON0.ctrl_upd_range=0x1 */ + writel(0x17127A00, &phy0_ctrl->phy_con0); + writel(0x17127A00, &phy1_ctrl->phy_con0); + + /* Step45. Enable PHY_CON2.DLLDeSkewEn */ + if (exynos_pkg_is_pop()) { + /* PHY_CON2.DllDeskewEn=1. */ + writel(0x2011044, &phy0_ctrl->phy_con2); + writel(0x2011044, &phy1_ctrl->phy_con2); + } else { + /* PHY_CON2.DllDeskewEn=1. */ + writel(0x11044, &phy0_ctrl->phy_con2); + writel(0x11044, &phy1_ctrl->phy_con2); + } + /* Step46. Update the DLL information */ + /* fp_resync=1 */ + writel(0x8, &dmc->phycontrol0); + /* fp_resync=0 */ + writel(0x0, &dmc->phycontrol0); +#endif - /* Start DLL Locking */ - config_ctrl_start(SET, phy0_ctrl, phy1_ctrl); - sdelay(0x10000); + /* Step47. ODT is not supported in LPDDR2/LPDDR3 */ + if (exynos_pkg_is_pop()) { + /* Set PHY_PHY_CON0.ctrl_read_disable=0x0 */ + /* Set PHY_PHY_CON16.zq_term. */ + writel(0x17127A00, &phy0_ctrl->phy_con0); + writel(0xE080304, &phy0_ctrl->phy_con16); + writel(0x17127A00, &phy1_ctrl->phy_con0); + writel(0xE080304, &phy1_ctrl->phy_con16); + } + + /* Step48. Issue the PALL command to memory */ + writel(0x1000000, &dmc->directcmd); + writel(0x1100000, &dmc->directcmd); + writel(0x11000000, &dmc->directcmd); + writel(0x11100000, &dmc->directcmd); + /* Step49. Set the MEMCONTROL if power-down modes are required. */ + /* DMC.MEMCONTROL.tp_en=0x0. */ + writel(0x312700, &dmc->memcontrol); + /* DMC.PRECHCONFIG.tp_cnt=0xFF */ + writel(0xFF000000, &dmc->prechconfig); + /* DMC.PWRDNCONFIG.dsref_cyc=0xFFFF0000 */ + writel(0xFFFF00FF, &dmc->pwrdnconfig); + /* Set DMC.MEMCONTROL.dsref_en=0x20. */ + writel(0x312720, &dmc->memcontrol); + /* Set DMC.PWRDNCONFIG.dpwrdn_cyc=0xFF */ + writel(0xFFFF00FF, &dmc->pwrdnconfig); + /* Set DMC.MEMCONTROL.dpwrdn_en=0x2., dpwrdn_type=0x0 */ + writel(0x312722, &dmc->memcontrol); + /* DMC.MEMCONTROL.clk_stop_en=0x1. */ + writel(0x312723, &dmc->memcontrol); + /* Set DMC.PHYCONTROL.io_pd_con=0x1. */ + writel(0xFFF2108, &dmc->concontrol); + /* Step50. Set the CONCONTROL to turn on an auto refresh counter. */ + writel(0xFFF2128, &dmc->concontrol); + +} - update_reset_dll(dmc); +#else +static void mem_ctrl_init_ddr3(void) +{ + struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; + struct exynos5_dmc *dmc; + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; -#if defined(CONFIG_RD_LVL) - config_rdlvl(dmc, phy0_ctrl, phy1_ctrl); + phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE; + phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE; + dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; + unsigned int ap_odt, dram_odt; + +#if defined(CONFIG_ODTOFF_GATELEVELINGON) + ap_odt = 0xE2C0000; + dram_odt = 0x2; +#else + /* ODT On and Gate Leveling Off */ + ap_odt = 0xE240000; + dram_odt = 0x42; #endif - config_prech(dmc); + + set_memclk(); + + /* wait 300ms */ + sdelay(0x10000); + + /* Run Phyreset when only not wakeup */ + if (!(readl(&pmu->wakeup_stat) & 0x80300000)) { + /* PHY_RESET[0]=0 */ + writel(0x00000000, &clk->lpddr3phy_ctrl); + sdelay(100); + /* PHY_RESET[0]=1 */ + writel(0x00000001, &clk->lpddr3phy_ctrl); + sdelay(100); + } + + /* PHY_CON39 : dds of CA = 0x3 */ + writel(0x000006DB, &phy0_ctrl->phy_con39); + writel(0x000006DB, &phy1_ctrl->phy_con39); + /* Set PHY_CON42.ctrl_bstlen[12:8]=8, ctrl_rdlat[4:0]=11 */ + writel(0x0000080B, &phy0_ctrl->phy_con42); + writel(0x0000080B, &phy1_ctrl->phy_con42); + + /* Set PHY.PHY_CON16 */ + /* zq_mode_dds[26:24], zq_mode_term[23:21], zq_clk_div_en[18]=1 */ + writel(ap_odt|0x0304, &phy0_ctrl->phy_con16); + writel(ap_odt|0x0304, &phy1_ctrl->phy_con16); + /* zq_mode_dds[26:24], zq_mode_term[23:21], zq_mode_noterm[19]=0 */ + writel(ap_odt|0x0304, &phy0_ctrl->phy_con16); + writel(ap_odt|0x0304, &phy1_ctrl->phy_con16); + /* zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=1 */ + writel(ap_odt|0x0306, &phy0_ctrl->phy_con16); + writel(ap_odt|0x0306, &phy1_ctrl->phy_con16); + /* Wait for PHY_CON17.zq_done */ + while((readl(&phy0_ctrl->phy_con17) & 0x1) != 0x1); + while((readl(&phy1_ctrl->phy_con17) & 0x1) != 0x1); + /* zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0 */ + writel(ap_odt|0x0304, &phy0_ctrl->phy_con16); + writel(ap_odt|0x0304, &phy1_ctrl->phy_con16); + + /* PHY_CON14.ctrl_pulld_dqs[3:0]=0xf */ + writel(0x0000000F, &phy0_ctrl->phy_con14); + writel(0x0000000F, &phy1_ctrl->phy_con14); + + /* dfi_init_start[28]=1, rd_fetch[14:12]=3 */ + writel((0x1FFF0000 | (0x3 << 12)), &dmc->concontrol); + /* mem_term_en[31]=1, phy_term_en[30]=1, */ + /* gate signal length[29]=1, fp_resync[3]=1*/ + writel(0xE0000008, &dmc->phycontrol0); + /* mem_term_en[31]=1, phy_term_en[30]=1, */ + /* gate signal length[29]=1, fp_resync[3]=0*/ + writel(0xE0000000, &dmc->phycontrol0); + + /* Set PHY_CON4.ctrl_offsetr0~3 & PHY_CON6.ctrl_offsetw0~3 to 0x8.*/ + /* READ SDLL : offsetr=0:0x08, 1:0x08, 2:0x08, 3:0x08 */ + writel(0x8080808, &phy0_ctrl->phy_con4); + writel(0x8080808, &phy1_ctrl->phy_con4); + /* WRTIE SDLL : offsetw=0:0x08, 1:0x08, 2:0x08, 3:0x08 */ + writel(0x8080808, &phy0_ctrl->phy_con6); + writel(0x8080808, &phy1_ctrl->phy_con6); + + /* Set the PHY_CON104.ctrl_offsetd value to 0x8. */ + writel(0x8, &phy0_ctrl->phy_con10); + writel(0x8, &phy1_ctrl->phy_con10); + + /* ctrl_force[14:8]=0x0, ctrl_start[6]=0, ctrl_dll_on[5]=1 */ + writel(0x10100030, &phy0_ctrl->phy_con12); + writel(0x10100030, &phy1_ctrl->phy_con12); + sdelay(100); + /* ctrl_dll_start[6]=1 */ + writel(0x10100070, &phy0_ctrl->phy_con12); + writel(0x10100070, &phy1_ctrl->phy_con12); + sdelay(100); + + /* Wait for DMC.dfi_init_complete_ch0/1 */ + while((readl(&dmc->phystatus) & 0xC) != 0xC); + + /* mem_term_en[31]=1, phy_term_en[30]=1, */ + /* gate signal length[29]=1, fp_resync[3]=1 */ + writel(0xE0000008, &dmc->phycontrol0); + /* fp_resync[3]=0 */ + writel(0xE0000000, &dmc->phycontrol0); + /* fp_resync[3]=1 */ + writel(0xE0000008, &dmc->phycontrol0); + /* fp_resync[3]=0 */ + writel(0xE0000000, &dmc->phycontrol0); + + /* dfi_init_start[28]=0, rd_fetch[14:12]=3 */ + writel((0x0FFF0000 | (0x3 << 12)), &dmc->concontrol); + /* DMC.ivcontrol.iv_size=0x7 */ + writel(0x7, &dmc->ivcontrol); + + /* set memconfig0,1 for bank interleaving */ + writel(0x00001333, &dmc->memconfig0); + writel(0x00001333, &dmc->memconfig1); + /* chipbase0=0x40, mask=0x780 */ + writel(0x00400780, &dmc->membaseconfig0); + /* chipbase1=0x80, mask=0x780 */ + writel(0x00800780, &dmc->membaseconfig1); + /* precharge policy counter */ + writel(0xFF000000, &dmc->prechconfig); + + /* low power counter */ + writel(0xFFFF00FF, &dmc->pwrdnconfig); + /* refresh counter */ + writel(0x000000BB, &dmc->timingaref); + /* timing row */ + writel(0x8C36650E, &dmc->timingrow); + /* timing data */ + writel(0x3630580B, &dmc->timingdata); + /* timing power */ + writel(0x41000A44, &dmc->timingpower); /* - * Dynamic Clock: Stops During Idle Period - * Dynamic Power Down: Enable - * Dynamic Self refresh: Enable + * Set the QOSCONTROL0~15 and BRBQOSCONFIG register + * if Qos Scheme is required. */ - val = readl(&dmc->memcontrol); - val |= CLK_STOP_EN | DPWRDN_EN | DSREF_EN; - writel(val, &dmc->memcontrol); - - /* Start Auto refresh */ - val = readl(&dmc->concontrol); - val |= AREF_EN; - writel(val, &dmc->concontrol); + /* QOS#0~14.=0xFFF, QOS#15=0x0 */ + writel(0xFFF, &dmc->qoscontrol0); + writel(0xFFF, &dmc->qoscontrol1); + writel(0xFFF, &dmc->qoscontrol2); + writel(0xFFF, &dmc->qoscontrol3); + writel(0xFFF, &dmc->qoscontrol4); + writel(0xFFF, &dmc->qoscontrol5); + writel(0xFFF, &dmc->qoscontrol6); + writel(0xFFF, &dmc->qoscontrol7); + writel(0xFFF, &dmc->qoscontrol8); + writel(0xFFF, &dmc->qoscontrol9); + writel(0xFFF, &dmc->qoscontrol10); + writel(0xFFF, &dmc->qoscontrol11); + writel(0xFFF, &dmc->qoscontrol12); + writel(0xFFF, &dmc->qoscontrol13); + writel(0xFFF, &dmc->qoscontrol14); + writel(0x0, &dmc->qoscontrol15); + + /* Issue the PALL command to memory */ + writel(0x01000000, &dmc->directcmd); + writel(0x01100000, &dmc->directcmd); + writel(0x11000000, &dmc->directcmd); + writel(0x11100000, &dmc->directcmd); + + writel(0x07000000, &dmc->directcmd); + writel(0x00020000 | 0x18, &dmc->directcmd); + writel(0x00030000, &dmc->directcmd); + writel(0x00010000 | dram_odt, &dmc->directcmd); + writel(0x00000000 | 0xD70, &dmc->directcmd); + writel(0x0a000000, &dmc->directcmd); + writel(0x17000000, &dmc->directcmd); + writel(0x10020000 | 0x18, &dmc->directcmd); + writel(0x10030000, &dmc->directcmd); + writel(0x10010000 | dram_odt, &dmc->directcmd); + writel(0x10000000 | 0xD70, &dmc->directcmd); + writel(0x1a000000, &dmc->directcmd); + +#if defined(CONFIG_ODTOFF_GATELEVELINGON) + /* ctrl_atgate=1 */ + writel(0x17020A40, &phy0_ctrl->phy_con0); + writel(0x17020A40, &phy1_ctrl->phy_con0); + + /* p0_cmd_en=1 */ + writel(0x17024A40, &phy0_ctrl->phy_con0); + writel(0x17024A40, &phy1_ctrl->phy_con0); + + /* InitDeskewEn=1 */ + writel(0x00010044, &phy0_ctrl->phy_con2); + writel(0x00010044, &phy1_ctrl->phy_con2); + + /* byte_rdlvl_en=1 */ + writel(0x17026A40, &phy0_ctrl->phy_con0); + writel(0x17026A40, &phy1_ctrl->phy_con0); + + /* ctrl_force[14:8], ctrl_dll_on[5]=0 */ + writel(0x10101950, &phy0_ctrl->phy_con12); + writel(0x10101950, &phy1_ctrl->phy_con12); + + /* rdlvl_gate_en=1 */ + writel(0x01010044, &phy0_ctrl->phy_con2); + writel(0x01010044, &phy1_ctrl->phy_con2); + + /* ctrl_shgate=1 */ + writel(0x17026B40, &phy0_ctrl->phy_con0); + writel(0x17026B40, &phy1_ctrl->phy_con0); + + /* ctrl_gateduradj=0 */ + writel(0x9010100, &phy0_ctrl->phy_con1); + writel(0x9010100, &phy1_ctrl->phy_con1); + + /* ctrl_rdlvl_data_en[1]=1 */ + writel(0x00000001, &dmc->rdlvl_config); + /* Wait DMC.rdlvl_complete_ch0/1 */ + while((readl(&dmc->phystatus) & 0xC000) != 0xC000); + /* ctrl_rdlvl_data_en[1]=0 */ + writel(0x00000000, &dmc->rdlvl_config); + + /* ctrl_pulld_dq[11:8]=0x0, ctrl_pulld_dqs[3:0]=0x0 */ + writel(0x00000000, &phy0_ctrl->phy_con14); + writel(0x00000000, &phy1_ctrl->phy_con14); + + /* ctrl_force[14:8], ctrl_start[6]=1, ctrl_dll_on[5]=1 */ + writel(0x10101970, &phy0_ctrl->phy_con12); + writel(0x10101970, &phy1_ctrl->phy_con12); + sdelay(100); + + /* ctrl_shgate[29]=1, fp_resync[3]=1 */ + writel(0xE0000008, &dmc->phycontrol0); + writel(0xE0000000, &dmc->phycontrol0); + + /* Issue the PALL command to memory */ + writel(0x01000000, &dmc->directcmd); + writel(0x01100000, &dmc->directcmd); + writel(0x11000000, &dmc->directcmd); + writel(0x11100000, &dmc->directcmd); +#endif + + /* bl[22:20]=8, mem_type[11:8]=7, dsref_en[5]=1, */ + /* dpwrdn_en[1]=1, clk_stop_en[0]=1 */ + writel(0x00302620, &dmc->memcontrol); + /* dfi_init_start[28]=1, rd_fetch[14:12]=3, aref_en[5]=1 */ + writel((0x0FFF0020 | (0x3 << 12)), &dmc->concontrol); +} +#endif + +void mem_ctrl_init() +{ + struct exynos5_dmc *dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; +#if defined(CONFIG_LPDDR3) + mem_ctrl_init_lpddr3(); +#else + mem_ctrl_init_ddr3(); +#endif + +#if defined(CONFIG_DMC_BRB) + /* DMC BRB QoS */ + writel(0x66668666, &dmc->brbrsvconfig); + writel(0xFF, &dmc->brbrsvcontrol); + writel(0x1, &dmc->brbqosconfig); + + /* DMC FBM */ + writel(0x0, DDR_R1_FBM_BASE + FBM_MODESEL0); + writel(0x4, DDR_R1_FBM_BASE + FBM_THRESHOLDSEL0); + writel(0x2, DDR_R0_FBM_BASE + FBM_MODESEL0); + writel(0x1, DDR_R0_FBM_BASE + FBM_THRESHOLDSEL0); +#endif } diff --git a/board/samsung/smdk5250/lowlevel_init.S b/board/samsung/smdk5250/lowlevel_init.S index bc6cb6f73..69c2ec0df 100644 --- a/board/samsung/smdk5250/lowlevel_init.S +++ b/board/samsung/smdk5250/lowlevel_init.S @@ -36,6 +36,14 @@ lowlevel_init: ldr sp, =CONFIG_IRAM_STACK stmdb r13!, {ip,lr} + /* PS-Hold high */ + ldr r0, =0x1004330c + ldr r1, [r0] + orr r1, r1, #0x100 + str r1, [r0] + + bl relocate_code + /* check reset status */ ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) ldr r1, [r0] @@ -55,6 +63,10 @@ lowlevel_init: cmp r1, r2 beq wakeup_reset + bl pmic_init + + bl read_om + /* * If U-boot is already running in RAM, no need to relocate U-Boot. * Memory controller must be configured before relocating U-Boot @@ -75,22 +87,106 @@ lowlevel_init: bl mem_ctrl_init 1: - bl tzpc_init ldmia r13!, {ip,pc} wakeup_reset: + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) + mov r1, #0x0 + str r1, [r0] + + bl read_om + + /* If eMMC booting */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + /* init system clock */ bl system_clock_init + + /* Memory initialize */ bl mem_ctrl_init - bl tzpc_init exit_wakeup: - /* Load return address and jump to kernel */ - ldr r0, =(EXYNOS5_POWER_BASE + INFORM0_OFFSET) + b warmboot - /* r1 = physical address of exynos5_cpu_resume function*/ +read_om: + /* Read booting information */ + ldr r0, =(EXYNOS5_POWER_BASE + OM_STATUS_OFFSET) ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC BOOT */ + cmp r2, #0x6 + moveq r3, #BOOT_EMMC + + /* eMMC 4.4 BOOT */ + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x28 + moveq r3, #BOOT_EMMC_4_4 + + ldr r0, =(EXYNOS5_POWER_BASE + INFORM3_OFFSET) + str r3, [r0] + + mov pc, lr + +/* + * Relocate code + */ +relocate_code: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + .word 0xF57FF04F @dsb sy + .word 0xF57FF06F @isb sy + + mov pc, lr + +/******************************************************************************/ + +/* + * CPU1 waits here until CPU0 wake it up. + * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory. + */ +nscode_base: + adr r0, _ns_reg5 + b 1f + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 + .word 0x0 @ REG4 +_ns_reg5: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6: REG_DIRECTGO_FLAG + .word 0x0 @ REG7: REG_DIRECTGO_ADDR + .word 0x0 @ REG8 + .word 0x0 @ REG9 - /* Jump to kernel */ - mov pc, r1 nop nop + +1: +cpu1_wait: + .word 0xE320F002 @ wfe instruction + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + b cpu1_wait + nop +nscode_end: diff --git a/board/samsung/smdk5250/mmc_boot.c b/board/samsung/smdk5250/mmc_boot.c index 449a919d5..54e726478 100644 --- a/board/samsung/smdk5250/mmc_boot.c +++ b/board/samsung/smdk5250/mmc_boot.c @@ -20,25 +20,90 @@ * MA 02111-1307 USA */ -#include<common.h> -#include<config.h> +#include <common.h> +#include <config.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/mmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/clk.h> +#include <asm/arch/smc.h> +#include "setup.h" + +#define SECOND_BOOT_MODE 0xFEED0002 +#define SDMMC_SECOND_DEV 0x101 +#define USB_SECOND_DEV 0x100 /* * Copy U-boot from mmc to RAM: * COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains * Pointer to API (Data transfer from mmc to ram) */ -void copy_uboot_to_ram(void) +void copy_uboot_to_ram(unsigned int boot_dev) { +#if 0 u32 (*copy_bl2)(u32, u32, u32) = (void *) *(u32 *)COPY_BL2_FNPTR_ADDR; copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE); +#else + switch(boot_dev) { + case BOOT_MMCSD: + case BOOT_SEC_DEV: + boot_dev = SDMMC_CH2; + break; + case BOOT_EMMC_4_4: + boot_dev = EMMC; + break; + case BOOT_USB: + boot_dev = USB; + + break; + + } + /* TODO : add functions for loading image */ + /* Load u-boot image to ram */ + load_uboot_image(boot_dev); + + /* Load tzsw image & U-Boot boot */ + coldboot(boot_dev); +#endif +} + +/* find boot device for secondary booting */ +static int find_second_boot_dev(void) +{ + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; + unsigned int dev = readl(&pmu->irom_data_reg0); + + writel(0x1, CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (dev == SDMMC_SECOND_DEV) + return BOOT_SEC_DEV; + else if (dev == USB_SECOND_DEV) + return BOOT_USB; + else return 0; +} + +void load_uboot(void) +{ + unsigned int om_status = readl(EXYNOS5_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + + /* TODO : find second boot function */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + copy_uboot_to_ram(boot_dev); + } void board_init_f(unsigned long bootflag) { __attribute__((noreturn)) void (*uboot)(void); - copy_uboot_to_ram(); + load_uboot(); /* Jump to U-Boot image */ uboot = (void *)CONFIG_SYS_TEXT_BASE; diff --git a/board/samsung/smdk5250/pmic.c b/board/samsung/smdk5250/pmic.c new file mode 100644 index 000000000..5268a337f --- /dev/null +++ b/board/samsung/smdk5250/pmic.c @@ -0,0 +1,748 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/pmic.h> +#include <asm/arch/cpu.h> + +void Delay(void) +{ + unsigned long i; + for(i=0;i<DELAY;i++); +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + IIC0_ESDA_INP; // Function <- Input + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPD1DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + ack = (ack>>0)&0x1; +// while(ack!=0); + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + IIC0_ESDA_OUTP; // Function <- Output + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + + IIC0_ESDA_INP; // Function <- Input (SDA) + + IIC0_SCLL_SDAL(); +} + +void IIC0_ESetport(void) +{ + GPD1PUD &= ~(0xf<<0); // Pull Up/Down Disable SCL, SDA + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + IIC0_ESCL_OUTP; // Function <- Output (SCL) + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + Delay(); +} + +void IIC0_EWrite (unsigned char ChipId, unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + +////////////////// write reg. data. ////////////////// + for(i = 8; i>0; i--) + { + if((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EEnd(); +} + +void IIC0_ERead (unsigned char ChipId, unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EHigh(); // read + + IIC0_EAck_write(); // ACK + +////////////////// read reg. data. ////////////////// + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for(i = 8; i>0; i--) + { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPD1DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + reg = (reg >> 0) & 0x1; + + data |= reg << (i-1); + } + + IIC0_EAck_read(); // ACK + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + +#define CALC_S5M8767_BUCK234_VOLT(x) ( (x<600) ? 0 : ((x-600)/6.25) ) +#define CALC_S5M8767_BUCK156_VOLT(x) ( (x<650) ? 0 : ((x-650)/6.25) ) +#define CALC_S5M8767_LDO1267815_VOLT(x) ( (x<800) ? 0 : ((x-800)/25) ) +#define CALC_S5M8767_ALL_LDO_VOLT(x) ( (x<800) ? 0 : ((x-800)/50) ) + +void I2C_S5M8767_VolSetting(PMIC_RegNum eRegNum, unsigned char ucVolLevel, unsigned char ucEnable) +{ + unsigned char reg_addr, reg_bitpos, reg_bitmask, vol_level; + + reg_bitpos = 0; + reg_bitmask = 0xFF; + if(eRegNum == 0) // BUCK1 + { + reg_addr = 0x33; + } + else if(eRegNum == 1) // BUCK2 + { + reg_addr = 0x35; + } + else if(eRegNum == 2) // BUCK3 + { + reg_addr = 0x3E; + } + else if(eRegNum == 3) // BUCK4 + { + reg_addr = 0x47; + } + else if(eRegNum == 4) // LDO2 + { + reg_addr = 0x5D; + reg_bitmask = 0x3F; + } + else if(eRegNum == 5) // LDO3 + { + reg_addr = 0x61; + reg_bitmask = 0x3F; + } + else if(eRegNum == 6) // LDO5 + { + reg_addr = 0x63; + reg_bitmask = 0x3F; + } + else if(eRegNum == 7) // LDO10 + { + reg_addr = 0x68; + reg_bitmask = 0x3F; + } + else if(eRegNum == 8) // LDO7 + { + reg_addr = 0x65; + reg_bitmask = 0x3F; + } + else if(eRegNum == 9) // BUCK5 + { + reg_addr = 0x50; + } + else + while(1); + + vol_level = ucVolLevel & reg_bitmask | (ucEnable << 6); + IIC0_EWrite(S5M8767_ADDR, reg_addr, vol_level); + +} + +void I2C_MAX8997_EnableReg(PMIC_RegNum eRegNum, u8 ucEnable) +{ + u8 reg_addr, reg_bitpos; + u8 read_data; + + reg_bitpos = 0; + if(eRegNum == 0) + { + reg_addr = 0x18; + } + else if(eRegNum == 1) + { + reg_addr = 0x21; + } + else if(eRegNum == 2) + { + reg_addr = 0x2A; + } + else if(eRegNum == 3) + { + reg_addr = 0x2C; + } + else if(eRegNum == 4) + { + reg_addr = 0x48; + reg_bitpos = 0x6; + } + else if(eRegNum == 5) + { + reg_addr = 0x44; + reg_bitpos = 0x6; + } + else if(eRegNum == 6) + { + reg_addr = 0x4D; + reg_bitpos = 0x6; + } + else + while(1); + + IIC0_ERead(MAX8997_ADDR, reg_addr, &read_data); + + read_data = (read_data & (~(1<<reg_bitpos))) | (ucEnable<<reg_bitpos); + + IIC0_EWrite(MAX8997_ADDR, reg_addr, read_data); +} + +void I2C_MAX8997_VolSetting(PMIC_RegNum eRegNum, u8 ucVolLevel, u8 ucEnable) +{ + u8 reg_addr, reg_bitpos, reg_bitmask, vol_level; + u8 read_data; + + reg_bitpos = 0; + reg_bitmask = 0x3F; + if(eRegNum == 0) + { + reg_addr = 0x19; + } + else if(eRegNum == 1) + { + reg_addr = 0x22; + } + else if(eRegNum == 2) + { + reg_addr = 0x2B; + } + else if(eRegNum == 3) + { + reg_addr = 0x2D; + } + else if(eRegNum == 4) + { + reg_addr = 0x48; + } + else if(eRegNum == 5) + { + reg_addr = 0x44; + } + else if(eRegNum == 6) + { + reg_addr = 0x4D; + } + else + while(1); + + vol_level = ucVolLevel®_bitmask; + + IIC0_ERead(MAX8997_ADDR, reg_addr, &read_data); + + read_data = (read_data & (~(reg_bitmask<<reg_bitpos))) | (vol_level<<reg_bitpos); + + IIC0_EWrite(MAX8997_ADDR, reg_addr, read_data); + + I2C_MAX8997_EnableReg(eRegNum, ucEnable); +} + +void I2C_MAX77686_EnableReg(PMIC_RegNum eRegNum, u8 ucEnable) +{ + u8 reg_addr, reg_bitpos; + u8 read_data; + + reg_bitpos = 0; + if(eRegNum == 0) + { + reg_addr = 0x10; + } + else if(eRegNum == 1) + { + reg_addr = 0x12; + reg_bitpos = 0x4; + } + else if(eRegNum == 2) + { + reg_addr = 0x1C; + reg_bitpos = 0x4; + } + else if(eRegNum == 3) + { + reg_addr = 0x26; + reg_bitpos = 0x4; + } + else if(eRegNum == 9) + { + reg_addr = 0x30; + } + else + while(1); + + IIC0_ERead(MAX77686_ADDR, reg_addr, &read_data); + + read_data = (read_data & (~(0x3<<reg_bitpos))) | (ucEnable<<reg_bitpos); + + IIC0_EWrite(MAX77686_ADDR, reg_addr, read_data); +} + +void I2C_MAX77686_VolSetting(PMIC_RegNum eRegNum, u8 ucVolLevel, u8 ucEnable) +{ + u8 reg_addr, vol_bitpos, reg_bitmask, vol_level; + u8 read_data; + + vol_bitpos = 0; + reg_bitmask = 0x3F; + if(eRegNum == 0) + { + reg_addr = 0x11; + } + else if(eRegNum == 1) + { + reg_addr = 0x14; + reg_bitmask = 0xff; + } + else if(eRegNum == 2) + { + reg_addr = 0x1E; + } + else if(eRegNum == 3) + { + reg_addr = 0x28; + } + else if(eRegNum == 4) + { + reg_addr = 0x41; + } + else if(eRegNum == 5) + { + reg_addr = 0x42; + } + else if(eRegNum == 6) + { + reg_addr = 0x44; + } + else if(eRegNum == 7) + { + reg_addr = 0x49; + } + else if(eRegNum == 8) + { + reg_addr = 0x46; + } + else if(eRegNum == 9) + { + reg_addr = 0x31; + } + else + while(1); + + vol_level = ucVolLevel; + + IIC0_ERead(MAX77686_ADDR, reg_addr, &read_data); + + read_data = (read_data & (~(reg_bitmask<<vol_bitpos))) | (vol_level<<vol_bitpos); + + if (reg_addr < 0x40) { + /* BUCK Voltage Set */ + IIC0_EWrite(MAX77686_ADDR, reg_addr, read_data); + /* Buck Enable */ + I2C_MAX77686_EnableReg(eRegNum, ucEnable); + } else { + /* LDO Voltage Set & Enable */ + read_data = (read_data | ucEnable); + IIC0_EWrite(MAX77686_ADDR, reg_addr, read_data); + } + +} + +void pmic8997_init(void) +{ + u8 vdd_arm, vdd_int, vdd_g3d; + u8 vdd_mif; + u8 vdd_apll; + u8 vddq_m1_m2; + + vdd_arm = CALC_MAXIM_BUCK1245_VOLT(CONFIG_PM_VDD_ARM); + vdd_int = CALC_MAXIM_BUCK1245_VOLT(CONFIG_PM_VDD_INT); + vdd_g3d = CALC_MAXIM_BUCK37_VOLT(CONFIG_PM_VDD_G3D); + vdd_mif = CALC_MAXIM_BUCK1245_VOLT(CONFIG_PM_VDD_MIF); +#if defined(CONFIG_PM_VDD_APLL) + vdd_apll = CALC_MAXIM_ALL_LDO(CONFIG_PM_VDD_APLL); +#endif +#if defined(CONFIG_PM_VDDQ_M1_M2) + vddq_m1_m2 = CALC_MAXIM_ALL_LDO(CONFIG_PM_VDDQ_M1_M2); +#endif + + I2C_MAX8997_VolSetting(PMIC_BUCK1, vdd_arm, 1); + I2C_MAX8997_VolSetting(PMIC_BUCK2, vdd_int, 1); + I2C_MAX8997_VolSetting(PMIC_BUCK3, vdd_g3d, 1); + I2C_MAX8997_VolSetting(PMIC_BUCK4, vdd_mif, 1); +#if defined(CONFIG_PM_VDD_APLL) + /* LDO10: APLL VDD */ + I2C_MAX8997_VolSetting(PMIC_LDO10, vdd_apll, 3); +#endif +#if defined(CONFIG_PM_VDDQ_M1_M2) + /* VDDQ_M1_M, VDDQ_M2_M */ + I2C_MAX8997_VolSetting(PMIC_LDO21, vddq_m1_m2, 3); +#endif +} + +void pmic77686_init(void) +{ + u8 vdd_arm, vdd_int, vdd_g3d; + u8 vdd_mif; + u8 vdd_mem, vdd_mem_set = 0; + u8 vddq_m1_m2, vddq_m1_m2_set = 0; + u8 vdd_apll; + +#if defined(CONFIG_CPU_EXYNOS5250_EVT1) + /* set DVS1,2,3 as 0 by GPD1 */ + *((volatile unsigned int *)0x11400180) = 0x00000111; /* DVS1~3 : GPD1_0~2(output) */ + *((volatile unsigned int *)0x11400C40) = 0x00111000; /* SELB1~3 : GPX2_3~5(output) */ + *((volatile unsigned int *)0x11400184) = 0x0; /* DVS1~3 : Low */ + *((volatile unsigned int *)0x11400C44) = 0x0; /* SELB1~3 : Low */ + *((volatile unsigned int *)0x11400C44) = 0x38; /* SELB1~3 : High */ + *((volatile unsigned int *)0x11400C44) = 0x0; /* SELB1~3 : Low */ + *((volatile unsigned int *)0x11400180) = 0x0; /* DVS1~3 : GPD1_0~2(input) */ + *((volatile unsigned int *)0x11400C40) = 0x0; /* SELB1~3 : GPX2_3~5(input) */ + + if(PRO_PKGINFO == POP_TYPE) { + vdd_arm = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_PM_VDD_ARM); + vdd_int = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_PM_VDD_INT); + vdd_g3d = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_PM_VDD_G3D); + vdd_mif = CALC_MAXIM77686_BUCK156789_VOLT(CONFIG_PM_VDD_MIF); +#if defined(CONFIG_PM_VDD_MEM) + vdd_mem = CALC_MAXIM77686_BUCK156789_VOLT(CONFIG_PM_VDD_MEM); + vdd_mem_set = 1; +#endif +#if defined(CONFIG_PM_VDDQ_M1_M2) + vddq_m1_m2 = CALC_MAXIM77686_LDO1267815_VOLT(CONFIG_PM_VDDQ_M1_M2); + vddq_m1_m2_set = 1; +#endif + } else { + vdd_arm = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_SCP_PM_VDD_ARM); + vdd_int = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_SCP_PM_VDD_INT); + vdd_g3d = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_SCP_PM_VDD_G3D); + vdd_mif = CALC_MAXIM77686_BUCK156789_VOLT(CONFIG_SCP_PM_VDD_MIF); +#if defined(CONFIG_SCP_PM_VDD_MEM) + vdd_mem = CALC_MAXIM77686_BUCK156789_VOLT(CONFIG_SCP_PM_VDD_MEM); + vdd_mem_set = 1; +#endif +#if defined(CONFIG_SCP_PM_VDDQ_M1_M2) + vddq_m1_m2 = CALC_MAXIM77686_LDO1267815_VOLT(CONFIG_SCP_PM_VDDQ_M1_M2); + vddq_m1_m2_set = 1; +#endif + } +#else + vdd_arm = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_PM_VDD_ARM); + vdd_int = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_PM_VDD_INT); + vdd_g3d = CALC_MAXIM77686_BUCK234_VOLT(CONFIG_PM_VDD_G3D); + vdd_mif = CALC_MAXIM77686_BUCK156789_VOLT(CONFIG_PM_VDD_MIF); +#if defined(CONFIG_PM_VDD_MEM) + vdd_mem = CALC_MAXIM77686_BUCK156789_VOLT(CONFIG_PM_VDD_MEM); + vdd_mem_set = 1; +#endif +#if defined(CONFIG_PM_VDD_APLL) + vdd_apll = CALC_MAXIM77686_LDO1267815_VOLT(CONFIG_PM_VDD_APLL); +#endif +#if defined(CONFIG_PM_VDDQ_M1_M2) + vddq_m1_m2 = CALC_MAXIM77686_LDO1267815_VOLT(CONFIG_PM_VDDQ_M1_M2); + vddq_m1_m2_set = 1; +#endif +#endif /* CONFIG_CPU_EXYNOS5250_EVT1 */ + + /* ARM VDD */ + I2C_MAX77686_VolSetting(PMIC_BUCK2, vdd_arm, 1); + /* INT VDD */ + I2C_MAX77686_VolSetting(PMIC_BUCK3, vdd_int, 1); + /* G3D VDD */ + I2C_MAX77686_VolSetting(PMIC_BUCK4, vdd_g3d, 1); + /* MIF VDD */ + I2C_MAX77686_VolSetting(PMIC_BUCK1, vdd_mif, 3); + /* MEM VDD */ + if (vdd_mem_set) + I2C_MAX77686_VolSetting(0x09, vdd_mem, 3); + /* LDO2: VDDQ_M1_M, VDDQ_M2_M */ + if (vddq_m1_m2_set) + I2C_MAX77686_VolSetting(0x04, vddq_m1_m2, 3); +#if defined(CONFIG_PM_VDD_APLL) + /* LDO7: APLL VDD */ + I2C_MAX77686_VolSetting(0x08, vdd_apll, 3); +#endif +} + +void pmic8767_init(void) +{ +#if defined(CONFIG_CPU_EXYNOS5250_EVT1) + u8 vdd_arm, vdd_int, vdd_g3d; + u8 vdd_mif; + u8 vdd_mem, vdd_mem_set = 0; + u8 vddq_m1_m2, vddq_m1_m2_set = 0; + u8 vdd_apll; + + if (PRO_PKGINFO == POP_TYPE) { + + } else { + vdd_arm = CALC_S5M8767_BUCK234_VOLT(CONFIG_SCP_PM_VDD_ARM); + vdd_int = CALC_S5M8767_BUCK234_VOLT(CONFIG_SCP_PM_VDD_INT); + vdd_g3d = CALC_S5M8767_BUCK234_VOLT(CONFIG_SCP_PM_VDD_G3D); + vdd_mif = CALC_S5M8767_BUCK156_VOLT(CONFIG_SCP_PM_VDD_MIF); +#if defined(CONFIG_SCP_PM_VDDQ_M1_M2) + vddq_m1_m2 = CALC_S5M8767_LDO1267815_VOLT(CONFIG_SCP_PM_VDDQ_M1_M2); + vddq_m1_m2_set = 1; +#endif + } + + I2C_S5M8767_VolSetting(PMIC_BUCK1, vdd_mif, 1); + I2C_S5M8767_VolSetting(PMIC_BUCK2, vdd_arm, 1); + I2C_S5M8767_VolSetting(PMIC_BUCK3, vdd_int, 1); + I2C_S5M8767_VolSetting(PMIC_BUCK4, vdd_g3d, 1); + if (vddq_m1_m2_set) + I2C_S5M8767_VolSetting(0x04, vddq_m1_m2, 3); + + /* BUCK9: VDDF_eMMC 2.8V */ + IIC0_EWrite(S5M8767_ADDR, 0x5A, 0x58); + + /* BUCK6: Memory */ + IIC0_EWrite(S5M8767_ADDR, 0x54, 0x58); + + /* LDO4: VDD_eMMC_1V8_PM */ + IIC0_EWrite(S5M8767_ADDR, 0x62, 0x14); + + /* BUCK3: remote sense on */ + IIC0_EWrite(S5M8767_ADDR, 0x3D, 0xFA); + +#else + float vdd_arm, vdd_int, vdd_g3d; + float vdd_mif; + + vdd_arm = CONFIG_PM_VDD_ARM; + vdd_int = CONFIG_PM_VDD_INT; + vdd_g3d = CONFIG_PM_VDD_G3D; + vdd_mif = CONFIG_PM_VDD_MIF; + +#ifdef CONFIG_DDR3 + I2C_S5M8767_VolSetting(PMIC_BUCK1, CALC_S5M8767_BUCK156_VOLT(vdd_mif), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK2, CALC_S5M8767_BUCK234_VOLT(vdd_arm), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK3, CALC_S5M8767_BUCK234_VOLT(vdd_int), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK4, CALC_S5M8767_BUCK234_VOLT(vdd_g3d), 1); + + IIC0_EWrite(S5M8767_ADDR, 0x59, 0x4C); // BUCK8 1.4 -> 1.7V + IIC0_EWrite(S5M8767_ADDR, 0x5D, 0xDC); // LDO2 1.2 -> 1.5V + + IIC0_EWrite(S5M8767_ADDR, 0x34, 0x78); + IIC0_EWrite(S5M8767_ADDR, 0x3d, 0x58); + IIC0_EWrite(S5M8767_ADDR, 0x46, 0x78); + + IIC0_EWrite(S5M8767_ADDR, 0x5A, 0x58); + + IIC0_EWrite(S5M8767_ADDR, 0x65, 0xCE); // LDO7 1.0 -> 1.2V +#else + I2C_S5M8767_VolSetting(PMIC_BUCK1, CALC_S5M8767_BUCK156_VOLT(vdd_mif), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK2, CALC_S5M8767_BUCK234_VOLT(vdd_arm), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK3, CALC_S5M8767_BUCK234_VOLT(vdd_int), 1); + I2C_S5M8767_VolSetting(PMIC_BUCK4, CALC_S5M8767_BUCK234_VOLT(vdd_g3d), 1); + IIC0_EWrite(S5M8767_ADDR, 0x34, 0x78); + IIC0_EWrite(S5M8767_ADDR, 0x3d, 0x58); + IIC0_EWrite(S5M8767_ADDR, 0x46, 0x78); + + IIC0_EWrite(S5M8767_ADDR, 0x5A, 0x58); + + IIC0_EWrite(S5M8767_ADDR, 0x63, 0xE8); // LDO5 + IIC0_EWrite(S5M8767_ADDR, 0x64, 0xD0); // LDO6 + IIC0_EWrite(S5M8767_ADDR, 0x65, 0xD0); // LDO7 + +#endif +#endif /* CONFIG_CPU_EXYNOS5250_EVT1 */ + +} + + +void pmic_init(void) +{ + u8 read_data; + + IIC0_ESetport(); + + /* read ID */ + IIC0_ERead(MAX8997_ADDR, 0, &read_data); + + if (read_data == 0x77) + pmic8997_init(); + else if (read_data >= 0x0 && read_data <= 0x5) + pmic8767_init(); + else + pmic77686_init(); +} diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h index 1276fd3e6..5408936a2 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -73,7 +73,7 @@ | (ARM_RATIO)) /* CLK_DIV_CPU1 */ -#define HPM_RATIO 0x4 +#define HPM_RATIO 0x2 #define COPY_RATIO 0x0 #define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) \ | (COPY_RATIO)) @@ -86,9 +86,13 @@ #define MPLL_PDIV 0x3 #define MPLL_SDIV 0x0 -#define CPLL_MDIV 0x96 +#define CPLL_MDIV 0xDE #define CPLL_PDIV 0x4 -#define CPLL_SDIV 0x0 +#define CPLL_SDIV 0x2 + +#define GPLL_MDIV 0x215 +#define GPLL_PDIV 0xC +#define GPLL_SDIV 0x1 /* APLL_CON1 */ #define APLL_CON1_VAL (0x00203800) @@ -99,6 +103,9 @@ /* CPLL_CON1 */ #define CPLL_CON1_VAL (0x00203800) +/* GPLL_CON1 */ +#define GPLL_CON1_VAL (0x00203800) + #define EPLL_MDIV 0x60 #define EPLL_PDIV 0x3 #define EPLL_SDIV 0x3 @@ -113,9 +120,9 @@ #define VPLL_CON1_VAL 0x00000000 #define VPLL_CON2_VAL 0x00000080 -#define BPLL_MDIV 0x215 -#define BPLL_PDIV 0xC -#define BPLL_SDIV 0x1 +#define BPLL_MDIV 0x263 +#define BPLL_PDIV 0xB +#define BPLL_SDIV 0x0 #define BPLL_CON1_VAL 0x00203800 @@ -125,49 +132,53 @@ #define APLL_CON0_VAL set_pll(APLL_MDIV, APLL_PDIV, APLL_SDIV) #define MPLL_CON0_VAL set_pll(MPLL_MDIV, MPLL_PDIV, MPLL_SDIV) #define CPLL_CON0_VAL set_pll(CPLL_MDIV, CPLL_PDIV, CPLL_SDIV) +#define GPLL_CON0_VAL set_pll(GPLL_MDIV, GPLL_PDIV, GPLL_SDIV) #define EPLL_CON0_VAL set_pll(EPLL_MDIV, EPLL_PDIV, EPLL_SDIV) #define VPLL_CON0_VAL set_pll(VPLL_MDIV, VPLL_PDIV, VPLL_SDIV) #define BPLL_CON0_VAL set_pll(BPLL_MDIV, BPLL_PDIV, BPLL_SDIV) /* CLK_SRC_CORE0 */ -#define CLK_SRC_CORE0_VAL 0x00060000 +#define CLK_SRC_CORE0_VAL 0x00000000 /* CLK_SRC_CORE1 */ #define CLK_SRC_CORE1_VAL 0x100 /* CLK_DIV_CORE0 */ -#define CLK_DIV_CORE0_VAL 0x120000 +#define CLK_DIV_CORE0_VAL 0x00120000 /* CLK_DIV_CORE1 */ #define CLK_DIV_CORE1_VAL 0x07070700 +/* CLK_DIV_SYSRGT */ +#define CLK_DIV_SYSRGT_VAL 0x00000111 + +/* CLK_SRC_CDREX/CLK_DIV_CDREX INIT */ +#define CLK_SRC_CDREX_INIT_VAL 0x0 +#define CLK_DIV_CDREX_INIT_VAL 0x71720071 + /* CLK_SRC_CDREX */ -#define CLK_SRC_CDREX_INIT_VAL 0x1 -#define CLK_SRC_CDREX_VAL 0x111 +#define CLK_SRC_CDREX_VAL 0x1 /* CLK_DIV_CDREX */ -#define CLK_DIV_CDREX_INIT_VAL 0x71771111 - -#define MCLK_CDREX2_RATIO 0x0 -#define ACLK_EFCON_RATIO 0x1 -#define MCLK_DPHY_RATIO 0x0 -#define MCLK_CDREX_RATIO 0x0 +#define MCLK_DPHY_RATIO 0x1 +#define MCLK_CDREX_RATIO 0x1 #define ACLK_C2C_200_RATIO 0x1 #define C2C_CLK_400_RATIO 0x1 -#define PCLK_CDREX_RATIO 0x3 +#define PCLK_CDREX_RATIO 0x1 #define ACLK_CDREX_RATIO 0x1 -#define CLK_DIV_CDREX_VAL ((MCLK_DPHY_RATIO << 20) \ - | (MCLK_CDREX_RATIO << 16) \ - | (ACLK_C2C_200_RATIO << 12) \ - | (C2C_CLK_400_RATIO << 8) \ - | (PCLK_CDREX_RATIO << 4) \ - | (ACLK_CDREX_RATIO)) -#define MCLK_EFPHY_RATIO 0x4 -#define CLK_DIV_CDREX2_VAL MCLK_EFPHY_RATIO +#define CLK_DIV_CDREX_VAL ((MCLK_DPHY_RATIO << 20) \ + | (MCLK_CDREX_RATIO << 16) \ + | (ACLK_C2C_200_RATIO << 12) \ + | (C2C_CLK_400_RATIO << 8) \ + | (PCLK_CDREX_RATIO << 4) \ + | (ACLK_CDREX_RATIO)) \ /* CLK_DIV_ACP */ -#define CLK_DIV_ACP_VAL 0x12 +#define CLK_DIV_ACP_VAL 0x12 + +/* CLK_DIV_SYSLFT */ +#define CLK_DIV_SYSLFT_VAL 0x00000311 /* CLK_SRC_TOP0 */ #define MUX_ACLK_300_GSCL_SEL 0x1 @@ -188,100 +199,106 @@ | (MUX_ACLK_166_SEL << 8)) /* CLK_SRC_TOP1 */ -#define MUX_ACLK_400_ISP_SEL 0x0 -#define MUX_ACLK_400_IOP_SEL 0x0 -#define MUX_ACLK_MIPI_HSI_TXBASE_SEL 0x0 -#define CLK_SRC_TOP1_VAL ((MUX_ACLK_400_ISP_SEL << 24) \ - |(MUX_ACLK_400_IOP_SEL << 20) \ - |(MUX_ACLK_MIPI_HSI_TXBASE_SEL << 16)) - +#define MUX_ACLK_400_G3D_SEL 0x1 +#define MUX_ACLK_400_ISP_SEL 0x0 +#define MUX_ACLK_400_IOP_SEL 0x0 +#define MUX_ACLK_MIPI_HSI_TXBASE_SEL 0x0 +#define MUX_ACLK_300_GSCL_MID1_SEL 0x1 +#define MUX_ACLK_300_DISP1_MID1_SEL 0x1 +#define CLK_SRC_TOP1_VAL ((MUX_ACLK_400_G3D_SEL << 28) \ + |(MUX_ACLK_400_ISP_SEL << 24) \ + |(MUX_ACLK_400_IOP_SEL << 20) \ + |(MUX_ACLK_MIPI_HSI_TXBASE_SEL << 16) \ + |(MUX_ACLK_300_GSCL_MID1_SEL << 12) \ + |(MUX_ACLK_300_DISP1_MID1_SEL << 8)) /* CLK_SRC_TOP2 */ -#define MUX_BPLL_USER_SEL 0x1 -#define MUX_MPLL_USER_SEL 0x1 -#define MUX_VPLL_SEL 0x0 -#define MUX_EPLL_SEL 0x0 -#define MUX_CPLL_SEL 0x0 -#define VPLLSRC_SEL 0x0 -#define CLK_SRC_TOP2_VAL ((MUX_BPLL_USER_SEL << 24) \ - | (MUX_MPLL_USER_SEL << 20) \ - | (MUX_VPLL_SEL << 16) \ - | (MUX_EPLL_SEL << 12) \ - | (MUX_CPLL_SEL << 8) \ +#define MUX_GPLL_SEL 0x1 +#define MUX_BPLL_USER_SEL 0x0 +#define MUX_MPLL_USER_SEL 0x0 +#define MUX_VPLL_SEL 0x1 +#define MUX_EPLL_SEL 0x1 +#define MUX_CPLL_SEL 0x1 +#define VPLLSRC_SEL 0x0 +#define CLK_SRC_TOP2_VAL ((MUX_GPLL_SEL << 28) \ + | (MUX_BPLL_USER_SEL << 24) \ + | (MUX_MPLL_USER_SEL << 20) \ + | (MUX_VPLL_SEL << 16) \ + | (MUX_EPLL_SEL << 12) \ + | (MUX_CPLL_SEL << 8) \ | (VPLLSRC_SEL)) /* CLK_SRC_TOP3 */ -#define MUX_ACLK_333_SUB_SEL 0x1 -#define MUX_ACLK_400_SUB_SEL 0x1 -#define MUX_ACLK_266_ISP_SUB_SEL 0x1 -#define MUX_ACLK_266_GPS_SUB_SEL 0x1 -#define MUX_ACLK_300_GSCL_SUB_SEL 0x1 -#define MUX_ACLK_266_GSCL_SUB_SEL 0x1 -#define MUX_ACLK_300_DISP1_SUB_SEL 0x1 -#define MUX_ACLK_200_DISP1_SUB_SEL 0x1 -#define CLK_SRC_TOP3_VAL ((MUX_ACLK_333_SUB_SEL << 24) \ - | (MUX_ACLK_400_SUB_SEL << 20) \ - | (MUX_ACLK_266_ISP_SUB_SEL << 16) \ - | (MUX_ACLK_266_GPS_SUB_SEL << 12) \ - | (MUX_ACLK_300_GSCL_SUB_SEL << 10) \ - | (MUX_ACLK_266_GSCL_SUB_SEL << 8) \ - | (MUX_ACLK_300_DISP1_SUB_SEL << 6) \ - | (MUX_ACLK_200_DISP1_SUB_SEL << 4)) - -/* CLK_DIV_TOP0 */ -#define ACLK_300_RATIO 0x0 -#define ACLK_400_RATIO 0x3 -#define ACLK_333_RATIO 0x2 -#define ACLK_266_RATIO 0x2 -#define ACLK_200_RATIO 0x3 -#define ACLK_166_RATIO 0x5 -#define ACLK_133_RATIO 0x1 -#define ACLK_66_RATIO 0x5 -#define CLK_DIV_TOP0_VAL ((ACLK_300_RATIO << 28) \ - | (ACLK_400_RATIO << 24) \ - | (ACLK_333_RATIO << 20) \ - | (ACLK_266_RATIO << 16) \ - | (ACLK_200_RATIO << 12) \ - | (ACLK_166_RATIO << 8) \ - | (ACLK_133_RATIO << 4) \ +#define MUX_ACLK_333_SUB_SEL 0x1 +#define MUX_ACLK_400_SUB_SEL 0x1 +#define MUX_ACLK_266_ISP_SUB_SEL 0x1 +#define MUX_ACLK_266_GPS_SUB_SEL 0x0 +#define MUX_ACLK_300_GSCL_SUB_SEL 0x1 +#define MUX_ACLK_266_GSCL_SUB_SEL 0x1 +#define MUX_ACLK_300_DISP1_SUB_SEL 0x1 +#define MUX_ACLK_200_DISP1_SUB_SEL 0x1 +#define CLK_SRC_TOP3_VAL ((MUX_ACLK_333_SUB_SEL << 24) \ + | (MUX_ACLK_400_SUB_SEL << 20) \ + | (MUX_ACLK_266_ISP_SUB_SEL << 16) \ + | (MUX_ACLK_266_GPS_SUB_SEL << 12) \ + | (MUX_ACLK_300_GSCL_SUB_SEL << 10) \ + | (MUX_ACLK_266_GSCL_SUB_SEL << 8) \ + | (MUX_ACLK_300_DISP1_SUB_SEL << 6) \ + | (MUX_ACLK_200_DISP1_SUB_SEL << 4)) + +/* CLK_DIV_TOP0 */ +#define ACLK_300_DISP1_RATIO 0x0 +#define ACLK_400_G3D_RATIO 0x0 +#define ACLK_333_RATIO 0x0 +#define ACLK_266_RATIO 0x2 +#define ACLK_200_RATIO 0x3 +#define ACLK_166_RATIO 0x1 +#define ACLK_133_RATIO 0x1 +#define ACLK_66_RATIO 0x5 + +#define CLK_DIV_TOP0_VAL ((ACLK_300_DISP1_RATIO << 28) \ + | (ACLK_400_G3D_RATIO << 24) \ + | (ACLK_333_RATIO << 20) \ + | (ACLK_266_RATIO << 16) \ + | (ACLK_200_RATIO << 12) \ + | (ACLK_166_RATIO << 8) \ + | (ACLK_133_RATIO << 4) \ | (ACLK_66_RATIO)) -/* CLK_DIV_TOP1 */ -#define ACLK_MIPI_HSI_TX_BASE_RATIO 0x3 -#define ACLK_66_PRE_RATIO 0x1 -#define ACLK_400_ISP_RATIO 0x1 -#define ACLK_400_IOP_RATIO 0x1 -#define ACLK_300_GSCL_RATIO 0x0 -#define ACLK_266_GPS_RATIO 0x7 - -#define CLK_DIV_TOP1_VAL ((ACLK_MIPI_HSI_TX_BASE_RATIO << 28) \ - | (ACLK_66_PRE_RATIO << 24) \ - | (ACLK_400_ISP_RATIO << 20) \ - | (ACLK_400_IOP_RATIO << 16) \ - | (ACLK_300_GSCL_RATIO << 12) \ - | (ACLK_266_GPS_RATIO << 8)) +/* CLK_DIV_TOP1 */ +#define ACLK_MIPI_HSI_TX_BASE_RATIO 0x3 +#define ACLK_66_PRE_RATIO 0x1 +#define ACLK_400_ISP_RATIO 0x1 +#define ACLK_400_IOP_RATIO 0x1 +#define ACLK_300_GSCL_RATIO 0x0 + +#define CLK_DIV_TOP1_VAL ((ACLK_MIPI_HSI_TX_BASE_RATIO << 28) \ + | (ACLK_66_PRE_RATIO << 24) \ + | (ACLK_400_ISP_RATIO << 20) \ + | (ACLK_400_IOP_RATIO << 16) \ + | (ACLK_300_GSCL_RATIO << 12)) /* APLL_LOCK */ -#define APLL_LOCK_VAL (0x3E8) +#define APLL_LOCK_VAL (0x546) /* MPLL_LOCK */ -#define MPLL_LOCK_VAL (0x2F1) +#define MPLL_LOCK_VAL (0x546) /* CPLL_LOCK */ -#define CPLL_LOCK_VAL (0x3E8) +#define CPLL_LOCK_VAL (0x546) +/* GPLL_LOCK */ +#define GPLL_LOCK_VAL (0x546) /* EPLL_LOCK */ -#define EPLL_LOCK_VAL (0x2321) +#define EPLL_LOCK_VAL (0x3A98) /* VPLL_LOCK */ -#define VPLL_LOCK_VAL (0x2321) +#define VPLL_LOCK_VAL (0x3A98) /* BPLL_LOCK */ -#define BPLL_LOCK_VAL (0x3E8) +#define BPLL_LOCK_VAL (0x546) /* CLK_SRC_PERIC0 */ /* SRC_CLOCK = SCLK_MPLL */ #define PWM_SEL 0 -#define UART4_SEL 6 #define UART3_SEL 6 #define UART2_SEL 6 #define UART1_SEL 6 #define UART0_SEL 6 #define CLK_SRC_PERIC0_VAL ((PWM_SEL << 24) \ - | (UART4_SEL << 16) \ | (UART3_SEL << 12) \ | (UART2_SEL << 8) \ | (UART1_SEL << 4) \ @@ -289,27 +306,20 @@ #define CLK_SRC_FSYS_VAL 0x66666 #define CLK_DIV_FSYS0_VAL 0x0BB00000 -#define CLK_DIV_FSYS1_VAL 0x000f000f -#define CLK_DIV_FSYS2_VAL 0x020f020f -#define CLK_DIV_FSYS3_VAL 0x000f +#define CLK_DIV_FSYS1_VAL 0x00000109 +#define CLK_DIV_FSYS2_VAL 0x00000903 /* CLK_DIV_PERIC0 */ -#define UART5_RATIO 8 -#define UART4_RATIO 8 -#define UART3_RATIO 8 -#define UART2_RATIO 8 -#define UART1_RATIO 8 -#define UART0_RATIO 8 -#define CLK_DIV_PERIC0_VAL ((UART4_RATIO << 16) \ - | (UART3_RATIO << 12) \ +#define UART5_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 +#define CLK_DIV_PERIC0_VAL ((UART3_RATIO << 12) \ | (UART2_RATIO << 8) \ | (UART1_RATIO << 4) \ | (UART0_RATIO << 0)) -/* CLK_DIV_PERIC3 */ -#define PWM_RATIO 8 -#define CLK_DIV_PERIC3_VAL (PWM_RATIO << 0) - /* CLK_SRC_LEX */ #define CLK_SRC_LEX_VAL 0x0 @@ -322,8 +332,6 @@ /* CLK_DIV_L0X */ #define CLK_DIV_R1X_VAL 0x10 -/* SCLK_SRC_ISP */ -#define SCLK_SRC_ISP_VAL 0x600 /* CLK_DIV_ISP0 */ #define CLK_DIV_ISP0_VAL 0x31 @@ -347,105 +355,9 @@ */ #define DECPROTXSET 0xFF -/* DMC Init */ -#define SET 1 -#define RESET 0 -/* (Memory Interleaving Size = 1 << IV_SIZE) */ -#define CONFIG_IV_SIZE 0x07 - -#define PHY_RESET_VAL (0 << 0) - -/*ZQ Configurations */ -#define PHY_CON16_RESET_VAL 0x08000304 - -#define ZQ_MODE_DDS_VAL (0x5 << 24) -#define ZQ_MODE_TERM_VAL (0x5 << 21) -#define SET_ZQ_MODE_DDS_VAL(x) (x = (x & ~(0x7 << 24)) | ZQ_MODE_DDS_VAL) -#define SET_ZQ_MODE_TERM_VAL(x) (x = (x & ~(0x7 << 21)) | ZQ_MODE_TERM_VAL) - -#define ZQ_MODE_NOTERM (1 << 19) -#define ZQ_CLK_DIV_EN (1 << 18) -#define ZQ_MANUAL_STR (1 << 1) - -/* Channel and Chip Selection */ -#define CONFIG_DMC_CHANNELS 2 -#define CONFIG_CHIPS_PER_CHANNEL 2 - -#define SET_CMD_CHANNEL(x, y) (x = (x & ~(1 << 28)) | y << 28) -#define SET_CMD_CHIP(x, y) (x = (x & ~(1 << 20)) | y << 20) - -/* Diret Command */ -#define DIRECT_CMD_NOP 0x07000000 -#define DIRECT_CMD_MRS1 0x00071C00 -#define DIRECT_CMD_MRS2 0x00010BFC -#define DIRECT_CMD_MRS3 0x00000708 -#define DIRECT_CMD_MRS4 0x00000818 -#define DIRECT_CMD_PALL 0x01000000 - -/* DLL Resync */ -#define FP_RSYNC (1 << 3) - -#define CONFIG_CTRL_DLL_ON(x, y) (x = (x & ~(1 << 5)) | y << 5) -#define CONFIG_CTRL_START(x, y) (x = (x & ~(1 << 6)) | y << 6) -#define SET_CTRL_FORCE_VAL(x, y) (x = (x & ~(0x7F << 8)) | y << 8) - -/* RDLVL */ -#define PHY_CON0_RESET_VAL 0x17023240 -#define DDR_MODE_LPDDR2 0x2 -#define BYTE_RDLVL_EN (1 << 13) -#define CTRL_ATGATE (1 << 6) -#define SET_CTRL_DDR_MODE(x, y) (x = (x & ~(0x3 << 11)) | y << 11) - -#define PHY_CON1_RESET_VAL 0x9210100 -#define RDLVL_RDDATAPADJ 0x1 -#define SET_RDLVL_RDDATAPADJ ((PHY_CON1_RESET_VAL & ~(0xFFFF << 0))\ - | RDLVL_RDDATAPADJ << 0) - -#define PHY_CON2_RESET_VAL 0x00010004 -#define RDLVL_EN (1 << 25) -#define RDDSKEW_CLEAR (1 << 13) - -#define CTRL_RDLVL_DATA_EN (1 << 1) -#define LPDDR2_ADDR 0x00000208 - -#define DMC_MEMCONFIG0_VAL 0x00001323 -#define DMC_MEMCONFIG1_VAL 0x00001323 -#define DMC_MEMBASECONFIG0_VAL 0x00400780 -#define DMC_MEMBASECONFIG1_VAL 0x00800780 -#define DMC_MEMCONTROL_VAL 0x00212500 -#define DMC_PRECHCONFIG_VAL 0xFF000000 -#define DMC_PWRDNCONFIG_VAL 0xFFFF00FF -#define DMC_TIMINGREF_VAL 0x0000005D -#define DMC_TIMINGROW_VAL 0x2336544C -#define DMC_TIMINGDATA_VAL 0x24202408 -#define DMC_TIMINGPOWER_VAL 0x38260235 - -#define CTRL_BSTLEN 0x04 -#define CTRL_RDLAT 0x08 -#define PHY_CON42_VAL (CTRL_BSTLEN << 8 | CTRL_RDLAT << 0) - -/* DQS, DQ, DEBUG offsets */ -#define SET_DQS_OFFSET_VAL 0x7F7F7F7F -#define SET_DQ_OFFSET_VAL 0x7F7F7F7F -#define SET_DEBUG_OFFSET_VAL 0x7F - -#define RESET_DQS_OFFSET_VAL 0x08080808 -#define RESET_DQ_OFFSET_VAL 0x08080808 -#define RESET_DEBUG_OFFSET_VAL 0x8 - -#define CTRL_PULLD_DQ (0x0F << 8) -#define CTRL_PULLD_DQS (0x0F << 0) - -#define DFI_INIT_START (1 << 28) - -#define CLK_STOP_EN (1 << 0) -#define DPWRDN_EN (1 << 1) -#define DSREF_EN (1 << 5) - -#define AREF_EN (1 << 5) void sdelay(unsigned long); void mem_ctrl_init(void); void system_clock_init(void); void tzpc_init(void); - +extern unsigned int second_boot_info; #endif diff --git a/board/samsung/smdk5250/smc.c b/board/samsung/smdk5250/smc.c new file mode 100644 index 000000000..22c465b3f --- /dev/null +++ b/board/samsung/smdk5250/smc.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <asm/arch/smc.h> + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1) + + ); + + return reg1; +} + + +unsigned int load_uboot_image(u32 boot_device) +{ + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } + + info_image->image_base_addr = CONFIG_PHY_UBOOT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_UBOOT_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, 0); +} + +unsigned int coldboot(u32 boot_device) +{ + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } + + info_image->image_base_addr = CONFIG_PHY_TZSW_BASE; + info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_TZSW_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_COLDBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, CONFIG_PHY_UBOOT_BASE); +} + +void warmboot(void) +{ + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, (EXYNOS5_POWER_BASE + INFORM0_OFFSET)); +} + +unsigned int find_second_boot(void) +{ + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT); +} + +void emmc_endbootop(void) +{ + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +} diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index 3b078da65..1f170d00d 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -24,12 +24,18 @@ #include <asm/io.h> #include <netdev.h> #include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> #include <asm/arch/gpio.h> #include <asm/arch/mmc.h> #include <asm/arch/pinmux.h> #include <asm/arch/sromc.h> +#include <asm/arch/pmic.h> +#include <asm/arch/sysreg.h> +#include "board_rev.h" DECLARE_GLOBAL_DATA_PTR; +unsigned int pmic; #ifdef CONFIG_SMC911X static int smc9115_pre_init(void) @@ -59,9 +65,110 @@ static int smc9115_pre_init(void) } #endif +static void i2c_interrupt_src_init(void) +{ + struct exynos5_sysreg *sysreg = + (struct exynos5_sysreg *)samsung_get_base_sysreg(); + + /* I2C interrupt source is for i2c, not for USI */ + writel(0x0, (unsigned int)&sysreg->i2c_cfg); + +} + +static void display_bl1_version(void) +{ + char bl1_version[9] = {0}; + + /* display BL1 version */ + printf("\nTrustZone Enabled BSP"); + strncpy(&bl1_version[0], (char *)0x0204f810, 8); + printf("\nBL1 version: %s\n", &bl1_version[0]); +} + +static void display_pmic_info(void) +{ + unsigned char read_vol_arm; + unsigned char read_vol_int; + unsigned char read_vol_g3d; + unsigned char read_vol_mif; + unsigned char read_vol_mem; + unsigned char read_vol_apll; + unsigned char pmic_id; + + /* read ID */ + IIC0_ERead(MAX8997_ADDR, MAX8997_ID, &pmic_id); + + if (pmic_id == 0x77) { + /* MAX8997 */ + printf("PMIC: MAX8997\n"); + pmic = SMDK5250_REGULATOR_MAX8997; + IIC0_ERead(MAX8997_ADDR, MAX8997_BUCK1TV_DVS, &read_vol_arm); + IIC0_ERead(MAX8997_ADDR, MAX8997_BUCK2TV_DVS, &read_vol_int); + IIC0_ERead(MAX8997_ADDR, MAX8997_BUCK3TV_DVS, &read_vol_g3d); + IIC0_ERead(MAX8997_ADDR, MAX8997_BUCK4TV_DVS, &read_vol_mif); + IIC0_ERead(MAX8997_ADDR, MAX8997_LDO10CTRL, &read_vol_apll); + + printf("ARM: %dmV\t", ((unsigned int)read_vol_arm * 25) + 650); + printf("INT: %dmV\t", ((unsigned int)read_vol_int * 25) + 650); + printf("G3D: %dmV\n", ((unsigned int)read_vol_g3d * 50) + 750); + printf("MIF: %dmV\t", ((unsigned int)read_vol_mif * 25) + 650); + printf("APLL: %dmV\n", ((unsigned int)(read_vol_apll & 0x3F) + * 50) + 800); + } else if (pmic_id >= 0x0 && pmic_id <= 0x5) { + /* S5M8767 */ + printf("PMIC: S5M8767\n"); + pmic = SMDK5250_REGULATOR_S5M8767; + } else { + /* MAX77686 */ + printf("PMIC: MAX77686\n"); + pmic = SMDK5250_REGULATOR_MAX77686; + IIC0_ERead(MAX77686_ADDR, MAX77686_BUCK2TV_DVS1, &read_vol_arm); + IIC0_ERead(MAX77686_ADDR, MAX77686_BUCK3TV_DVS1, &read_vol_int); + IIC0_ERead(MAX77686_ADDR, MAX77686_BUCK4TV_DVS1, &read_vol_g3d); + IIC0_ERead(MAX77686_ADDR, MAX77686_BUCK1OUT, &read_vol_mif); + IIC0_ERead(MAX77686_ADDR, MAX77686_BUCK5OUT, &read_vol_mem); + + printf("ARM: %dmV\t", ((unsigned int)(read_vol_arm >> 1) * 25) + 600); + printf("INT: %dmV\t", ((unsigned int)(read_vol_int >> 1) * 25) + 600); + printf("G3D: %dmV\n", ((unsigned int)(read_vol_g3d >> 1)* 25) + 600); + printf("MIF: %dmV\t", ((unsigned int)(read_vol_mif & 0x3F) * 50) + 750); + printf("MEM: %dmV\n", ((unsigned int)(read_vol_mem & 0x3F) * 50) + 750); + + } +} + +static void display_boot_device_info(void) +{ + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; + int OmPin; + + OmPin = readl(&pmu->inform3); + + printf("\nChecking Boot Mode ..."); + + if (OmPin == BOOT_MMCSD) { + printf(" SDMMC\n"); + } else if (OmPin == BOOT_EMMC) { + printf(" EMMC\n"); + } else if (OmPin == BOOT_EMMC_4_4) { + printf(" EMMC\n"); + } else { + printf(" Please check OM_pin\n"); + } +} + int board_init(void) { + display_bl1_version(); + + display_pmic_info(); + + display_boot_device_info(); + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); + + i2c_interrupt_src_init(); + return 0; } @@ -128,7 +235,10 @@ int checkboard(void) #ifdef CONFIG_GENERIC_MMC int board_mmc_init(bd_t *bis) { - int err; + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; + int err, OmPin; + + OmPin = readl(&pmu->inform3); err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); if (err) { @@ -136,7 +246,39 @@ int board_mmc_init(bd_t *bis) return err; } - err = s5p_mmc_init(2, 4); + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); + if (err) { + debug("MSHC0 not configured\n"); + return err; + } + + switch (OmPin) { + case BOOT_EMMC_4_4: +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif + break; + default: +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif + break; + } + return err; } #endif @@ -178,3 +320,88 @@ int board_early_init_f(void) return board_uart_init(); } #endif + +int board_late_init(void) +{ + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); + int err; + u32 second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + + err = exynos_pinmux_config(PERIPH_ID_INPUT_X0_0, PINMUX_FLAG_NONE); + if (err) { + debug("GPX0_0 INPUT not configured\n"); + return err; + } + + udelay(10); + if ((s5p_gpio_get_value(&gpio1->x0, 0) == 0) || second_boot_info == 1) + setenv("bootcmd", CONFIG_BOOTCOMMAND2); + + if (second_boot_info == 1) + printf("###Secondary Boot###\n"); + + if((readl(&pmu->sysip_dat0)) == CONFIG_FACTORY_RESET_MODE) { + writel(0x0, &pmu->sysip_dat0); + setenv ("bootcmd", CONFIG_FACTORY_RESET_BOOTCOMMAND); + } + + return 0; +} + +unsigned int get_board_rev(void) +{ + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; + unsigned int rev = 0; + int adc_val = 0; + unsigned int timeout, con; + + writel(0x7, &pmu->isp_configuration); + timeout = 1000; + while ((readl(&pmu->isp_status) & 0x7) != 0x7) { + if (timeout == 0) + printf("A5 power on failed1\n"); + timeout--; + udelay(1); + goto err_power; + } + writel(0x1, MTCADC_PHY_CONTROL); + + writel(0x00000031, &clk->div_isp0); + writel(0x00000031, &clk->div_isp1); + writel(0x00000001, &clk->div_isp2); + + writel(0xDFF000FF, &clk->gate_ip_isp0); + writel(0x00003007, &clk->gate_ip_isp1); + + /* SELMUX Channel 3 */ + writel(ADCCON_SELMUX(3), FIMC_IS_ADC_BASE + ADCMUX); + + con = readl(FIMC_IS_ADC_BASE + ADCCON); + con &= ~ADCCON_MUXMASK; + con &= ~ADCCON_STDBM; + con &= ~ADCCON_STARTMASK; + con |= ADCCON_PRSCEN; + + /* ENABLE START */ + con |= ADCCON_ENABLE_START; + writel(con, FIMC_IS_ADC_BASE + ADCCON); + + udelay (50); + + /* Read Data*/ + adc_val = readl(FIMC_IS_ADC_BASE + ADCDAT0) & 0xFFF; + /* CLRINT */ + writel(0, FIMC_IS_ADC_BASE + ADCCLRINT); + + rev = (adc_val < SMDK5250_REV_0_2_ADC_VALUE/2) ? + SMDK5250_REV_0_0 : SMDK5250_REV_0_2; + +err_power: + rev &= SMDK5250_REV_MASK; + pmic = (pmic & SMDK5250_REGULATOR_MASK) << SMDK5250_REGULATOR_SHIFT; + + return (rev | pmic); +} diff --git a/board/samsung/smdk5410/Makefile b/board/samsung/smdk5410/Makefile new file mode 100644 index 000000000..fc9ca7356 --- /dev/null +++ b/board/samsung/smdk5410/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2012 Samsung Electronics +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +SOBJS := lowlevel_init.o + +COBJS := pmic.o +COBJS += smc.o +SOBJS += clock_init.o +COBJS += dmc_init.o + +ifndef CONFIG_SPL_BUILD +COBJS += smdk5410.o +endif + +ifdef CONFIG_SPL_BUILD +COBJS += mmc_boot.o +endif + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +ALL := $(obj).depend $(LIB) + +all: $(ALL) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/smdk5410/clock_init.S b/board/samsung/smdk5410/clock_init.S new file mode 100644 index 000000000..6f5c1ca03 --- /dev/null +++ b/board/samsung/smdk5410/clock_init.S @@ -0,0 +1,363 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + + +#include <config.h> +#include <asm/arch/cpu.h> + +#include "smdk5410_val.h" + + + +/******************************************************************************* +* Functions for waiting +*******************************************************************************/ +wait_div_state: + add r2, r2, #0x100 +check_div_state: + ldr r1, [r0, r2] + mov r4, #0x10000 + orr r4, r4, #0x6A0 + cmp r2, r4 + lsreq r1, r1, #4 + cmp r1, r3 + bne check_div_state + mov pc, lr + +wait_mux_state: + add r2, r2, #0x200 +check_mux_state: + ldr r1, [r0, r2] + cmp r1, r3 + bne check_mux_state + mov pc, lr + +wait_pll_lock: + ldr r1, [r0, r2] + tst r1, #(1<<29) + beq wait_pll_lock + mov pc, lr + + + +/* + * system_clock_init: Initialize core clock and bus clock. + * void system_clock_init(void) + */ + + .globl system_clock_init +system_clock_init: + push {lr} + + ldr r0, =EXYNOS5_CLOCK_BASE @0x1001_0000 + +@ Set PLL locktime + ldr r1, =APLL_LOCK_VAL @0x320 + ldr r2, =APLL_LOCK_OFFSET @0x0 + str r1, [r0, r2] + + ldr r1, =MPLL_LOCK_VAL @0x258 + ldr r2, =MPLL_LOCK_OFFSET @0x4000 + str r1, [r0, r2] + + ldr r1, =BPLL_LOCK_VAL @0x258 + ldr r2, =BPLL_LOCK_OFFSET @0x20010 + str r1, [r0, r2] + + ldr r1, =CPLL_LOCK_VAL + ldr r2, =CPLL_LOCK_OFFSET + str r1, [r0, r2] + + ldr r1, =KPLL_LOCK_VAL @0x258 + ldr r2, =KPLL_LOCK_OFFSET @0x28000 + str r1, [r0, r2] + +@ Turn off PLL Mout + ldr r1, =0x00100000 + ldr r2, =CLK_SRC_CPU_OFFSET @0x00200 + str r1, [r0, r2] + + ldr r1, =0x0 + ldr r2, =CLK_SRC_CORE1_OFFSET @0x04204 + str r1, [r0, r2] + + ldr r1, =0x01100000 + ldr r2, =CLK_SRC_TOP2_OFFSET @0x10218 + str r1, [r0, r2] + + ldr r1, =0x00001000 + ldr r2, =CLK_SRC_CDREX_OFFSET @0x20200 + str r1, [r0, r2] + + ldr r1, =0x00008000 + ldr r2, =CLK_SRC_KFC_OFFSET @0x28200 + str r1, [r0, r2] + + ldr r3, =0x00210001 + bl wait_mux_state + +@ Set CMU_CPU, MUX & DIV + ldr r1, =0x00100000 + ldr r2, =CLK_SRC_CPU_OFFSET @0x00200 + str r1, [r0, r2] + + ldr r1, =0x1 + ldr r2, =CLK_DIV_CPU1_OFFSET @0x00504 + str r1, [r0, r2] + + ldr r3, =0x0 + bl wait_div_state + + ldr r1, =CLK_DIV_CPU0_VAL + ldr r2, =CLK_DIV_CPU0_OFFSET @0x00500 + str r1, [r0, r2] + + ldr r1, =APLL_CON1_VAL @0x0020F300 + ldr r2, =APLL_CON1_OFFSET @0x00104 + str r1, [r0, r2] + + ldr r1, =APLL_CON0_VAL + ldr r2, =APLL_CON0_OFFSET @0x00100 + str r1, [r0, r2] + + bl wait_pll_lock + +@ Set CMU_KFC, MUX & DIV + ldr r1, =0x00008000 + ldr r2, =CLK_SRC_KFC_OFFSET @0x28200 + str r1, [r0, r2] + + ldr r3, =0x00210001 + bl wait_mux_state + + ldr r1, =CLK_DIV_KFC0_VAL + ldr r2, =CLK_DIV_KFC0_OFFSET @0x28500 + str r1, [r0, r2] + + ldr r1, =KPLL_CON1_VAL @0x00200000 + ldr r2, =KPLL_CON1_OFFSET @0x28104 + str r1, [r0, r2] + + ldr r1, =KPLL_CON0_VAL + ldr r2, =KPLL_CON0_OFFSET @0x28100 + str r1, [r0, r2] + + bl wait_pll_lock + +@ Set MPLL + ldr r1, =MPLL_CON1_VAL @0x0020F300 + ldr r2, =MPLL_CON1_OFFSET @0x04104 + str r1, [r0, r2] + + ldr r1, =MPLL_CON0_VAL @0x810A0302 + ldr r2, =MPLL_CON0_OFFSET @0x04100 + str r1, [r0, r2] + + bl wait_pll_lock + + /* ByPass :: BYPASS = 1, bypass mode is enabled - FOUT=FIN */ + ldr r2, =MPLL_CON1_OFFSET + ldr r1, [r0, r2] + mov r3, #1 + mov r3, r3, lsl #22 + orr r1, r1, r3 + str r1, [r0, r2] + +@ Set BPLL + ldr r1, =BPLL_CON1_VAL @0x0020F300 + ldr r2, =BPLL_CON1_OFFSET @0x20114 + str r1, [r0, r2] + + ldr r1, =BPLL_CON0_VAL @0x80C80301 + ldr r2, =BPLL_CON0_OFFSET @0x20110 + str r1, [r0, r2] + + bl wait_pll_lock + +@ Set CPLL + ldr r1, =CPLL_CON1_VAL + ldr r2, =CPLL_CON1_OFFSET + str r1, [r0, r2] + + ldr r1, =CPLL_CON0_VAL + ldr r2, =CPLL_CON0_OFFSET + str r1, [r0, r2] + + bl wait_pll_lock + +@ Set CMU_CPERI, MUX & DIV + ldr r1, =CLK_SRC_CORE0_VAL @0x00090000 + ldr r2, =CLK_SRC_CORE0_OFFSET @0x04200 + str r1, [r0, r2] + + ldr r1, =CLK_DIV_CORE1_VAL @0x00000F00 + ldr r2, =CLK_DIV_CORE1_OFFSET @0x04504 + str r1, [r0, r2] + + ldr r3, =0x0 + bl wait_div_state + +@ Set CMU_CDREX, MUX & DIV + ldr r1, =CLK_SRC_CDREX_VAL @0x00001000 + ldr r2, =CLK_SRC_CDREX_OFFSET @0x20200 + str r1, [r0, r2] + + ldr r1, =CLK_DIV_CDREX0_VAL @0x31010100 + ldr r2, =CLK_DIV_CDREX0_OFFSET @0x20500 + str r1, [r0, r2] + + ldr r1, =CLK_DIV_CDREX1_VAL @0x00000011 + ldr r2, =CLK_DIV_CDREX1_OFFSET @0x20504 + str r1, [r0, r2] + + ldr r2, =CLK_DIV_CDREX0_OFFSET + ldr r3, =0x0 + bl wait_div_state + +@ Set CMU_TOP, MUX & DIV + ldr r1, =CLK_SRC_TOP0_VAL @0x00000000 + ldr r2, =CLK_SRC_TOP0_OFFSET @0x10210 + str r1, [r0, r2] + + ldr r1, =CLK_SRC_TOP1_VAL @0x0 + ldr r2, =CLK_SRC_TOP1_OFFSET @0x10214 + str r1, [r0, r2] + + ldr r1, =CLK_SRC_TOP2_VAL @0x01100000 + ldr r2, =CLK_SRC_TOP2_OFFSET @0x10218 + str r1, [r0, r2] + + ldr r3, =0x02211111 + bl wait_mux_state + +@ SCLK mux setting + ldr r1, =CLK_SRC_FSYS_VAL @0x30000666 + ldr r2, =CLK_SRC_FSYS_OFFSET @0x10244 + str r1, [r0, r2] + + mov r1, #0x50000 +1: subs r1, r1, #1 + bne 1b + + ldr r1, =CLK_DIV_TOP0_VAL @0x02112303 + ldr r2, =CLK_DIV_TOP0_OFFSET @0x10510 + str r1, [r0, r2] + + ldr r1, =CLK_DIV_TOP1_VAL @0x71700000 + ldr r2, =CLK_DIV_TOP1_OFFSET @0x10514 + str r1, [r0, r2] + + /* related to SSS, + * If MPLL is 800Mhz, then this divider bit[2:0] should be '2'. + * If MPLL is 532Mhz, then this divider bit[2:0] should be '1'. + */ + ldr r1, =CLK_DIV_G2D_VAL @0x00000011 + ldr r2, =CLK_DIV_G2D_OFFSET @0x08500 + str r1, [r0, r2] + + ldr r1, =CLK_DIV_FSYS0_VAL @0x0 + ldr r2, =CLK_DIV_FSYS0_OFFSET @0x10548 + str r1, [r0, r2] + + ldr r1, =CLK_DIV_FSYS1_VAL @0x000A000A + ldr r2, =CLK_DIV_FSYS1_OFFSET @0x1054C + str r1, [r0, r2] + + ldr r1, =CLK_DIV_FSYS2_VAL @0x0000000A + ldr r2, =CLK_DIV_FSYS2_OFFSET @0x10550 + str r1, [r0, r2] + str r1, [r0, r2] + + ldr r1, =CLKDIV4_RATIO_VAL @0x00000303 + ldr r2, =CLKDIV4_RATIO_OFFSET @0x105A0 + str r1, [r0, r2] + + ldr r3, =0x0 + bl wait_div_state + +@ Turn on PLL Mout + ldr r1, =0x00100001 + ldr r2, =CLK_SRC_CPU_OFFSET + str r1, [r0, r2] + + ldr r1, =0x00000100 + ldr r2, =CLK_SRC_CORE1_OFFSET + str r1, [r0, r2] + + ldr r3, =0x00000200 + bl wait_mux_state + + ldr r1, =0x01100100 + ldr r2, =CLK_SRC_TOP2_OFFSET + str r1, [r0, r2] + + ldr r1, =0x00008001 + ldr r2, =CLK_SRC_KFC_OFFSET + str r1, [r0, r2] + + ldr r3, =0x00210002 + bl wait_mux_state + + /* ByPass :: BYPASS = 0, PLL operates normally */ + ldr r2, =MPLL_CON1_OFFSET + ldr r1, [r0, r2] + mov r3, #1 + mov r3, r3, lsl #22 + bic r1, r1, r3 + str r1, [r0, r2] + +@ Setting CLKOUT + /* CLKOUT_CMU_CPU */ + ldr r1, =0x00010904 @ ARMCLK/10 + ldr r2, =CLKOUT_CMU_CPU_OFFSET + str r1, [r0, r2] + + /* CLKOUT_CMU_CPERI */ +@ ldr r1, =0x00010900 @ FOUT_MPLL/10 +@ ldr r2, =CLKOUT_CMU_CORE_OFFSET +@ str r1, [r0, r2] + + /* CLKOUT_CMU_TOP */ +@ ldr r1, =0x00010900 @ FOUT_EPLL/10 +@ ldr r1, =0x00010003 @ SCLK_HDMI27M/1 +@ ldr r1, =0x00010004 @ SCLK_DPTXPHY/1 +@ ldr r1, =0x00010005 @ SCLK_UHOSTPHY/1 +@ ldr r1, =0x00010006 @ SCLK_HDMIPHY/1 +@ ldr r2, =CLKOUT_CMU_TOP_OFFSET +@ str r1, [r0, r2] + + /* CLKOUT_CMU_CDREX */ +@ ldr r1, =0x00010900 @ MCLK_CDREX/10 +@ ldr r1, =0x00010908 @ ACLK_CDREX/10 +@ ldr r1, =0x00010909 @ PCLK_CDREX/10 +@ ldr r2, =CLKOUT_CMU_CDREX_OFFSET +@ str r1, [r0, r2] + + /* PMU_DEBUG */ +@ ldr r1, =0x0 @ CLKOUT_DEBUG +@ ldr r1, =0x00000100 @ CLKOUT_DEBUG1 +@ ldr r1, =0x00000200 @ CLKOUT_CMU_CDREX +@ ldr r1, =0x00000300 @ CLKOUT_CMU_CPERI +@ ldr r1, =0x00000900 @ CLKOUT_CMU_TOP + ldr r1, =0x00000A00 @ CLKOUT_CMU_CPU +@ ldr r1, =0x00000C00 @ CLKOUT_CMU_KFC +@ ldr r1, =0x00001000 @ XXTI +@ ldr r1, =0x00001100 @ XUSBXTI +@ ldr r1, =0x00001200 @ TICCLK +@ ldr r1, =0x00001300 @ RTCCLK + +@ ldr r2, =0x10040A00 +@ str r1, [r2] + + + pop {pc} + diff --git a/board/samsung/smdk5410/dmc_init.c b/board/samsung/smdk5410/dmc_init.c new file mode 100644 index 000000000..b800a9ad3 --- /dev/null +++ b/board/samsung/smdk5410/dmc_init.c @@ -0,0 +1,1686 @@ +/* + * Memory setup for SMDK5410 board based on EXYNOS5 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 <config.h> +#include <asm/arch/cpu.h> + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define SetBits(uAddr, uBaseBit, uMaskValue, uSetValue) \ + Outp32(uAddr, (Inp32(uAddr) & ~((uMaskValue)<<(uBaseBit))) \ + | (((uMaskValue)&(uSetValue))<<(uBaseBit))) + +#define CA_SWAP 1 +#define NUM_CHIP 1 +#define ZQ_MODE_DDS 6 +#define PERFORM_LEVELING 0 +#define PHY0_BASE 0x10C00000 +#define PHY1_BASE 0x10C10000 +#define DREX1_0 0x10C20000 +#define DREX1_1 0x10C30000 +#define CMU_COREPART 0x10010000 +#define CMU_TOPPART 0x10020000 +#define CMU_MEMPART 0x10030000 + + +void DMC_Delay(u32 x) +{ + while(--x) + __asm ("NOP"); +} + +void Prepare_levelings_lpddr3(u32 PHY_address, u32 DREX_address) +{ + u32 data, w_data, r_data; + + // LPDDR3 Leveling and Calibration Test + // Set the ConControl to turn off an auto refresh counter. + data = Inp32(DREX_address+0x0000); + data = data&(~0x00000020); + Outp32( DREX_address+0x0000, data); // Auto-Refresh cnt disable + + // Turn off dynamic power down control + // [5]dynamic self refresh enable + // [1]dynamic power down enable + // [0]clcok stop enable: 0-clock always runs, 1-clock stops during idle periods + data = Inp32(DREX_address+0x0004); + data = data&(~0x00000023); + Outp32( DREX_address+0x0004, data); // Auto-Refresh cnt disable + + // Precharge ALL + Outp32( DREX_address+0x0010, 0x01000000); // DirectCmd PALL + + // Initialize PHY + data = Inp32(PHY_address+0x0000); + data = data|(0x00004040); + Outp32( PHY_address+0x0000, data); // ctrl_atgate[6]=1, p0_cmd_en[14]=1 + + // r_data is used as w_data because w_data is used in below lines + data = Inp32(PHY_address+0x0008); + data = data&(~0x00000040); + data = data|(0x00000040); + Outp32( PHY_address+0x0008, data); // r_data[6]=1 + + data = Inp32(PHY_address+0x0000); + data = data&(~0x00002000); + data = data|(0x00002000); + Outp32( PHY_address+0x0000, data); // byte_rdlvl_en[13]=1 + + data = Inp32(PHY_address+0x0030); + data = data&(~0x00000020); + Outp32( PHY_address+0x0030, data); // ctrl_dll_on=0 + + // w_data[14:8]=r_data[16:10] + data = Inp32(PHY_address+0x0034); // PHY_CON13 read lock value + r_data = data>>10; + + // write lock value to ctrl_force + data = Inp32(PHY_address+0x0000); + w_data = data|(r_data << 8); + Outp32( PHY_address+0x0000, w_data); // ctrl_force[14:8] + + return; +} + +void Write_dq_leveling_lpddr3(u32 PHY_address, u32 DREX_address) +{ + u32 wrlvlTemp, data; + + // Set WL + data = Inp32(PHY_address+0x006C); // PHY_CON26 + wrlvlTemp=data&(~0x001F0000); + data=wrlvlTemp+(0x00070000); + Outp32( PHY_address+0x006C, data); // T_wrdata_en[20:16]=0x7 + + // RdlvlConfig1 --> RdlvlConfig + // Enable WrtraConfig.write_training_en + data = Inp32(DREX_address+0x00F8); // RdlvlConfig + wrlvlTemp=data&(~0x00000001); + data=wrlvlTemp|(0x00000001); + Outp32( DREX_address+0x00F8, data); // RdlvlConfig ctrl_rdlvl_gate_en[0]=1 + + // Issue write command to DRAM base to make DRAM in active state + // erased because active command is generated automatically after above setting wr_buffer[0]=0 + + // store read command in PHY_CON22 + if (CA_SWAP==1) + wrlvlTemp=data&(~0x000FFDFB); + else + wrlvlTemp=data&(~0x000FFFFA); + Outp32( PHY_address+0x005C, wrlvlTemp); // PHY_CON22 lpddr2_addr[19:0] + + // set write leveling pattern + data = Inp32(PHY_address+0x0004); // PHY_CON1 + data=data&(0xFFFF0000); + data=data+(0x000000FF); + Outp32( PHY_address+0x0004, data); // rdlvl_rddata_adj[15:0]=0x00FF + + // byte_rdlvl_en=0 + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00002000); + data=data|(0x00002000); + Outp32( PHY_address+0x0000, data); // byte_rdlvl_en[13]=0 + + // If read dq calibration is performed prior to write dq calibration, below step have to be performed + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00004000); + data=data|(0x00004000); + Outp32( PHY_address+0x0000, data); // p0_cmd_en [14]=1 + + // write traning mode enter + data = Inp32(PHY_address+0x0008); // PHY_CON2 + data=data&(~0x04000000); + data=data|(0x04000000); + Outp32( PHY_address+0x0008, data); // wr_deskew_con[26]=1 + + // write traning start + data = Inp32(PHY_address+0x0008); // PHY_CON2 + data=data&(~0x08000000); + data=data|(0x08000000); + Outp32( PHY_address+0x0008, data); // wr_deskew_en[27]=1 + + // wait until write training done + while( ( Inp32( DREX_address+0x0040 ) & 0x00004000 ) != 0x00004000 ); // PhyStatus rdlvl_complete[14] + + // RdlvlConfig0 --> RdlvlConfig, 27-bit = zero? + // Enable WrtraConfig.write_training_en + data = Inp32(DREX_address+0x00F8); // RdlvlConfig + data=data&(~0x08000000); + Outp32( DREX_address+0x00F8, data); // RdlvlConfig ctrl_rdlvl_gate_en[27]=0 + Outp32( PHY_address+0x0008, data); // wr_deskew_en[27]=0 + return; +} + +void Read_leveling_lpddr3(u32 PHY_address, u32 DREX_address) +{ + // u32 rPhyData, rPhySDLL_code; + u32 rdlvlTemp, data; + + // Note that maximum wating time of read leveling is 20us + // set read leveling pattern + data = Inp32(PHY_address+0x0004); // PHY_CON1 + data=data&(0xFFFF0000); + data=data+(0x000000FF); + Outp32( PHY_address+0x0004, data); // rdlvl_rddata_adj[15:0]=0x00FF + + // byte_rdlvl_en=0 + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00002000); + Outp32( PHY_address+0x0000, data); // byte_rdlvl_en[13]=0 + + // setting MR32 for dq calibration + if (CA_SWAP==1) + Outp32( PHY_address+0x005C, 0x00000041); // PHY_CON22 lpddr2_addr[19:0] + else + Outp32( PHY_address+0x005C, 0x00000208); // PHY_CON22 lpddr2_addr[19:0] + + // enable rdlvl_get_en + data = Inp32(PHY_address+0x0008); // PHY_CON2 + data=data&(0xFF80FFFF); + data=data+(0x00600000); + Outp32( PHY_address+0x0008, data); // rdlvl_incr_adj[22:16]=7'b110_0000 + // rdlvl_en + rdlvlTemp=data&(~0x02000000); + data=rdlvlTemp|(0x02000000); + Outp32( PHY_address+0x0008, data); // rdlvl_en[25]=1 + + // RdlvlConfig0 --> RdlvlConfig + // enable ctrl_rdlvl_en and ctrl_rdlvl_gate_en + Outp32( DREX_address+0x00F8, 0x00000002); // RdlvlConfig ctrl_rdlvl_data_en [1]=1, ctrl_rdlvl_gate_en [0]=0 + + // wait for leveling done + while( ( Inp32( DREX_address+0x0040 ) & 0x00004000 ) != 0x00004000 ); // PhyStatus rdlvl_complete[14] + + // disable ctrl_rdlvl_en and ctrl_rdlvl_gate_en - move FSM to IDLE state + Outp32( DREX_address+0x00F8, 0x00000000); // RdlvlConfig ctrl_rdlvl_data_en[1]=0, ctrl_rdlvl_gate_en [0]=0 + return; +} + +void Write_leveling_lpddr3(u32 PHY_address, u32 DREX_address) +{ + u32 r_data_lvl0, r_data_lvl8, r_data_lvl16, r_data_lvl31; + u32 wrlvl_byte0_done, wrlvl_byte1_done, wrlvl_byte2_done, wrlvl_byte3_done; + u32 wrlvlSDLL_code; + u32 wrlvlTemp, data; + + // Configure memory in write leveling mode + Outp32( DREX_address+0x0010, 0x0000A28); // DirectCmd + + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00010000); + data=data|(0x00010000); + Outp32( PHY_address+0x0000, data); // ctrl_wrlvl_en [16]=1 + data = Inp32(DREX_address+0x0120); // WRLVLCONFIG0 + data=data&(~0x00000001); + data=data|(0x00000001); + Outp32( DREX_address+0x0120, data); // otd_on[0]=1 + + // ///// Finding optimal SDLL code start ///// + wrlvl_byte0_done=0; + wrlvl_byte1_done=0; + wrlvl_byte2_done=0; + wrlvl_byte3_done=0; + wrlvlSDLL_code=0; + wrlvlSDLL_code=0x08080808; + + while ((wrlvl_byte0_done==0)||(wrlvl_byte1_done==0)||(wrlvl_byte2_done==0)||(wrlvl_byte3_done==0)) + { + // 1. set SDLL code + Outp32( PHY_address+0x0030, wrlvlSDLL_code); // ctrl_wrlvl[16] + + // 2. resync command enable to SDLL + data = Inp32(PHY_address+0x0030); // PHY_CON30 + data=data&(~0x00000001); + data=data|(0x00000001); + Outp32( PHY_address+0x0030, data); // ctrl_wrlvl[16]=1 + + // 3. resync command disable + data = Inp32(PHY_address+0x0030); // PHY_CON30 + data=data&(~0x00000001); + Outp32( PHY_address+0x0030, data); // ctrl_wrlvl[16]=0 + + // 4. dqs pulse generation + Outp32( DREX_address+0x0124, 0x00000001); // wrlvl_wrdata_en[0]=1 + + // 5. wait until write leveling data from LPDDR3 + while( ( Inp32( DREX_address+0x0128 ) & 0x0000001F ) != 0x0000001F ); // wrlvl_fsm[4:0] + + // 6. byte-by-byte update of SDLL codes + data = Inp32(DREX_address+0x0150); // CTRL_IO_RDATA + r_data_lvl0=data&(0x00000001); + r_data_lvl8=data&(0x00000100); + r_data_lvl16=data&(0x00010000); + r_data_lvl31=data&(0x80000000); + if ((wrlvl_byte0_done==1)||(r_data_lvl0==0x00000001)) + wrlvl_byte0_done=1; + else + { + wrlvlTemp=wrlvlSDLL_code&(0x0000007F); + wrlvlTemp=wrlvlTemp+0x00000001; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x0000007F)); + } + + if ((wrlvl_byte1_done==1)||(r_data_lvl8==0x00000100)) + wrlvl_byte1_done=1; + else + { + wrlvlTemp=wrlvlSDLL_code&(0x00007F00); + wrlvlTemp=wrlvlTemp+0x00000100; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x00007F00)); + } + + if ((wrlvl_byte2_done==1)||(r_data_lvl16==0x00010000)) + wrlvl_byte2_done=1; + else + { + wrlvlTemp=wrlvlSDLL_code&(0x00FE0000); + wrlvlTemp=wrlvlTemp+0x00020000; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x00FE0000)); + } + + if ((wrlvl_byte3_done==1)||(r_data_lvl31==0x80000000)) + wrlvl_byte3_done=1; + else + { + wrlvlTemp=wrlvlSDLL_code&(0x7F000000); + wrlvlTemp=wrlvlTemp+0x01000000; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x7F000000)); + } + }; + + // optimal SDLL code is current SDLL code - 1 + wrlvlTemp=(wrlvlSDLL_code&(0x0000007F))-0x00000001; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x0000007F)); + wrlvlTemp=(wrlvlSDLL_code&(0x00007F00))-0x00000100; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x00007F00)); + wrlvlTemp=(wrlvlSDLL_code&(0x00007F00))-0x00020000; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x00007F00)); + wrlvlTemp=(wrlvlSDLL_code&(0x7F000000))-0x01000000; + wrlvlSDLL_code=wrlvlSDLL_code|(wrlvlTemp&(0x7F000000)); + Outp32( PHY_address+0x0030, wrlvlSDLL_code); + // resync enable + wrlvlTemp=wrlvlSDLL_code&(~0x00010000); + wrlvlSDLL_code=wrlvlTemp|(0x00010000); + Outp32( PHY_address+0x0030, wrlvlSDLL_code); // ctrl_wrlvl[16]=1 + // resync disable + wrlvlSDLL_code=wrlvlSDLL_code&(~0x00010000); + Outp32( PHY_address+0x0030, wrlvlSDLL_code); // ctrl_wrlvl[16]=0 + + // ///// Finding optimal SDLL code end ///// + // Check whether SDLL code is correct + data = Inp32(PHY_address+0x0030); // PHY_CON30 + + // Write level disable + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00010000); + Outp32( PHY_address+0x0000, data); // ctrl_wrlvl_en[16]=0 + + // commadn to DRAM to exit from write level state + Outp32( DREX_address+0x0010, 0x0000828); // DirectCmd + + // ODT disable + data = Inp32(DREX_address+0x0120); // WRLVLCONFIG0 + data=data&(~0x00000001); + Outp32( DREX_address+0x0120, data); // otd_on[0]=0 + + return; +} + +void CA_calibration_lpddr3(u32 PHY_address, u32 DREX_address) +{ + u32 w_data, data; + u32 r_data0_1, r_data0_2, r_data1_1, r_data1_2, r_data2_1, r_data2_2, r_data3_1, r_data3_2, r_data4_1, r_data4_2, r_data5_1, r_data5_2; + u32 r_data6_1, r_data6_2, r_data7_1, r_data7_2, r_data8_1, r_data8_2, r_data9_1, r_data9_2; + u32 cal_temp1, cal_temp2, cal_temp3; + u32 calibration_done_ca, left_code_found_ca, calibbration_done_ca_ca4, calibbration_done_ca_ca9; + u32 SDLL_code_ca3, SDLL_code_ca2, SDLL_code_ca1, SDLL_code_ca0; + u32 SDLL_code_ca8, SDLL_code_ca7, SDLL_code_ca6, SDLL_code_ca5; + u32 SDLL_code_ca4, SDLL_code_ca9; + u32 left_code_ca0, left_code_ca1, left_code_ca2, left_code_ca3, left_code_ca4; + u32 left_code_ca5, left_code_ca6, left_code_ca7, left_code_ca8, left_code_ca9; + u32 wrlvl_byte0_done, wrlvl_byte1_done, wrlvl_byte2_done, wrlvl_byte3_done; + u32 wrSDLL_code; + + // 1. CA calibration mode enable to LPDDR3 (CA[3:0] and CA[8:5] will be calibrated) + Outp32( DREX_address+0x0010, 0x00050690); // DirectCmd cmd_type[27:24], cmd_chip[20], cmd_bank[18:16], cmd_addr[15:0] + + // Deasserting CKE and set t_adr + data = Inp32(DREX_address+0x0160); + data = data|(0x00000031); + Outp32( DREX_address+0x0160, data); // t_adr[7:4]=4'h3, deassert_cke[0]=1 + + // 2. Configure PHY in CA calibration mode + data = Inp32(PHY_address+0x0000); + data = data&(~0x00010000); + data = data|(0x00010000); + Outp32( PHY_address+0x0000, data); // wrlvl_en[16]=1 + data = Inp32(PHY_address+0x0008); + data = data&(~0x00800000); + data = data|(0x00800000); + Outp32( PHY_address+0x0008, data); // rdlvl_ca_en[23]=1 + + // 3. Finding optimal CA SDLL code + // set the initial CA SDLL codes + left_code_found_ca=0; + calibration_done_ca=0; + SDLL_code_ca0=0x8; + SDLL_code_ca1=0x8; + SDLL_code_ca2=0x8; + SDLL_code_ca3=0x8; + SDLL_code_ca5=0x8; + SDLL_code_ca6=0x8; + SDLL_code_ca7=0x8; + SDLL_code_ca8=0x8; + // ca4 and ca9 will be calibrated in separate step + calibration_done_ca=0x00000210; + + // left_code_ca is zero? + left_code_ca0=0; + left_code_ca1=0; + left_code_ca2=0; + left_code_ca3=0; + left_code_ca4=0; + left_code_ca5=0; + left_code_ca6=0; + left_code_ca7=0; + left_code_ca8=0; + left_code_ca9=0; + while (calibration_done_ca != 0x3FF) + { + cal_temp1=((left_code_ca0<<0)&0x0000007E)|((left_code_ca1<<7)&0x0000007E)|((left_code_ca2<<14)&0x001FC000)|((left_code_ca3<<21)&0x0FE00000); + Outp32( PHY_address+0x0080, cal_temp1); // PHY_CON31 + cal_temp1=((left_code_ca5<<3)&0x000003F8)|((left_code_ca6<<10)&0x0001FC00)|((left_code_ca7<<17)&0x00FE0000)|((left_code_ca8<<24)&0x7F000000); + Outp32( PHY_address+0x0084, cal_temp1); + + // asserting ctrl_resync to update SDLL code + data = Inp32(PHY_address+0x0028); + data=data&(~0x01000000); + data=data|(0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=1 + data=data&(~0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=0 + + // generating dfi_cs_n_p0 pulse + data = Inp32(DREX_address+0x0164); + data=data&(~0x00000001); + data=data|(0x00000001); + Outp32( DREX_address+0x0164, data); // calcal_csn[0]=1 + + // wait for valid ctrl_io_rdata + while( ( Inp32( DREX_address+0x0168 ) & 0x0000001F ) != 0x0000001F ); // PHY_CON17 zq_done[0]=ZQ Calibration is finished. + + data = Inp32(DREX_address+0x0150); // CTRL_IO_RDATA ctrl_io_rdata[31:0] + r_data0_1=data&(0x00000001); + r_data0_2=data&(0x00000002); + r_data1_1=data&(0x00000004); + r_data1_2=data&(0x00000008); + r_data2_1=data&(0x00000010); + r_data2_2=data&(0x00000020); + r_data3_1=data&(0x00000040); + r_data3_2=data&(0x00000080); + r_data5_1=data&(0x00000100); + r_data5_2=data&(0x00000200); + r_data6_1=data&(0x00000400); + r_data6_2=data&(0x00000800); + r_data7_1=data&(0x00001000); + r_data7_2=data&(0x00002000); + r_data8_1=data&(0x00004000); + r_data8_2=data&(0x00008000); + + // test CA[0] + cal_temp1=calibration_done_ca&(0x00000001); + if (cal_temp1==0) + { + if ((r_data0_1==0x00000001)&&(r_data0_2==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca0==0x60) + { + SDLL_code_ca0=(SDLL_code_ca0+left_code_ca0)/2; + cal_temp3=calibration_done_ca&(~0x00000001); + calibration_done_ca=cal_temp3|(0x00000001); + } + SDLL_code_ca0=SDLL_code_ca0+1; + cal_temp2=left_code_found_ca&(0x00000001); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000001); + left_code_found_ca=cal_temp3|(0x00000001); + left_code_ca0=SDLL_code_ca0; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000001); + if (cal_temp2==1) + { + SDLL_code_ca0=(SDLL_code_ca0+left_code_ca0)/2; + cal_temp3=calibration_done_ca&(~0x00000001); + calibration_done_ca=cal_temp3|(0x00000001); + } + else + { + SDLL_code_ca0=SDLL_code_ca0+1; + } + } + } + // test CA[1] + cal_temp1=calibration_done_ca&(0x00000002); + if (cal_temp1==0) + { + if ((r_data1_1==0x00000004)&&(r_data1_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca1==0x60) + { + SDLL_code_ca1=(SDLL_code_ca1+left_code_ca1)/2; + cal_temp3=calibration_done_ca&(~0x00000002); + calibration_done_ca=cal_temp3|(0x00000002); + } + SDLL_code_ca1=SDLL_code_ca1+1; + cal_temp2=left_code_found_ca&(0x00000002); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000002); + left_code_found_ca=cal_temp3|(0x00000002); + left_code_ca1=SDLL_code_ca1; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000002); + if (cal_temp2==1) + { + SDLL_code_ca1=(SDLL_code_ca1+left_code_ca1)/2; + cal_temp3=calibration_done_ca&(~0x00000002); + calibration_done_ca=cal_temp3|(0x00000002); + } + else + { + SDLL_code_ca1=SDLL_code_ca1+1; + } + } + } + // test CA[2] + cal_temp1=calibration_done_ca&(0x00000004); + if (cal_temp1==0) + { + if ((r_data2_1==0x00000010)&&(r_data2_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca2==0x60) + { + SDLL_code_ca2=(SDLL_code_ca2+left_code_ca2)/2; + cal_temp3=calibration_done_ca&(~0x00000004); + calibration_done_ca=cal_temp3|(0x00000004); + } + SDLL_code_ca2=SDLL_code_ca2+1; + cal_temp2=left_code_found_ca&(0x00000004); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000004); + left_code_found_ca=cal_temp3|(0x00000004); + left_code_ca2=SDLL_code_ca2; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000004); + if (cal_temp2==1) + { + SDLL_code_ca2=(SDLL_code_ca2+left_code_ca2)/2; + cal_temp3=calibration_done_ca&(~0x00000004); + calibration_done_ca=cal_temp3|(0x00000004); + } + else + { + SDLL_code_ca2=SDLL_code_ca2+1; + } + } + } + // test CA[3] + cal_temp1=calibration_done_ca&(0x00000008); + if (cal_temp1==0) + { + if ((r_data3_1==0x00000010)&&(r_data3_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca3==0x60) + { + SDLL_code_ca3=(SDLL_code_ca3+left_code_ca3)/2; + cal_temp3=calibration_done_ca&(~0x00000008); + calibration_done_ca=cal_temp3|(0x00000008); + } + SDLL_code_ca3=SDLL_code_ca3+1; + cal_temp2=left_code_found_ca&(0x00000008); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000008); + left_code_found_ca=cal_temp3|(0x00000008); + left_code_ca3=SDLL_code_ca3; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000008); + if (cal_temp2==1) + { + SDLL_code_ca3=(SDLL_code_ca3+left_code_ca3)/2; + cal_temp3=calibration_done_ca&(~0x00000008); + calibration_done_ca=cal_temp3|(0x00000008); + } + else + { + SDLL_code_ca3=SDLL_code_ca3+1; + } + } + } + // test CA[5] + cal_temp1=calibration_done_ca&(0x00000020); + if (cal_temp1==0) + { + if ((r_data5_1==0x00000100)&&(r_data5_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca5==0x60) + { + SDLL_code_ca5=(SDLL_code_ca5+left_code_ca5)/2; + cal_temp3=calibration_done_ca&(~0x00000020); + calibration_done_ca=cal_temp3|(0x00000020); + } + SDLL_code_ca5=SDLL_code_ca5+1; + cal_temp2=left_code_found_ca&(0x00000020); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000020); + left_code_found_ca=cal_temp3|(0x00000020); + left_code_ca5=SDLL_code_ca5; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000020); + if (cal_temp2==1) + { + SDLL_code_ca5=(SDLL_code_ca5+left_code_ca5)/2; + cal_temp3=calibration_done_ca&(~0x00000020); + calibration_done_ca=cal_temp3|(0x00000020); + } + else + { + SDLL_code_ca5=SDLL_code_ca5+1; + } + } + } + // test CA[6] + cal_temp1=calibration_done_ca&(0x00000040); + if (cal_temp1==0) + { + if ((r_data6_1==0x00000400)&&(r_data6_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca6==0x60) + { + SDLL_code_ca6=(SDLL_code_ca6+left_code_ca6)/2; + cal_temp3=calibration_done_ca&(~0x00000040); + calibration_done_ca=cal_temp3|(0x00000040); + } + SDLL_code_ca6=SDLL_code_ca6+1; + cal_temp2=left_code_found_ca&(0x00000040); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000040); + left_code_found_ca=cal_temp3|(0x00000040); + left_code_ca6=SDLL_code_ca6; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000040); + if (cal_temp2==1) + { + SDLL_code_ca6=(SDLL_code_ca6+left_code_ca6)/2; + cal_temp3=calibration_done_ca&(~0x00000040); + calibration_done_ca=cal_temp3|(0x00000040); + } + else + { + SDLL_code_ca6=SDLL_code_ca6+1; + } + } + } + // test CA[7] + cal_temp1=calibration_done_ca&(0x00000080); + if (cal_temp1==0) + { + if ((r_data7_1==0x00000800)&&(r_data7_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca7==0x60) + { + SDLL_code_ca7=(SDLL_code_ca7+left_code_ca7)/2; + cal_temp3=calibration_done_ca&(~0x00000080); + calibration_done_ca=cal_temp3|(0x00000080); + } + SDLL_code_ca7=SDLL_code_ca7+1; + cal_temp2=left_code_found_ca&(0x00000080); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000080); + left_code_found_ca=cal_temp3|(0x00000080); + left_code_ca7=SDLL_code_ca7; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000080); + if (cal_temp2==1) + { + SDLL_code_ca7=(SDLL_code_ca7+left_code_ca7)/2; + cal_temp3=calibration_done_ca&(~0x00000080); + calibration_done_ca=cal_temp3|(0x00000080); + } + else + { + SDLL_code_ca7=SDLL_code_ca7+1; + } + } + } + // test CA[8] + cal_temp1=calibration_done_ca&(0x00000100); + if (cal_temp1==0) + { + if ((r_data8_1==0x00000800)&&(r_data8_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca8==0x60) + { + SDLL_code_ca8=(SDLL_code_ca8+left_code_ca8)/2; + cal_temp3=calibration_done_ca&(~0x00000100); + calibration_done_ca=cal_temp3|(0x00000100); + } + SDLL_code_ca8=SDLL_code_ca8+1; + cal_temp2=left_code_found_ca&(0x00000100); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000100); + left_code_found_ca=cal_temp3|(0x00000100); + left_code_ca8=SDLL_code_ca8; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000100); + if (cal_temp2==1) + { + SDLL_code_ca8=(SDLL_code_ca8+left_code_ca8)/2; + cal_temp3=calibration_done_ca&(~0x00000100); + calibration_done_ca=cal_temp3|(0x00000100); + } + else + { + SDLL_code_ca8=SDLL_code_ca8+1; + } + } + } + } + + // Update CA SDLL codes + cal_temp1=(SDLL_code_ca0&0x0000007E)|((SDLL_code_ca1<<7)&0x0000007E)|((SDLL_code_ca2<<14)&0x001FC000)|((SDLL_code_ca3<<21)&0x0FE00000); + Outp32( PHY_address+0x0080, cal_temp1); // PHY_CON31 + cal_temp1=((SDLL_code_ca5<<3)&0x000003F8)|((SDLL_code_ca6<<10)&0x0001FC00)|((SDLL_code_ca7<<17)&0x00FE0000)|((SDLL_code_ca8<<24)&0x7F000000); + Outp32( PHY_address+0x0084, cal_temp1); // PHY_CON32 + + // asserting ctrl_resync to update SDLL code + data = Inp32(PHY_address+0x0028); // PHY_CON10 + data=data&(~0x01000000); + data=data|(0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=1 + data=data&(~0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=0 + + // Set PHY to normal mode + data = Inp32(PHY_address+0x0008); // PHY_CON2 + data=data&(~0x00800000); + Outp32( PHY_address+0x0008, data); // rdlvl_ca_en[23]=0 + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00010000); + Outp32( PHY_address+0x0000, data); // ctrl_wrlvl_en[16]=0 + + // asserting CKE for MRS command below + data = Inp32(DREX_address+0x0160); // CACAL_CONFIG0 + data=data&(~0x00000001); + Outp32( DREX_address+0x0160, data); // deassert_cke[0]=0 + + // 1. CA calibration mode enable to LPDDR3 (CA4 and CA9 will be calibrated) + Outp32( DREX_address+0x0010, 0x00050AA0); // DirectCmd + Outp32( DREX_address+0x0010, 0x00060300); // DirectCmd + + // 2. Deasserting CKE and set t_adr + data = Inp32(DREX_address+0x0160); // CACAL_CONFIG0 + data=data|(0x00000031); + Outp32( DREX_address+0x0160, data); // t_adr[7:4]=4'h3, deassert_cke[0]=1 + + // 3. Configure PHY in CA calibration mode + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00010000); + data=data|(0x00010000); + Outp32( PHY_address+0x0000, data); // wrlvl_en[16]=1 + data = Inp32(PHY_address+0x0008); // PHY_CON2 + data=data&(~0x00800000); + data=data|(0x00800000); + Outp32( PHY_address+0x0008, data); // rdlvl_ca_en[23]=1 + + // 4. Set the initial CA SDLL codes + SDLL_code_ca4=0x8; + SDLL_code_ca9=0x8; + calibration_done_ca=0; + left_code_found_ca=0; + calibbration_done_ca_ca4=0xF; + calibbration_done_ca_ca9=0xF; + + // 5. Finding optimal CS SDLL code + while (calibration_done_ca != 0x3FF) + { + Outp32( PHY_address+0x0080, SDLL_code_ca4<<28); // PHY_CON31 + cal_temp1=((SDLL_code_ca9&(0x00000001))<<31)&(0x80000000); + cal_temp1=cal_temp1&(((SDLL_code_ca4&0x00000070)>>4)&0x00000007); + Outp32( PHY_address+0x0084, cal_temp1); // PHY_CON32 + + // asserting ctrl_resync to update SDLL code + data = Inp32(PHY_address+0x0028); // PHY_CON10 + data=data&(~0x01000000); + data=data|(0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=1 + data=data&(~0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=0 + + // generating dfi_cs_n_p0 pulse + data = Inp32(DREX_address+0x0164); // CACAL_CONFIG1 + data=data&(~0x00000001); + data=data|(0x00000001); + Outp32( DREX_address+0x0164, data); // calcal_csn[0]=1 + + // wait for valid ctrl_io_rdata + while( ( Inp32( DREX_address+0x0168 ) & 0x0000001F ) != 0x0000001F ); // CACAL_STATUS cacal_fsm[4:0] + + data = Inp32(DREX_address+0x0150); // CTRL_IO_RDATA ctrl_io_rdata[31:0] + r_data4_1=data&(0x00000001); + r_data4_2=data&(0x00000002); + r_data9_1=data&(0x00000004); + r_data9_2=data&(0x00000008); + + // test CA[4] + cal_temp1=calibration_done_ca&(0x00000010); + if (cal_temp1==0) + { + if ((r_data4_1==0x00000001)&&(r_data4_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca4==0x60) + { + SDLL_code_ca4=(SDLL_code_ca4+left_code_ca4)/2; + cal_temp3=calibration_done_ca&(~0x00000010); + calibration_done_ca=cal_temp3|(0x00000010); + } + SDLL_code_ca4=SDLL_code_ca4+1; + cal_temp2=left_code_found_ca&(0x00000010); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000010); + left_code_found_ca=cal_temp3|(0x00000010); + left_code_ca8=SDLL_code_ca4; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000010); + if (cal_temp2==1) + { + SDLL_code_ca4=(SDLL_code_ca4+left_code_ca4)/2; + cal_temp3=calibration_done_ca&(~0x00000010); + calibration_done_ca=cal_temp3|(0x00000010); + } + else + { + SDLL_code_ca4=SDLL_code_ca4+1; + } + } + } + // test CA[9] + cal_temp1=calibration_done_ca&(0x00000200); + if (cal_temp1==0) + { + if ((r_data9_1==0x00000001)&&(r_data9_1==0)) + { + // CA calibration fail - valid code not found + if (SDLL_code_ca9==0x60) + { + SDLL_code_ca9=(SDLL_code_ca9+left_code_ca4)/2; + cal_temp3=calibration_done_ca&(~0x00000200); + calibration_done_ca=cal_temp3|(0x00000200); + } + SDLL_code_ca9=SDLL_code_ca9+1; + cal_temp2=left_code_found_ca&(0x00000200); + if (cal_temp2==0) + { + cal_temp3=left_code_found_ca&(~0x00000200); + left_code_found_ca=cal_temp3|(0x00000200); + left_code_ca8=SDLL_code_ca9; + } + } + else + { + // left code not found yet or right code just found + cal_temp2=left_code_found_ca&(0x00000200); + if (cal_temp2==1) + { + SDLL_code_ca9=(SDLL_code_ca9+left_code_ca4)/2; + cal_temp3=calibration_done_ca&(~0x00000200); + calibration_done_ca=cal_temp3|(0x00000200); + } + else + { + SDLL_code_ca9=SDLL_code_ca9+1; + } + } + } + } + + // Update CA SDLL codes + cal_temp1=(SDLL_code_ca0&0x0000007E)|((SDLL_code_ca1<<7)&0x0000007E)|((SDLL_code_ca2<<14)&0x001FC000)|((SDLL_code_ca3<<21)&0x0FE00000)|((SDLL_code_ca4<<28)&0xF0000000); + Outp32( PHY_address+0x0080, cal_temp1); // PHY_CON31 + w_data=((SDLL_code_ca5<<3)&0x000003F8)|((SDLL_code_ca6<<10)&0x0001FC00)|((SDLL_code_ca7<<17)&0x00FE0000)|((SDLL_code_ca8<<24)&0x7F000000)|((SDLL_code_ca9<<31)&0x80000000)|((SDLL_code_ca4>>4)&0x00000007); + Outp32( PHY_address+0x0084, w_data); // PHY_CON32 + w_data=0; + w_data=SDLL_code_ca9>>1; + Outp32( PHY_address+0x0088, w_data); // PHY_CON33 + + // asserting ctrl_resync to update SDLL code + data = Inp32(PHY_address+0x0028); // PHY_CON10 + data=data&(~0x01000000); + data=data|(0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=1 + data=data&(~0x01000000); + Outp32( PHY_address+0x0028, data); // ctrl_resync[24]=0 + + // Set PHY to normal mode + data = Inp32(PHY_address+0x0000); // PHY_CON0 + data=data&(~0x00010000); + Outp32( PHY_address+0x0000, data); // ctrl_wrlvl_en[16]=0 + + // asserting CKE for MRS command below + data = Inp32(DREX_address+0x0160); // CACAL_CONFIG0 + data=data&(~0x00000001); + Outp32( DREX_address+0x0160, data); // deassert_cke[0]=0 + + // 1. CA calibration mode enable to LPDDR3 (CA4 and CA9 will be calibrated) + Outp32( DREX_address+0x0010, 0x00050AA0); // DirectCmd +} + +void CA_swap_lpddr3(u32 PHY_address) +{ + // u32 data; + + Outp32( CMU_MEMPART+0x0A20, 0xC0000000 ); // DREX1 CA swap [30] : DREX0 CA swap + + Outp32( PHY_address+0x0064, 0x00000001 ); // ca_swap_mode[0]=1 + return; +} + +void Low_frequency_init_lpddr3(u32 PHY_address, u32 DREX_address) +{ + u32 data; + u32 *testbit; + u32 nLoop; + u32 data_RST_STAT; + u32 status = __REG(EXYNOS5_POWER_BASE + INFORM1_OFFSET); + + // Reset Status Check..! + data_RST_STAT = Inp32(0x10040404); + data_RST_STAT = data_RST_STAT & (0x00000C00); + + // 1. To provide stable power for controller and memory device, the controller must assert and hold CKE to a logic low level + // 2. DRAM mode setting + Outp32( PHY_address+0x0000, 0x17021A00 ); // PHY_CON0 ctrl_ddr_mode[12:11]=3(LPDDR3), ctrl_atgate (automatic gate control-controller drive gate signals)[6]=1 + + if((status != S5P_CHECK_SLEEP) && (data_RST_STAT == 0)) + { + // 3. Force lock values (DLL cannot be locked under 400MHz) + Outp32( PHY_address+0x0030, 0x10107F50 ); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + Outp32( PHY_address+0x0028, 0x0000007F ); // ctrl_offsetd[7:0]=0x7F + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x7F7F7F7F ); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value + Outp32( PHY_address+0x0018, 0x7F7F7F7F ); // PHY_CON6 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x0C183060 ); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x60C18306 ); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000030 ); // PHY_CON33 DeSkew Code for CA + + // Setting PHY_CON12 later + // 6. Set ctrl_dll_on to 0 + // Outp32( PHY_address+0x0030, 0x10107F50); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + // DMC_Delay(100); // Wait for 10 PCLK cycles + + // 7. Issue dfi_ctrlupd_req for more than 10 cycles + Outp32( DREX_address+0x0018, 0x00000008); // PHYCONTROL0 assert fp_resync[3]=1(Force DLL Resyncronization) + // "dfi_ctrlupd_req" should be issued more than 10 cycles after ctrl_dll_on is disabled. + DMC_Delay(100); // Wait for 10 PCLK cycles + Outp32( DREX_address+0x0018, 0x00000000); // PHYCONTROL0 deassert fp_resync[3]=1(Force DLL Resyncronization) + + // 8. Set MemControl. At this moment, all power down modes should be off. + Outp32( DREX_address+0x0004, 0x00312700); // MEMCONTROL bl[22:20]=Memory Burst Length 0x3 = 8, mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit, mem_type [11:8]=Type of Memory 0x7 = LPDDR3 + } else + { + // 8. Set MemControl. At this moment, all power down modes should be off. + Outp32( DREX_address+0x0004, 0x00312700); // MEMCONTROL bl[22:20]=Memory Burst Length 0x3 = 8, mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit, mem_type [11:8]=Type of Memory 0x7 = LPDDR3 + } + + if((status != S5P_CHECK_SLEEP) && (data_RST_STAT == 0)) + { + // Start :: Adding option for handshaking between DREX and PHY + // Deasserting the dfi_init_start + // 2012.11.08 :: rd_fetch 3 -> 2 + Outp32( DREX_address+0x0000, 0x1FFF2100); // CONCONTROL dfi_init_start[28]=0 auto refresh not yet. + // Disable DLL + Outp32( PHY_address+0x0030, 0x10107F10); // PHY_CON12 + // End :: Adding option for handshaking between DREX and PHY + + // Direct Command P0 CH0..! + // 9. CKE low for tINIT1 and CKE high for tINIT3 + Outp32( DREX_address+0x0010, 0x07000000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + DMC_Delay(53333); // MIN 200us + + // 10. RESET command to LPDDR3 + // Add :: 2012.11.01 :: Not send reset command when occured by wake-up + Outp32( DREX_address+0x0010, 0x00071C00); // 0x0 = MRS/EMRS (mode register setting), MR63_Reset (MA<7:0> = 3FH): MRW only + + // tINIT4(MIN 1us), tINIT5(MAX 10us) + + // 12. DRAM ZQ calibration + Outp32( DREX_address+0x0010, 0x00010BFC); // 0x0 = MRS/EMRS (mode register setting), MR10_Calibration, FFH: Calibration command after initialization + // 13. Wait for minimum 1us (tZQINIT). + DMC_Delay(267); // MIN 1us + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x0000050C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + + // 2012.10.11 + // Outp32( DREX_address+0x0010, 0x00000828); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x00000868); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + + // Add 20120501..! + // 14. I/O Configuration :: Drive Strength + Outp32( DREX_address+0x0010, 0x00000C04); // MR(3) OP(1) + DMC_Delay(267); // MIN 1us + } + + // Initialization of second DRAM + if(NUM_CHIP == 1) + { + if((status != S5P_CHECK_SLEEP) && (data_RST_STAT == 0)) + { + // 9. CKE low for tINIT1 and CKE high for tINIT3 + Outp32( DREX_address+0x0010, 0x07100000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + DMC_Delay(53333); // MIN 200us + + // 10. RESET command to LPDDR3 + // Add :: 2012.11.01 :: Not send reset command when occured by wake-up + Outp32( DREX_address+0x0010, 0x00171C00); // 0x0 = MRS/EMRS (mode register setting), MR63_Reset (MA<7:0> = 3FH): MRW only + + // tINIT4(MIN 1us), tINIT5(MAX 10us) + + // 12. DRAM ZQ calibration + Outp32( DREX_address+0x0010, 0x00110BFC); // 0x0 = MRS/EMRS (mode register setting), MR10_Calibration, FFH: Calibration command after initialization + // 13. Wait for minimum 1us (tZQINIT). + DMC_Delay(267); // MIN 1us + + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x0010050C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + + // 2012.10.11 + // Outp32( DREX_address+0x0010, 0x00100828); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x00100868); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + + // Add 20120501..! + // 14. I/O Configuration :: Drive Strength + Outp32( DREX_address+0x0010, 0x00100C04); // MR(3) OP(1) + DMC_Delay(267); // MIN 1us + } + } + + if((status != S5P_CHECK_SLEEP) && (data_RST_STAT == 0)) + { + // Reset SDLL codes + // 2012.10.11 + // Outp32( PHY_address+0x0028, 0x00000000); // PHY_CON10 ctrl_offsetd[7:0]=0x8 + Outp32( PHY_address+0x0028, 0x00000008); // PHY_CON10 ctrl_offsetd[7:0]=0x8 + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x08080808); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value + Outp32( PHY_address+0x0018, 0x08080808); // PHY_CON5 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x00000000); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x00000000); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000000); // PHY_CON33 DeSkew Code for CA + } + + return; +} + +void High_frequency_init_lpddr3(u32 PHY_address, u32 DREX_address, u32 nMEMCLK) +{ + u32 data; + u32 data_temp; + u32 status = __REG(EXYNOS5_POWER_BASE + INFORM1_OFFSET); + + // Pulldn and Pullup enable + // ctrl_pulld_dq[11:8]=Active HIGH signal to down DQ signals. For normal operation this field should be zero. + // ctrl_pulld_dqs[3:0]=Active HIGH signal to pull-up or down PDQS/NDQS signals. + Outp32( PHY_address+0x0038, 0x0000000F); // PHY_CON14 ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf + + // ZQ calibration + // zq_mode_dds :: Driver strength selection. . It recommends one of the following settings instead of 3'h0 + // Outp32( PHY_address+0x0040, 0x0F040306); // PHY_CON16 zq_clk_en[27]=ZQ I/O Clock enable, zq_manual_mode[3:2]=Manual calibration mode selection 2'b01: long calibration, zq_manual_str[1]=Manual calibration start + // PHY_CON39 :: Driver Strength + // Outp32( PHY_address+0x00A0 , 0x0FFF0FFF); // PHY_CON39 + if (ZQ_MODE_DDS == 7) + { + Outp32( PHY_address+0x0040, 0x0F040306); + Outp32( PHY_address+0x00A0, 0x0FFF0FFF); + } + else if (ZQ_MODE_DDS == 6) + { + Outp32( PHY_address+0x0040, 0x0E040306); + Outp32( PHY_address+0x00A0, 0x0DB60DB6); + } + else if (ZQ_MODE_DDS == 5) + { + Outp32( PHY_address+0x0040, 0x0D040306); + Outp32( PHY_address+0x00A0, 0x0B6D0B6D); + } + else if (ZQ_MODE_DDS == 4) + { + Outp32( PHY_address+0x0040, 0x0C040306); + Outp32( PHY_address+0x00A0, 0x09240924); + } + else + { + Outp32( PHY_address+0x0040, 0x0F040306); + Outp32( PHY_address+0x00A0 , 0x0FFF0FFF); + } + + // Checking the completion of ZQ calibration + // GOSUB Delay 100ms; GOSUB read &PHY_address+0x0048; zq_done[0]=1 + // GOSUB Delay 100ms; GOSUB read &PHY1_BASE+0x0048; zq_done[0]=1 + while( ( Inp32( PHY_address+0x0048 ) & 0x00000001 ) != 0x00000001 ); // PHY_CON17 zq_done[0]=ZQ Calibration is finished. + + // ZQ calibration exit + data_temp = Inp32( PHY_address+0x0040 ); + data_temp = data_temp&(~0x000FFFFF); + data = data_temp|0x00040304; + Outp32( PHY_address+0x0040, data); // PHY_CON16 zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0 + + // 1. Set DRAM burst length and READ latency + Outp32( PHY_address+0x00AC, 0x0000080C); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + + // 2. Set DRAM write latency + Outp32( PHY_address+0x006C, 0x0007000F); // PHY_CON26 T_wrdata_en[20:16]=WL for DDR3 + + // DLL LOCK Setting..! + // Set the DLL lock parameters + // Reserved [31] ctrl_start_point [30:24]=0x10 Reserved [23] ctrl_inc [22:16]=0x10 ctrl_force [14:8] ctrl_start [6]=0x1 ctrl_dll_on [5]=0x1 ctrl_ref [4:1]=0x8 Reserved [0] + // Next Step : Same Operation "CONCONTROL dfi_init_start[28]=1" + // 2012.10.11 + // Outp32( PHY_address+0x0030, 0x10100070); // PHY_CON12 + Outp32( PHY_address+0x0030, 0x10100030); // PHY_CON12, "ctrl_dll_on[6] = 0" + DMC_Delay(20); // PCLK 10 cycle. + Outp32( PHY_address+0x0030, 0x10100070); // PHY_CON12, "ctrl_start[6] = 1" + + // 1. Set the Concontrol. At this moment, an auto refresh counter should be off. + // 20120511 :: Change dll lock start point. + // 2012.11.08 :: rd_fetch 3 -> 2 + Outp32( DREX_address+0x0000, 0x1FFF2000); // CONCONTROL dfi_init_start [28], timeout_level0 [27:16], rd_fetch [14:12], empty [8], aref_en [5], clk_ratio [2:1] + + // 2. Set the MemConfig0 register. If there are two external memory chips, also set the MemConfig1 register. + // LPDDR2_P0_CS0 : 32'h2000_000 ~ 32'h27FF_FFFF (4Gbit) + Outp32( DREX_address+0x010C, 0x002007E0); // MemBaseConfig0 chip_base[26:16]=0x10, chip_mask[10:0]=0x7E0 + Outp32( DREX_address+0x0110, 0x004007E0); // MemBaseConfig1 chip_base[26:16]=0x30, chip_mask[10:0]=0x7E0 + + // 3. Set the MemConfig0 + // chip_map [15:12] Address Mapping Method (AXI to Memory). 0x1 = Interleaved ({row, bank, column, width}) + // chip_col [11:8] Number of Column Address Bits. 0x3 = 10 bits + // chip_row [7:4] Number of Row Address Bits. 0x2 = 14 bits + // chip_bank [3:0] Number of Banks. 0x3 = 8 banks + Outp32( DREX_address+0x0008, 0x00001323); // MemConfig0 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] + Outp32( DREX_address+0x000C, 0x00001323); // MemConfig1 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] + + // 4. Set the PrechConfig and PwrdnConfig registers. + Outp32( DREX_address+0x0014, 0xFF000000); // PrechConfig tp_cnt[31:24]=Timeout Precharge Cycles. 0xn = n cclk cycles. Refer to chapter 1.6.2 .Timeout precharge + Outp32( DREX_address+0x0028, 0xFFFF00FF); // PwrdnConfig dsref_cyc[31:16]=Number of Cycles for dynamic self refresh entry. 0xn = n aclk cycles. Refer to chapter 1.5.3 . Dynamic self refresh + + // 5. Set the TimingAref, TimingRow, TimingData and TimingPower registers. + // according to memory AC parameters. At this moment, TimingData.w1 and TimingData.r1 + // registers must be programmed according to initial clock frequency. + // 2012.10.10 + // Outp32( DREX_address+0x0030, 0x000000BB); // TimingAref autorefresh counter @24MHz + // Outp32( DREX_address+0x0030, 0x0000005E); // TimingAref autorefresh counter @24MHz + // 2013.01.14 + Outp32( DREX_address+0x0030, 0x0000002E); // TimingAref autorefresh counter @24MHz + + // TimingAref autorefresh counter @24MHz + // 2012.10.11 + // Outp32( DREX_address+0x0034, 0x34498611); // TimingRow + // 2012.11.08 :: tRC : 0x18(24) ---> 0x1A(26), tRAS : 0x12(18) ---> 0x11(17) + Outp32( DREX_address+0x0034, 0x345A8692); // TimingRow + Outp32( DREX_address+0x0038, 0x3630560C); // TimingData + Outp32( DREX_address+0x003C, 0x50380336); // TimingPower + + // If QoS scheme is required, set the QosControl10~15 and QosConfig0~15 registers. + + // 6. Wait until dfi_init_complete become 1. + while( ( Inp32( DREX_address+0x0040 ) & 0x00000008 ) != 0x00000008 ); // PhyStatus dfi_init_complete[3]=1 + + // Outp32( DREX_address+0x0040, 0x00000008); // PhyStatus dfi_init_complete[3]=1 + + // Deasserting the dfi_init_start + // 2012.11.08 :: rd_fetch 3 -> 2 + Outp32( DREX_address+0x0000, 0x0FFF2000 ); // CONCONTROL dfi_init_start[0]=0 + + // Forcing DLL 2013.01.19 + if (status != S5P_CHECK_SLEEP) { +// while( ( Inp32( PHY_address+0x0034 ) & 0x00000001 ) != 0x00000001 ); // Wait lock status +// data = ((Inp32( PHY_address+0x0034 ) & (0x7f << 10)) >> 10); +// Outp32( PHY_address+0x0030, ((Inp32(PHY_address+0x0030) & ~(0x7f << 8))) | (data << 8)); // forcing dll lock value +// Outp32( PHY_address+0x0030, (Inp32(PHY_address+0x0030) & ~(1 << 5))); // dll off +// Outp32( EXYNOS5_POWER_BASE + 0x0904, data); + } else { + Outp32( PHY_address+0x0030, (Inp32(PHY_address+0x0030) & ~(1 << 5))); // dll off + data = Inp32( EXYNOS5_POWER_BASE + 0x0904 ); + if ( PHY_address == PHY0_BASE ) + data = (data & 0x7f); + else + data = ((data & (0x7f << 16)) >> 16); + Outp32( PHY_address+0x0030, ((Inp32(PHY_address+0x0030) & ~(0x7f << 8))) | (data << 8)); // forcing dll lock value + } + + // 7. Forcing DLL resynchronization - dfi_ctrlupd_req + Outp32( DREX_address+0x0018, 0x00000008); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=1 + DMC_Delay(20); // Wait for 10 PCLK cycles, PCLK(200MHz=10clock=50ns), DMC_Delay(40us) + Outp32( DREX_address+0x0018, 0x00000000); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=0 + + // 8. calibration & levelings + if( PERFORM_LEVELING == 1) + { + Prepare_levelings_lpddr3( PHY_address, DREX_address); + CA_calibration_lpddr3( PHY_address, DREX_address); + Write_leveling_lpddr3( PHY_address, DREX_address); + Read_leveling_lpddr3( PHY_address, DREX_address); + Write_dq_leveling_lpddr3( PHY_address, DREX_address); + } + + //----------------------------------------------- + //- end_levelings_lpddr3_l + //----------------------------------------------- + + // ctrl_atgate = 0 + // T_WrWrCmd [30:24] It controls the interval between Write and Write during DQ Calibration. This value should be always kept by 5'h17. It will be used for debug purpose. + // T_WrRdCmd [19:17] It controls the interval between Write and Read by cycle unit during Write Calibration. It will be used for debug purpose. 3'b111 : tWTR = 6 cycles (=3'b001) + // ctrl_ddr_mode[12:11] 2'b11: LPDDR3 + // ctrl_dfdqs[9] 1¡¯b1: differential DQS + Outp32( PHY_address+0x0000, 0x17021A00); // PHY_CON0 byte_rdlvl_en[13]=1, ctrl_ddr_mode[12:11]=01, ctrl_atgate[6]=1, Bit Leveling + + if(PERFORM_LEVELING == 1) { + // dfi_ctrlupd_req to make sure ALL SDLL is updated + // forcing DLL resynchronization - dfi_ctrlupd_req + Outp32( DREX_address+0x0018, 0x00000008); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=1 + DMC_Delay(20); // Wait for 10 PCLK cycles, PCLK(200MHz=10clock=50ns), DMC_Delay(40us) + Outp32( DREX_address+0x0018, 0x00000000); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=0 + } + + #if 0 // Move..! 2012.11.30 + // 26. Set the ConControl to turn on an auto refresh counter. + // aref_en[5]=Auto Refresh Counter. 0x1 = Enable + // 2012.11.08 :: rd_fetch 3 -> 2 + Outp32( DREX_address+0x0000, 0x0FFF2128); // CONCONTROL aref_en[5]=1 + #endif + + // 27. If power down modes are required, set the MemControl register. + // bl[22:20]=Memory Burst Length 0x3 = 8 + // mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit + // mem_type[11:8]=Type of Memory 0x7 = LPDDR3 + // dsref_en[5]=Dynamic Self Refresh. 0x1 = Enable. + // dpwrdn_en[1]=Dynamic Power Down. 0x1 = Enable + // clk_stop_en[0]=Dynamic Clock Control. 0x1 = Stops during idle periods. + Outp32( DREX_address+0x0004, 0x00312723); // MemControl bl[22:20]=8, mem_type[11:8]=7, two chip selection + + + if(nMEMCLK==100) + { + // 3. Force lock values (DLL cannot be locked under 400MHz) + Outp32( PHY_address+0x0030, 0x10107F30 ); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + Outp32( PHY_address+0x0028, 0x0000007F ); // ctrl_offsetd[7:0]=0x7F + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x7F7F7F7F ); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value, ¡Ú Best Tuning Value + Outp32( PHY_address+0x0018, 0x7F7F7F7F ); // PHY_CON6 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x0C183060 ); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x60C18306 ); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000030 ); // PHY_CON33 DeSkew Code for CA + + Outp32( PHY_address+0x0030, 0x10107F10 ); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + + // Setting PHY_CON12 later + // 6. Set ctrl_dll_on to 0 + // Outp32( PHY_address+0x0030, 0x10107F50); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + // DMC_Delay(100); // Wait for 10 PCLK cycles + + // 7. Issue dfi_ctrlupd_req for more than 10 cycles + Outp32( DREX_address+0x0018, 0x00000008); // PHYCONTROL0 assert fp_resync[3]=1(Force DLL Resyncronization) + // "dfi_ctrlupd_req" should be issued more than 10 cycles after ctrl_dll_on is disabled. + DMC_Delay(100); // Wait for 10 PCLK cycles + Outp32( DREX_address+0x0018, 0x00000000); // PHYCONTROL0 deassert fp_resync[3]=1(Force DLL Resyncronization) + } + + return; +} + +void DMC_InitForLPDDR3(u32 nMEMCLK) +{ + u32 data; + u32 status = __REG(EXYNOS5_POWER_BASE + INFORM1_OFFSET); + u32 *testbit; + u32 nLoop; + + /****************************************/ + /***** CA SWAP *****/ + /****************************************/ + if (CA_SWAP == 1) + { + CA_swap_lpddr3(PHY0_BASE); + CA_swap_lpddr3(PHY1_BASE); + } + + // Remove because handshaking between DREX and PHY when operate in low frequency(24MHz) + // DLL LOCK Setting..! + // DLL_lock_lpddr3(PHY0_BASE, DREX1_0); + // DLL_lock_lpddr3(PHY1_BASE, DREX1_1); + + // Remove because handshaking between DREX and PHY when operate in low frequency(24MHz) + // CMU Setting..! + // Clock = 50MHz + // Outp32( CMU_MEMPART+0x0114, 0x0020F300); // BPLL_CON1 + // Outp32( CMU_MEMPART+0x0110, 0x80C80305); // BPLL_CON0 + // DMC_Delay(100); + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + //* DREX Pause Disable + data = Inp32( 0x1003091C ); + data = data&~(0x1<<0); + Outp32(0x1003091C, data); + // Lock Time Setting : PDIV * 200 + Outp32( 0x10030010, 0x00000258 ); + + // ENABLE(1), MDIV(200), PDIV(3), SDIV(1) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); + // rBPLL_CON0 BPLL=800MHz(3:200:1) + Outp32( CMU_MEMPART+0x0110, 0x80C80301); + + // PLL locking indication + // 0 = Unlocked + // 1 = Locked + while ((Inp32(0x10030110) & (1 << 29)) == 0); + + // ByPass :: BYPASS = 1, bypass mode is enabled - FOUT=FIN + SetBits(CMU_MEMPART+0x0114, 22, 0x1, 0x1); + + // C2C_CLK_400(1), BPLL(1) + // uBits = (1 << 12) | (1 << 0); + Outp32( CMU_MEMPART+0x0200, 0x00001001); // rCLK_SRC_CDREX + + // CLK_MUX_STAT_CDREX Check + // Opened by cju, 13.01.16 + do { + data = Inp32(0x10030400) & (7 << 0); + } while (data != 0x2); + + // Opened by cju + #if 1 + // ByPass :: BYPASS = 1, bypass mode is Disabled - FOUT=BPLL FOUT + SetBits(0x10030114, 22, 0x1, 0x0); + DMC_Delay(200); + + //* Add CLK_DIV_CDREX0, PCLK_CDREX(28:1/2),SCLK_CDREX(24:1/8),ACLK_CDREX1(16:1/2),CCLK_DREX(8:1/2),CLK2X_PHY0(3:1/1) + data=(1<<28)|(7<<24)|(1<<16)|(1<<8)|(0<<3); + Outp32(0x10030500, data); + #else + //* Add CLK_DIV_CDREX0, PCLK_CDREX(28:1/2),SCLK_CDREX(24:1/8),ACLK_CDREX1(16:1/2),CCLK_DREX(8:1/2),CLK2X_PHY0(3:1/1) + data=(1<<28)|(7<<24)|(1<<16)|(1<<8)|(0<<3); + Outp32(0x10030500, data); + #endif + + /****************************************/ + /***** LOW FREQUENCY *****/ + /****************************************/ + // PHY0+DREX1_0 + Low_frequency_init_lpddr3(PHY0_BASE, DREX1_0); + // PHY1+DREX1_1 + Low_frequency_init_lpddr3(PHY1_BASE, DREX1_1); + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + if (nMEMCLK==400) + { + // ENABLE(1), MDIV(200), PDIV(3), SDIV(1) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x80C80301); // rBPLL_CON0 BPLL=800MHz(3:200:1) + DMC_Delay(100); + + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(1/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (1 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x31010100); // rCLK_DIV_CDREX0 + DMC_Delay(100); + } + else if (nMEMCLK==533) + { + // ENABLE(1), MDIV(266), PDIV(3), SDIV(2) + // uBits = (1 << 31) | (266 << 16) | (3 << 8) | (2 << 0); + Outp32( CMU_MEMPART+0x0110, 0x810A0302); // rBPLL_CON0 BPLL=533MHz(3:266:2) + DMC_Delay(100); + + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(0/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + + DMC_Delay(100); + } + else if (nMEMCLK==666) + { + // ENABLE(1), MDIV(222), PDIV(4), SDIV(1) + // uBits = (1 << 31) | (266 << 16) | (4 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x80DE0401); // rBPLL_CON0 BPLL=666MHz(4:222:1) + DMC_Delay(100); + + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(0/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + + DMC_Delay(100); + } + else if (nMEMCLK==732) + { + // ENABLE(1), MDIV(122), PDIV(2), SDIV(1) + // uBits = (1 << 31) | (122 << 16) | (2 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x807A0201); // rBPLL_CON0 BPLL=732MHz(2:122:1) + DMC_Delay(100); + + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(0/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + + DMC_Delay(100); + } + else if (nMEMCLK==800) + { + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(0/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + + DMC_Delay(100); + } +#ifdef CONFIG_CPU_EXYNOS5410_EVT2 + else if (nMEMCLK==933) + { + // ENABLE(1), MDIV(200), PDIV(3), SDIV(1) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x80E90301); // rBPLL_CON0 BPLL=933MHz(3:233:1) + DMC_Delay(100); + + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(0/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + + DMC_Delay(100); + } + else if (nMEMCLK==1065) + { + // ENABLE(1), MDIV(200), PDIV(3), SDIV(1) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x81630401); // rBPLL_CON0 BPLL=1065MHz(4:355:1) + DMC_Delay(100); + + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(0/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + + DMC_Delay(100); + } +#endif + else + { + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(0/2), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + + DMC_Delay(100); + } + + + /****************************************/ + /***** HIGH FREQUENCY *****/ + /****************************************/ + // PHY0+DREX1_0 + High_frequency_init_lpddr3(PHY0_BASE, DREX1_0,nMEMCLK); + // PHY1+DREX1_1 + High_frequency_init_lpddr3(PHY1_BASE, DREX1_1,nMEMCLK); + + if (status == S5P_CHECK_SLEEP) { + // (5) DRAM PAD Retention Release + // - PAD_RETENTION_DRAM_CONFIGURATION + // 0x1004_3000[0] = 0x1 + testbit = (u32 *)(0x10043000); + *testbit = 0x1; + while(*(testbit+1) != 0x00001); + + // (6-1) setup CMU for DDR self-refresh Exit + // - CLK_GATE_BUS_CDREX + // 0x10030700[7:6] = 0x3 + data = Inp32( 0x10030700 ); + data = data & (~0x00000C0); + data = data | 0x00000C0; + Outp32( 0x10030700, data); + + // (6-2) + // clock gating release check. + while ((Inp32(0x1004091C) & 0x6) != 0x6); + + // (7) LPI Masking ¼³Á¤ + // LPI_MASK0[0x1004_0004] = 0x7000 + // LPI_MASK1[0x1004_0008] = 0x30 + // LPI_MASK2[0x1004_000C] = 0x0 + // LPI_NOC_MASK0[0x1004_159C] = 0x0 + // LPI_NOC_MASK1[0x1004_15A0] = 0x0 + // LPI_NOC_MASK1[0x1004_15A4] = 0x0 + Outp32( 0x10040004, 0x00007000); + Outp32( 0x10040008, 0x00000030); + Outp32( 0x1004000C, 0x00000000); + Outp32( 0x1004159C, 0x00000000); + Outp32( 0x100415A0, 0x00000000); + Outp32( 0x100415A4, 0x00000000); + + #if 1 // Adding..! 2012.11.30 + Outp32( DREX1_0+0x0010, 0x07000000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + Outp32( DREX1_1+0x0010, 0x07000000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + if(NUM_CHIP == 1) { + Outp32( DREX1_0+0x0010, 0x07100000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + Outp32( DREX1_1+0x0010, 0x07100000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + } + #endif + + #if 0 + DMC_Delay(1000); + + for(nLoop=0;nLoop<10;nLoop++) { + Outp32( DREX1_0+0x0010, 0x05000000); // 0x5 = REFA (auto refresh), + Outp32( DREX1_1+0x0010, 0x05000000); // 0x5 = REFA (auto refresh), + if(NUM_CHIP == 1) { + Outp32( DREX1_0+0x0010, 0x05100000); // 0x5 = REFA (auto refresh), + Outp32( DREX1_1+0x0010, 0x05100000); // 0x5 = REFA (auto refresh), + } + } + #endif + } + + #if 1 // Move..! 2012.11.30 + // 26. Set the ConControl to turn on an auto refresh counter. + // aref_en[5]=Auto Refresh Counter. 0x1 = Enable + // 2012.11.08 :: rd_fetch 3 -> 2 + Outp32( DREX1_0+0x0000, 0x0FFF2128); // CONCONTROL aref_en[5]=1 + Outp32( DREX1_1+0x0000, 0x0FFF2128); // CONCONTROL aref_en[5]=1 + #endif + + // For 100MHz & 200MHz..! + if(nMEMCLK == 100) + { + Outp32( CMU_MEMPART+0x0500, 0x37010100); //CLK_DIV_CDREX0 SCLK_CDREX_RATIO[26:24]=2 + DMC_Delay(100); + } + else if (nMEMCLK == 200) + { + Outp32( CMU_MEMPART+0x0500, 0x33010100); //CLK_DIV_CDREX0 SCLK_CDREX_RATIO[26:24]=7 + DMC_Delay(100); + } + + // BRB Space Reservation Setting..! +#if defined(CONFIG_BTS_SUPPORT) + Outp32( DREX1_0+0x0100, 0x00000033); // BRBRSVCONTROL + Outp32( DREX1_0+0x0104, 0x88588858); // BRBRSVCONFIG + Outp32( DREX1_1+0x0100, 0x00000033); // BRBRSVCONTROL + Outp32( DREX1_1+0x0104, 0x88588858); // BRBRSVCONFIG + Outp32( DREX1_0+0x00D8, 0x00000000); // QOSCONTROL + Outp32( DREX1_0+0x00C0, 0x00000080); // QOSCONTROL + Outp32( DREX1_0+0x0108, 0x00000001); // BRBQOSCONFIG + Outp32( DREX1_1+0x00D8, 0x00000000); // QOSCONTROL + Outp32( DREX1_1+0x00C0, 0x00000080); // QOSCONTROL + Outp32( DREX1_1+0x0108, 0x00000001); // BRBQOSCONFIG +#else + Outp32( DREX1_0+0x0100, 0x00000033); // BRBRSVCONTROL + Outp32( DREX1_0+0x0104, 0x88778877); // BRBRSVCONFIG + Outp32( DREX1_1+0x0100, 0x00000033); // BRBRSVCONTROL + Outp32( DREX1_1+0x0104, 0x88778877); // BRBRSVCONFIG +#endif + { + u32 nLockR, nLockW; + + // ;; Pause Enable...! + // Closed by cju, 13.01.16 + #if 0 + Outp32( 0x1003091C, 0xFFF8FFFF); + #endif +#if 0 + // ;; Lock value..! + nLockR = Inp32(PHY0_BASE+0x0034); + nLockW = (nLockR & 0x0001FC00) >> 2; + nLockR = Inp32(PHY0_BASE+0x0030); + nLockR = nLockR & (~0x00007F00); + nLockW = nLockW | nLockR; + Outp32( PHY0_BASE+0x0030, nLockW); + + nLockR = Inp32(PHY1_BASE+0x0034); + nLockW = (nLockR & 0x0001FC00) >> 2; + nLockR = Inp32(PHY1_BASE+0x0030); + nLockR = nLockR & (~0x00007F00); + nLockW = nLockW | nLockR; + Outp32( PHY1_BASE+0x0030, nLockW); +#endif + // ;; SDLL Power..! + // ;; Phycontrol0.sl_dll_dyn_con + Outp32( DREX1_0+0x0018, 0x00000002); + Outp32( DREX1_1+0x0018, 0x00000002); + } + + return; +} + + +void mem_ctrl_init() +{ + u32 nMEMCLK; +#if defined(MCLK_CDREX_800) + nMEMCLK = 800; +#elif defined(MCLK_CDREX_400) + nMEMCLK = 400; +#endif + + /* CMU_MEMPART reset */ + // Outp32( CMU_MEMPART+0x0A10, 0x00000001); + // DMC_Delay(10000); + // Outp32( CMU_MEMPART+0x0A10, 0x00000000); + // DMC_Delay(10000); + + + +#if defined(CONFIG_LPDDR3) + DMC_InitForLPDDR3(nMEMCLK); +#elif defined(CONFIG_LPDDR2) + DMC_InitForLPDDR2(nMEMCLK); +#elif defined(CONFIG_DDR3) + DMC_InitForDDR3(nMEMCLK); +#endif + +} + diff --git a/board/samsung/smdk5410/lowlevel_init.S b/board/samsung/smdk5410/lowlevel_init.S new file mode 100644 index 000000000..aba44d674 --- /dev/null +++ b/board/samsung/smdk5410/lowlevel_init.S @@ -0,0 +1,366 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +#include "smdk5410_val.h" + + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + +#ifdef CONFIG_MACH_UNIVERSAL5410 +delay_for_t32: + subs r0, r0, #1 + bne delay_for_t32 + mov pc, lr +#endif + + .globl lowlevel_init +lowlevel_init: + /* PS-HOLD high */ + ldr r0, =0x1004330C + mov r1, #0x5300 + str r1, [r0] + ldr r0, =0x13400C48 + mov r1, #0 + str r1, [r0] + ldr r0, =0x13400020 + mov r1, #0x22 + str r1, [r0] + ldr r0, =0x13400028 + mov r1, #0 + str r1, [r0] + + /* use iRAM stack in bl2 */ + ldr sp, =CONFIG_IRAM_STACK + stmdb r13!, {ip,lr} + + bl relocate_nscode + + /* check reset status */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + + /* AFTR wakeup reset */ + ldr r2, =S5P_CHECK_DIDLE + cmp r1, r2 + beq exit_wakeup + + /* LPA wakeup reset */ + ldr r2, =S5P_CHECK_LPA + cmp r1, r2 + beq exit_wakeup + + /* Sleep wakeup reset */ + ldr r2, =S5P_CHECK_SLEEP + cmp r1, r2 + beq wakeup_reset + +#ifdef CONFIG_PM + bl pmic_init +#endif + + bl uart_asm_init + + bl read_om + + /* + * If U-boot is already running in RAM, no need to relocate U-Boot. + * Memory controller must be configured before relocating U-Boot + * in ram. + */ + ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ + bic r1, pc, r0 /* pc <- current addr of code */ + /* r1 <- unmasked bits of pc */ + ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ + bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ + cmp r1, r2 /* compare r1, r2 */ + beq after_copy /* r0 == r1 then skip sdram init */ + +#ifdef CONFIG_MACH_UNIVERSAL5410 + /* wail 1 second for t32 attach */ + ldr r0, =0x400000 + bl delay_for_t32 +#endif + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + + /* Change clocks for eMMC and SDMMC */ + bl emmc_devider_change + bl sdmmc_devider_change + + ldmia r13!, {ip,pc} + +after_copy: +#ifndef CONFIG_SPL_BUILD +#ifdef CONFIG_PM + bl pmic_late_init +#endif +#endif + + ldmia r13!, {ip,pc} + +wakeup_reset: + bl read_om + + /* If eMMC booting */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +exit_wakeup: + b warmboot + +read_om: + /* Read booting information */ + ldr r0, =EXYNOS5_POWER_BASE + ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC BOOT */ + cmp r2, #0x6 + moveq r3, #BOOT_EMMC + + /* eMMC 4.4 BOOT */ + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x28 + moveq r3, #BOOT_EMMC_4_4 + + ldr r0, =EXYNOS5_POWER_BASE + str r3, [r0, #INFORM3_OFFSET] + + mov pc, lr + +/* + * uart_asm_init: Initialize UART in asm mode, 115200bps fixed. + * void uart_asm_init(void) + */ + .globl uart_asm_init +uart_asm_init: + + /* set GPIO to enable UART */ + @ GPIO setting for UART for UART0/1/2/3 + ldr r0, =0x13400000 @GPA0CON + ldr r1, =0x22222222 @UART0,1 + str r1, [r0] + ldr r0, =0x13400020 @GPA1CON + ldr r1, =0x00222222 @UART2,3 + str r1, [r0] + + ldr r0, =EXYNOS5_CLOCK_BASE + ldr r1, =0x99999 + ldr r2, =CLK_SRC_PERIC0_OFFSET @0x10250 + str r1, [r0, r2] + + ldr r1, =0x99999 + ldr r2, =CLK_DIV_PERIC0_OFFSET @0x10558 + str r1, [r0, r2] + + ldr r0, =UART_CONSOLE_BASE + ldr r1, =0x3 + str r1, [r0, #ULCON_OFFSET] + + ldr r1, =0x3c5 + str r1, [r0, #UCON_OFFSET] +#if defined(CONFIG_MACH_ASB5410) + ldr r1, =0x117 + str r1, [r0, #UFCON_OFFSET] +#else + ldr r1, =0x111 + str r1, [r0, #UFCON_OFFSET] +#endif + + ldr r1, =UART_UBRDIV_VAL + str r1, [r0, #UBRDIV_OFFSET] + + ldr r1, =UART_UDIVSLOT_VAL + str r1, [r0, #0x2C] + + mov pc, lr + +/* + * MPLL is Changed from 400MHz to 800MHz. + * So, eMMC devider need to change. + */ +emmc_devider_change: +#if defined(USE_MMC4) + ldr r0, =EXYNOS5_CLOCK_BASE + ldr r2, =CLK_DIV_FSYS3_OFFSET + ldr r1, [r0, r2] + bic r1, r1, #(0xFF << 8) + bic r1, r1, #(0xF) + orr r1, r1, #(0x1<< 8) + orr r1, r1, #0x9 + str r1, [r0, r2] +#elif defined(USE_MMC0) + ldr r0, =EXYNOS5_CLOCK_BASE + ldr r2, =CLK_DIV_FSYS1_OFFSET + ldr r1, [r0, r2] + bic r1, r1, #(0xFF << 8) + bic r1, r1, #(0xF) + orr r1, r1, #(0x7 << 8) + orr r1, r1, #2 + str r1, [r0, r2] +#endif + mov pc, lr + +sdmmc_devider_change: + ldr r0, =EXYNOS5_CLOCK_BASE + ldr r2, =CLK_DIV_FSYS2_OFFSET + ldr r1, [r0, r2] + bic r1, r1, #(0xFF << 8) + bic r1, r1, #(0xF) + orr r1, r1, #(0x7<< 8) + orr r1, r1, #0x2 + str r1, [r0, r2] + mov pc, lr + +/* + * Relocate code + */ +relocate_nscode: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + .word 0xF57FF04F @dsb sy + .word 0xF57FF06F @isb sy + + mov pc, lr + .ltorg + +/* + * CPU1 waits here until CPU0 wake it up. + * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory. + */ +nscode_base: + b 1f + nop @ for backward compatibility + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 +_switch_addr: + .word 0x0 @ REG4: SWITCH_ADDR +_hotplug_addr: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6 +_c2_addr: + .word 0x0 @ REG7: REG_C2_ADDR +_cpu_state: + .word 0x1 @ CPU0_STATE : RESET + .word 0x2 @ CPU1_STATE : SECONDARY RESET + .word 0x2 @ CPU2_STATE : SECONDARY RESET + .word 0x2 @ CPU3_STATE : SECONDARY RESET +_gic_state: + .word 0x0 @ CPU0 - GICD_IGROUPR0 + .word 0x0 @ CPU1 - GICD_IGROUPR0 + .word 0x0 @ CPU2 - GICD_IGROUPR0 + .word 0x0 @ CPU3 - GICD_IGROUPR0 + +#define RESET (1 << 0) +#define SECONDARY_RESET (1 << 1) +#define HOTPLUG (1 << 2) +#define C2_STATE (1 << 3) +#define SWITCH (1 << 4) + +1: + adr r0, _cpu_state + + mrc p15, 0, r7, c0, c0, 5 @ read MPIDR + and r7, r7, #0xf @ r7 = cpu id + + /* read the current cpu state */ + ldr r10, [r0, r7, lsl #2] + + /* HYP entry */ + + /* + * Set the HYP spsr to itself, so that the entry point + * does not see the difference between a function call + * and an exception return. + */ + mrs r4, cpsr + msr spsr_cxsf, r4 + + bic r6, r4, #0x1f + orr r6, r6, #0x13 + msr spsr_cxsf, r6 /* Setup SPSR to jump to NS SVC mode */ + add r4, pc, #4 + .word 0xe12ef304 /* msr elr_hyp, r4 */ + .word 0xe160006e /* ERET */ +ns_svc_entry: + tst r10, #SWITCH + adrne r0, _switch_addr + bne wait_for_addr + tst r10, #C2_STATE + adrne r0, _c2_addr + bne wait_for_addr + + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + cmp r1, #0x0 + movne r1, #0x0 + strne r1, [r0] + ldrne r1, =(EXYNOS5_POWER_BASE + INFORM0_OFFSET) + ldrne pc, [r1] + + tst r10, #RESET + ldrne pc, =CONFIG_SYS_TEXT_BASE + + adr r0, _hotplug_addr +wait_for_addr: + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + wfe + b wait_for_addr + .ltorg +nscode_end: + diff --git a/board/samsung/smdk5410/mmc_boot.c b/board/samsung/smdk5410/mmc_boot.c new file mode 100644 index 000000000..d7fd65da3 --- /dev/null +++ b/board/samsung/smdk5410/mmc_boot.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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<config.h> + +#define SDMMC_SECOND_DEV 0x28 +#define SIGNATURE_CHECK_FAIL -1 +#define SECOND_BOOT_MODE 0xFEED0002 + +/* +* Copy U-boot from mmc to RAM: +* COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains +* Pointer to API (Data transfer from mmc to ram) +*/ + +static int find_second_boot_dev(void) +{ + unsigned int om_status = readl(EXYNOS5_POWER_BASE + OM_STATUS_OFFSET); + + om_status &= 0x3E; + + writel(0x1, CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (om_status == SDMMC_SECOND_DEV) + return BOOT_SEC_DEV; + else + while (1); + + return 0; +} + +void copy_uboot_to_ram(unsigned int boot_dev) +{ + int ret = 0; + + switch (boot_dev) { + case BOOT_MMCSD: + case BOOT_SEC_DEV: + boot_dev = SDMMC_CH2; + break; + case BOOT_EMMC_4_4: + boot_dev = EMMC; + break; + case BOOT_USB: + boot_dev = USB; + break; + } + /* Load u-boot image to ram */ + ret = load_uboot_image(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) { + sdmmc_enumerate(); + if (find_second_boot_dev() == BOOT_SEC_DEV) + boot_dev = SDMMC_CH2; + ret = load_uboot_image(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) + while (1); + } + + /* Load tzsw image & U-Boot boot */ + ret = coldboot(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) { + sdmmc_enumerate(); + if (find_second_boot_dev() == BOOT_SEC_DEV) + boot_dev = SDMMC_CH2; + ret = coldboot(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) + while (1); + } +} + +void load_uboot(void) +{ + unsigned int om_status = readl(EXYNOS5_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + + /* TODO : find second boot function */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + copy_uboot_to_ram(boot_dev); +} + +void board_init_f(unsigned long bootflag) +{ + __attribute__((noreturn)) void (*uboot)(void); + load_uboot(); + + /* Jump to U-Boot image */ + /* + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); + */ + /* Never returns Here */ +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /* Function attribute is no-return */ + /* This Function never executes */ + while (1) + ; +} + +void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} diff --git a/board/samsung/smdk5410/pmic.c b/board/samsung/smdk5410/pmic.c new file mode 100644 index 000000000..ea49fc15c --- /dev/null +++ b/board/samsung/smdk5410/pmic.c @@ -0,0 +1,348 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/pmic.h> + +void Delay(void) +{ + unsigned long i; + for(i=0;i<DELAY;i++); +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + IIC0_ESDA_INP; // Function <- Input + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPD1DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + ack = (ack>>0)&0x1; +// while(ack!=0); + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + IIC0_ESDA_OUTP; // Function <- Output + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + + IIC0_ESDA_INP; // Function <- Input (SDA) + + IIC0_SCLL_SDAL(); +} + +void IIC0_ESetport(void) +{ +#ifdef CONFIG_MACH_UNIVERSAL5410 + GPD1PUD |= (0xf<<4); +#else + GPD1PUD &= ~(0xf<<0); // Pull Up/Down Disable SCL, SDA +#endif + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + IIC0_ESCL_OUTP; // Function <- Output (SCL) + IIC0_ESDA_OUTP; // Function <- Output (SDA) + + Delay(); +} + +void IIC0_EWrite (unsigned char ChipId, unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + +////////////////// write reg. data. ////////////////// + for(i = 8; i>0; i--) + { + if((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EEnd(); +} + +void IIC0_ERead (unsigned char ChipId, unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_ELow(); // write + + IIC0_EAck_write(); // ACK + +////////////////// write reg. addr. ////////////////// + for(i = 8; i>0; i--) + { + if((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EAck_write(); // ACK + + IIC0_EStart(); + +////////////////// write chip id ////////////////// + for(i = 7; i>0; i--) + { + if((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + IIC0_EHigh(); // read + + IIC0_EAck_write(); // ACK + +////////////////// read reg. data. ////////////////// + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for(i = 8; i>0; i--) + { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPD1DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); +#ifdef CONFIG_MACH_UNIVERSAL5410 + reg = (reg >> 2) & 0x1; +#else + reg = (reg >> 0) & 0x1; +#endif + + data |= reg << (i-1); + } + + IIC0_EAck_read(); // ACK + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + + +void pmic_ema_init(void) +{ + unsigned int reg; + + /* Ema setting for A15 */ + if (CONFIG_PM_VDD_ARM >= 1.045) + reg = 0x122; + else if (CONFIG_PM_VDD_ARM >= 0.95) + reg = 0x324; + else + reg = 0x427; + + __REG(EXYNOS5_CLOCK_BASE + ARM_EMA_CTRL_OFFSET) = reg; + + /* EMA setting for A7 */ + if (CONFIG_PM_VDD_KFC >= 1.045) + reg = 0x11; + else if (CONFIG_PM_VDD_KFC >= 0.95) + reg = 0x33; + else + reg = 0x44; + + __REG(EXYNOS5_CLOCK_BASE + ARM_EMA_CTRL_KFC_OFFSET) = reg; +} + + +void pmic_init(void) +{ + float vdd_arm, vdd_kfc; + float vdd_int, vdd_g3d; + unsigned char chk_ver; + + vdd_arm = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_ARM); + vdd_kfc = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_KFC); + vdd_int = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_INT); + vdd_g3d = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_G3D); + + IIC0_ESetport(); + IIC0_EWrite(0xcc, 0x28, vdd_arm); // BUCK2 VDD_ARM + IIC0_EWrite(0xcc, 0x2a, vdd_int); // BUCK3 VDD_INT + IIC0_EWrite(0xcc, 0x2c, vdd_g3d); // BUCK4 VDD_G3D + IIC0_EWrite(0xcc, 0x34, vdd_kfc); // BUCK6 VDD_KFC + + IIC0_ERead(0xcc, 0x00, &chk_ver); + if (chk_ver == 0x00) { + IIC0_EWrite(0xcc, 0x43, 0xD4); // LDO7 always on + IIC0_EWrite(0xcc, 0x49, 0xE8); // LDO13 always on + + IIC0_EWrite(0xcc, 0x39, 0xD8); // BUCK-Boost Enable + IIC0_EWrite(0xcc, 0x8D, 0x4F); // BUCK-Boost Burn Protection + + IIC0_EWrite(0xcc, 0x8C, 0x52); + + IIC0_EWrite(0xcc, 0x81, 0x53); + IIC0_EWrite(0xcc, 0x87, 0x66); + IIC0_EWrite(0xcc, 0x94, 0x66); + } + else if (chk_ver == 0x02) { + IIC0_EWrite(0xcc, 0x91, 0xF3); // BUCK1 undershoot + IIC0_EWrite(0xcc, 0x97, 0xF3); // BUCK6 undershoot + } + +#ifdef CONFIG_MACH_UNIVERSAL5410 + IIC0_EWrite(0xcc, 0x0B, 0x07); /* 32KHZ_AP/CP/BT Enable */ +#endif + + /* To advance margin, below EMA setting is executed */ + /* If you use EMA, remove comment mark and use below function */ + /* pmic_ema_init(); */ +} + + +void pmic_late_init(void) +{ + float vdd_mif; + + vdd_mif = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_MIF); + + IIC0_ESetport(); + IIC0_EWrite(0xcc, 0x26, vdd_mif); // BUCK1 VDD_MIF +} diff --git a/board/samsung/smdk5410/smc.c b/board/samsung/smdk5410/smc.c new file mode 100644 index 000000000..730fc5eb8 --- /dev/null +++ b/board/samsung/smdk5410/smc.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * + * BL3 SMC CMD + */ + +#include <common.h> +#include <asm/arch/movi_partition.h> +#include <asm/arch/cpu.h> + +typedef struct sdmmc_dev { + /* for SDMMC */ + u32 image_pos; + u32 blkcnt; + u32 base_addr; +} sdmmc_t; + +typedef struct emmc_dev { + /* for eMMC */ + u32 blkcnt; + u32 base_addr; +} emmc_t; + +typedef struct sata_dev { + /* for SATA */ + u64 read_sector_of_hdd; + u32 trans_byte; + u32 *read_buffer; + u32 position_of_mem; +} sata_t; + +typedef struct sfmc_dev { + /* for SFMC */ + u32 cs; + u32 byte_offset; + u32 byte_size; + void *dest_addr; +} sfmc_t; + +typedef struct spi_sf_dev { + /* for SPI SERIAL FLASH */ + u32 flash_read_addr; + u32 read_size; + u8 *read_buff; +} spi_sf_t; + +/* boot device */ +typedef union boot_device_u { + sdmmc_t sdmmc; + emmc_t emmc; + sata_t sata; + sfmc_t sfmc; + spi_sf_t spi_sf; +} boot_device_t; + +typedef struct ld_image_info { + /* for Signature */ + u32 image_base_addr; + u32 size; + u32 secure_context_base; + u32 signature_size; + boot_device_t bootdev; + +} image_info; + +#define CONFIG_PHY_SDRAM_BASE (0x40000000) +#define CONFIG_PHY_IRAM_BASE (0x02020000) + +#define SMC_SECURE_CONTEXT_BASE (CONFIG_PHY_IRAM_BASE + 0xcc00) +#define CONFIG_PHY_TZSW_BASE (CONFIG_PHY_IRAM_BASE + 0x10000) + +#define SMC_CMD_LOAD_UBOOT (-230) +#define SMC_CMD_COLDBOOT (-231) +#define SMC_CMD_WARMBOOT (-232) +#define SMC_CMD_CHECK_SECOND_BOOT (-233) +#define SMC_CMD_EMMC_ENDBOOTOP (-234) +#define SMC_CMD_SDMMC_ENUMERATE (-235) + +#ifdef CONFIG_SECURE_BOOT +#define SMC_SIGNATURE_SIZE 256 +#else +#define SMC_SIGNATURE_SIZE 0 +#endif + +#define CONFIG_IMAGE_INFO_BASE (CONFIG_PHY_SDRAM_BASE) + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1) + + ); + + return reg1; +} + + +unsigned int load_uboot_image(u32 boot_device) +{ + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_SYS_TEXT_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_SYS_TEXT_BASE; + + } + + info_image->image_base_addr = CONFIG_SYS_TEXT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, 0); +} + + +unsigned int coldboot(u32 boot_device) +{ + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } + + info_image->image_base_addr = CONFIG_PHY_TZSW_BASE; + info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; +#if defined(CONFIG_SECURE_TZSW_ONLY) + info_image->signature_size = 256; +#else + info_image->signature_size = SMC_SIGNATURE_SIZE; +#endif + + return exynos_smc(SMC_CMD_COLDBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, CONFIG_PHY_IRAM_NS_BASE); +} + +void warmboot(void) +{ + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, CONFIG_PHY_IRAM_NS_BASE); +} + +u32 find_second_boot(void) +{ + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT); +} + +void emmc_endbootop(void) +{ + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +} + +void sdmmc_enumerate(void) +{ + exynos_smc(SMC_CMD_SDMMC_ENUMERATE, 0, 0, 0); +} + diff --git a/board/samsung/smdk5410/smdk5410.c b/board/samsung/smdk5410/smdk5410.c new file mode 100644 index 000000000..163964de8 --- /dev/null +++ b/board/samsung/smdk5410/smdk5410.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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 <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pmic.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/sromc.h> + +#define DEBOUNCE_DELAY 10000 + +unsigned int OmPin; + +DECLARE_GLOBAL_DATA_PTR; +unsigned int second_boot_info = 0xffffffff; + + +int board_init(void) +{ + u8 read_vol_arm, read_vol_kfc; + u8 read_vol_int, read_vol_g3d; + u8 read_vol_mif; + u8 read_buck; + u8 read_pmic_id; + u8 read_bb9_ctrl2; + + char bl1_version[9] = {0}; + + /* display BL1 version */ +#ifdef CONFIG_TRUSTZONE + printf("\nTrustZone Enabled BSP"); + strncpy(&bl1_version[0], (char *)(CONFIG_PHY_IRAM_NS_BASE + 0x810), 8); +#else + strncpy(&bl1_version[0], (char *)0x02022fc8, 8); +#endif + printf("\nBL1 version: %s\n", &bl1_version[0]); + +#if defined(CONFIG_PM) + IIC0_ERead(0xcc, 0x26, &read_vol_mif); + IIC0_ERead(0xcc, 0x28, &read_vol_arm); + IIC0_ERead(0xcc, 0x2a, &read_vol_int); + IIC0_ERead(0xcc, 0x2c, &read_vol_g3d); + IIC0_ERead(0xcc, 0x34, &read_vol_kfc); +#ifdef CONFIG_MACH_UNIVERSAL5410 + IIC0_ERead(0xcc, 0x00, &read_pmic_id); + IIC0_ERead(0xcc, 0x3a, &read_bb9_ctrl2); + printf("id: %x\n", read_pmic_id); + printf("bb9_ctrl2: %x\n", read_bb9_ctrl2); + printf("GPH0DAT: %x\n", *(unsigned int *)(0x13400284)); + if ((read_pmic_id == 2) && ((read_bb9_ctrl2 & (1 << 6)) != 0) + && (*(unsigned int *)(0x13400284) == 0xD)) + printf("week: 49/50, board rev: 0.1\n"); +#endif + printf("vol_mif: %x\n", read_vol_mif); + printf("vol_arm: %x\n", read_vol_arm); + printf("vol_int: %x\n", read_vol_int); + printf("vol_g3d: %x\n", read_vol_g3d); + printf("vol_kfc: %x\n", read_vol_kfc); +#endif + + /* legacy - need to check */ + *(unsigned int *)0x10050234 = 0; + + gd->bd->bi_arch_number = MACH_TYPE_SMDK5410; + + gd->bd->bi_boot_params = (PHYS_SDRAM_1+0x100); + + OmPin = __REG(EXYNOS5_POWER_BASE + INFORM3_OFFSET); + printf("\nChecking Boot Mode ..."); + if (OmPin == BOOT_ONENAND) { + printf(" OneNand\n"); + } else if (OmPin == BOOT_NAND) { + printf(" NAND\n"); + } else if (OmPin == BOOT_MMCSD) { + printf(" SDMMC\n"); + } else if (OmPin == BOOT_EMMC) { + printf(" EMMC4.3\n"); + } else if (OmPin == BOOT_EMMC_4_4) { + printf(" EMMC4.41\n"); + } else { + printf(" Please check OM_pin\n"); + } + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE) + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE) + + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, + PHYS_SDRAM_4_SIZE); + gd->bd->bi_dram[4].start = PHYS_SDRAM_5; + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5, + PHYS_SDRAM_5_SIZE); + gd->bd->bi_dram[5].start = PHYS_SDRAM_6; + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6, + PHYS_SDRAM_6_SIZE); + gd->bd->bi_dram[6].start = PHYS_SDRAM_7; + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7, + PHYS_SDRAM_7_SIZE); + gd->bd->bi_dram[7].start = PHYS_SDRAM_8; + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8, + PHYS_SDRAM_8_SIZE); +} + +int board_eth_init(bd_t *bis) +{ + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + printf("\nBoard: SMDK5410\n"); + + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + int err; + + err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); + if (err) { + debug("SDMMC2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); + if (err) { + debug("MSHC0 not configured\n"); + return err; + } + + if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) { +#ifdef USE_MMC0 + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif +#ifdef USE_MMC2 + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif + } + else { +#ifdef USE_MMC2 + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif +#ifdef USE_MMC0 + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif + } + + return err; +} +#endif + +static int board_uart_init(void) +{ + int err; + + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE); + if (err) { + debug("UART0 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE); + if (err) { + debug("UART1 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE); + if (err) { + debug("UART2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); + if (err) { + debug("UART3 not configured\n"); + return err; + } + + return 0; +} + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f(void) +{ + return board_uart_init(); +} +#endif + +int board_late_init(void) +{ + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; +#ifdef CONFIG_RAMDUMP_MODE + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1(); + unsigned int gpio_debounce_cnt = 0; + int err; + + err = exynos_pinmux_config(PERIPH_ID_INPUT_X0_0, PINMUX_FLAG_NONE); + if (err) { + debug("GPX0_0 INPUT not configured\n"); + return err; + } + + while (s5p_gpio_get_value(&gpio1->x0, 0) == 0) { + /* wait for 50ms */ + if (gpio_debounce_cnt < 5) { + udelay(DEBOUNCE_DELAY); + gpio_debounce_cnt++; + } else { + setenv("bootcmd", CONFIG_BOOTCOMMAND_RAMDUMP); + break; + } + } +#endif +#ifdef CONFIG_RECOVERY_MODE + u32 second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (second_boot_info == 1) { + printf("###Recovery Mode###\n"); + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + setenv("bootcmd", CONFIG_BOOTCOMMAND2); + } +#endif + + if ((readl(&pmu->sysip_dat0)) == CONFIG_FACTORY_RESET_MODE) { + writel(0x0, &pmu->sysip_dat0); + setenv("bootcmd", CONFIG_FACTORY_RESET_BOOTCOMMAND); + } + + return 0; +} diff --git a/board/samsung/smdk5410/smdk5410_val.h b/board/samsung/smdk5410/smdk5410_val.h new file mode 100644 index 000000000..c832157ea --- /dev/null +++ b/board/samsung/smdk5410/smdk5410_val.h @@ -0,0 +1,451 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef _VAL_SMDK5410_H +#define _VAL_SMDK5410_H + +#include <config.h> +#include <version.h> + + +/******************************************************************************* + * PLL LOCK + ******************************************************************************/ +#define APLL_LOCK_OFFSET 0x00000 +#define KPLL_LOCK_OFFSET 0x28000 +#define BPLL_LOCK_OFFSET 0x20010 +#define CPLL_LOCK_OFFSET 0x10020 +#define MPLL_LOCK_OFFSET 0x04000 + +#define APLL_LOCK_VAL (0x320) +#define MPLL_LOCK_VAL (0x258) +#define BPLL_LOCK_VAL (0x258) +#define CPLL_LOCK_VAL (0x258) +#define KPLL_LOCK_VAL (0x258) + + +/******************************************************************************* + * SRC + ******************************************************************************/ +#define CLK_SRC_CPU_OFFSET 0x00200 +#define CLK_SRC_CORE0_OFFSET 0x04200 +#define CLK_SRC_CORE1_OFFSET 0x04204 +#define CLK_SRC_TOP0_OFFSET 0x10210 +#define CLK_SRC_TOP1_OFFSET 0x10214 +#define CLK_SRC_TOP2_OFFSET 0x10218 +#define CLK_SRC_FSYS_OFFSET 0x10244 +#define CLK_SRC_CDREX_OFFSET 0x20200 +#define CLK_SRC_KFC_OFFSET 0x28200 + +#define CLK_SRC_CORE0_VAL (0x00090000) +#define CLK_SRC_CORE1_VAL (0x0) +#define CLK_SRC_TOP0_VAL (0x00000000) +#define CLK_SRC_TOP1_VAL (0x1 << 20) +#define CLK_SRC_TOP2_VAL (0x01100000) +#define CLK_SRC_FSYS_VAL (0x30000666) +#ifndef CONFIG_CPU_EXYNOS5410_EVT0 +#define CLKDIV4_RATIO_VAL (0x00000303) +#else +#define CLKDIV4_RATIO_VAL (0x00000313) +#endif +#define CLK_SRC_CDREX_VAL (0x00001000) + + +/******************************************************************************* + * DIV + ******************************************************************************/ +#define CLK_DIV_CPU0_OFFSET 0x00500 +#define CLK_DIV_CPU1_OFFSET 0x00504 +#define CLK_DIV_CORE1_OFFSET 0x04504 +#define CLK_DIV_G2D_OFFSET 0x08500 +#define CLK_DIV_TOP0_OFFSET 0x10510 +#define CLK_DIV_TOP1_OFFSET 0x10514 +#define CLK_DIV_FSYS0_OFFSET 0x10548 +#define CLK_DIV_FSYS1_OFFSET 0x1054C +#define CLK_DIV_FSYS2_OFFSET 0x10550 +#define CLK_DIV_FSYS3_OFFSET 0x10554 +#define CLKDIV4_RATIO_OFFSET 0x105A0 +#define CLK_DIV_CDREX0_OFFSET 0x20500 +#define CLK_DIV_CDREX1_OFFSET 0x20504 +#define CLK_DIV_KFC0_OFFSET 0x28500 + +/* DIV CPU0 VAL */ +#if defined(CONFIG_CPU_EXYNOS5410_EVT2) +#if defined(CONFIG_CLK_ARM_2000) +#define CLK_DIV_CPU0_VAL (0x03770040) +#elif defined(CONFIG_CLK_ARM_1900) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1800) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1700) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1600) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1500) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1400) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1300) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1200) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1100) +#define CLK_DIV_CPU0_VAL (0x03770030) +#elif defined(CONFIG_CLK_ARM_1000) +#define CLK_DIV_CPU0_VAL (0x03660030) +#elif defined(CONFIG_CLK_ARM_900) +#define CLK_DIV_CPU0_VAL (0x03660070) +#elif defined(CONFIG_CLK_ARM_800) +#define CLK_DIV_CPU0_VAL (0x03550030) +#elif defined(CONFIG_CLK_ARM_700) +#define CLK_DIV_CPU0_VAL (0x03550030) +#elif defined(CONFIG_CLK_ARM_600) +#define CLK_DIV_CPU0_VAL (0x03440020) +#elif defined(CONFIG_CLK_ARM_500) +#define CLK_DIV_CPU0_VAL (0x03330020) +#elif defined(CONFIG_CLK_ARM_400) +#define CLK_DIV_CPU0_VAL (0x03330010) +#elif defined(CONFIG_CLK_ARM_300) +#define CLK_DIV_CPU0_VAL (0x03330010) +#elif defined(CONFIG_CLK_ARM_200) +#define CLK_DIV_CPU0_VAL (0x03330010) +#endif +#elif defined(CONFIG_CPU_EXYNOS5410_EVT1) +#if defined(CONFIG_CLK_ARM_1200) +#define CLK_DIV_CPU0_VAL (0x03660030) +#elif defined(CONFIG_CLK_ARM_1100) +#define CLK_DIV_CPU0_VAL (0x02660030) +#elif defined(CONFIG_CLK_ARM_1000) +#define CLK_DIV_CPU0_VAL (0x02660030) +#elif defined(CONFIG_CLK_ARM_900) +#define CLK_DIV_CPU0_VAL (0x02660020) +#elif defined(CONFIG_CLK_ARM_800) +#define CLK_DIV_CPU0_VAL (0x01550020) +#elif defined(CONFIG_CLK_ARM_600) +#define CLK_DIV_CPU0_VAL (0x01440020) +#elif defined(CONFIG_CLK_ARM_533) +#define CLK_DIV_CPU0_VAL (0x00230010) +#elif defined(CONFIG_CLK_ARM_400) +#define CLK_DIV_CPU0_VAL (0x01330010) +#elif defined(CONFIG_CLK_ARM_333) +#define CLK_DIV_CPU0_VAL (0x00130010) +#elif defined(CONFIG_CLK_ARM_300) +#define CLK_DIV_CPU0_VAL (0x00130010) +#elif defined(CONFIG_CLK_ARM_200) +#define CLK_DIV_CPU0_VAL (0x01330010) +#elif defined(CONFIG_CLK_ARM_100) +#define CLK_DIV_CPU0_VAL (0x00130010) +#endif +#else /* CONFIG_CPU_EXYNOS5410_EVT0 */ +#if defined(CONFIG_CLK_ARM_1200) +#define CLK_DIV_CPU0_VAL (0x03460030) +#elif defined(CONFIG_CLK_ARM_1100) +#define CLK_DIV_CPU0_VAL (0x02460030) +#elif defined(CONFIG_CLK_ARM_1000) +#define CLK_DIV_CPU0_VAL (0x02460030) +#elif defined(CONFIG_CLK_ARM_900) +#define CLK_DIV_CPU0_VAL (0x02360030) +#elif defined(CONFIG_CLK_ARM_800) +#define CLK_DIV_CPU0_VAL (0x01340020) +#elif defined(CONFIG_CLK_ARM_600) +#define CLK_DIV_CPU0_VAL (0x00240020) +#elif defined(CONFIG_CLK_ARM_533) +#define CLK_DIV_CPU0_VAL (0x00230010) +#elif defined(CONFIG_CLK_ARM_400) +#define CLK_DIV_CPU0_VAL (0x00130010) +#elif defined(CONFIG_CLK_ARM_333) +#define CLK_DIV_CPU0_VAL (0x00130010) +#elif defined(CONFIG_CLK_ARM_300) +#define CLK_DIV_CPU0_VAL (0x00130010) +#elif defined(CONFIG_CLK_ARM_200) +#define CLK_DIV_CPU0_VAL (0x00130010) +#elif defined(CONFIG_CLK_ARM_100) +#define CLK_DIV_CPU0_VAL (0x00130010) +#endif +#endif + +/* DIV KFC VAL */ +#if defined(CONFIG_CPU_EXYNOS5410_EVT2) +#if defined(CONFIG_CLK_KFC_1300) +#define CLK_DIV_KFC0_VAL (0x03600130) +#elif defined(CONFIG_CLK_KFC_1200) +#define CLK_DIV_KFC0_VAL (0x03500130) +#elif defined(CONFIG_CLK_KFC_1100) +#define CLK_DIV_KFC0_VAL (0x03500130) +#elif defined(CONFIG_CLK_KFC_1000) +#define CLK_DIV_KFC0_VAL (0x03500130) +#elif defined(CONFIG_CLK_KFC_900) +#define CLK_DIV_KFC0_VAL (0x03500120) +#elif defined(CONFIG_CLK_KFC_800) +#define CLK_DIV_KFC0_VAL (0x03500120) +#elif defined(CONFIG_CLK_KFC_700) +#define CLK_DIV_KFC0_VAL (0x03400120) +#elif defined(CONFIG_CLK_KFC_600) +#define CLK_DIV_KFC0_VAL (0x03400170) +#elif defined(CONFIG_CLK_KFC_500) +#define CLK_DIV_KFC0_VAL (0x03400120) +#elif defined(CONFIG_CLK_KFC_400) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_300) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_200) +#define CLK_DIV_KFC0_VAL (0x03300110) +#endif +#elif defined(CONFIG_CPU_EXYNOS5410_EVT1) +#if defined(CONFIG_CLK_KFC_1200) +#define CLK_DIV_KFC0_VAL (0x01500120) +#elif defined(CONFIG_CLK_KFC_1000) +#define CLK_DIV_KFC0_VAL (0x01400120) +#elif defined(CONFIG_CLK_KFC_800) +#define CLK_DIV_KFC0_VAL (0x01300120) +#elif defined(CONFIG_CLK_KFC_600) +#define CLK_DIV_KFC0_VAL (0x01300010) +#elif defined(CONFIG_CLK_KFC_432) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_400) +#define CLK_DIV_KFC0_VAL (0x00300110) +#elif defined(CONFIG_CLK_KFC_350) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_330) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_300) +#define CLK_DIV_KFC0_VAL (0x00300110) +#elif defined(CONFIG_CLK_KFC_200) +#define CLK_DIV_KFC0_VAL (0x00300110) +#elif defined(CONFIG_CLK_KFC_100) +#define CLK_DIV_KFC0_VAL (0x03300110) +#endif +#else /* CONFIG_CPU_EXYNOS5410_EVT0 */ +#if defined(CONFIG_CLK_KFC_1200) +#define CLK_DIV_KFC0_VAL (0x03300120) +#elif defined(CONFIG_CLK_KFC_1000) +#define CLK_DIV_KFC0_VAL (0x03300120) +#elif defined(CONFIG_CLK_KFC_800) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_600) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_432) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_400) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_350) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_330) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_300) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_200) +#define CLK_DIV_KFC0_VAL (0x03300110) +#elif defined(CONFIG_CLK_KFC_100) +#define CLK_DIV_KFC0_VAL (0x03300110) +#endif +#endif + +/* DIV values */ +#define CLK_DIV_CORE1_VAL (0x00000F00) +#if defined(CONFIG_CPU_EXYNOS5410_EVT2) +#define CLK_DIV_TOP0_VAL (0x02112303) +#define CLK_DIV_TOP1_VAL (0x71700000) +#elif defined(CONFIG_CPU_EXYNOS5410_EVT1) +#define CLK_DIV_TOP0_VAL (0x03123303) +#define CLK_DIV_TOP1_VAL (0x32700000) +#else +#define CLK_DIV_TOP0_VAL (0x01123305) +#define CLK_DIV_TOP1_VAL (0x31100000) +#endif +#define CLK_DIV_G2D_VAL (0x00000011) +#define CLK_DIV_FSYS0_VAL (0x0) +#define CLK_DIV_FSYS1_VAL (0x000A000A) +#define CLK_DIV_FSYS2_VAL (0x0000000A) +#define CLK_DIV_CDREX0_VAL (0x31010100) +#define CLK_DIV_CDREX1_VAL (0x00000011) + + +/******************************************************************************* + * PLL CON + ******************************************************************************/ +/* APLL */ +#define APLL_CON0_OFFSET 0x00100 +#define APLL_CON1_OFFSET 0x00104 + +#if defined(CONFIG_CLK_ARM_2000) +#define APLL_CON0_VAL (0x80FA0300) +#elif defined(CONFIG_CLK_ARM_1900) +#define APLL_CON0_VAL (0x81DB0600) +#elif defined(CONFIG_CLK_ARM_1800) +#define APLL_CON0_VAL (0x80E10300) +#elif defined(CONFIG_CLK_ARM_1700) +#define APLL_CON0_VAL (0x81A90600) +#elif defined(CONFIG_CLK_ARM_1600) +#define APLL_CON0_VAL (0x80C80300) +#elif defined(CONFIG_CLK_ARM_1500) +#define APLL_CON0_VAL (0x80FA0400) +#elif defined(CONFIG_CLK_ARM_1400) +#define APLL_CON0_VAL (0x80AF0300) +#elif defined(CONFIG_CLK_ARM_1300) +#define APLL_CON0_VAL (0x81450600) +#elif defined(CONFIG_CLK_ARM_1200) +#define APLL_CON0_VAL (0x80C80201) +#elif defined(CONFIG_CLK_ARM_1100) +#define APLL_CON0_VAL (0x81130301) +#elif defined(CONFIG_CLK_ARM_1000) +#define APLL_CON0_VAL (0x80FA0301) +#elif defined(CONFIG_CLK_ARM_900) +#define APLL_CON0_VAL (0x80960201) +#elif defined(CONFIG_CLK_ARM_800) +#define APLL_CON0_VAL (0x80C80301) +#elif defined(CONFIG_CLK_ARM_700) +#define APLL_CON0_VAL (0x80AF0301) +#elif defined(CONFIG_CLK_ARM_600) +#define APLL_CON0_VAL (0x80C80202) +#elif defined(CONFIG_CLK_ARM_533) +#define APLL_CON0_VAL (0x810A0302) +#elif defined(CONFIG_CLK_ARM_500) +#define APLL_CON0_VAL (0x80FA0302) +#elif defined(CONFIG_CLK_ARM_400) +#define APLL_CON0_VAL (0x80C80302) +#elif defined(CONFIG_CLK_ARM_333) +#define APLL_CON0_VAL (0x80DE0402) +#elif defined(CONFIG_CLK_ARM_300) +#define APLL_CON0_VAL (0x81900403) +#elif defined(CONFIG_CLK_ARM_200) +#define APLL_CON0_VAL (0x80C80303) +#elif defined(CONFIG_CLK_ARM_100) +#define APLL_CON0_VAL (0x80C80304) +#endif + +#define APLL_CON1_VAL (0x0020F300) + +/* KPLL */ +#define KPLL_CON0_OFFSET 0x28100 +#define KPLL_CON1_OFFSET 0x28104 + +#if defined(CONFIG_CLK_KFC_1300) +#define KPLL_CON0_VAL (0x81450600) +#elif defined(CONFIG_CLK_KFC_1200) +#define KPLL_CON0_VAL (0x80C80201) +#elif defined(CONFIG_CLK_KFC_1100) +#define KPLL_CON0_VAL (0x81130301) +#elif defined(CONFIG_CLK_KFC_1000) +#define KPLL_CON0_VAL (0x80FA0301) +#elif defined(CONFIG_CLK_KFC_900) +#define KPLL_CON0_VAL (0x80960201) +#elif defined(CONFIG_CLK_KFC_800) +#define KPLL_CON0_VAL (0x80C80301) +#elif defined(CONFIG_CLK_KFC_700) +#define KPLL_CON0_VAL (0x80AF0301) +#elif defined(CONFIG_CLK_KFC_600) +#define KPLL_CON0_VAL (0x80C80202) +#elif defined(CONFIG_CLK_KFC_500) +#define KPLL_CON0_VAL (0x80FA0302) +#elif defined(CONFIG_CLK_KFC_432) +#define KPLL_CON0_VAL (0x81200402) +#elif defined(CONFIG_CLK_KFC_400) +#define KPLL_CON0_VAL (0x80C80302) +#elif defined(CONFIG_CLK_KFC_350) +#define KPLL_CON0_VAL (0x80AF0302) +#elif defined(CONFIG_CLK_KFC_330) +#define KPLL_CON0_VAL (0x806E0202) +#elif defined(CONFIG_CLK_KFC_300) +#define KPLL_CON0_VAL (0x80C80203) +#elif defined(CONFIG_CLK_KFC_200) +#define KPLL_CON0_VAL (0x80C80303) +#elif defined(CONFIG_CLK_KFC_100) +#define KPLL_CON0_VAL (0x80C80304) +#endif + +#define KPLL_CON1_VAL (0x00200000) + +/* BPLL */ +#define BPLL_CON0_OFFSET 0x20110 +#define BPLL_CON1_OFFSET 0x20114 + +#define BPLL_CON0_VAL (0x80C80301) +#define BPLL_CON1_VAL (0x0020F300) + +/* CPLL */ +#define CPLL_CON0_OFFSET 0x10120 +#define CPLL_CON1_OFFSET 0x10124 + +#define CPLL_CON0_VAL (0x80A00301) +#define CPLL_CON1_VAL (0x0020F300) + +/* MPLL */ +#define MPLL_CON0_OFFSET 0x04100 +#define MPLL_CON1_OFFSET 0x04104 + +#define MPLL_CON0_VAL (0x810A0302) +#define MPLL_CON1_VAL (0x0020F300) + + +/******************************************************************************* + * UART + ******************************************************************************/ +#define CLK_SRC_PERIC0_OFFSET 0x10250 +#define CLK_DIV_PERIC0_OFFSET 0x10558 + +#define UART0_OFFSET 0x00000 +#define UART1_OFFSET 0x10000 +#define UART2_OFFSET 0x20000 +#define UART3_OFFSET 0x30000 + +#define EXYNOS5410_UART_BASE 0x12C00000 + +#if defined(CONFIG_SERIAL0) +#define UART_CONSOLE_BASE (EXYNOS5410_UART_BASE + UART0_OFFSET) +#elif defined(CONFIG_SERIAL1) +#define UART_CONSOLE_BASE (EXYNOS5410_UART_BASE + UART1_OFFSET) +#elif defined(CONFIG_SERIAL2) +#define UART_CONSOLE_BASE (EXYNOS5410_UART_BASE + UART2_OFFSET) +#elif defined(CONFIG_SERIAL3) +#define UART_CONSOLE_BASE (EXYNOS5410_UART_BASE + UART3_OFFSET) +#else +#define UART_CONSOLE_BASE (EXYNOS5410_UART_BASE + UART0_OFFSET) +#endif + +#define ULCON_OFFSET 0x00 +#define UCON_OFFSET 0x04 +#define UFCON_OFFSET 0x08 +#define UMCON_OFFSET 0x0C +#define UTRSTAT_OFFSET 0x10 +#define UERSTAT_OFFSET 0x14 +#define UFSTAT_OFFSET 0x18 +#define UMSTAT_OFFSET 0x1C +#define UTXH_OFFSET 0x20 +#define URXH_OFFSET 0x24 +#define UBRDIV_OFFSET 0x28 +#define UDIVSLOT_OFFSET 0x2C +#define UINTP_OFFSET 0x30 +#define UINTSP_OFFSET 0x34 +#define UINTM_OFFSET 0x38 +#define UART_ERR_MASK 0xF + +/* (SCLK_UART/(115200*16) -1) */ +#define UART_UBRDIV_VAL 0x21 + +/*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/ +#define UART_UDIVSLOT_VAL 0xb + + +/******************************************************************************* + * CLOCK OUT + ******************************************************************************/ +#define CLKOUT_CMU_CPU_OFFSET 0x00A00 +#define CLKOUT_CMU_CORE_OFFSET 0x04A00 +#define CLKOUT_CMU_TOP_OFFSET 0x10A00 +#define CLKOUT_CMU_CDREX_OFFSET 0x20A00 + + +/******************************************************************************* + * End of smdk5410_val.h + ******************************************************************************/ +#endif diff --git a/board/samsung/smdk5412/Makefile b/board/samsung/smdk5412/Makefile new file mode 100644 index 000000000..28150c4ca --- /dev/null +++ b/board/samsung/smdk5412/Makefile @@ -0,0 +1,64 @@ +# +# Copyright (C) 2013 Samsung Electronics +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +SOBJS := lowlevel_init.o + +COBJS := clock_init.o +COBJS += dmc_init.o +COBJS += wdmc_init.o +COBJS += pmic.o +COBJS += smc.o + +ifdef CONFIG_TZPC +COBJS += tzpc_init.o +endif + +ifndef CONFIG_SPL_BUILD +COBJS += smdk5412.o +endif + +ifdef CONFIG_SPL_BUILD +COBJS += mmc_boot.o +endif + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +ALL := $(obj).depend $(LIB) + +all: $(ALL) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/smdk5412/clock_init.c b/board/samsung/smdk5412/clock_init.c new file mode 100644 index 000000000..5dc1b36f6 --- /dev/null +++ b/board/samsung/smdk5412/clock_init.c @@ -0,0 +1,170 @@ +/* + * Clock setup for SMDK5412 board based on EXYNOS5 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include "setup.h" + +void system_clock_init() +{ + struct exynos5412_clock *clk = + (struct exynos5412_clock *)EXYNOS5_CLOCK_BASE; + + /* Set CMU_CPU, MUX & DIV */ + writel(0x00000000, &clk->src_cpu); + writel(0x00000000, &clk->src_top7); + writel(0x00000000, &clk->src_cdrex); + writel(0x00000000, &clk->src_cci); + writel(0x00000000, &clk->src_kfc); + writel(0x00000077, &clk->div_cpu1); + writel(0x03550020, &clk->div_cpu0); + + /* Set APLL */ + writel(0x00000258, &clk->apll_lock); + writel(0x0020F300, &clk->apll_con1); + writel(0x80C80301, &clk->apll_con0); + while(!(readl(&clk->apll_con0) & (0x1 << 29))); + + /* Set KPLL */ + writel(0x00000190, &clk->kpll_lock); + writel(0x00008000, &clk->src_kfc); + writel(0x03400720, &clk->div_kfc0); + writel(0x00200000, &clk->kpll_con1); + writel(0x80C80202, &clk->kpll_con0); + while(!(readl(&clk->kpll_con0) & (0x1 << 29))); + + /* Set MPLL */ + writel(0x00000258, &clk->mpll_lock); + writel(0x0020F300, &clk->mpll_con1); + writel(0x810A0302, &clk->mpll_con0); + while(!(readl(&clk->mpll_con0) & (0x1 << 29))); + + /* Set DPLL */ + writel(0x00000190, &clk->dpll_lock); + writel(0x0020F300, &clk->dpll_con1); + writel(0x80640201, &clk->dpll_con0); + while(!(readl(&clk->dpll_con0) & (0x1 << 29))); + + /* Set EPLL */ + writel(0x00002328, &clk->epll_lock); + writel(0x00000080, &clk->epll_con2); + writel(0x00000000, &clk->epll_con1); + writel(0x80C80304, &clk->epll_con0); + while(!(readl(&clk->epll_con0) & (0x1 << 29))); + + /* Set RPLL */ + writel(0x00002328, &clk->rpll_lock); + writel(0x00000080, &clk->rpll_con2); + writel(0x00000000, &clk->rpll_con1); + writel(0x810A0303, &clk->rpll_con0); + while(!(readl(&clk->rpll_con0) & (0x1 << 29))); + + /* Set CPLL */ + writel(0x00000190, &clk->cpll_lock); + writel(0x0020F300, &clk->cpll_con1); + writel(0x806f0201, &clk->cpll_con0); + while(!(readl(&clk->cpll_con0) & (0x1 << 29))); + + /* Set IPLL */ + writel(0x00000190, &clk->ipll_lock); + writel(0x0020F300, &clk->ipll_con1); + writel(0x80900202, &clk->ipll_con0); + while(!(readl(&clk->ipll_con0) & (0x1 << 29))); + + /* Set VPLL */ + writel(0x00000258, &clk->vpll_lock); + writel(0x0020F300, &clk->vpll_con1); + writel(0x80C80302, &clk->vpll_con0); + while(!(readl(&clk->vpll_con0) & (0x1 << 29))); + + /* Setting SPLL */ + writel(0x00000258, &clk->spll_lock); + writel(0x0020F300, &clk->spll_con1); + writel(0x80C80302, &clk->spll_con0); + while(!(readl(&clk->spll_con0) & (0x1 << 29))); + + /* Setting BPLL(466MHz) */ + writel(0x00000258, &clk->bpll_lock); + writel(0x0020f300, &clk->bpll_con1); + writel(0x80E90302, &clk->bpll_con0); + while(!(readl(&clk->bpll_con0) & (0x1 << 29))); + + /* Setting XPLL(825MHz) */ + writel(0x00000320, &clk->xpll_lock); + writel(0x0020f300, &clk->xpll_con1); + writel(0x81130401, &clk->xpll_con0); + while(!(readl(&clk->xpll_con0) & (0x1 << 29))); + + /* Setting TPLL(532MHz) */ + writel(0x00000258, &clk->tpll_lock); + writel(0x0020f300, &clk->tpll_con1); + writel(0x810a0302, &clk->tpll_con0); + while(!(readl(&clk->tpll_con0) & (0x1 << 29))); + + /* Set CMU_CDREX, MUX & DIV */ + writel(0x30010100, &clk->div_cdrex0); + writel(0x00000300, &clk->div_cdrex1); + + /* Set CMU_TOP, MUX & DIV */ + writel(0x11101102, &clk->src_top0); + writel(0x00200000, &clk->src_top1); + writel(0x1510C030, &clk->src_top2); + writel(0x03033300, &clk->src_top9); + + writel(0x22502200, &clk->div_top0); + writel(0x13100900, &clk->div_top1); + writel(0x12101713, &clk->div_top2); + writel(0x00901000, &clk->div_top3); + + writel(0x00010011, &clk->src_top10); + writel(0x00000000, &clk->src_top11); + writel(0x44040000, &clk->src_top12); + + writel(0x11111111, &clk->src_top3); + writel(0x11111111, &clk->src_top4); + writel(0x15111011, &clk->src_top5); + writel(0x00111111, &clk->src_top6); + writel(0x00000001, &clk->src_top8); + writel(0x10000000, &clk->src_disp10); + + writel(0x00044400, &clk->src_fsys); + writel(0x00000000, &clk->div_fsys0); + writel(0x00902809, &clk->div_fsys1); + + writel(0x03033330, &clk->src_peric0); + writel(0x90999900, &clk->div_peric0); + writel(0x00000030, &clk->div_cci0); + + /* Turn On PLL Mout */ + writel(0x00000001, &clk->src_cpu); + writel(0x00000001, &clk->src_kfc); + writel(0x11111111, &clk->src_top7); + writel(0x00000001, &clk->src_cci); + writel(0x00000001, &clk->src_cdrex); +} diff --git a/board/samsung/smdk5412/dmc_init.c b/board/samsung/smdk5412/dmc_init.c new file mode 100644 index 000000000..79f8eadd3 --- /dev/null +++ b/board/samsung/smdk5412/dmc_init.c @@ -0,0 +1,1127 @@ +/* + * Memory setup for SMDK5412 board based on EXYNOS5 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/smc.h> + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define SetBits(uAddr, uBaseBit, uMaskValue, uSetValue) \ + Outp32(uAddr, (Inp32(uAddr) & ~((uMaskValue)<<(uBaseBit))) \ + | (((uMaskValue)&(uSetValue))<<(uBaseBit))) + +#define dmcOutp32(a, d) Outp32(g_uBaseAddr+a, d) +#define dmcInp32(a) Inp32(g_uBaseAddr+a) + +typedef enum { + nRESET = 0x10, // Booting sequence #9 + IRAMON_COREON_TOPON = 0x7, // Booting sequence #1 + IRAMOFF_COREON_TOPON = 0x6, // Booting sequence #2 + IRAMON_COREOFF_TOPON = 0x5, // Booting sequence #3 + IRAMOFF_COREOFF_TOPON = 0x4, // Booting sequence #4 + IRAMON_COREON_TOPOFF = 0x3, // Booting sequence #5 + IRAMOFF_COREON_TOPOFF = 0x2, // Booting sequence #6 + IRAMON_COREOFF_TOPOFF = 0x1, // Booting sequence #7 + IRAMOFF_COREOFF_TOPOFF = 0x0 // Booting sequence #8 +}BOOT_STAT; + +static u32 g_uBaseAddr; +static const u32 IROM_ARM_CLK = 400; + +static unsigned int g_nMEMCLK; +static unsigned int g_cal = 0; +static unsigned int g_zq_mode_dds = 6; + +unsigned int crl_dfdqs = 0; + +enum DMC_SFR +{ + CONCONTROL = 0x0000, + MEMCONTROL = 0x0004, + MEMCONFIG0 = 0x0008, + MEMCONFIG1 = 0x000c, + DIRECTCMD = 0x0010, + PRECHCONFIG = 0x0014, + PHYCONTROL0 = 0x0018, + PHYCONTROL1 = 0x001c, + PHYCONTROL2 = 0x0020, + PHYCONTROL3 = 0x0024, + PWRDNCONFIG = 0x0028, + TIMINGPZQ = 0x002c, + TIMINGAREF = 0x0030, + TIMINGROW = 0x0034, + TIMINGDATA = 0x0038, + TIMINGPOWER = 0x003c, + PHYSTATUS = 0x0040, + PHYZQCONTROL = 0x0044, + CHIP0STATUS = 0x0048, + CHIP1STATUS = 0x004c, + AREFSTATUS = 0x0050, + MRSTATUS = 0x0054, + IVCONTROL = 0x00f0, +}; + + + +static void DMC_Delay(u32 x) +{ + while(--x) + __asm ("NOP"); +} + +void DMC_RdCalibration(void) +{ + u32 phyBase; + u32 code, lock, vwmc; + int dq0, dq1, dq2, dq3, ch; + + for( ch = 0; ch < 2; ch++ ) { + + phyBase = 0x10c00000+(0x10000 * ch); + + Outp32( phyBase + 0x0004, 0x92100FF ); //- Set PHY0.CON1.rdlvl_rddata_adj + + Outp32( phyBase + 0x005C, 0x00000041 ); //- PHY0.CON22.lpddr2_addr=0x041 + + Outp32( phyBase + 0x0008, 0x2010044 ); //- Set PHY0.CON2.rdlvl_en + } + + Outp32( 0x10DD0000+0x00F8, 0x2 ); //- DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=1 + + while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Wait DMC.rdlvl_complete_ch0/1 + Outp32( 0x10DD0000+0x00F8, 0x0 ); //- Set DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=0 + + for(ch = 0; ch < 2; ch ++ ) { + + Outp32( phyBase + 0014, 0x8); + vwmc = Inp32(phyBase + 0x0050); + + lock = Inp32( phyBase + 0x0034 ); + lock &= 0x1FF00; + lock >>= 8; + + if( (lock & 0x3) == 0x3 ) { + lock++; + } + + dq0 = (vwmc & 0xFF) - (lock >> 2); + dq1 = ((vwmc >> 8) & 0xFF) - (lock >> 2); + dq2 = ((vwmc >> 16) & 0xFF) - (lock >> 2); + dq3 = ((vwmc >> 24) & 0xFF) - (lock >> 2); + + if(dq0 < 0) { + dq0 *= -1; + dq0 |= 0x80; + } + + if(dq1 < 0) { + dq1 *= -1; + dq1 |= 0x80; + } + + if(dq2 < 0) { + dq2 *= -1; + dq2 |= 0x80; + } + + if(dq3 < 0) { + dq3 *= -1; + dq3 |= 0x80; + } + + code = ((dq3 & 0xFF) << 24) | ((dq2 & 0xFF) << 16) | + ((dq1 & 0xFF) << 8) | (dq0 & 0xFF); + + Outp32( phyBase + 0x0010, code ); + + Outp32( phyBase + 0x0008, Inp32( phyBase + 0x0008) & 0xFDFFFFFF ); + } +} + +void DMC_WrCalibration(void) +{ + //-Write DQ Calibration. + while( ( Inp32( 0x10DD0000+0x0048 ) & 0x3 ) != 0x0 ); //- Wait for DMC.chip_busy_state CH0 + while( ( Inp32( 0x10DD0000+0x004C ) & 0x3 ) != 0x0 ); //- Wait for DMC.chip_busy_state CH1 + Outp32( 0x10DD0000+0x00F4, 0x1 ); //- DMC.WRTRACONFIG + Outp32( 0x10C00000+0x005C, 0x204 ); //- + Outp32( 0x10C10000+0x005C, 0x204 ); //- + Outp32( 0x10C00000+0x0004, 0x9210001 ); //- + Outp32( 0x10C10000+0x0004, 0x9210001 ); //- + Outp32( 0x10C00000+0x0008, 0x6010044 ); //- + Outp32( 0x10C10000+0x0008, 0x6010044 ); //- + Outp32( 0x10C00000+0x0008, 0xE010044 ); //- + Outp32( 0x10C10000+0x0008, 0xE010044 ); //- + while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Wait DMC.rdlvl_complete_ch0/1 + Outp32( 0x10C00000+0x0008, 0x6010044 ); //- + Outp32( 0x10C10000+0x0008, 0x6010044 ); //- +} + +void DMC_CaTraining(int ch) +{ + unsigned char code; + int find_vmw; + unsigned int phyBase; + unsigned int ioRdOffset; + unsigned int temp, mr41, mr48, vwml, vwmr, vwmc; + unsigned int lock; + + + phyBase = 0x10c00000+(0x10000 * ch); + ioRdOffset = 0x150 + (0x4 * ch); + + temp = Inp32( phyBase + 0x0000 ); + temp |= (1 << 16); + Outp32( phyBase + 0x0000, temp ); + + temp = Inp32( phyBase + 0x0008 ); + temp |= (1 << 23); + Outp32( phyBase + 0x0008, temp ); + + code = 0x8; + find_vmw = 0; + vwml = vwmr = vwmc = 0; + + while (1) { + + //- code update + temp = Inp32( phyBase + 0x0028 ); + temp &= 0xFFFFFF00; + temp |= code; + Outp32( phyBase + 0x0028, temp ); + + //- resync + temp = Inp32( phyBase + 0x0028 ); + temp &= 0xFEFFFFFF; + Outp32( phyBase + 0x0028, temp ); + temp |= 0x01000000; + Outp32( phyBase + 0x0028, temp ); + temp &= 0xFEFFFFFF; + Outp32( phyBase + 0x0028, temp ); + + if(ch == 0) { + Outp32( 0x10DD0000+0x0010, 0x50690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x50690 + //Outp32( 0x10DD0000+0x0010, 0x001050690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x50690 + } else { + Outp32( 0x10DD0000+0x0010, 0x10050690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x10050690 + //Outp32( 0x10DD0000+0x0010, 0x10150690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x10050690 + } + + Outp32( 0x10DD0000+0x0160, 0x3FF011 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=1 + Outp32( 0x10DD0000+0x0164, 0x1 ); //- Set DMC.CACAL_CONFIG1.cacal_csn=1 + DMC_Delay(0x100); + + mr41 = Inp32( 0x10DD0000 + ioRdOffset ); + mr41 &= 0xFFFF; + + Outp32( 0x10DD0000+0x0160, 0x3FF010 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=0 + DMC_Delay(0x100); + + if( ch == 0 ) { + Outp32( 0x10DD0000+0x0010, 0x60300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x60300 + //Outp32( 0x10DD0000+0x0010, 0x001060300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x60300 + } else { + Outp32( 0x10DD0000+0x0010, 0x10060300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x10060300 + //Outp32( 0x10DD0000+0x0010, 0x10160300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x10060300 + } + + Outp32( 0x10DD0000+0x0160, 0x3FF011 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=1 + Outp32( 0x10DD0000+0x0164, 0x1 ); //- Set DMC.CACAL_CONFIG1.cacal_csn=1 + DMC_Delay(0x100); + + mr48 = Inp32( 0x10DD0000 + ioRdOffset ); + mr48 &= 0x0303; + + Outp32( 0x10DD0000+0x0160, 0x3FF010 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=0 + DMC_Delay(0x100); + + if( (find_vmw == 0) && (mr41 == 0x5555 ) && ( mr48 == 0x0101 ) ) { + find_vmw = 0x1; + vwml = code; + } + + if( (find_vmw == 1) && ( (mr41 != 0x5555 ) || ( mr48 != 0x0101 ) ) ) { + find_vmw = 0x3; + vwmr = code - 1; + + if( ch == 0 ) { + Outp32( 0x10DD0000+0x0010, 0x50AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0 + //Outp32( 0x10DD0000+0x0010, 0x001050AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0 + } else { + Outp32( 0x10DD0000+0x0010, 0x10050AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0 + //Outp32( 0x10DD0000+0x0010, 0x10150AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0 + } + //DMC_Delay(0x10000); + break; + } + + code++; + + if(code == 255) { + while(1); + } + } + + vwmc = (vwml + vwmr) / 2; + +#if 1 + { + u32 lock_force; + u32 temp = 0; + + lock_force = (Inp32( phyBase + 0x30 ) >> 8) & 0x7F; + + temp = ((vwml & 0xFF) << 16) | + ((vwmr & 0xFF) << 8) | + ((vwmc & 0xFF)); + + if(ch == 0) { + Outp32(0x10040818, temp); + } + else { + Outp32(0x1004081C, temp); + } + } +#endif + + //- code update + temp = Inp32( phyBase + 0x0028 ); + temp &= 0xFFFFFF00; + temp |= vwmc; + Outp32( phyBase + 0x0028, temp ); + + //- resync + temp = Inp32( phyBase + 0x0028 ); + temp &= 0xFEFFFFFF; + Outp32( phyBase + 0x0028, temp ); + temp |= 0x01000000; + Outp32( phyBase + 0x0028, temp ); + temp &= 0xFEFFFFFF; + Outp32( phyBase + 0x0028, temp ); + + temp = Inp32( phyBase+0x0000 ); + temp &= 0xFFFEFFFF; + Outp32( phyBase + 0x0000, temp ); + +#if 1 + + //- vmwc convert to offsetd value. + + lock = Inp32( phyBase + 0x0034 ); + lock &= 0x1FF00; + lock >>= 8; + + if( (lock & 0x3) == 0x3 ) { + lock++; + } + + code = vwmc - (lock >> 2); + + temp = Inp32( phyBase + 0x0028 ); + temp &= 0xFFFFFF00; + temp |= code; + Outp32( phyBase + 0x0028, temp ); + + temp = Inp32( phyBase + 0x0008 ); + temp &= 0xFF7FFFFF; + Outp32( phyBase + 0x0008, temp ); +#endif +} + +static void DMC_ZqInit(u8 dq, u8 ck, u8 cke, u8 cs, u8 ca) +{ + u32 temp; + u32 zqBase; + int ch; + + for( ch = 0; ch < 2; ch++ ) { + + zqBase = 0x10c00000 + ( 0x10000 * ch ); + + temp = Inp32( zqBase + 0x40 ); + temp &= 0xF8FBFFF1; + temp |= ( ( dq & 0x7 ) << 24 ); + temp |= ( ( 1 << 18 ) | ( 1 << 2 ) ); + + Outp32( zqBase + 0x40, temp ); + + temp |= (1 << 1); + + Outp32( zqBase + 0x40, temp ); + + while( ( Inp32( zqBase + 0x48 ) & 0x5 ) != 0x1 ); + + temp = Inp32( zqBase + 0x40 ); + + temp &= ~( 1 << 18 ); + + Outp32( zqBase + 0x40, temp ); + + temp = ( ( ck & 0x7 ) << 9 ) | ( ( cke & 0x7 ) << 6 ) | + ( ( cs & 0x7 ) << 3 ) | ( ca & 0x7 ); + + Outp32( zqBase + 0xA0, temp ); + } +} + +#define CA_SWAP 0 +#define NUM_CHIP 1 +#define ZQ_MODE_DDS 6 +#define PERFORM_LEVELING 0 +#define PHY0_BASE 0x10C00000 +#define PHY1_BASE 0x10C10000 +#define DREX1_0 0x10C20000 +#define DREX1_1 0x10C30000 +#define CMU_COREPART 0x10010000 +#define CMU_TOPPART 0x10020000 +#define CMU_MEMPART 0x10030000 +#define TZASC_0 0x10D40000 +#define TZASC_1 0x10D50000 +#define USED_DYNAMIC_AUTO_CLOCK_GATING 1 + +#define D25_3GB 0 +#define CONFIG_MEMCLK 825 + + + +void CA_swap_lpddr3(u32 DREX_address) +{ + u32 data; + + // ca_swap_mode[0]=1 + data = Inp32( DREX_address+0x0000 ); + data=data&(~0x00000001); + data=data|(0x00000001); + Outp32( DREX_address+0x0000, data ); + + return; +} + + + + +void Low_frequency_init_lpddr3(u32 PHY_address, u32 DREX_address) +{ + u32 data; + + // 1. To provide stable power for controller and memory device, the controller must assert and hold CKE to a logic low level + // 2. DRAM mode setting + Outp32( PHY_address+0x0000, 0x17021A00 ); // PHY_CON0 ctrl_ddr_mode[12:11]=3(LPDDR3), ctrl_atgate (automatic gate control-controller drive gate signals)[6]=1 + + // 3. Force lock values (DLL cannot be locked under 400MHz) + Outp32( PHY_address+0x0030, 0x10107F50 ); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + Outp32( PHY_address+0x0028, 0x0000007F ); // ctrl_offsetd[7:0]=0x7F + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x7F7F7F7F ); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value, Best Tuning Value + Outp32( PHY_address+0x0018, 0x7F7F7F7F ); // PHY_CON6 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x0C183060 ); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x60C18306 ); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000030 ); // PHY_CON33 DeSkew Code for CA + + // Setting PHY_CON12 later + // 6. Set ctrl_dll_on to 0 + // Outp32( PHY_address+0x0030, 0x10107F50); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + // DMC_Delay(100); // Wait for 10 PCLK cycles + + // 7. Issue dfi_ctrlupd_req for more than 10 cycles + Outp32( DREX_address+0x0018, 0x00000008); // PHYCONTROL0 assert fp_resync[3]=1(Force DLL Resyncronization) + // "dfi_ctrlupd_req" should be issued more than 10 cycles after ctrl_dll_on is disabled. + DMC_Delay(100); // Wait for 10 PCLK cycles + Outp32( DREX_address+0x0018, 0x00000000); // PHYCONTROL0 deassert fp_resync[3]=1(Force DLL Resyncronization) + + // 8. Set MemControl. At this moment, all power down modes should be off. + Outp32( DREX_address+0x0004, 0x00312700); // MEMCONTROL bl[22:20]=Memory Burst Length 0x3 = 8, mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit, mem_type [11:8]=Type of Memory 0x7 = LPDDR3 + + // Start :: Adding option for handshaking between DREX and PHY + // Deasserting the dfi_init_start + // 2012.11.08 :: rd_fetch 3 -> 2 + // 2013.05.14 :: rd_fetch 3@933MHz + Outp32( DREX_address+0x0000, 0x1FFF3100); // CONCONTROL dfi_init_start[28]=0 auto refresh not yet. + + // Disable DLL + Outp32( PHY_address+0x0030, 0x10107F10); // PHY_CON12 + // End :: Adding option for handshaking between DREX and PHY + + // Direct Command P0 CH0..! + // 9. CKE low for tINIT1 and CKE high for tINIT3 + Outp32( DREX_address+0x0010, 0x07000000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + + #if 0 + SetBits(0x14000060, 0, 0xF, 0x1); + Outp32(0x14000068, 0x0); + SetBits(0x14000064, 0, 0x1, 0x1); + #endif + + DMC_Delay(53333); // MIN 200us + DMC_Delay(53333); // MIN 200us + DMC_Delay(53333); // MIN 200us + DMC_Delay(53333); // MIN 200us + + #if 0 + SetBits(0x14000064, 0, 0x1, 0x0); + #endif + + // 10. RESET command to LPDDR3 + // Add :: 2012.11.01 :: Not send reset command when occured by wake-up + Outp32( DREX_address+0x0010, 0x00071C00); // 0x0 = MRS/EMRS (mode register setting), MR63_Reset (MA<7:0> = 3FH): MRW only + + // tINIT4(MIN 1us), tINIT5(MAX 10us) + // 2013.04.15 :: Check DAI complete..! + DMC_Delay(267); // MIN 1us + do{ + Outp32( DREX_address+0x0010, 0x09000000); // 0x9 = MRR (mode register reading), MR0_Device Information + }while ((Inp32(DREX_address+0x0054) & (1 << 0)) != 0); // OP0=DAI (Device Auto-Initialization Status) + + // 12. DRAM ZQ calibration + Outp32( DREX_address+0x0010, 0x00010BFC); // 0x0 = MRS/EMRS (mode register setting), MR10_Calibration, FFH: Calibration command after initialization + // 13. Wait for minimum 1us (tZQINIT). + + #if 0 + SetBits(0x14000064, 0, 0x1, 0x1); + #endif + + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + + #if 0 + SetBits(0x14000064, 0, 0x1, 0x0); + #endif + + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x0000050C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + + // 2012.10.11 + // Outp32( DREX_address+0x0010, 0x00000828); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x00000868); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + + // Add 20120501..! + // 14. I/O Configuration :: Drive Strength + Outp32( DREX_address+0x0010, 0x00000C04); // MR(3) OP(1) + + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + + // Initialization of second DRAM + if(NUM_CHIP == 1) + { + #if 0 + SetBits(0x14000064, 4, 0x1, 0x1); + #endif + + // 9. CKE low for tINIT1 and CKE high for tINIT3 + Outp32( DREX_address+0x0010, 0x07100000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + + DMC_Delay(53333); // MIN 200us + DMC_Delay(53333); // MIN 200us + DMC_Delay(53333); // MIN 200us + DMC_Delay(53333); // MIN 200us + + // 10. RESET command to LPDDR3 + // Add :: 2012.11.01 :: Not send reset command when occured by wake-up + Outp32( DREX_address+0x0010, 0x00171C00); // 0x0 = MRS/EMRS (mode register setting), MR63_Reset (MA<7:0> = 3FH): MRW only + + // tINIT4(MIN 1us), tINIT5(MAX 10us) + // 2013.04.15 :: Check DAI complete..! + DMC_Delay(267); // MIN 1us + do{ + Outp32( DREX_address+0x0010, 0x09100000); // 0x9 = MRR (mode register reading), MR0_Device Information + }while ((Inp32(DREX_address+0x0054) & (1 << 0)) != 0); // OP0=DAI (Device Auto-Initialization Status) + + // 12. DRAM ZQ calibration + Outp32( DREX_address+0x0010, 0x00110BFC); // 0x0 = MRS/EMRS (mode register setting), MR10_Calibration, FFH: Calibration command after initialization + + // 13. Wait for minimum 1us (tZQINIT). + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x0010050C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + Outp32( DREX_address+0x0010, 0x00100868); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + + // Add 20120501..! + // 14. I/O Configuration :: Drive Strength + Outp32( DREX_address+0x0010, 0x00100C04); // MR(3) OP(1) + + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + DMC_Delay(267); // MIN 1us + } + + // Reset SDLL codes + // 2012.10.11 + // Outp32( PHY_address+0x0028, 0x00000000); // PHY_CON10 ctrl_offsetd[7:0]=0x8 + Outp32( PHY_address+0x0028, 0x00000008); // PHY_CON10 ctrl_offsetd[7:0]=0x8 + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x08080808); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value, Best Tuning Value + Outp32( PHY_address+0x0018, 0x08080808); // PHY_CON5 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x00000000); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x00000000); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000000); // PHY_CON33 DeSkew Code for CA + + return; +} + +void Low_frequency_init_lpddr3_ReInit(u32 PHY_address, u32 DREX_address) +{ + u32 data; + + // 1. To provide stable power for controller and memory device, the controller must assert and hold CKE to a logic low level + // 2. DRAM mode setting + Outp32( PHY_address+0x0000, 0x17021A00 ); // PHY_CON0 ctrl_ddr_mode[12:11]=3(LPDDR3), ctrl_atgate (automatic gate control-controller drive gate signals)[6]=1 + + // 8. Set MemControl. At this moment, all power down modes should be off. + Outp32( DREX_address+0x0004, 0x00312700); // MEMCONTROL bl[22:20]=Memory Burst Length 0x3 = 8, mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit, mem_type [11:8]=Type of Memory 0x7 = LPDDR3 + + return; +} + +void High_frequency_init_lpddr3(u32 PHY_address, u32 DREX_address, u32 TZASC_address, u32 nMEMCLK) +{ +#if defined(CONFIG_SMC_CMD) + reg_arr_t reg_arr; +#endif + u32 data; + u32 data_temp; + + // Pulldn and Pullup enable + // ctrl_pulld_dq[11:8]=Active HIGH signal to down DQ signals. For normal operation this field should be zero. + // ctrl_pulld_dqs[3:0]=Active HIGH signal to pull-up or down PDQS/NDQS signals. + // Outp32( PHY_address+0x0038, 0x001F000F); // PHY_CON14 ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf + Outp32( PHY_address+0x0038, 0x001F000F); // PHY_CON14 ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf + + // ZQ calibration + // zq_mode_dds :: Driver strength selection. . It recommends one of the following settings instead of 3'h0. + // Outp32( PHY_address+0x0040, 0x0F040306); // PHY_CON16 zq_clk_en[27]=ZQ I/O Clock enable, zq_manual_mode[3:2]=Manual calibration mode selection 2'b01: long calibration, zq_manual_str[1]=Manual calibration start + // PHY_CON39 :: Driver Strength + // Outp32( PHY_address+0x00A0 , 0x0FFF0FFF); // PHY_CON39 + if (ZQ_MODE_DDS == 7) + { + Outp32( PHY_address+0x0040, 0x0F040306); + Outp32( PHY_address+0x00A0, 0x0FFF0FFF); + } + else if (ZQ_MODE_DDS == 6) + { + Outp32( PHY_address+0x0040, 0x0E040306); + Outp32( PHY_address+0x00A0, 0x0DB60DB6); + } + else if (ZQ_MODE_DDS == 5) + { + Outp32( PHY_address+0x0040, 0x0D040306); + Outp32( PHY_address+0x00A0, 0x0B6D0B6D); + } + else if (ZQ_MODE_DDS == 4) + { + Outp32( PHY_address+0x0040, 0x0C040306); + Outp32( PHY_address+0x00A0, 0x09240924); + } + else + { + Outp32( PHY_address+0x0040, 0x0F040306); + Outp32( PHY_address+0x00A0 , 0x0FFF0FFF); + } + + // Checking the completion of ZQ calibration + // GOSUB Delay 100ms; GOSUB read &PHY_address+0x0048; zq_done[0]=1 + // GOSUB Delay 100ms; GOSUB read &PHY1_BASE+0x0048; zq_done[0]=1 + while( ( Inp32( PHY_address+0x0048 ) & 0x00000001 ) != 0x00000001 ); // PHY_CON17 zq_done[0]=ZQ Calibration is finished. + + // ZQ calibration exit + data_temp = Inp32( PHY_address+0x0040 ); + data_temp = data_temp&(~0x000FFFFF); + data = data_temp|0x00040304; + Outp32( PHY_address+0x0040, data); // PHY_CON16 zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0 + + // 1. Set DRAM burst length and READ latency + Outp32( PHY_address+0x00AC, 0x0000080C); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + // 2. Set DRAM write latency + Outp32( PHY_address+0x006C, 0x0007000F); // PHY_CON26 T_wrdata_en[20:16]=WL for DDR3 + + // DLL LOCK Setting..! + // Set the DLL lock parameters + // Reserved [31] ctrl_start_point [30:24]=0x10 Reserved [23] ctrl_inc [22:16]=0x10 ctrl_force [14:8] ctrl_start [6]=0x1 ctrl_dll_on [5]=0x1 ctrl_ref [4:1]=0x8 Reserved [0] + // Next Step : Same Operation "CONCONTROL dfi_init_start[28]=1" + // 2012.10.11 + // Outp32( PHY_address+0x0030, 0x10100070); // PHY_CON12 + Outp32( PHY_address+0x0030, 0x10100030); // PHY_CON12, "ctrl_dll_on[6] = 0" + DMC_Delay(20); // PCLK 10 cycle. + + #if 0 + SetBits(0x14000060, 16, 0xF, 0x1); + Outp32(0x14000068, 0x0); + SetBits(0x14000064, 4, 0x1, 0x1); + #endif + + Outp32( PHY_address+0x0030, 0x10100070); // PHY_CON12, "ctrl_start[6] = 1" + DMC_Delay(1); + + //while( ( Inp32( PHY_address+0x0034 ) & 0x00000001 ) != 0x00000001 ); // ctrl_locked[0]=1 + + #if 0 + SetBits(0x14000064, 4, 0x1, 0x0); + #endif + + // 1. Set the Concontrol. At this moment, an auto refresh counter should be off. + // 20120511 :: Change dll lock start point. + Outp32( DREX_address+0x0000, 0x1FFF3000); // CONCONTROL dfi_init_start [28], timeout_level0 [27:16], rd_fetch [14:12], empty [8], aref_en [5], clk_ratio [2:1] + + // 2. Set the MemConfig0 register. If there are two external memory chips, also set the MemConfig1 register. + // LPDDR2_P0_CS0 : 32'h2000_000 ~ 32'h27FF_FFFF (4Gbit) + //Outp32( DREX_address+0x010C, 0x006007E0); // MemBaseConfig0 chip_base[26:16]=0x10, chip_mask[10:0]=0x7E0 + //Outp32( DREX_address+0x0110, 0x008007E0); // MemBaseConfig1 chip_base[26:16]=0x30, chip_mask[10:0]=0x7E0 +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_address+0x0F00; + reg_arr.set0.val = 0x006007C0; + reg_arr.set1.addr = TZASC_address+0x0F04; + reg_arr.set1.val = 0x00A007C0; + reg_arr.set2.addr = TZASC_address+0x0F10; + reg_arr.set2.val = 0x00402423; + reg_arr.set3.addr = TZASC_address+0x0F14; + reg_arr.set3.val = 0x00402423; + + set_secure_reg((u32)®_arr, 4); +#else + Outp32( TZASC_address+0x0F00, 0x006007C0); // MemBaseConfig0 chip_base[26:16]=0x10, chip_mask[10:0]=0x7E0 + Outp32( TZASC_address+0x0F04, 0x00A007C0); // MemBaseConfig1 chip_base[26:16]=0x30, chip_mask[10:0]=0x7E0 + + // 3. Set the MemConfig0 + // chip_map [15:12] Address Mapping Method (AXI to Memory). 0x1 = Interleaved ({row, bank, column, width}) + // chip_col [11:8] Number of Column Address Bits. 0x3 = 10 bits + // chip_row [7:4] Number of Row Address Bits. 0x2 = 14 bits + // chip_bank [3:0] Number of Banks. 0x3 = 8 banks + //Outp32( DREX_address+0x0008, 0x00001323); // MemConfig0 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] + //Outp32( DREX_address+0x000C, 0x00001323); // MemConfig1 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] + Outp32( TZASC_address+0x0F10, 0x00402423); // MemConfig0 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] + Outp32( TZASC_address+0x0F14, 0x00402423); // MemConfig1 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] +#endif + // 4. Set the PrechConfig and PwrdnConfig registers. + // 2013.04.18 :: DREX1_0_3 adding..! + // Outp32( DREX_address+0x0014, 0xFF000000); // PrechConfig tp_cnt[31:24]=Timeout Precharge Cycles. 0xn = n cclk cycles. Refer to chapter 1.6.2 .Timeout precharge + Outp32( DREX_address+0x0014, 0xF0000000); // PrechConfig tp_en[31:28]=Timeout Precharge per Port + Outp32( DREX_address+0x001C, 0xFFFFFFFF); + + // 2013.06.07 :: (0xD) Dynamic PD & Dynamic Self Change..! + // Outp32( DREX_address+0x0028, 0xFFFF00FF); // PwrdnConfig dsref_cyc[31:16]=Number of Cycles for dynamic self refresh entry. 0xn = n aclk cycles. Refer to chapter 1.5.3 . Dynamic self refresh + Outp32( DREX_address+0x0028, 0x1FFF000D); // PwrdnConfig dsref_cyc[31:16]=Number of Cycles for dynamic self refresh entry. 0xn = n aclk cycles. Refer to chapter 1.5.3 . Dynamic self refresh + + // 5. Set the TimingAref, TimingRow, TimingData and TimingPower registers. + // according to memory AC parameters. At this moment, TimingData.w1 and TimingData.r1 + // registers must be programmed according to initial clock frequency. + // 2012.10.10 + // Outp32( DREX_address+0x0030, 0x000000BB); // TimingAref autorefresh counter @24MHz + // Outp32( DREX_address+0x0030, 0x0000005E); // TimingAref autorefresh counter @24MHz + // 2012.12.20 :: 3.875 us * 8192 row = 250us + Outp32( DREX_address+0x0030, 0x0000005D); // TimingAref autorefresh counter @24MHz + + // TimingAref autorefresh counter @24MHz + if (nMEMCLK == 800) { + Outp32( DREX_address+0x0034, 0x345A96D3); // TimingRow + Outp32( DREX_address+0x0038, 0x3630065C); // TimingData + Outp32( DREX_address+0x003C, 0x50380336); // TimingPower + } else if (nMEMCLK == 825) { + Outp32( DREX_address+0x0034, 0x36598692); // TimingRow + Outp32( DREX_address+0x0038, 0x4640065C); // TimingData + Outp32( DREX_address+0x003C, 0x543A0446); // TimingPower + } else { + ; + } + + // If QoS scheme is required, set the QosControl10~15 and QosConfig0~15 registers. + + // 6. Wait until dfi_init_complete become 1. + while( ( Inp32( DREX_address+0x0040 ) & 0x00000008 ) != 0x00000008 ); // PhyStatus dfi_init_complete[3]=1 + + // Outp32( DREX_address+0x0040, 0x00000008); // PhyStatus dfi_init_complete[3]=1 + + // Deasserting the dfi_init_start + // 2012.11.08 :: rd_fetch 3 -> 2 + // 2013.05.14 :: rd_fetch 3@933MHz + Outp32( DREX_address+0x0000, 0x0FFF3000 ); // CONCONTROL dfi_init_start[0]=0 + + // 7. Forcing DLL resynchronization - dfi_ctrlupd_req + Outp32( DREX_address+0x0018, 0x00000008); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=1 + DMC_Delay(20); // Wait for 10 PCLK cycles, PCLK(200MHz=10clock=50ns), DMC_Delay(40us) + Outp32( DREX_address+0x0018, 0x00000000); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=0 + + // 8. calibration & levelings + + //----------------------------------------------- + //- end_levelings_lpddr3_l + //----------------------------------------------- + + // ctrl_atgate = 0 + // T_WrWrCmd [30:24] It controls the interval between Write and Write during DQ Calibration. This value should be always kept by 5'h17. It will be used for debug purpose. + // T_WrRdCmd [19:17] It controls the interval between Write and Read by cycle unit during Write Calibration. It will be used for debug purpose. 3'b111 : tWTR = 6 cycles (=3'b001) + // ctrl_ddr_mode[12:11] 2'b11: LPDDR3 + // ctrl_dfdqs[9] 1b1: differential DQS + Outp32( PHY_address+0x0000, 0x17021A00); // PHY_CON0 byte_rdlvl_en[13]=1, ctrl_ddr_mode[12:11]=01, ctrl_atgate[6]=1, Bit Leveling + + #if 0 // Move..! 2012.11.30 + // 26. Set the ConControl to turn on an auto refresh counter. + // aref_en[5]=Auto Refresh Counter. 0x1 = Enable + // 2012.11.08 :: rd_fetch 3 -> 2 + // 2013.05.14 :: rd_fetch 3@933MHz + if(nMEMCLK == 933) { + Outp32( DREX_address+0x0000, 0x0FFF3128); // CONCONTROL aref_en[5]=1 + } else { + Outp32( DREX_address+0x0000, 0x0FFF2128); // CONCONTROL aref_en[5]=1 + } + #endif + + // 27. If power down modes are required, set the MemControl register. + // bl[22:20]=Memory Burst Length 0x3 = 8 + // mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit + // mem_type[11:8]=Type of Memory 0x7 = LPDDR3 + // dsref_en[5]=Dynamic Self Refresh. 0x1 = Enable. + // dpwrdn_en[1]=Dynamic Power Down. 0x1 = Enable + // clk_stop_en[0]=Dynamic Clock Control. 0x1 = Stops during idle periods. + Outp32( DREX_address+0x0004, 0x00312722); // MemControl bl[22:20]=8, mem_type[11:8]=7, two chip selection + + return; +} + +void DMC_Low_Freqeuncy_Setting(u32 nMEMCLK) +{ + u32 data; + + // Pause Enable..! + // data = Inp32( 0x1003091C ); + // data = data | (0x1<<0); + // Outp32(0x1003091C, data); + + // uBits = (1 << 21) | (3 << 14) |(3 << 12) | (3 << 8); + Outp32( CMU_MEMPART+0x0114, 0x0020F300); // rBPLL_CON1 + + if(nMEMCLK==800) + { + // Lock Time Setting + Outp32(0x10030010, 0x00000258); // PDIV*200 = 3*200 + + // ENABLE(1), MDIV(200), PDIV(3), SDIV(1) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x80C80301); // rBPLL_CON0 BPLL=800MHz(3:200:1) + } + else if (nMEMCLK==825) + { + // //LOCKTIME(P*200(P=4)) + // uBits = 800; + Outp32(0x10030010, 0x00000320); // rXPLL_LOCK + + // //ENABLE(1), MDIV(275), PDIV(4), SDIV(1) + // uBits = (1 << 31) | (275 << 16) | (4 << 8) | (1 << 0); + Outp32(0x10030110, 0x81130401); // rXPLL_CON0 XPLL=825MHz(4:275:1) + } + else if(nMEMCLK==933) + { + // Lock Time Setting + Outp32(0x10030010, 0x00000320); // PDIV*200 = 4*200 + + // ENABLE(1), MDIV(200), PDIV(3), SDIV(1) + // uBits = (1 << 31) | (311 << 16) | (3 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x81370401); // rBPLL_CON0 BPLL=933MHz(4:311:1) + } + else + { + // Lock Time Setting + Outp32(0x10030010, 0x00000258); // PDIV*200 = 3*200 + + // ENABLE(1), MDIV(200), PDIV(3), SDIV(1) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x80C80301); // rBPLL_CON0 BPLL=800MHz(3:200:1) + } + + // PLL locking indication + // 0 = Unlocked + // 1 = Locked + while ((Inp32(0x10030110) & (1 << 29)) == 0); + + // ByPass :: BYPASS = 1, bypass mode is enabled - FOUT=FIN + SetBits(CMU_MEMPART+0x0114, 22, 0x1, 0x1); + + // MUX_MCLK_CDREX(0), BPLL(1) + // uBits = (0 << 4) | (1 << 0); + Outp32( CMU_MEMPART+0x0200, 0x00000001); // rCLK_SRC_CDREX + + // CLK_MUX_STAT_CDREX Check + do { + data = Inp32(0x10030400) & (7 << 0); + }while (data != 0x2); // Opened by cju, 13.01.16 + //}while ((data == 0)||(data > 2)); // Closed by cju, 13.01.16 + + // ByPass :: BYPASS = 1, bypass mode is Disabled - FOUT=BPLL FOUT + SetBits(0x10030114, 22, 0x1, 0x0); + DMC_Delay(200); + + //* Add CLK_DIV_CDREX0, PCLK_CDREX(28:1/2),SCLK_CDREX(24:1/8),ACLK_CDREX1(16:1/2),CCLK_DREX(8:1/2),CLK2X_PHY0(3:1/1) + data=(1<<28)|(15<<24)|(1<<16)|(1<<8)|(0<<3); + Outp32(0x10030500, data); +} + +void DMC_High_Freqeuncy_Setting(u32 nMEMCLK) +{ + u32 data; + + if (nMEMCLK==400) + { + // Lock Time Setting + Outp32(0x10030010, 0x00000258); // PDIV*200 = 3*200 + + // ENABLE(1), MDIV(200), PDIV(3), SDIV(2) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (2 << 0); + Outp32( CMU_MEMPART+0x0110, 0x80C80302); // rBPLL_CON0 BPLL=400MHz(3:200:2) + DMC_Delay(100); + } + else if (nMEMCLK==533) + { + // Lock Time Setting + Outp32(0x10030010, 0x00000258); // PDIV*200 = 3*200 + + // ENABLE(1), MDIV(266), PDIV(3), SDIV(2) + // uBits = (1 << 31) | (266 << 16) | (3 << 8) | (2 << 0); + Outp32( CMU_MEMPART+0x0110, 0x810A0302); // rBPLL_CON0 BPLL=532MHz(3:266:2) + DMC_Delay(100); + } + else if (nMEMCLK==667) + { + // Lock Time Setting + Outp32(0x10030010, 0x00000190); // PDIV*200 = 2*200 + + // ENABLE(1), MDIV(111), PDIV(2), SDIV(1) + // uBits = (1 << 31) | (111 << 16) | (2 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x806F0201); // rBPLL_CON0 BPLL=666MHz(2:111:1) + DMC_Delay(100); + } + else if (nMEMCLK==733) + { + // Lock Time Setting + Outp32(0x10030010, 0x00000190); // PDIV*200 = 2*200 + + // ENABLE(1), MDIV(122), PDIV(2), SDIV(1) + // uBits = (1 << 31) | (122 << 16) | (2 << 8) | (1 << 0); + Outp32( CMU_MEMPART+0x0110, 0x807A0201); // rBPLL_CON0 BPLL=732MHz(2:122:1) + DMC_Delay(100); + } + else if (nMEMCLK==800) + { + // used previous setting + } + else if (nMEMCLK==825) + { + // used previous setting + } + else if (nMEMCLK==933) + { + // used previous setting + } + else if (nMEMCLK==1065) + { + // Lock Time Setting + //Outp32(0x10030010, 0x00000320); // PDIV*200 = 4*200 + + // ENABLE(1), MDIV(355), PDIV(4), SDIV(1) + // uBits = (1 << 31) | (355 << 16) | (4 << 8) | (1 << 0); + // Outp32( CMU_MEMPART+0x0110, 0x81630401); // rBPLL_CON0 BPLL=1065MHz(4:355:1) + // DMC_Delay(100); + } + else + { + } + + // PLL locking indication + // 0 = Unlocked + // 1 = Locked + while ((Inp32(0x10030110) & (1 << 29)) == 0); + + // ACLK_CDREX1_RATIO and CCLK_DREX0_RATIO should always have same + // value to keep synchronization between two DREXs and BUS. + // PCLK_CDREX(1/4), SCLK_CDREX(1/1), ACLK_CDREX1(1/2), CCLK_DREX0(1/2), CLK2X_PHY0(1/1) + // uBits = (3 << 28) | (0 << 24) | (1 << 16) | (1 << 8) | (0 << 3) ; + Outp32( CMU_MEMPART+0x0500, 0x30010100); // rCLK_DIV_CDREX0 + DMC_Delay(100); +} + +void DMC_InitForLPDDR3(u32 nMEMCLK, BOOT_STAT eBootStat) +{ + u32 data; + + /* CORE_MISC */ + // Outp32(0x10CE0050, 0x00000001); + //Outp32(0x10CE0050, 0x00000100); // EVT1 no exist + + /****************************************/ + /***** CA SWAP *****/ + /****************************************/ + if (CA_SWAP == 1) { + CA_swap_lpddr3(DREX1_0); + } + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + DMC_Low_Freqeuncy_Setting(nMEMCLK); + + /****************************************/ + /***** LOW FREQUENCY *****/ + /****************************************/ + Low_frequency_init_lpddr3(PHY0_BASE, DREX1_0); + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + DMC_High_Freqeuncy_Setting(nMEMCLK); + + /****************************************/ + /***** HIGH FREQUENCY *****/ + /****************************************/ + High_frequency_init_lpddr3(PHY0_BASE, DREX1_0, TZASC_0, nMEMCLK); + + #if 1 // Move..! 2012.11.30 + // 26. Set the ConControl to turn on an auto refresh counter. + // aref_en[5]=Auto Refresh Counter. 0x1 = Enable + // 2012.11.08 :: rd_fetch 3 -> 2 + // 2013.04.12 :: Automatic control for ctrl_pd in none read state + // 2013.05.08 :: update_mode[3] :: 0x1 = MC initiated update/acknowledge mode + // 2013.05.14 :: rd_fetch 3@933MHz + Outp32( DREX1_0+0x0000, 0x0FFF31A8); // CONCONTROL aref_en[5]=1 + #endif + + #if 0 + // BRB Space Reservation Setting..! + Outp32( DREX1_0+0x0100, 0x00000033); // BRBRSVCONTROL + Outp32( DREX1_0+0x0104, 0x88588858); // BRBRSVCONFIG + Outp32( DREX1_0+0x00D8, 0x00000000); // QOSCONTROL + Outp32( DREX1_0+0x00C0, 0x00000080); // QOSCONTROL + Outp32( DREX1_0+0x0108, 0x00000001); // BRBQOSCONFIG + #endif + + #ifdef USED_DYNAMIC_AUTO_CLOCK_GATING + // Clock Gating Control Register..! + Outp32( DREX1_0+0x0008, 0x0000001F); + #endif + + Outp32( DREX1_0+0x0018, 0x00000002); + + return; +} + +void DMC_InitForLPDDR3_ReInit(u32 nMEMCLK, BOOT_STAT eBootStat) +{ + u32 data; + + /* CORE_MISC */ + // Outp32(0x10CE0050, 0x00000001); + // Outp32(0x10CE0050, 0x00000100); + + /****************************************/ + /***** CA SWAP *****/ + /****************************************/ + if (CA_SWAP == 1) { + CA_swap_lpddr3(DREX1_0); + } + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + DMC_Low_Freqeuncy_Setting(nMEMCLK); + + /****************************************/ + /***** LOW FREQUENCY *****/ + /****************************************/ + // PHY0+DREX1_0 + Low_frequency_init_lpddr3_ReInit(PHY0_BASE, DREX1_0); + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + DMC_High_Freqeuncy_Setting(nMEMCLK); + + /****************************************/ + /***** HIGH FREQUENCY *****/ + /****************************************/ + // PHY0+DREX1_0 + High_frequency_init_lpddr3(PHY0_BASE, DREX1_0, TZASC_0, nMEMCLK); + + + #if 1 // Move..! 2012.11.30 + // 26. Set the ConControl to turn on an auto refresh counter. + // aref_en[5]=Auto Refresh Counter. 0x1 = Enable + // 2012.11.08 :: rd_fetch 3 -> 2 + // 2013.04.12 :: Automatic control for ctrl_pd in none read state + // 2013.05.08 :: update_mode[3] :: 0x1 = MC initiated update/acknowledge mode + // 2013.05.14 :: rd_fetch 3@933MHz + Outp32( DREX1_0+0x0000, 0x0FFF21A8); // CONCONTROL aref_en[5]=1 + #endif + + #if 0 + // BRB Space Reservation Setting..! + Outp32( DREX1_0+0x0100, 0x00000033); // BRBRSVCONTROL + Outp32( DREX1_0+0x0104, 0x88588858); // BRBRSVCONFIG + Outp32( DREX1_0+0x00D8, 0x00000000); // QOSCONTROL + Outp32( DREX1_0+0x00C0, 0x00000080); // QOSCONTROL + Outp32( DREX1_0+0x0108, 0x00000001); // BRBQOSCONFIG + #endif + + #ifdef USED_DYNAMIC_AUTO_CLOCK_GATING + // Clock Gating Control Register..! + Outp32( DREX1_0+0x0008, 0x0000001F); + #endif + + return; +} + +void dmc_ctrl_init(void) +{ + u32 eBootStat; + u32 nMEMCLK; + + nMEMCLK = CONFIG_MEMCLK; + eBootStat = __REG(EXYNOS5_POWER_BASE + INFORM1_OFFSET); + + DMC_InitForLPDDR3(nMEMCLK, eBootStat); +} + +void dmc_ctrl_init_resume(void) +{ + u32 eBootStat; + u32 nMEMCLK; + + nMEMCLK = CONFIG_MEMCLK; + eBootStat = __REG(EXYNOS5_POWER_BASE + INFORM1_OFFSET); + + DMC_InitForLPDDR3_ReInit(nMEMCLK, eBootStat); +} diff --git a/board/samsung/smdk5412/lowlevel_init.S b/board/samsung/smdk5412/lowlevel_init.S new file mode 100644 index 000000000..4ef13d415 --- /dev/null +++ b/board/samsung/smdk5412/lowlevel_init.S @@ -0,0 +1,289 @@ +/* + * Lowlevel setup for SMDK5412 board based on EXYNOS5 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + + .globl lowlevel_init +lowlevel_init: + /* PS-HOLD high */ + ldr r0, =0x1004330C + mov r1, #0x5300 + str r1, [r0] +#if defined(CONFIG_MACH_UNIVERSAL5412) + ldr r0, =0x13400C48 + mov r1, #0x0 + str r1, [r0] +#endif + + /* enable WAS */ + ldr r0, =0x10011008 + ldr r1, [r0] + orr r1, r1, #0x1000 + str r1, [r0] + + /* use iRAM stack in bl2 */ + ldr sp, =CONFIG_IRAM_STACK + stmdb r13!, {ip,lr} + + bl relocate_nscode + + /* check reset status */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + + /* AFTR wakeup reset */ + ldr r2, =S5P_CHECK_DIDLE + cmp r1, r2 + beq exit_wakeup + + /* LPA wakeup reset */ + ldr r2, =S5P_CHECK_LPA + cmp r1, r2 + beq exit_wakeup + + /* Sleep wakeup reset */ + ldr r2, =S5P_CHECK_SLEEP + cmp r1, r2 + beq wakeup_reset + +#ifdef CONFIG_PM + bl pmic_init +#endif + + bl read_om + + /* + * If U-boot is already running in RAM, no need to relocate U-Boot. + * Memory controller must be configured before relocating U-Boot + * in ram. + */ + ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ + bic r1, pc, r0 /* pc <- current addr of code */ + /* r1 <- unmasked bits of pc */ + ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ + bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ + cmp r1, r2 /* compare r1, r2 */ + beq 1f /* r0 == r1 then skip sdram init */ + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl dmc_ctrl_init + bl wdmc_ctrl_init + +#if defined(CONFIG_TZPC) + bl tzpc_init +#endif + +1: + ldmia r13!, {ip,pc} + +wakeup_reset: + bl read_om + + /* If eMMC booting */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl dmc_ctrl_init_resume + bl wdmc_ctrl_init_resume + bl pad_retention_release + + /* W/A for abnormal MMC interrupt */ + ldr r0, =0x1220009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + ldr r0, =0x1221009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + ldr r0, =0x1222009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + +exit_wakeup: + b warmboot + +read_om: + /* Read booting information */ + ldr r0, =(EXYNOS5_POWER_BASE + OM_STATUS_OFFSET) + ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* NOR BOOT */ + cmp r2, #0x1A + moveq r3, #BOOT_EMMC_4_4 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC BOOT */ + cmp r2, #0x6 + moveq r3, #BOOT_EMMC + + /* eMMC 4.4 BOOT */ + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x28 + moveq r3, #BOOT_EMMC_4_4 +#if defined(CONFIG_MACH_UNIVERSAL5412) + cmp r2, #0x22 + moveq r3, #BOOT_EMMC_4_4 +#endif + + ldr r0, =(EXYNOS5_POWER_BASE + INFORM3_OFFSET) + str r3, [r0] + + mov pc, lr + +/* + * Relocate code + */ +relocate_nscode: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + .word 0xF57FF04F @dsb sy + .word 0xF57FF06F @isb sy + + mov pc, lr + .ltorg + +/* + * CPU1 waits here until CPU0 wake it up. + * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory. + */ +nscode_base: + b 1f + nop @ for backward compatibility + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 +_switch_addr: + .word 0x0 @ REG4: SWITCH_ADDR +_hotplug_addr: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6 +_c2_addr: + .word 0x0 @ REG7: REG_C2_ADDR +_cpu_state: + .word 0x1 @ CPU0_STATE : RESET + .word 0x2 @ CPU1_STATE : SECONDARY RESET + .word 0x2 @ CPU2_STATE : SECONDARY RESET + .word 0x2 @ CPU3_STATE : SECONDARY RESET +_gic_state: + .word 0x0 @ CPU0 - GICD_IGROUPR0 + .word 0x0 @ CPU1 - GICD_IGROUPR0 + .word 0x0 @ CPU2 - GICD_IGROUPR0 + .word 0x0 @ CPU3 - GICD_IGROUPR0 + +#define RESET (1 << 0) +#define SECONDARY_RESET (1 << 1) +#define HOTPLUG (1 << 2) +#define C2_STATE (1 << 3) +#define SWITCH (1 << 4) + +1: + adr r0, _cpu_state + + mrc p15, 0, r7, c0, c0, 5 @ read MPIDR + and r7, r7, #0xf @ r7 = cpu id + + /* read the current cpu state */ + ldr r10, [r0, r7, lsl #2] + + /* HYP entry */ + + /* + * Set the HYP spsr to itself, so that the entry point + * does not see the difference between a function call + * and an exception return. + */ + mrs r4, cpsr + msr spsr_cxsf, r4 + + bic r6, r4, #0x1f + orr r6, r6, #0x13 + msr spsr_cxsf, r6 /* Setup SPSR to jump to NS SVC mode */ + add r4, pc, #12 + .word 0xe12ef304 /* msr elr_hyp, r4 */ + .word 0xF57FF04F /* dsb sy */ + .word 0xF57FF06F /* isb sy */ + .word 0xe160006e /* ERET */ +ns_svc_entry: + nop + tst r10, #SWITCH + adrne r0, _switch_addr + bne wait_for_addr + tst r10, #C2_STATE + adrne r0, _c2_addr + bne wait_for_addr + + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + cmp r1, #0x0 + movne r1, #0x0 + strne r1, [r0] + ldrne r1, =(EXYNOS5_POWER_BASE + INFORM0_OFFSET) + ldrne pc, [r1] + + tst r10, #RESET + ldrne pc, =CONFIG_SYS_TEXT_BASE + + adr r0, _hotplug_addr +wait_for_addr: + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + wfe + b wait_for_addr + .ltorg +nscode_end: diff --git a/board/samsung/smdk5412/mmc_boot.c b/board/samsung/smdk5412/mmc_boot.c new file mode 100644 index 000000000..698d8f363 --- /dev/null +++ b/board/samsung/smdk5412/mmc_boot.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> + +#define SDMMC_SECOND_DEV 0x28 +#define SIGNATURE_CHECK_FAIL -1 +#define SECOND_BOOT_MODE 0xFEED0002 + +/* +* Copy U-boot from mmc to RAM: +* COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains +* Pointer to API (Data transfer from mmc to ram) +*/ + +static int find_second_boot_dev(void) +{ + unsigned int om_status = readl(EXYNOS5_POWER_BASE + OM_STATUS_OFFSET); + + om_status &= 0x3E; + + writel(0x1, CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (om_status == SDMMC_SECOND_DEV) + return BOOT_SEC_DEV; + else + while (1); + + return 0; +} + +void copy_uboot_to_ram(unsigned int boot_dev) +{ + int ret = 0; + + switch (boot_dev) { + case BOOT_MMCSD: + case BOOT_SEC_DEV: + boot_dev = SDMMC_CH2; + break; + case BOOT_EMMC_4_4: + boot_dev = EMMC; + break; + case BOOT_USB: + boot_dev = USB; + break; + } + /* Load u-boot image to ram */ + ret = load_uboot_image(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) { + sdmmc_enumerate(); + if (find_second_boot_dev() == BOOT_SEC_DEV) + boot_dev = SDMMC_CH2; + ret = load_uboot_image(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) + while (1); + } + + /* Load tzsw image & U-Boot boot */ + ret = coldboot(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) { + sdmmc_enumerate(); + if (find_second_boot_dev() == BOOT_SEC_DEV) + boot_dev = SDMMC_CH2; + ret = coldboot(boot_dev); + if (ret == SIGNATURE_CHECK_FAIL) + while (1); + } +} + +void load_uboot(void) +{ + unsigned int om_status = readl(EXYNOS5_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + + /* TODO : find second boot function */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + copy_uboot_to_ram(boot_dev); +} + +void board_init_f(unsigned long bootflag) +{ + __attribute__((noreturn)) void (*uboot)(void); + load_uboot(); +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /* Function attribute is no-return */ + /* This Function never executes */ + while (1) + ; +} + +void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} diff --git a/board/samsung/smdk5412/pmic.c b/board/samsung/smdk5412/pmic.c new file mode 100644 index 000000000..7b015baa4 --- /dev/null +++ b/board/samsung/smdk5412/pmic.c @@ -0,0 +1,293 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/pmic.h> +#include <asm/arch/cpu.h> + +void Delay(void) +{ + unsigned long i; + for (i = 0; i < DELAY; i++) + ; +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + /* Function <- Input */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPD1DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + ack = (ack>>0)&0x1; + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + /* Function <- Output */ + IIC0_ESDA_OUTP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + /* Function <- Input (SDA) */ + IIC0_ESDA_INP; + + IIC0_SCLL_SDAL(); +} + +void IIC0_ESetport(void) +{ + /* Pull Up/Down Disable SCL, SDA */ + GPD1PUD &= ~(0xf<<0); + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + /* Function <- Output (SCL) */ + IIC0_ESCL_OUTP; + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + Delay(); +} + +void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. data. */ + for (i = 8; i > 0; i--) { + if ((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EEnd(); +} + +void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* read */ + IIC0_EHigh(); + /* ACK */ + IIC0_EAck_write(); + + /* read reg. data. */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for (i = 8; i > 0; i--) { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPD1DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + reg = (reg >> 0) & 0x1; + + data |= reg << (i-1); + } + + /* ACK */ + IIC0_EAck_read(); + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + +void pmic_init(void) +{ + float vdd_arm, vdd_kfc; + float vdd_int, vdd_g3d, vdd_mif; + + vdd_arm = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_ARM); + vdd_kfc = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_KFC); + vdd_mif = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_MIF); + vdd_int = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_INT); + vdd_g3d = CONFIG_PM_CALC_VOLT(CONFIG_PM_VDD_G3D); + + IIC0_ESetport(); + /* BUCK2 VDD_ARM */ + IIC0_EWrite(0xcc, 0x28, vdd_arm); + /* BUCK6 VDD_KFC */ + IIC0_EWrite(0xcc, 0x34, vdd_kfc); + /* BUCK1 VDD_MIF */ + IIC0_EWrite(0xcc, 0x26, vdd_mif); + /* BUCK3 VDD_INT */ + IIC0_EWrite(0xcc, 0x2a, vdd_int); + /* BUCK4 VDD_G3D */ + IIC0_EWrite(0xcc, 0x2c, vdd_g3d); +} diff --git a/board/samsung/smdk5412/setup.h b/board/samsung/smdk5412/setup.h new file mode 100644 index 000000000..4d4a41c1f --- /dev/null +++ b/board/samsung/smdk5412/setup.h @@ -0,0 +1,66 @@ +/* + * Machine Specific Values for SMDK5412 board based on EXYNOS5 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 _SMDK5412_SETUP_H +#define _SMDK5412_SETUP_H + +#include <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* TZPC : Register Offsets */ +#define TZPC0_BASE 0x10100000 +#define TZPC1_BASE 0x10110000 +#define TZPC2_BASE 0x10120000 +#define TZPC3_BASE 0x10130000 +#define TZPC4_BASE 0x10140000 +#define TZPC5_BASE 0x10150000 +#define TZPC6_BASE 0x10160000 +#define TZPC7_BASE 0x10170000 +#define TZPC8_BASE 0x10180000 +#define TZPC9_BASE 0x10190000 +#define TZPC10_BASE 0x100E0000 +#define TZPC11_BASE 0x100F0000 + +/* + * TZPC Register Value : + * R0SIZE: 0x0 : Size of secured ram + */ +#define R0SIZE 0x0 + +/* + * TZPC Decode Protection Register Value : + * DECPROTXSET: 0xFF : Set Decode region to non-secure + */ +#define DECPROTXSET 0xFF + +void sdelay(unsigned long); +void dmc_ctrl_init(void); +void wdmc_ctrl_init(void); +void dmc_ctrl_init_resume(void); +void wdmc_ctrl_init_resume(void); +void pad_retention_release(void); +void system_clock_init(void); +extern unsigned int second_boot_info; +#endif diff --git a/board/samsung/smdk5412/smc.c b/board/samsung/smdk5412/smc.c new file mode 100644 index 000000000..feca083ce --- /dev/null +++ b/board/samsung/smdk5412/smc.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <asm/arch/smc.h> + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1) + + ); + + return reg1; +} + + +unsigned int load_uboot_image(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_SYS_TEXT_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_SYS_TEXT_BASE; + + } + + info_image->image_base_addr = CONFIG_PHY_UBOOT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->signature_size = SMC_UBOOT_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, 0); +#else + if (boot_device == SDMMC_CH2) { + + u32 (*copy_uboot)(u32, u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + SDMMC_DEV_OFFSET); + + copy_uboot(MOVI_UBOOT_POS, + MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } else if (boot_device == EMMC) { + + u32 (*copy_uboot)(u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + EMMC_DEV_OFFSET); + + copy_uboot(MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } + +#endif +} + +unsigned int coldboot(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } + + return exynos_smc(SMC_CMD_COLDBOOT, boot_device, + CONFIG_IMAGE_INFO_BASE, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*uboot)(void); + + /* Jump to U-Boot image */ + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); +#endif + /* Never returns Here */ +} + +void warmboot(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*wakeup_kernel)(void); + + /* Jump to kernel for wakeup */ + wakeup_kernel = (void *)readl(EXYNOS5_POWER_BASE + INFORM0_OFFSET); + (*wakeup_kernel)(); + /* Never returns Here */ +#endif +} + +unsigned int find_second_boot(void) +{ +#if defined(CONFIG_SMC_CMD) + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT); +#else + return readl(IROM_FNPTR_BASE + SECCOND_BOOT_INFORM_OFFSET); +#endif +} + +void emmc_endbootop(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +#else + +#endif +} + +void sdmmc_enumerate(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_SDMMC_ENUMERATE, 0, 0, 0); +#else + +#endif +} + +void set_secure_reg(u32 reg_val, u32 num) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_SET_SECURE_REG, reg_val, num, 0); +#else + +#endif +} diff --git a/board/samsung/smdk5412/smdk5412.c b/board/samsung/smdk5412/smdk5412.c new file mode 100644 index 000000000..427e15dee --- /dev/null +++ b/board/samsung/smdk5412/smdk5412.c @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/sromc.h> +#include <asm/arch/pmic.h> +#include <asm/arch/sysreg.h> + +#define DEBOUNCE_DELAY 10000 + +#define PRODUCT_ID (0x10000000 + 0x000) +#define PKG_ID (0x10000000 + 0x004) + +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define GetBits(uAddr, uBaseBit, uMaskValue) \ + ((Inp32(uAddr)>>(uBaseBit))&(uMaskValue)) +#define GetEvtNum() (GetBits(PRODUCT_ID, 4, 0xf)) +#define GetEvtSubNum() (GetBits(PRODUCT_ID, 0, 0xf)) +#define GetPopOption() (GetBits(PKG_ID, 4, 0x3)) +#define GetDdrType() (GetBits(PKG_ID, 14, 0x1)) + +DECLARE_GLOBAL_DATA_PTR; +unsigned int pmic; + +#ifdef CONFIG_SMC911X +static int smc9115_pre_init(void) +{ + u32 smc_bw_conf, smc_bc_conf; + int err; + + /* Ethernet needs data bus width of 16 bits */ + smc_bw_conf = SROMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK) + | SROMC_BYTE_ENABLE(CONFIG_ENV_SROM_BANK); + + smc_bc_conf = SROMC_BC_TACS(0x01) | SROMC_BC_TCOS(0x01) + | SROMC_BC_TACC(0x06) | SROMC_BC_TCOH(0x01) + | SROMC_BC_TAH(0x0C) | SROMC_BC_TACP(0x09) + | SROMC_BC_PMC(0x01); + + /* Select and configure the SROMC bank */ + err = exynos_pinmux_config(PERIPH_ID_SROMC, + CONFIG_ENV_SROM_BANK | PINMUX_FLAG_16BIT); + if (err) { + debug("SROMC not configured\n"); + return err; + } + + s5p_config_sromc(CONFIG_ENV_SROM_BANK, smc_bw_conf, smc_bc_conf); + return 0; +} +#endif + +static void display_bl1_version(void) +{ + char bl1_version[9] = {0}; + + /* display BL1 version */ +#if defined(CONFIG_TRUSTZONE_ENABLE) + printf("\nTrustZone Enabled BSP"); + strncpy(&bl1_version[0], (char *)(CONFIG_PHY_IRAM_NS_BASE + 0x810), 8); + printf("\nBL1 version: %s\n", &bl1_version[0]); +#endif +} + +static void display_pmic_info(void) +{ + unsigned char read_vol_arm; + unsigned char read_vol_int; + unsigned char read_vol_g3d; + unsigned char read_vol_mif; + unsigned char pmic_id; + +} + +static void display_boot_device_info(void) +{ + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; + int OmPin; + + OmPin = readl(&pmu->inform3); + + printf("\nChecking Boot Mode ..."); + + if (OmPin == BOOT_MMCSD) + printf(" SDMMC\n"); + else if (OmPin == BOOT_EMMC) + printf(" EMMC\n"); + else if (OmPin == BOOT_EMMC_4_4) + printf(" EMMC\n"); + else + printf(" Please check OM_pin\n"); +} + +int board_init(void) +{ + display_bl1_version(); + + display_pmic_info(); + + display_boot_device_info(); + + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE) + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE) + + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE) + + get_ram_size((long *)PHYS_SDRAM_9, PHYS_SDRAM_9_SIZE) + + get_ram_size((long *)PHYS_SDRAM_10, PHYS_SDRAM_10_SIZE) + + get_ram_size((long *)PHYS_SDRAM_11, PHYS_SDRAM_11_SIZE) + + get_ram_size((long *)PHYS_SDRAM_12, PHYS_SDRAM_12_SIZE); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, + PHYS_SDRAM_4_SIZE); + gd->bd->bi_dram[4].start = PHYS_SDRAM_5; + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5, + PHYS_SDRAM_5_SIZE); + gd->bd->bi_dram[5].start = PHYS_SDRAM_6; + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6, + PHYS_SDRAM_6_SIZE); + gd->bd->bi_dram[6].start = PHYS_SDRAM_7; + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7, + PHYS_SDRAM_7_SIZE); + gd->bd->bi_dram[7].start = PHYS_SDRAM_8; + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8, + PHYS_SDRAM_8_SIZE); + gd->bd->bi_dram[8].start = PHYS_SDRAM_9; + gd->bd->bi_dram[8].size = get_ram_size((long *)PHYS_SDRAM_9, + PHYS_SDRAM_9_SIZE); + gd->bd->bi_dram[9].start = PHYS_SDRAM_10; + gd->bd->bi_dram[9].size = get_ram_size((long *)PHYS_SDRAM_10, + PHYS_SDRAM_10_SIZE); + gd->bd->bi_dram[10].start = PHYS_SDRAM_11; + gd->bd->bi_dram[10].size = get_ram_size((long *)PHYS_SDRAM_11, + PHYS_SDRAM_11_SIZE); + gd->bd->bi_dram[11].start = PHYS_SDRAM_12; + gd->bd->bi_dram[11].size = get_ram_size((long *)PHYS_SDRAM_12, + PHYS_SDRAM_12_SIZE - CONFIG_UBOOT_ATAG_RESERVED_DRAM); +} + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_SMC911X + if (smc9115_pre_init()) + return -1; + return smc911x_initialize(0, CONFIG_SMC911X_BASE); +#endif + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + printf("\nBoard: SMDK5412\n"); + + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; + int err, OmPin; + + OmPin = readl(&pmu->inform3); + + err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); + if (err) { + debug("SDMMC2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); + if (err) { + debug("MSHC0 not configured\n"); + return err; + } + + switch (OmPin) { + case BOOT_EMMC_4_4: +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 0); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 0); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif + break; + default: +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif + break; + } + + return err; +} +#endif + +static int board_uart_init(void) +{ + int err; + + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE); + if (err) { + debug("UART0 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE); + if (err) { + debug("UART1 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE); + if (err) { + debug("UART2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); + if (err) { + debug("UART3 not configured\n"); + return err; + } + + return 0; +} + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f(void) +{ + return board_uart_init(); +} +#endif + +int board_late_init(void) +{ + struct exynos5_power *pmu = (struct exynos5_power *)EXYNOS5_POWER_BASE; +#ifdef CONFIG_RAMDUMP_MODE + struct exynos5_gpio_part1 *gpio1 = + (struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1(); + unsigned int gpio_debounce_cnt = 0; + int err; + + err = exynos_pinmux_config(PERIPH_ID_INPUT_X0_0, PINMUX_FLAG_NONE); + if (err) { + debug("GPX0_0 INPUT not configured\n"); + return err; + } + + while (s5p_gpio_get_value(&gpio1->x0, 0) == 0) { + /* wait for 50ms */ + if (gpio_debounce_cnt < 5) { + udelay(DEBOUNCE_DELAY); + gpio_debounce_cnt++; + } else { + setenv("bootcmd", CONFIG_BOOTCOMMAND_RAMDUMP); + break; + } + } +#endif +#ifdef CONFIG_RECOVERY_MODE + u32 second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (second_boot_info == 1) { + printf("###Recovery Mode###\n"); + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + setenv("bootcmd", CONFIG_RECOVERYCOMMAND); + } +#endif + + if ((readl(&pmu->sysip_dat0)) == CONFIG_FACTORY_RESET_MODE) { + writel(0x0, &pmu->sysip_dat0); + setenv("bootcmd", CONFIG_FACTORY_RESET_BOOTCOMMAND); + } + + return 0; +} + +unsigned int get_board_rev(void) +{ + unsigned int rev = 0; + unsigned int board_rev_info; + + board_rev_info = rev | pmic; + + return board_rev_info; +} diff --git a/board/samsung/smdk5412/tzpc_init.c b/board/samsung/smdk5412/tzpc_init.c new file mode 100644 index 000000000..1b0127d3b --- /dev/null +++ b/board/samsung/smdk5412/tzpc_init.c @@ -0,0 +1,45 @@ +/* + * Lowlevel setup for SMDK5412 board based on EXYNOS5 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <asm/arch/tzpc.h> +#include"setup.h" + +/* Setting TZPC[TrustZone Protection Controller] */ +void tzpc_init(void) +{ + struct exynos_tzpc *tzpc; + unsigned int addr; + + for (addr = TZPC0_BASE; addr <= TZPC11_BASE; addr += TZPC_BASE_OFFSET) { + tzpc = (struct exynos_tzpc *)addr; + + if (addr == TZPC0_BASE) + writel(R0SIZE, &tzpc->r0size); + + writel(DECPROTXSET, &tzpc->decprot0set); + writel(DECPROTXSET, &tzpc->decprot1set); + writel(DECPROTXSET, &tzpc->decprot2set); + writel(DECPROTXSET, &tzpc->decprot3set); + } +} diff --git a/board/samsung/smdk5412/wdmc_init.c b/board/samsung/smdk5412/wdmc_init.c new file mode 100644 index 000000000..7dba13bfc --- /dev/null +++ b/board/samsung/smdk5412/wdmc_init.c @@ -0,0 +1,385 @@ +/* + * Memory setup for SMDK5412 board based on EXYNOS5 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/smc.h> + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define SetBits(uAddr, uBaseBit, uMaskValue, uSetValue) \ + Outp32(uAddr, (Inp32(uAddr) & ~((uMaskValue)<<(uBaseBit))) \ + | (((uMaskValue)&(uSetValue))<<(uBaseBit))) + +//////////////////////////////////////////////////////////////////////////////// +/// +/// Added by moonki.jun +/// +//////////////////////////////////////////////////////////////////////////////// +typedef enum __REMAP_CASE{ + REMAP_CASE_1 = 0, + REMAP_CASE_2 = 1, + REMAP_CASE_3 = 2 +} REMAP_CASE; + +#define CA_SWAP 0 +#define NUM_CHIP 1 +#define ZQ_MODE_DDS 7 +#define PERFORM_LEVELING 0 +//#define PHY0_BASE 0x10C00000 +//#define PHY1_BASE 0x10C10000 +//#define DREX1_0 0x10C20000 +//#define DREX1_1 0x10C30000 +#define CMU_COREPART 0x10010000 +#define CMU_TOPPART 0x10020000 +#define CMU_MEMPART 0x10030000 +#define TZASC_0 0x10D40000 +#define TZASC_1 0x10D50000 +#define WIDEIO_PHY0 0x10F00000 +#define WIDEIO_PHY1 0x10F40000 +#define WIDEIO_PHY2 0x10F80000 +#define WIDEIO_PHY3 0x10FC0000 +#define WDREX0 0x10F10000 +#define WDREX1 0x10F50000 +#define WDREX2 0x10F90000 +#define WDREX3 0x10FD0000 + +#define WIO_GATE_TRAINING 0 + +#if 0 /* In EVT1, REMAP register is removed.*/ +static void remap_memory(u32 remap_case) +{ + if (remap_case == REMAP_CASE_1) { + /* EVT0 TSV: wideIO 1G + LPDDR3 1G */ + Outp32(0x10CE0050, 0x00000100); + } else if (remap_case == REMAP_CASE_2) { + /* EVT0 SCP: LPDDR3 2G */ + Outp32(0x10CE0050, 0x00000001); + } else { + /* n/a */ + ; + } +} +#endif + +static void init_wideIO_sdr(u32 PHY_address, u32 DREX_address, u32 wioFreq, u32 init_DRAM) +{ +#if defined(CONFIG_SMC_CMD) + reg_arr_t reg_arr; +#endif + u32 data; + + /* MEMCONTROL + bl=1 (burst length 2), mem_width=4 (128-bit), clk_stop_en=0 (if CGCONTROL is set to save power, this bit should be zero.) + */ + Outp32(DREX_address+0x0004, 0x00104000); + + /* MEMCONFIG0 + bank_interleave on, col_address=7bits, row_address=15bits, bank=4 + */ +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = DREX_address+0x10F10; + reg_arr.set0.val = 0x00001032; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(DREX_address+0x10F10, 0x00001032); +#endif + + /* PHYCONTROL0 + drv_bus_en=1 + */ + Outp32(DREX_address+0x0018, 0x00000004); + + /* TIMINGAREF + Need to set tREFI for hot temp. compensation - 1/2 tREFI (0x5D = 3.9us x 24MHz so, 1/2 * 0x5D = 0x2E) + */ + Outp32( DREX_address+0x0030, 0x0000002E); + + /* TIMING + For WDREX clk 266MHz (1tCLK=3.75ns) + TIMINGROW: t_rfc = 210 ns, t_rrd = 10 ns, t_rp = 18 ns, t_rcd = 18ns, t_rc = 60 ns, t_ras = 42 ns + */ + + if (wioFreq == 266) { + Outp32(DREX_address+0x0034, 0x3835540C); //0x3835540C + // TIMINGDATA: t_wtr = 15 ns, t_wr = 15 ns, trtp = 2, t_srr = 2, dqsck = 2, wl = 1, t_src = 7, rl = 3 + Outp32(DREX_address+0x0038, 0x44300123); //0x44222173 + // TIMINGPOWER: t_faw = 50 ns, t_xsr = 220 ns, t_xp = 10 ns, t_cke = 3, t_mrd = 2 + Outp32(DREX_address+0x003C, 0x383B0332); //0x383B0332 + } else { + ; + } + + /* MEMBASECONFIG + : dram_base=0x2000_0000, dram_siz=256M --> chip_base=0x08, chip_mask=0x7f0 + */ +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = DREX_address+0x10F00; + reg_arr.set0.val = 0x000807F0; + + set_secure_reg((u32)®_arr, 1); +#else + Outp32(DREX_address+0x10F00, 0x000807F0); +#endif + + if (init_DRAM) { + /* DRAMNOPCTRL + For WDREX clk 266MHz (1tCLK=3.75ns) + .assert NOP, wait for tINIT5 + .tINIT5 min. should be 200us. Thus 200us/1tCLK = 200us/3.75ns = 53333.33.. + */ + Outp32(PHY_address+0x0074, 0x000D0FC1); + while(( Inp32(PHY_address+0x0074) & 0x00000001 ) != 0x00000001); + + /* DRAMMRSCTRL + */ + // wideIO mode register setting, WL=1, RL=3, BL=2 + Outp32(PHY_address+0x0078, 0x20001311); + while((Inp32(PHY_address+0x0078) & 0x00000001 ) != 0x00000001); + // wideIO mode register setting, nWR=3, drive_strength=weak, thermal_offset=5~15 + Outp32(PHY_address+0x0078, 0x22002211); + //Outp32(PHY_address+0x0078, 0x22001011); // drive_strength=strong + while((Inp32(PHY_address+0x0078) & 0x00000001 ) != 0x00000001); + + if (WIO_GATE_TRAINING) { + /* STARTPOINT + */ + Outp32(PHY_address+0x0018, 0x00000010); + + /* INC + */ + Outp32(PHY_address+0x0020, 0x00000010); + + Outp32(PHY_address+0x002C, 0x00000001); // DLLON - DLL clock enable + Outp32(PHY_address+0x0024, 0x00000001); // START - DLL lock start + while((Inp32(PHY_address+0x0054) & 0x00000007) != 0x00000007); // LOCKSTATUS - DLL lock check + + Outp32(PHY_address+0x0070, 0x00000002); // PHYFASTINIT - gate trainig + while((Inp32(PHY_address+0x0070) & 0x00000002) != 0x00000002); // check gate training completion + + Outp32(PHY_address+0x002C, 0x00000000); // DLLON - DLL clock disable + + // Outp32(DREX_address+0x0018, 0x20000004); + Outp32(DREX_address+0x0018, 0x00000004); + + /* GATEDURATION + : gate duration=1, butst_length(2)-1 + */ + Outp32(PHY_address+0x00e4, 0x00000001); + } + + /* Dummy read for EVT1 WIO DRAM + Venus EVT1 WIO DRAM has non-high-z DQS state, to eliminate the need of gate training while DVFS, + and which is enabled after a READ operation. (ACT->READ->PRECH) + */ + { + // direct cmd - ACT + Outp32(PHY_address+0x007C, 0x000000C1); + while((Inp32(PHY_address+0x007C) & 0x00000001) != 0x00000001); + // direct cmd - READ + Outp32(PHY_address+0x006C, 0x53000001); + while((Inp32(PHY_address+0x006C) & 0x00000001) != 0x00000001); + // direct cmd - PRECH + Outp32(PHY_address+0x0080, 0x00800011); + while((Inp32(PHY_address+0x0080) & 0x00000001) != 0x00000001); + + // resync + Outp32(PHY_address+0x0034, 0x00000001); + Outp32(PHY_address+0x0034, 0x00000000); + } + } + /* DRAMCOMMANDSEL + : DREX takes over the DRAM control + */ + Outp32(PHY_address+0x0068, 0x00000000); + + /* CONCONTROL + : auto refresh enable + */ + Outp32(DREX_address+0x0000, 0x0FFF1028); + + /* CGCONTROL + DREX dynamic clock gating control (added in EVT1 WDREX 2.0.3) + */ + Outp32(DREX_address+0x0008, 0x0000001F); +} + +void enable_bypass_pll() +{ + u32 data; + + #if 0 + /* For Venus EVT0 - MPLL_CON1 */ + data = Inp32(0x10014104); + data=data&(~0x400000); + data=data|(0x400000); + Outp32(0x10014104, data); + Delay(100*1000); + #else + /* For Venus EVT1 - TPLL_CON1 */ + data = Inp32(0x10020194); + data=data&(~0x400000); + data=data|(0x400000); + Outp32(0x10020194, data); + #endif +} + +void disable_bypass_pll() +{ + u32 data; + + #if 0 + /* For Venus EVT0 -MPLL_CON1 */ + data = Inp32(0x10014104); + data=data&(~0x400000); + Outp32(0x10014104, data); + #else + /* For Venus EVT0 - TPLL_CON1 */ + data = Inp32(0x10020194); + data=data&(~0x400000); + Outp32(0x10020194, data); + #endif +} + + void wdmc_ctrl_init(void) +{ + u32 data; + u32 uFreq; + + /* CMU setting for WDREX + */ + ; + + /* Memory usage policy for Venus + .REMAP_CASE_1: LPDDR3 1G + WideIO SDR 1G (evt0 TSV, evt1) + .REMAP_CASE_2: LPDDR3 2G (evt0 SCP) + */ + /* In EVT1, REMAP register is removed.*/ + //remap_memory(REMAP_CASE_1); + + /* DRAM reset + : WideIO SDR reset should be done by WDREX ch1. + */ + // Enable bypass MPLL - DRAM reset should be performed along with low frequency + enable_bypass_pll(); + + /* USEATGATEGEN + : automatic gate generation disable by mhjang : for re-initializing + */ + //Outp32(WIDEIO_PHY0+0x00e0, 0x00000000); + //Outp32(WIDEIO_PHY1+0x00e0, 0x00000000); + //Outp32(WIDEIO_PHY2+0x00e0, 0x00000000); + //Outp32(WIDEIO_PHY3+0x00e0, 0x00000000); + + Outp32(WIDEIO_PHY0+0x0068, 0x00000001); // PHY wrapper takes over the DRAM control for DRAM/PHY initialization + Outp32(WIDEIO_PHY2+0x0068, 0x00000001); + Outp32(WIDEIO_PHY3+0x0068, 0x00000001); + Outp32(WIDEIO_PHY1+0x0068, 0x00000001); + + // Reset control order on channels is suggested as ch0->ch2->ch3->ch1 + Outp32(WIDEIO_PHY0+0x0050, 0x00050001); // tINIT3 = 0x5000, De-assert RESET signal to DRAM + Outp32(WIDEIO_PHY2+0x0050, 0x00050001); + Outp32(WIDEIO_PHY3+0x0050, 0x00050001); + Outp32(WIDEIO_PHY1+0x0050, 0x00050001); + while(( Inp32( WIDEIO_PHY1+0x0050 ) & 0x00000001 ) != 0x00000001); + + // Disable bypass MPLL - DRAM reset should be performed along with low frequency + disable_bypass_pll(); + + /* Initialize wideIO SDR + : WDREX channel initialization sequency is recommended as follows. ch0->ch1->ch2->ch3 + */ + uFreq = 266; + init_wideIO_sdr(WIDEIO_PHY0, WDREX0, uFreq, 1); + init_wideIO_sdr(WIDEIO_PHY1, WDREX1, uFreq, 1); + init_wideIO_sdr(WIDEIO_PHY2, WDREX2, uFreq, 1); + init_wideIO_sdr(WIDEIO_PHY3, WDREX3, uFreq, 1); +} + +void wdmc_ctrl_init_resume(void) +{ + u32 data; + u32 uFreq; + + /* CMU setting for WDREX + */ + + /* Memory usage policy for Venus + .REMAP_CASE_1: LPDDR3 1G + WideIO SDR 1G (evt0 TSV, evt1) + .REMAP_CASE_2: LPDDR3 2G (evt0 SCP) + */ + /* In EVT1, REMAP register is removed.*/ + //remap_memory(REMAP_CASE_1); + + #if 1 + /* In this routine, we want to initialize DREX only. DRAM should not be initialized. + But, here, we have to assert DRAM reset as well, because Venus DRAM reset control also resets PHY FSM. + */ + /* DRAM reset + : WideIO SDR reset should be done by WDREX ch1. + */ + // Enable bypass MPLL - DRAM reset should be performed along with low frequency + enable_bypass_pll(); + + /* USEATGATEGEN + : automatic gate generation disable by mhjang : for re-initializing + */ + //Outp32(WIDEIO_PHY0+0x00e0, 0x00000000); + //Outp32(WIDEIO_PHY1+0x00e0, 0x00000000); + //Outp32(WIDEIO_PHY2+0x00e0, 0x00000000); + //Outp32(WIDEIO_PHY3+0x00e0, 0x00000000); + + Outp32(WIDEIO_PHY0+0x0068, 0x00000001); // PHY wrapper takes over the DRAM control for DRAM/PHY initialization + Outp32(WIDEIO_PHY2+0x0068, 0x00000001); + Outp32(WIDEIO_PHY3+0x0068, 0x00000001); + Outp32(WIDEIO_PHY1+0x0068, 0x00000001); + + // Reset control order on channels is suggested as ch0->ch2->ch3->ch1 + Outp32(WIDEIO_PHY0+0x0050, 0x00050001); // tINIT3 = 0x5000, De-assert RESET signal to DRAM + Outp32(WIDEIO_PHY2+0x0050, 0x00050001); + Outp32(WIDEIO_PHY3+0x0050, 0x00050001); + Outp32(WIDEIO_PHY1+0x0050, 0x00050001); + while(( Inp32( WIDEIO_PHY1+0x0050 ) & 0x00000001 ) != 0x00000001); + + // Disable bypass MPLL - DRAM reset should be performed along with low frequency + disable_bypass_pll(); + #endif + + /* Initialize wideIO SDR + : WDREX channel initialization sequency is recommended as follows. ch0->ch1->ch2->ch3 + */ + uFreq = 266; + init_wideIO_sdr(WIDEIO_PHY0, WDREX0, uFreq, 0); + init_wideIO_sdr(WIDEIO_PHY1, WDREX1, uFreq, 0); + init_wideIO_sdr(WIDEIO_PHY2, WDREX2, uFreq, 0); + init_wideIO_sdr(WIDEIO_PHY3, WDREX3, uFreq, 0); +} + +void pad_retention_release(void) +{ + Outp32(0x100431E8, 0x10000000); + while ((Inp32(0x10043004) & (0x1)) == 0); +} diff --git a/board/samsung/xyref4415/Makefile b/board/samsung/xyref4415/Makefile new file mode 100644 index 000000000..c52fe8e5d --- /dev/null +++ b/board/samsung/xyref4415/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2013 Samsung Electronics +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +SOBJS := lowlevel_init.o + +COBJS := clock_init.o +COBJS += dmc_init.o +COBJS += pmic.o +COBJS += smc.o + +ifdef CONFIG_LCD +COBJS += display.o +endif + +ifdef CONFIG_TZPC +COBJS += tzpc_init.o +endif + +ifndef CONFIG_SPL_BUILD +COBJS += xyref4415.o +endif + +ifdef CONFIG_SPL_BUILD +COBJS += mmc_boot.o +endif + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +ALL := $(obj).depend $(LIB) + +all: $(ALL) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/xyref4415/clock_init.c b/board/samsung/xyref4415/clock_init.c new file mode 100644 index 000000000..ec27eef21 --- /dev/null +++ b/board/samsung/xyref4415/clock_init.c @@ -0,0 +1,706 @@ +/* + * Clock setup for XYREF4415 board based on EXYNOS4 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include "setup.h" +#include "cmu.h" + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) ((*(volatile u32 *)(addr))) + +void CMU_Delay(int msec) +{ + volatile u32 i; + for(;msec > 0; msec--); + for(i=0; i<1000; i++) ; +} + + + + + + + + +void CMU_SetMuxDiv_LRBUS(void) +{ + volatile u32 uBits; + + // Set CMU_LEFTBUS, MUX & DIV + // MPLL_USER(1:4), GDL(1:0) + uBits = (1 << 4) | (0 << 0); + Outp32(rCLK_SRC_LEFTBUS, uBits); // rCLK_SRC_LEFTBUS + + // GPL(1/2:4), GDL(1/4:0) + uBits = (1 << 4) | (3 << 0); + Outp32(rCLK_DIV_LEFTBUS, uBits); // rCLK_DIV_LEFTBUS + + + // Set CMU_RIGHTBUS, MUX & DIV + // MPLL_USER(1:4), GDR(0:0) + uBits = (1 << 4) | (0 << 0); + Outp32(rCLK_SRC_RIGHTBUS, uBits); // rCLK_SRC_RIGHTBUS + + // GPR(1/2:4), GDR(1/4:0) + uBits = (1 << 4) | (3 << 0); + Outp32(rCLK_DIV_RIGHTBUS, uBits); // rCLK_DIV_RIGHTBUS +} + + + +void CMU_SetMuxDiv_ISP(void) +{ + volatile u32 uBits; + + // Set CMU_ISP, MUX & DIV + // + // Never write to CMU_ISP, because system hang when PMU power test (in case of Gaia) +#if 0 + // Do not access ISP clk div sfr, when ISP is off. (added at Carmen for the first time) + uBits = Inp32(0x10023CA4); // ISP_STATUS + if((uBits & 0x7) == 0x7) // ISP_STATUS.STATUS [2:0] + { + // ISPDIV1(1/4:4), ISPDIV0(1/2:0) + uBits = (3 << 4) | (1 << 0); + Outp32(0x10048300, uBits); // rCLK_DIV_ISP0 + + // MCUISPDIV1(1/4:8), MCUISPDIV0(1/2:4), MPWMDIV(1/1:0) + uBits = (3 << 8) | (1 << 4) | (0 << 0); + Outp32(0x10048304, uBits); // rCLK_DIV_ISP1 + } +#else + + // PHYCLK_RXBYTE_CLKHS0_S2A(1:24), PHYCLK_RXBYTE_CLKHS0_S4(1:20), PWM(1:16), MTCADC(1:12), SPI0(1:8), SPI1(1:4), UART(1:0) + uBits = (1 << 24) | (1 << 20) | (1 << 16) | (1 << 12) | (1 << 8) | (1 << 4) | (1 << 0); + Outp32(rCLK_SRC_ISP0, uBits); // 0x12060200 + + // rCLK_SRC_ISP1 :: Reserved + Outp32(rCLK_SRC_ISP1, 0x0); // 0x12070200 + + + // PCLK_ISP0_A_150(1/2:20), ISP_MPWM(1/4:16), SCLK_PCLKDBG(1/4:12), SCLK_ATCLK(1/2:8), PCLK_ISP0_B_75(1/4:4), PCLK_ISP0_B_150(1/2:0) + uBits = (1 << 20) | (3 << 16) | (3 << 12) | (1 << 8) | (3 << 4) | (1 << 0); + Outp32(rCLK_DIV_ISP0, uBits); // 0x12060500 + + // PCLK_ISP1_75(1/4:4), PCLK_ISP1_150(1/2:0) + uBits = (3 << 4) | (1 << 0); + Outp32(rCLK_DIV_ISP1, uBits); // 0x12070500 + +#endif + +} + + +void CMU_SetMuxDiv_TOP(void) +{ + volatile u32 uBits; + + // Set CMU_TOP, MUX & DIV + // + // EBI(0:28), ACLK_200(0:24), ACLK_160(0:20), ACLK_100(0:16), ACLK_266(0:12), G3D_PLL(0:8), EPLL(0:4), EBI_1(0:0) + uBits = (0 << 28) | (0 << 24) | (0 << 20) | (0 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | (0 << 0); + Outp32(rCLK_SRC_TOP0, uBits); //0x1003C210 + +#if 0 + // MPHY_PLL(0:28), ACLK_400_MCUISP_SUB(1:24), ACLK_266_SUB(1:20), MPLL_USER(1:12), ACLK_400_MCUISP(0:8), VPLLSRC(0:0) + uBits = (0 << 28) | (1 << 24) | (1 << 20) | (1 << 12) | (0 << 8) | (0 << 0); +#else + // ISP_PLL(0:28), DISP_PLL(1:16), MPLL_USER(1:12), ACLK_400_MCUISP(0:8), G3D_PLLSRC_SEL(0:0) + uBits = (1 << 28) | (1 << 16) | (1 << 12) | (0 << 8) | (0 << 0); +#endif + Outp32(rCLK_SRC_TOP1, uBits); // 0x1003C214 + +#if 0 // for NOR Booting + // 2013.01.04 support for nor booting + if ((Inp32(0x10020000) & 0x3F) == 0x1D) + { + // NOR Boot case + // ACLK_400_MCUISP(1/2:24), EBI(1/2:16), ACLK_200(1/8:12), ACLK_160(1/5:8), ACLK_100(1/8:4), ACLK_266(1/3:0) + uBits = (1 << 24) | (1 << 16) | (7 << 12) | (4 << 8) | (7 << 4) | (2 << 0); + } + else + { + // ACLK_400_MCUISP(1/2:24), EBI(1/1:16), ACLK_200(1/4:12), ACLK_160(1/5:8), ACLK_100(1/8:4), ACLK_266(1/3:0) + uBits = (1 << 24) | (0 << 16) | (3 << 12) | (4 << 8) | (7 << 4) | (2 << 0); + } + Outp32(0x1003C510, uBits); // rCLK_DIV_TOP +#endif + // ACLK_400_MCUISP(1/2:24), EBI(1/1:16), ACLK_200(1/4:12), ACLK_160(1/5:8), ACLK_100(1/8:4), ACLK_266(1/3:0) + uBits = (1 << 24) | (0 << 16) | (3 << 12) | (4 << 8) | (7 << 4) | (2 << 0); + Outp32(rCLK_DIV_TOP, uBits); //0x1003C510 +} + + +//DMC <== Core_L +void CMU_SetMuxDiv_DMC(void) +{ + volatile u32 uBits; + + // Set CMU_CORE_L, MUX & DIV + // MPLL(0:12), BPLL(0:10), DPHY(0:8), DMC_BUS(0:4) + uBits = (0 << 12) | (0 << 10) | (1 << 8) | (1 << 4); // use BPLL_IN source for DPHY,DMC in Hudson + Outp32(rCLK_SRC_DMC, uBits); // 0x105c0300 + // BPLL_PRE(1/2:30),DPHY(0:8) => Fixed + // DMC(1/2:27), DMC_PRE(1/1:19), COREP(1/2:15), CORED(1/2:11), MPLL_PRE(1/1:8) + //uBits = (4 << 27) | (1 << 23) | (3 << 19) | (1 << 15) | (1 << 11) | (0 << 8); // DMC [PLL/20] + // - 1266Mhz => 63.3MHz + // - 1066Mhz => 53.3MHz + //Temp for MIF L0 667 Test + uBits = (5 << 27) | (1 << 23) | (3 << 19) | (1 << 15) | (1 << 11) | (0 << 8); // DMC [PLL/24] + // - 1334Mhz => 55.58MHz + // - 1066Mhz => 44.42MHz + + + Outp32(rCLK_DIV_DMC1, uBits); // 0x105C0504 +} + + + +//ACP <== Core_R +void CMU_SetMuxDiv_ACP(void) +{ + volatile u32 uBits; + + // Set CMU_CORE_R, MUX & DIV + // G2D_ACP(0:28), G2D_ACP_1(1:24), G2D_ACP_0(0:20) PWI(0:16), MPLL_USER(1:13), BPLL_USER(1:11), CORE_BUS(0:4) + uBits = (0 << 28) | (1 << 24) | (0 << 20) | (1 << 16) | (1 << 13) | (1 << 11) | (0 << 4); + Outp32(rCLK_SRC_ACP, uBits); // 0x10450300 + + // COREP(1/2:16), CORED(1/2:12), DMC(1/2:8), ACP_PCLK(1/2:4), ACP(1/4:0) + uBits = (1 << 16) | (1 << 12) | (1 << 8) | (1 << 4) | (3 << 0); + Outp32(rCLK_DIV_ACP0, uBits); // 0x10450500 + + // PWI(1/1:5), G2D_ACP(1/4:0) + uBits = (0 << 5) | (3 << 0); + Outp32(rCLK_DIV_ACP1, uBits); // 0x10450504 + +} + + +void CMU_SetMuxDiv_TOP_Sub(void) +{ + volatile u32 uBits; + +// Set MUX + //TSADC(1:28), UFS_UNIPRO(1:16), MMC3(1:12), *MMC2(6:8), MMC1(6:4), *MMC0(6:0), // (*) : That means IROM booting device. + uBits = (1<<28)|(1<<16)|(1<<12)|(6<<8)|(6<<4)|(6<<0); + Outp32(rCLK_SRC_FSYS, uBits); // 0x1003C240 + + //UART4(1:16), *UART3(6:12), UART2(6:8), UART1(6:4), UART0(6:0) // Only UART3 is MPLL for IROM UART Booting + uBits = (1<<16)|(6<<12)|(1<<8)|(1<<4)|(1<<0); + Outp32(rCLK_SRC_PERIL0, uBits); // 0x1003C250 + + //SPI2(6:24), *SPI1(6:20), SPI0(6:16), SPDIF(0:8), AUDIO2(7:4), AUDIO1(7:0) // - MPLL(SPI) , EPLL(AUDIO) + uBits = (6<<24)|(6<<20)|(6<<16)|(0<<8)|(7<<4)|(7<<0); + Outp32(rCLK_SRC_PERIL1, uBits); // 0x1003C254 + + //AUDIO0(7:0) // - EPLL(AUDIO) + uBits = (7<<0); + Outp32(rCLK_SRC_MAUDIO, uBits); // 0x1003C23C + + //G3D(1:8), G3D_1(1:4), G3D_0(0:0), // - G3DPLL + uBits = (1<<8)|(1<<4)|(0<<0); + Outp32(rCLK_SRC_G3D, uBits); // 0x1003C22C + + //MIXER_SEL(4), HDMI_SEL(0) + uBits = (1<<4) | (1<<0); //ToDo :: + Outp32(rCLK_SRC_TV, uBits); // 0x1003C224 + + //MFC(0:8), MFC_1(1:4), MFC_0(0:0), // - MPLL(MFC) + uBits = (0<<8)|(1<<4)|(0<<0); + Outp32(rCLK_SRC_MFC, uBits); // 0x1003C228 + + + //ACLK_ISP0_300(1:8), USER_MUX_ACLK_ISP0_400(1:4), USER_MUX_ACLK_ISP0_300(1:0), ; - rCLK_SRC_ISP0_T + uBits=(0<<8)|(1<<4)|(1<<0); + Outp32(rCLK_SRC_ISP0_T, uBits); // 0x1003C25c + + //ACLK_ISP1_300(1:4), USER_MUX_ACLK_ISP1_300(0:0), ; - rCLK_SRC_ISP1_T + uBits=(1<<4)|(1<<0); + Outp32(rCLK_SRC_ISP1_T, uBits); // 0x1003C260 + + + + //CAM, LCD0,ISP CLK SRC ???????????????????????? + //ISP : all 6 - MPLL ==> Carmen + // hudson : 0x3 = ISPPLL ?? + + + + + + + // Set DIV + //UART4(1/1:16), *UART3(1/16:12), UART2(1/1:8), UART1(1/1:4), UART0(1/1:0) // UART3=800MHz/16=50MHz, UART0,1,2,4=24/1=24 + uBits = (0<<16)|(15<<12)|(0<<8)|(0<<4)|(0<<0); + Outp32(rCLK_DIV_PERIL0, uBits); // 0x1003C550 + + //SPI1_PRE(1/5:24), *SPI1(1/4:16), SPI1_PRE(1/5:8), SPI0(1/4:0) // - 800MHz/4/5=40MHz + uBits = (4<<24)|(3<<16)|(4<<8)|(3<<0); + Outp32(rCLK_DIV_PERIL1, uBits); // 0x1003C554 + + //SPI2_PRE(1/5:8), SPI2(1/4:0) // - 800MHz/4/5=40MHz + uBits = (4<<8)|(3<<0); + Outp32(rCLK_DIV_PERIL2, uBits); // 0x1003C558 + + //PCM2(1/2:20), AUDIO2(1/2:16), PCM1(1/2:4), AUDIO1(1/2:0) + uBits = (1<<20)|(1<<16)|(1<<4)|(1<<0); + Outp32(rCLK_DIV_PERIL4, uBits); // 0x1003C560 + + //I2S2(1/2:8), I2S1(1/2:0) + uBits = (1<<8)|(1<<0); + Outp32(rCLK_DIV_PERIL5, uBits); // 0x1003C564 + + + + //JPEG(1/5:0) , ACLK_JPEG=160MHz + uBits = (4<<0); + Outp32(rCLK_DIV_CAM1, (Inp32(rCLK_DIV_CAM1)&~(0xF<<0))|(uBits)); // 0x1003C568 + + //PCM0(1/2:4), AUDIO0(1/2:0) + uBits = (1<<4)|(1<<0); + Outp32(rCLK_DIV_MAUDIO, uBits); // 0x1003C53C + + //TV(1/4:0) + uBits = (3<<0); + Outp32(rCLK_DIV_TV, uBits); // 0x1003C524 + + //MFC(1/4:0) + uBits = (3<<0); + Outp32(rCLK_DIV_MFC, uBits); // 0x1003C528 + + //G3D(1/1:0) + uBits = (0<<0); + Outp32(rCLK_DIV_G3D, uBits); // 0x1003C52C + + //TSADC_PRE(1/1:8), TSADC(1/8:0) + uBits = (0<<8)|(7<<0); + Outp32(rCLK_DIV_FSYS0, uBits); // 0x1003C540 + + //MMC1_PRE(1/5:24), MMC1(1/4:16), MMC0_PRE(1/5:8), MMC0(1/4:0) // - 800MHz/4/5=40MHz + uBits = (4<<24)|(3<<16)|(4<<8)|(3<<0); + Outp32(rCLK_DIV_FSYS1, uBits); // 0x1003C544 + + //MMC3_PRE(1/5:24), MMC3(1/4:16), MMC2_PRE(1/5:8), MMC2(1/4:0) // - 800MHz/4/5=40MHz + uBits = (4<<24)|(3<<16)|(4<<8)|(3<<0); + Outp32(rCLK_DIV_FSYS2, uBits); // 0x1003C548 + + // UFS_UNIPRO(1/16:0) + uBits = (15 << 0); + Outp32(rCLK_DIV_FSYS3, uBits); // 0x1003C54C + + + //ACLK_ISP1_300(1/3:16) TSADC_ISP_B(1/5:8), TSADC_ISP_A(1/4:0) + uBits=(2<<16)|(4<<8)|(3<<0); + Outp32(rCLK_DIV_ISP1_T, uBits); // 0x1003C56c + + //ACLK_ISP0_300(1/16:0) + uBits=(0<<0); + Outp32(rCLK_DIV_ISP0_T, uBits); // 0x1003C570 + +} + + + + +void CMU_Init(u32 nARMCLK) +{ + volatile u32 uBits; + +// Set PLL Time + Outp32(rAPLL_LOCK, 2400); + Outp32(rMPLL_LOCK, 2400); + Outp32(rBPLL_LOCK, 2400); + Outp32(rG3DPLL_LOCK, 2400); + Outp32(rDISPPLL_LOCK, 2400); + Outp32(rISPPLL_LOCK, 2400); + + Outp32(rEPLL_LOCK, 7200); + +// Turn Off PLL Mout + //APLL + uBits = (1 << 0); + Outp32(rCLK_SRC_CPU, Inp32(rCLK_SRC_CPU) & ~uBits); // rCLK_SRC_CPU + //MPLL, BPLL + uBits = (1<<12)|(1<<10); + Outp32(rCLK_SRC_DMC, Inp32(rCLK_SRC_DMC) & ~uBits); // rCLK_SRC_DMC + //G3DPLL, EPLL + uBits = (1<<8)|(1<<4); + Outp32(rCLK_SRC_TOP0, Inp32(rCLK_SRC_TOP0) & ~uBits); // rCLK_SRC_TOP0 + //ISPPLL, DISPPLL + uBits = (1<<28)|(1<<16); + Outp32(rCLK_SRC_TOP1, Inp32(rCLK_SRC_TOP1) & ~uBits); // rCLK_SRC_TOP1 + + + // Set CMU_CPU, MUX & DIV + // Set CMU_CPU, MUX & DIV + // MPLL_USER(1:24), HPM(0:20), CORE(0:16), APLL(0:0) + uBits = (1 << 24) | (0 << 20) | (0 << 16) | (0 << 0); + Outp32(rCLK_SRC_CPU, uBits); // 0x10044200 + + // CORE2(1/1:28), APLL(1/2:24), PCLK_DBG(1/8:20), ATB(1/4:16), COREM1(1/4:8), COREM0(1/2:4), CORE(1/1:0) + uBits = (0 << 28) | (1 << 24) | (7 << 20) | (3 << 16) | (3 << 8)| (1 << 4) | (0 << 0); + Outp32(rCLK_DIV_CPU0, uBits); // 0x10044500 + + // HPM(1/1:4), COPY(1/3:0) + uBits = (0 << 4) | (2 << 0); + Outp32(rCLK_DIV_CPU1, uBits); // 0x10044504 + + + // Set PLL + // Setting APLL [P,M,S] + // + uBits = (1 << 23) | (1 << 21) | (3 << 14) | (3 << 12) | (3 << 10); + Outp32(rAPLL_CON1, uBits); // 0x10044104 + + uBits = (2 << 4); + Outp32(rAPLL_CON2, uBits); // 0x10044108 + + + // ARM Clock = 1200 MHz + // ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + if (nARMCLK == 1700) + { + uBits = (1 << 31) | (425 << 16) | (6 << 8) | (0 << 0); // APLL=1700MHz(6:425:0) + } + else if (nARMCLK == 1600) + { + uBits = (1 << 31) | (200 << 16) | (3 << 8) | (0 << 0); // APLL=1600MHz(3:200:0) + } + else if (nARMCLK == 1500) + { + uBits = (1 << 31) | (250 << 16) | (4 << 8) | (0 << 0); // APLL=1500MHz(4:250:0) + } + else if (nARMCLK == 1400) + { + uBits = (1 << 31) | (175 << 16) | (3 << 8) | (0 << 0); // APLL=1400MHz(3:175:0) + } + else if (nARMCLK == 1300) + { + uBits = (1 << 31) | (325 << 16) | (6 << 8) | (0 << 0); // APLL=1300MHz(6:325:0) + } + else if (nARMCLK == 1200) + { + uBits = (1 << 31) | (400 << 16) | (4 << 8) | (1 << 0); // APLL=1200MHz(4:400:1) + } + else if (nARMCLK == 1100) + { + uBits = (1 << 31) | (275 << 16) | (3 << 8) | (1 << 0); // APLL=1100MHz(3:275:1) + } + else if (nARMCLK == 1000) + { + uBits = (1 << 31) | (250 << 16) | (3 << 8) | (1 << 0); // APLL=1000MHz(3:250:1) + } + else if (nARMCLK == 900) + { + uBits = (1 << 31) | (300 << 16) | (4 << 8) | (1 << 0); // APLL=900MHz(4:300:1) + } + else if (nARMCLK == 800) + { + uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); // APLL=800MHz(3:200:1) + } + else if (nARMCLK == 700) + { + uBits = (1 << 31) | (175 << 16) | (3 << 8) | (1 << 0); // APLL=700MHz(3:175:1) + } + else if (nARMCLK == 600) + { + uBits = (1 << 31) | (400 << 16) | (4 << 8) | (2 << 0); // APLL=600MHz(4:400:2) + } + else if (nARMCLK == 500) + { + uBits = (1 << 31) | (250 << 16) | (3 << 8) | (2 << 0); // APLL=500MHz(3:250:2) + } + else if (nARMCLK == 400) + { + uBits = (1 << 31) | (200 << 16) | (3 << 8) | (2 << 0); // APLL=400MHz(3:200:2) + } + else if (nARMCLK == 300) + { + uBits = (1 << 31) | (400 << 16) | (4 << 8) | (3 << 0); // APLL=300MHz(4:400:3) + } + else if (nARMCLK == 200) + { + uBits = (1 << 31) | (200 << 16) | (3 << 8) | (3 << 0); // APLL=200MHz(3:200:3) + } + else //if (nARMCLK == 100) + { + uBits = (1 << 31) | (200 << 16) | (3 << 8) | (4 << 0); // APLL=100MHz(3:200:4) + } + + Outp32(rAPLL_CON0, uBits); // 0x10044100 + while ((Inp32(rAPLL_CON0) & (1 << 29)) == 0); + + CMU_Delay(0x30000); + + + + // Setting MPLL [P,M,S] + uBits = (1 << 23) | (1 << 21) | (3 << 14) | (3 << 12) | (3 << 10); + Outp32(rMPLL_CON1, uBits); // 0x105C010C + + uBits = (2 << 4); + Outp32(rMPLL_CON2, uBits); // 0x105C0110 + +// uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); // MPLL=800MHz(3:200:1) + uBits = (1 << 31) | (275 << 16) | (4 << 8) | (1 << 0); // MPLL=825MHz(4:275:1) + Outp32(rMPLL_CON0, uBits); // 0x105C0108 + while ((Inp32(rMPLL_CON0) & (1 << 29)) == 0); + + CMU_Delay(0x30000); + + + + // Setting BPLL [P,M,S] + uBits = (1 << 23) | (1 << 21) | (3 << 14) | (3 << 12) | (3 << 10); + Outp32(rBPLL_CON1, uBits); // 0x105C021C + + uBits = (2 << 4); + Outp32(rBPLL_CON2, uBits); // 0x105C0220 + + // ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) ... Set Max Value, Clock is on Div + //uBits = (1 << 31) | (533 << 16) | (6 << 8) | (0 << 0); // BPLL=2132MHz(6:533:0) + uBits = (1 << 31) | (362 << 16) | (4 << 8) | (1 << 0); // BPLL= 10864MHz(4:362:1) //543 + //uBits = (1 << 31) | (667 << 16) | (12 << 8) | (0 << 0); // BPLL=1334MHz(12:667:0) //667 + //uBits = (1 << 31) | (211 << 16) | (4 << 8) | (0 << 0); // BPLL=1266MHz(4:211:0) //633 + //uBits = (1 << 31) | (533 << 16) | (6 << 8) | (1 << 0); // BPLL=1066MHz(6:533:1) + //uBits = (1 << 31) | (220 << 16) | (3 << 8) | (1 << 0); // BPLL=880MHz(6:533:1) + // uBits = (1 << 31) | (200 << 16) | (3 << 8) | (1 << 0); // BPLL= 800MHz(3:200:1) + Outp32(rBPLL_CON0, uBits); // 0x105C0218 + while ((Inp32(rBPLL_CON0) & (1 << 29)) == 0); + + CMU_Delay(0x30000); + + + // Setting EPLL : SEL_PF[31:30],MRR[29:24],MFR[23:16], K[15:00] + uBits = (3 << 30) | (6 << 24) | (1 << 16)| (1 << 0); + Outp32(rEPLL_CON1, uBits); // 0x1003C114 + + // VCO_BOOST[28],AFCINIT_SEL[27] + uBits = (1 << 28) | (1 << 27); + Outp32(rEPLL_CON2, uBits); // 0x1003C118 + + // ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + uBits = (1 << 31) | (128 << 16) | (2 << 8) | (3 << 0); // EPLL=192MHz(2:128:3), + Outp32(rEPLL_CON0, uBits); // 0x1003C110 + while ((Inp32(rEPLL_CON0) & (1 << 29)) == 0); + + CMU_Delay(0x30000); + + + + // Setting G3DPLL + uBits = (1 << 23) | (1 << 21) | (3 << 14) | (3 << 12) | (3 << 10); + Outp32(rG3D_PLL_CON1, uBits); // 0x1003C124 + + uBits = (2 << 4); + Outp32(rG3D_PLL_CON2, uBits); // 0x1003C128 + + uBits = (1 << 31) | (170 << 16) | (3 << 8) | (2 << 0); // G3DPLL=340MHz(3:170:2) + Outp32(rG3D_PLL_CON0, uBits); // 0x1003C120 + while ((Inp32(rG3D_PLL_CON0) & (1 << 29)) == 0); + + CMU_Delay(0x30000); + + + + // Setting ISPPLL + uBits = (1 << 23) | (1 << 21) | (3 << 14) | (3 << 12) | (3 << 10); + Outp32(rISP_PLL_CON1, uBits); // 0x1003C134 + + uBits = (2 << 4); + Outp32(rISP_PLL_CON2, uBits); // 0x1003C138 + + + // ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + uBits = (1 << 31) | (400 << 16) | (4 << 8) | (3 << 0); // ISPPLL=300MHz(4:400:3) + //uBits = (1 << 31) | (533 << 16) | (6 << 8) | (3 << 0); // ISPPLL=266MHz(6:533:3) + Outp32(rISP_PLL_CON0, uBits); // 0x1003C130 + while ((Inp32(rISP_PLL_CON0) & (1 << 29)) == 0); + + CMU_Delay(0x30000); + + + // Setting DISPPLL [P,M,S] + uBits = (1 << 23) | (1 << 21) | (3 << 14) | (3 << 12) | (3 << 10); + Outp32(rDISP_PLL_CON1, uBits); // 0x1003C144 + + uBits = (2 << 4); + Outp32(rDISP_PLL_CON2, uBits); // 0x1003C148 + + + // ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //uBits = (1 << 31) | (260 << 16) | (3 << 8) | (2 << 0); // DISPPLL=520MHz(3:260:2) + uBits = (1 << 31) | (266 << 16) | (3 << 8) | (3 << 0); // DISPPLL=266MHz(3:266:3) + Outp32(rDISP_PLL_CON0, uBits); // 0x1003C140 + while ((Inp32(rDISP_PLL_CON0) & (1 << 29)) == 0); + + CMU_Delay(0x30000); + + + + // Set clk Mux and Div .. Sub_block + CMU_SetMuxDiv_ACP(); + CMU_SetMuxDiv_LRBUS(); + CMU_SetMuxDiv_ISP(); + CMU_SetMuxDiv_TOP(); + + //Special Clock MuxDiv in TOP + CMU_SetMuxDiv_TOP_Sub(); + CMU_SetMuxDiv_DMC(); + + +// Turn On PLL Mout + //APLL + uBits = (1 << 0); + Outp32(rCLK_SRC_CPU, Inp32(rCLK_SRC_CPU) | uBits); // rCLK_SRC_CPU + //BPLL + uBits = (1<<10); + Outp32(rCLK_SRC_DMC, Inp32(rCLK_SRC_DMC) | uBits); // rCLK_SRC_DMC + //MPLL + uBits = (1<<12); + Outp32(rCLK_SRC_DMC, Inp32(rCLK_SRC_DMC) | uBits); // rCLK_SRC_DMC + //G3DPLL, EPLL + uBits = (1<<8)|(1<<4); + Outp32(rCLK_SRC_TOP0, Inp32(rCLK_SRC_TOP0) | uBits); // rCLK_SRC_TOP0 + //ISPPLL, DISPPLL + uBits = (1<<28)|(1<<16); + Outp32(rCLK_SRC_TOP1, Inp32(rCLK_SRC_TOP1) | uBits); // rCLK_SRC_TOP1 + +} + +void CMU_InitForMif(u32 uMemClk) +{ + volatile u32 uBits,uTemp; + + // SCLK_DMC clock change to high + // BPLL_PRE(1/2:30),DPHY(0:8) => Fixed + // DMC(1/2:27), DMC_PHY(1/2:23), DMC_PRE(1/1:19), COREP(1/2:15), CORED(1/2:11), MPLL_PRE(1/1:8) + uBits = (1 << 27) | (1 << 23) | (0 << 19) | (1 << 15) | (1 << 11) | (0 << 8); // DMC Up to Working Clock + Outp32(rCLK_DIV_DMC1, uBits); // 0x105C0504 + + if (uMemClk <= 667) + { + //;DPHY clock gating for DLL lock + //&uBits=(0.<<3.)|(0.<<2.)|(3.<<0.); ; [3:2]SCLK_DPHY0,1 clock gating,[1:0]RSVD 0x3 + //GOSUB write 0x105C0800 &uBits ;"SCLK_DPHY0,1 gating" + uBits=(0<<3)|(0<<2)|(3<<0); // [3:2]SCLK_DPHY0,1 clock gating,[1:0]RSVD 0x3 + Outp32(rCLK_GATE_SCLK_DMC, uBits); // 0x105C0504 + + //;BPLL -> MPLL mux change + //GOSUB read 0x105C0300 + //ENTRY &clk_src_dmc + //&temp=&clk_src_dmc&(~(0x1<<4)) ; [4]0:SCLKMPLL_IN, 1: SCLKBPLL_IN + uTemp= Inp32(rCLK_SRC_DMC); + uBits=uTemp &(~(0x1<<4)) ; //[4]0:SCLKMPLL_IN, 1: SCLKBPLL_IN + Outp32(rCLK_SRC_DMC, uBits); // 0x105C0504 + + if (uMemClk==667) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + uBits=(1<<31)|(667<<16)|(12<<8)|(0<<0); //; BPLL=1334MHz(12:667:0), for DMC,DREX PHY + } + else if (uMemClk==633) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + uBits=(1<<31)|(211<<16)|(4<<8)|(0<<0); //; BPLL=1266MHz(4:211:0), for DMC,DREX PHY + } + else if (uMemClk==543) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(362.<<16.)|(4.<<8.)|(1.<<0.); ; BPLL=1086MHz(4:362:1), for DMC,DREX PHY + uBits=(1<<31)|(362<<16)|(4<<8)|(1<<0); //; BPLL=1086MHz(4:362:1), for DMC,DREX PHY + } + else if (uMemClk==480) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(320.<<16.)|(4.<<8.)|(1.<<0.); ; BPLL=960MHz(4:320:1) for DMC,DREX PHY + uBits=(1<<31)|(320<<16)|(4<<8)|(1<<0); //; BPLL=960MHz(4:320:1) for DMC,DREX PHY + } + else if (uMemClk==410) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(205.<<16.)|(3.<<8.)|(1.<<0.); ; BPLL=820MHz(3:205:1) for DMC,DREX PHY + uBits=(1<<31)|(205<<16)|(3<<8)|(1<<0); //; BPLL=820MHz(3:205:1) for DMC,DREX PHY + } + else if (uMemClk==275) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(275.<<16.)|(3.<<8.)|(2.<<0.); ; BPLL=550MHz(3:275:2) for DMC,DREX PHY + uBits=(1<<31)|(275<<16)|(3<<8)|(2<<0); // ; BPLL=550MHz(3:275:2) for DMC,DREX PHY + } + else if (uMemClk==206) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(206.<<16.)|(3.<<8.)|(2.<<0.); ; BPLL=412MHz(3:206:2) for DMC,DREX PHY + uBits=(1<<31)|(206<<16)|(3<<8)|(2<<0); // ; BPLL=412MHz(3:206:2) for DMC,DREX PHY + } + else if (uMemClk==165) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(220.<<16.)|(4.<<8.)|(2.<<0.); ; BPLL=330MHz(4:220:2) for DMC,DREX PHY + uBits=(1<<31)|(220<<16)|(4<<8)|(2<<0); // ; BPLL=330MHz(4:220:2) for DMC,DREX PHY + } + else if (uMemClk==138) + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(368.<<16.)|(4.<<8.)|(3.<<0.); ; BPLL=276MHz(4:368:3) for DMC,DREX PHY + uBits=(1<<31)|(368<<16)|(4<<8)|(3<<0);// ; BPLL=276MHz(4:368:3) for DMC,DREX PHY + } + else + { + //; ENABLE(1:31), MDIV(m:16), PDIV(p:8), SDIV(s:0) + //&uBits=(1.<<31.)|(368.<<16.)|(4.<<8.)|(3.<<0.); ; BPLL=276MHz(4:368:3) for DMC,DREX PHY + uBits=(1<<31)|(368<<16)|(4<<8)|(3<<0);// ; BPLL=276MHz(4:368:3) for DMC,DREX PHY + } + + //GOSUB write 0x105C0218 &uBits ;"rBPLL_CON0" + //GOSUB Waiting 0.3s + Outp32(rBPLL_CON0,uBits); + CMU_Delay(0x30000); + + //;MPLL -> BPLL mux change + //GOSUB read 0x105C0300 + //ENTRY &clk_src_dmc + //&temp=&clk_src_dmc|((0x1<<4)) ; [4]0:SCLKMPLL_IN, 1: SCLKBPLL_IN + uTemp= Inp32(rCLK_SRC_DMC); + uBits=uTemp |((0x1<<4)) ; //[4]0:SCLKMPLL_IN, 1: SCLKBPLL_IN + Outp32(rCLK_SRC_DMC, uBits); // 0x105C0504 + + } + +} + +void system_clock_init(void) +{ + CMU_Init(800); + return; +} + diff --git a/board/samsung/xyref4415/cmu.h b/board/samsung/xyref4415/cmu.h new file mode 100644 index 000000000..838b9eff1 --- /dev/null +++ b/board/samsung/xyref4415/cmu.h @@ -0,0 +1,403 @@ +/* + * Memory setup for XYREF4415 board based on EXYNOS4 + * + * Copyright (C) 2014 Samsung Electronics + * + * 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 __CMU_H__
+#define __CMU_H__
+
+
+static enum SYSC_CMU_REG
+{
+
+ //LEFT 0x10034000
+ rCLK_SRC_LEFTBUS = 0x10034200,
+ rCLK_MUX_STAT_LEFTBUS = 0x10034400,
+ rCLK_DIV_LEFTBUS = 0x10034500,
+ rCLK_DIV_STAT_LEFTBUS = 0x10034600,
+ rCLK_GATE_BUS_LEFTBUS = 0x10034700,
+ rCLK_GATE_BUS_IMAGE = 0x10034730,
+ rCLK_GATE_IP_LEFTBUS = 0x10034800,
+ rCLK_GATE_IP_IMAGE = 0x10034930,
+ rCLKOUT_CMU_LEFTBUS = 0x10034A00,
+ rCLKOUT_CMU_LEFTBUS_DIV_STAT = 0x10034A04,
+ rCMU_LEFTBUS_SPARE0 = 0x10036000,
+ rCMU_LEFTBUS_SPARE1 = 0x10036004,
+ rCMU_LEFTBUS_SPARE2 = 0x10036008,
+ rCMU_LEFTBUS_SPARE3 = 0x1003600C,
+ rCMU_LEFTBUS_SPARE4 = 0x10036010,
+
+ //RIGHT 0x10038000
+ rCLK_SRC_RIGHTBUS = 0x10038200,
+ rCLK_MUX_STAT_RIGHTBUS = 0x10038400,
+ rCLK_DIV_RIGHTBUS = 0x10038500,
+ rCLK_DIV_STAT_RIGHTBUS = 0x10038600,
+ rCLK_GATE_BUS_RIGHTBUS = 0x10038700,
+ rCLK_GATE_BUS_PERIR = 0x10038760,
+ rCLK_GATE_IP_RIGHTBUS = 0x10038800,
+ rCLK_GATE_IP_PERIR = 0x10038960,
+ rCLKOUT_CMU_RIGHTBUS = 0x10038A00,
+ rCLKOUT_CMU_RIGHTBUS_DIV_STAT = 0x10038A04,
+ rCMU_RIGHTBUS_SPARE0 = 0x1003A000,
+ rCMU_RIGHTBUS_SPARE1 = 0x1003A004,
+ rCMU_RIGHTBUS_SPARE2 = 0x1003A008,
+ rCMU_RIGHTBUS_SPARE3 = 0x1003A00C,
+ rCMU_RIGHTBUS_SPARE4 = 0x1003A010,
+
+ //TOP 0x1003C000
+ rEPLL_LOCK = 0x1003C010,
+ rG3DPLL_LOCK = 0x1003C020,
+ rDISPPLL_LOCK = 0x1003C030,
+ rISPPLL_LOCK = 0x1003C040,
+
+ rEPLL_CON0 = 0x1003C110,
+ rEPLL_CON1 = 0x1003C114,
+ rEPLL_CON2 = 0x1003C118,
+ rG3D_PLL_CON0 = 0x1003C120,
+ rG3D_PLL_CON1 = 0x1003C124,
+ rG3D_PLL_CON2 = 0x1003C128,
+ rISP_PLL_CON0 = 0x1003C130,
+ rISP_PLL_CON1 = 0x1003C134,
+ rISP_PLL_CON2 = 0x1003C138,
+ rDISP_PLL_CON0 = 0x1003C140,
+ rDISP_PLL_CON1 = 0x1003C144,
+ rDISP_PLL_CON2 = 0x1003C148,
+
+ rCLK_SRC_TOP0 = 0x1003C210,
+ rCLK_SRC_TOP1 = 0x1003C214,
+ rCLK_SRC_CAM0 = 0x1003C220,
+ rCLK_SRC_TV = 0x1003C224,
+ rCLK_SRC_MFC = 0x1003C228,
+ rCLK_SRC_G3D = 0x1003C22C,
+ rCLK_SRC_LCD = 0x1003C234,
+ rCLK_SRC_ISP = 0x1003C238,
+ rCLK_SRC_MAUDIO = 0x1003C23C,
+ rCLK_SRC_FSYS = 0x1003C240,
+ rCLK_SRC_PERIL0 = 0x1003C250,
+ rCLK_SRC_PERIL1 = 0x1003C254,
+ rCLK_SRC_CAM1 = 0x1003C258,
+ rCLK_SRC_ISP0_T = 0x1003C25c,
+ rCLK_SRC_ISP1_T = 0x1003C260,
+
+ rCLK_SRC_MASK_TOP = 0x1003C310,
+ rCLK_SRC_MASK_CAM0 = 0x1003C320,
+ rCLK_SRC_MASK_TV = 0x1003C324,
+ rCLK_SRC_MASK_LCD = 0x1003C334,
+ rCLK_SRC_MASK_ISP = 0x1003C338,
+ rCLK_SRC_MASK_MAUDIO = 0x1003C33C,
+ rCLK_SRC_MASK_FSYS = 0x1003C340,
+ rCLK_SRC_MASK_PERIL0 = 0x1003C350,
+ rCLK_SRC_MASK_PERIL1 = 0x1003C354,
+
+ rCLK_MUX_STAT_TOP0 = 0x1003C410,
+ rCLK_MUX_STAT_TOP1 = 0x1003C414,
+ rCLK_MUX_STAT_MFC = 0x1003C428,
+ rCLK_MUX_STAT_G3D = 0x1003C42C,
+ rCLK_MUX_STAT_CAM1 = 0x1003C458,
+ rCLK_MUX_STAT_ISP0 = 0x1003C45c,
+ rCLK_MUX_STAT_ISP1 = 0x1003C460,
+
+ rCLK_DIV_TOP = 0x1003C510,
+ rCLK_DIV_CAM0 = 0x1003C520,
+ rCLK_DIV_TV = 0x1003C524,
+ rCLK_DIV_MFC = 0x1003C528,
+ rCLK_DIV_G3D = 0x1003C52C,
+ rCLK_DIV_LCD = 0x1003C534,
+ rCLK_DIV_ISP = 0x1003C538,
+ rCLK_DIV_MAUDIO = 0x1003C53C,
+ rCLK_DIV_FSYS0 = 0x1003C540,
+ rCLK_DIV_FSYS1 = 0x1003C544,
+ rCLK_DIV_FSYS2 = 0x1003C548,
+ rCLK_DIV_FSYS3 = 0x1003C54C,
+ rCLK_DIV_PERIL0 = 0x1003C550,
+ rCLK_DIV_PERIL1 = 0x1003C554,
+ rCLK_DIV_PERIL2 = 0x1003C558,
+ rCLK_DIV_PERIL3 = 0x1003C55C,
+ rCLK_DIV_PERIL4 = 0x1003C560,
+ rCLK_DIV_PERIL5 = 0x1003C564,
+ rCLK_DIV_CAM1 = 0x1003C568,
+ rCLK_DIV_ISP1_T = 0x1003C56C,
+ rCLK_DIV_ISP0_T = 0x1003C570,
+ rCLKDIV2_RATIO = 0x1003C580,
+
+ rCLK_DIV_STAT_TOP = 0x1003C610,
+ rCLK_DIV_STAT_CAM0 = 0x1003C620,
+ rCLK_DIV_STAT_TV = 0x1003C624,
+ rCLK_DIV_STAT_MFC = 0x1003C628,
+ rCLK_DIV_STAT_G3D = 0x1003C62C,
+ rCLK_DIV_STAT_LCD = 0x1003C634,
+ rCLK_DIV_STAT_ISP = 0x1003C638,
+ rCLK_DIV_STAT_MAUDIO = 0x1003C63C,
+ rCLK_DIV_STAT_FSYS0 = 0x1003C640,
+ rCLK_DIV_STAT_FSYS1 = 0x1003C644,
+ rCLK_DIV_STAT_FSYS2 = 0x1003C648,
+ rCLK_DIV_STAT_FSYS3 = 0x1003C64C,
+ rCLK_DIV_STAT_PERIL0 = 0x1003C650,
+ rCLK_DIV_STAT_PERIL1 = 0x1003C654,
+ rCLK_DIV_STAT_PERIL2 = 0x1003C658,
+ rCLK_DIV_STAT_PERIL3 = 0x1003C65C,
+ rCLK_DIV_STAT_PERIL4 = 0x1003C660,
+ rCLK_DIV_STAT_PERIL5 = 0x1003C664,
+ rCLK_DIV_STAT_CAM1 = 0x1003C668,
+ rCLK_DIV_STAT_ISP1_T = 0x1003C66c,
+ rCLK_DIV_STAT_ISP0_T = 0x1003C670,
+
+ rCLKDIV2_STAT = 0x1003C680,
+
+ rCLK_GATE_BUS_CAM0 = 0x1003C720,
+ rCLK_GATE_BUS_TV = 0x1003C724,
+ rCLK_GATE_BUS_MFC = 0x1003C728,
+ rCLK_GATE_BUS_G3D = 0x1003C72C,
+ rCLK_GATE_BUS_LCD = 0x1003C734,
+ rCLK_GATE_BUS_CAM1 = 0x1003C738,
+ rCLK_GATE_BUS_FSYS0 = 0x1003C740,
+ rCLK_GATE_BUS_FSYS1 = 0x1003C744,
+ rCLK_GATE_BUS_PERIL = 0x1003C750,
+ rCLK_GATE_SCLK_CAM0 = 0x1003C820,
+ rCLK_GATE_SCLK_TV = 0x1003C824,
+ rCLK_GATE_SCLK_MFC = 0x1003C828,
+ rCLK_GATE_SCLK_G3D = 0x1003C82C,
+ rCLK_GATE_SCLK_LCD = 0x1003C834,
+ rCLK_GATE_SCLK_ISP_T = 0x1003C838, + rCLK_GATE_SCLK_MAUDIO = 0x1003C83C,
+ rCLK_GATE_SCLK_FSYS = 0x1003C840,
+ rCLK_GATE_SCLK_PERIL = 0x1003C850,
+ rCLK_GATE_IP_CAM = 0x1003C920,
+ rCLK_GATE_IP_TV = 0x1003C924,
+ rCLK_GATE_IP_MFC = 0x1003C928,
+ rCLK_GATE_IP_G3D = 0x1003C92C,
+ rCLK_GATE_IP_LCD = 0x1003C934,
+ rCLK_GATE_IP_ISP = 0x1003C938, + rCLK_GATE_IP_MAUDIO = 0x1003C93C,
+ rCLK_GATE_IP_FSYS = 0x1003C940,
+ rCLK_GATE_IP_PERIL = 0x1003C950,
+ rCLK_GATE_BLOCK = 0x1003C970,
+
+ rCLKOUT_CMU_TOP = 0x1003CA00,
+ rCLKOUT_CMU_TOP_DIV_STAT = 0x1003CA04,
+ rCMU_TOP_SPARE0 = 0x1003E000,
+ rCMU_TOP_SPARE1 = 0x1003E004,
+ rCMU_TOP_SPARE2 = 0x1003E008,
+ rCMU_TOP_SPARE3 = 0x1003E00C,
+ rCMU_TOP_SPARE4 = 0x1003E010,
+
+ //CPU 0x10044000
+ rAPLL_LOCK = 0x10044000,
+ rAPLL_CON0 = 0x10044100,
+ rAPLL_CON1 = 0x10044104,
+ rAPLL_CON2 = 0x10044108,
+ rCLK_SRC_CPU = 0x10044200,
+ rCLK_MUX_STAT_CPU = 0x10044400,
+ rCLK_DIV_CPU0 = 0x10044500,
+ rCLK_DIV_CPU1 = 0x10044504,
+ rCLK_DIV_STAT_CPU0 = 0x10044600,
+ rCLK_DIV_STAT_CPU1 = 0x10044604,
+ rCLK_GATE_BUS_CPU = 0x10044700,
+ rCLK_GATE_SCLK_CPU = 0x10044800,
+ rCLK_GATE_IP_CPU = 0x10044900,
+ rCLKOUT_CMU_CPU = 0x10044A00,
+ rCLKOUT_CMU_CPU_DIV_STAT = 0x10044A04,
+ rARMCLK_STOPCTRL = 0x10045000,
+ rATCLK_STOPCTRL = 0x10045004,
+ rARM_EMA_CTRL = 0x10045008,
+ rARM_EMA_STATUS = 0x1004500C,
+ rPARITYFAIL_STATUS = 0x10045010,
+ rPARITYFAIL_CLEAR = 0x10045014,
+ rPWR_CTRL = 0x10045020,
+ rPWR_CTRL2 = 0x10045024,
+ rAPLL_CON0_L8 = 0x10045100,
+ rAPLL_CON0_L7 = 0x10045104,
+ rAPLL_CON0_L6 = 0x10045108,
+ rAPLL_CON0_L5 = 0x1004510C,
+ rAPLL_CON0_L4 = 0x10045110,
+ rAPLL_CON0_L3 = 0x10045114,
+ rAPLL_CON0_L2 = 0x10045118,
+ rAPLL_CON0_L1 = 0x1004511C,
+ rIEM_CONTROL = 0x10045120,
+ rAPLL_CON1_L8 = 0x10045200,
+ rAPLL_CON1_L7 = 0x10045204,
+ rAPLL_CON1_L6 = 0x10045208,
+ rAPLL_CON1_L5 = 0x1004520C,
+ rAPLL_CON1_L4 = 0x10045210,
+ rAPLL_CON1_L3 = 0x10045214,
+ rAPLL_CON1_L2 = 0x10045218,
+ rAPLL_CON1_L1 = 0x1004521C,
+ rCLKDIV_IEM_L8 = 0x10045300,
+ rCLKDIV_IEM_L7 = 0x10045304,
+ rCLKDIV_IEM_L6 = 0x10045308,
+ rCLKDIV_IEM_L5 = 0x1004530C,
+ rCLKDIV_IEM_L4 = 0x10045310,
+ rCLKDIV_IEM_L3 = 0x10045314,
+ rCLKDIV_IEM_L2 = 0x10045318,
+ rCLKDIV_IEM_L1 = 0x1004531C,
+ rL2_STATUS = 0x10045400,
+ rCPU_STATUS = 0x10045410,
+ rPTM_STATUS = 0x10045420,
+ rCMU_CPU_SPARE0 = 0x10046000,
+ rCMU_CPU_SPARE1 = 0x10046004,
+ rCMU_CPU_SPARE2 = 0x10046008,
+ rCMU_CPU_SPARE3 = 0x1004600C,
+ rCMU_CPU_SPARE4 = 0x10046010,
+
+#if 0 //Carmen
+ //ISP 0x10048000
+ rCLK_DIV_ISP0 = 0x10048300,
+ rCLK_DIV_ISP1 = 0x10048304,
+ rCLK_DIV_STAT_ISP0 = 0x10048400,
+ rCLK_DIV_STAT_ISP1 = 0x10048404,
+ rCLK_GATE_BUS_ISP0 = 0x10048700,
+ rCLK_GATE_BUS_ISP1 = 0x10048704,
+ rCLK_GATE_BUS_ISP2 = 0x10048708,
+ rCLK_GATE_BUS_ISP3 = 0x1004870C,
+ rCLK_GATE_IP_ISP0 = 0x10048800,
+ rCLK_GATE_IP_ISP1 = 0x10048804,
+ rCLK_GATE_SCLK_ISP = 0x10048900,
+ rCLKOUT_CMU_ISP = 0x10048A00,
+ rCLKOUT_CMU_ISP_DIV_STAT = 0x10048A04,
+ rCMU_ISP_SPARE0 = 0x10048B00,
+ rCMU_ISP_SPARE1 = 0x10048B04,
+ rCMU_ISP_SPARE2 = 0x10048B08,
+ rCMU_ISP_SPARE3 = 0x10048B0C,
+#endif
+ //ISP0 0x12060000
+ rCLK_SRC_ISP0 = 0x12060200,
+ rCLK_SRC_MASK_ISP0 = 0x12060300,
+ rCLK_SRC_STAT_ISP0 = 0x12060400,
+ rCLK_DIV_ISP0 = 0x12060500,
+ rCLK_DIV_ISP0_SUB0 = 0x12060504,
+ rCLK_DIV_STAT_ISP0 = 0x12060600,
+ rCLK_DIV_STAT_ISP0_SUB0 = 0x12060604,
+ rCLK_GATE_ISP0_SUB0 = 0x12060700,
+ rCLK_GATE_ISP0_SUB1 = 0x12060704,
+ rCLK_GATE_ISP0_SUB2 = 0x12060708,
+ rCLK_GATE_ISP0_SUB3 = 0x1206070c,
+ rCLK_GATE_ISP0_SUB4 = 0x12060710,
+ rCLK_GATE_SCLK_ISP0_SUB0 = 0x12060800,
+ rCLK_GATE_SCLK_ISP0_SUB1 = 0x12060804,
+ rCLK_GATE_IP_ISP0_SUB0 = 0x12060900,
+ rCLK_GATE_IP_ISP0_SUB1 = 0x12060904,
+ rCLK_GATE_IP_ISP0_SUB2 = 0x12060908,
+ rCLK_GATE_IP_ISP0_SUB3 = 0x1206090c,
+ rCLK_GATE_IP_ISP0_SUB4 = 0x12060910,
+ rCLKOUT_CMU_ISP0 = 0x12060A00,
+ rCLKOUT_CMU_ISP0_DIV_STAT = 0x12060A04,
+ rCMU_ISP0_SPARE0 = 0x12060B00,
+ rCMU_ISP0_SPARE1 = 0x12060B04,
+ rCMU_ISP0_SPARE2 = 0x12060B08,
+ rCMU_ISP0_SPARE3 = 0x12060B0c,
+
+ //ISP1 0x12070000
+ rCLK_SRC_ISP1 = 0x12070200,
+ rCLK_SRC_MASK_ISP1 = 0x12070300,
+ rCLK_SRC_STAT_ISP1 = 0x12070400,
+ rCLK_DIV_ISP1 = 0x12070500,
+ rCLK_DIV_STAT_ISP1 = 0x12070600,
+ rCLK_GATE_ISP1_SUB0 = 0x12070700,
+ rCLK_GATE_ISP1_SUB1 = 0x12070704,
+ rCLK_GATE_SCLK_ISP1_SUB0 = 0x12070800,
+ rCLK_GATE_SCLK_ISP1_SUB1 = 0x12070804,
+ rCLK_GATE_IP_ISP1_SUB0 = 0x12070900,
+ rCLK_GATE_IP_ISP1_SUB1 = 0x12070904,
+ rCLKOUT_CMU_ISP1 = 0x12070A00,
+ rCLKOUT_CMU_ISP1_DIV_STAT = 0x12070A04,
+ rCMU_ISP1_SPARE0 = 0x12070B00,
+ rCMU_ISP1_SPARE1 = 0x12070B04,
+ rCMU_ISP1_SPARE2 = 0x12070B08,
+ rCMU_ISP1_SPARE3 = 0x12070B0c,
+
+ //DMC(CORE_L) 0x105C0000
+ rMPLL_LOCK = 0x105c0008,
+ rMPLL_CON0 = 0x105c0108,
+ rMPLL_CON1 = 0x105c010C,
+ rMPLL_CON2 = 0x105c0110,
+ rBPLL_LOCK = 0x105c0118,
+ rBPLL_CON0 = 0x105c0218,
+ rBPLL_CON1 = 0x105c021C,
+ rBPLL_CON2 = 0x105c0220,
+ rCLK_SRC_DMC = 0x105c0300,
+ rCLK_MUX_STAT_DMC = 0x105c0400,
+ rCLK_DIV_DYN_FREQ_SCALE = 0x105c0500,
+ rCLK_DIV_DMC1 = 0x105c0504,
+ rCLK_DIV_STAT_DMC0 = 0x105c0600,
+ rCLK_DIV_STAT_DMC1 = 0x105c0604,
+ rCLK_GATE_BUS_DMC0 = 0x105c0700,
+ rCLK_GATE_BUS_DMC1 = 0x105c0704,
+ rCLK_GATE_SCLK_DMC = 0x105c0800,
+ rCLK_GATE_IP_DMC0 = 0x105c0900,
+ rCLK_GATE_IP_DMC1 = 0x105c0904,
+ rCLKOUT_CMU_DMC = 0x105c0A00,
+ rCLKOUT_CMU_DMC_DIV_STAT = 0x105c0A04,
+// rDMC_FREQ_CTRL = 0x105c1090,
+ rDMC_PAUSE_CTRL = 0x105c1094,
+ rDDR_PHY_LOCK_CTRL = 0x105c1098,
+// rMIF_SEMAPHORE0 = 0x105c2000,
+// rMIF_SEMAPHORE1 = 0x105c2004,
+// rMIF_SEMAPHORE2 = 0x105c2008,
+// rCMU_CORE_SPARE0 = 0x105c200C,
+// rCMU_CORE_SPARE1 = 0x105c2010,
+ rCMU_DMC_SPARE0 = 0x105c2000,
+ rCMU_DMC_SPARE1 = 0x105c2004,
+// rDIVDMC_RATIO_DYN_CLK_GATE_CON = 0x105c3000,
+
+ //ACP(CORE_R) 0x10450000
+ rCLK_SRC_ACP = 0x10450300,
+ rCLK_SRC_MASK_ACP = 0x10450304,
+ rCLK_MUX_STAT_ACP0 = 0x10450400,
+ rCLK_MUX_STAT_ACP1 = 0x10450404,
+ rCLK_DIV_ACP0 = 0x10450500,
+ rCLK_DIV_ACP1 = 0x10450504,
+ rCLK_DIV_STAT_ACP0 = 0x10450600,
+ rCLK_DIV_STAT_ACP1 = 0x10450604,
+ rCLK_GATE_BUS_ACP0 = 0x10450700,
+ rCLK_GATE_BUS_ACP1 = 0x10450704,
+ rCLK_GATE_SCLK_ACP = 0x10450800,
+ rCLK_GATE_IP_ACP0 = 0x10450900,
+ rCLK_GATE_IP_ACP1 = 0x10450904,
+ rCLKOUT_CMU_ACP = 0x10450A00,
+ rCLKOUT_CMU_ACP_DIV_STAT = 0x10450A04,
+// rDCGIDX_MAP0 = 0x10451000,
+// rDCGIDX_MAP1 = 0x10451004,
+// rDCGIDX_MAP2 = 0x10451008,
+// rDCGPERF_MAP0 = 0x10451020,
+// rDCGPERF_MAP1 = 0x10451024,
+// rDVCIDX_MAP = 0x10451040,
+// rFREQ_CPU = 0x10451060,
+// rFREQ_DPM = 0x10451064,
+// rDVSEMCLK_EN = 0x10451080,
+// rMAXPERF = 0x10451084,
+ rCMU_ACP_SPARE0 = 0x10452000,
+ rCMU_ACP_SPARE1 = 0x10452004,
+ rCMU_ACP_SPARE2 = 0x10452008,
+ rCMU_ACP_SPARE3 = 0x1045200C,
+ rCMU_ACP_SPARE4 = 0x10452010,
+
+};
+
+#define rPMU_DEBUG_CLKOUT (SYSC_PMU_BASE + 0x0A00)
+
+
+
+void CMU_Init(u32 nARMCLK);
+void CMU_InitForMif(u32 uMemClk);
+
+#endif //__CMU_H__
+
diff --git a/board/samsung/xyref4415/display.c b/board/samsung/xyref4415/display.c new file mode 100644 index 000000000..2f8a164d6 --- /dev/null +++ b/board/samsung/xyref4415/display.c @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <lcd.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mipi_dsim.h> +#if defined(CONFIG_S6E8AA0) +#include "logo_588x95.h" +#elif defined(CONFIG_HX8369) +#include "logo_305x50.h" +#elif defined(CONFIG_NT35512) +#include "logo_305x50.h" +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* For panel info */ +#if defined(CONFIG_S6E8AA0) +#define XYREF4415_LCD_TYPE "s6e8aa0" +#define XYREF4415_HBP 11 +#define XYREF4415_HFP 11 +#define XYREF4415_VBP 3 +#define XYREF4415_VFP 3 +#define XYREF4415_HSP 2 +#define XYREF4415_VSW 2 +#define XYREF4415_XRES 800 +#define XYREF4415_YRES 1280 +#define XYREF4415_VIRTUAL_X 800 +#define XYREF4415_VIRTUAL_Y 1280 * 2 +#define XYREF4415_WIDTH 71 +#define XYREF4415_HEIGHT 114 +#define XYREF4415_MAX_BPP 32 +#define XYREF4415_DEFAULT_BPP 24 +#define XYREF4415_DEFAULT_FREQ 60 + +#elif defined(CONFIG_HX8369) +#define XYREF4415_LCD_TYPE "hx8369" +#define XYREF4415_HBP 150 +#define XYREF4415_HFP 180 +#define XYREF4415_VBP 20 +#define XYREF4415_VFP 20 +#define XYREF4415_HSP 32 +#define XYREF4415_VSW 2 +#define XYREF4415_XRES 480 +#define XYREF4415_YRES 800 +#define XYREF4415_VIRTUAL_X 480 +#define XYREF4415_VIRTUAL_Y 800 * 2 +#define XYREF4415_WIDTH 56 +#define XYREF4415_HEIGHT 94 +#define XYREF4415_MAX_BPP 32 +#define XYREF4415_DEFAULT_BPP 24 +#define XYREF4415_DEFAULT_FREQ 60 + +#elif defined(CONFIG_NT35512) +#define XYREF4415_LCD_TYPE "nt35512" +#define XYREF4415_HBP 8 +#define XYREF4415_HFP 8 +#define XYREF4415_VBP 8 +#define XYREF4415_VFP 27 +#define XYREF4415_HSP 2 +#define XYREF4415_VSW 2 +#define XYREF4415_XRES 480 +#define XYREF4415_YRES 800 +#define XYREF4415_VIRTUAL_X 480 +#define XYREF4415_VIRTUAL_Y 800 * 2 +#define XYREF4415_WIDTH 56 +#define XYREF4415_HEIGHT 94 +#define XYREF4415_MAX_BPP 32 +#define XYREF4415_DEFAULT_BPP 24 +#define XYREF4415_DEFAULT_FREQ 60 + +#endif + +/* For dsim info */ +#if defined(CONFIG_S6E8AA0) +#define DSIM_DATA_LANE DSIM_DATA_LANE_4 +#define DSIM_PLL_OUT_DIV DSIM_PLL_OUT_DIV8 +#define DSIM_BURST_MODE DSIM_BURST +#define DSIM_P 2 +#define DSIM_M 50 +#define DSIM_S 0 +#define DSIM_ESC_CLK 20 * 1000000 /* escape clk : 20MHz */ + +#elif defined(CONFIG_HX8369) +#define DSIM_DATA_LANE DSIM_DATA_LANE_2 +#define DSIM_PLL_OUT_DIV DSIM_PLL_OUT_DIV8 +#define DSIM_BURST_MODE DSIM_BURST +#define DSIM_P 2 +#define DSIM_M 80 +#define DSIM_S 1 +#define DSIM_ESC_CLK 20 * 1000000 /* escape clk : 20MHz */ + +#elif defined(CONFIG_NT35512) +#define DSIM_DATA_LANE DSIM_DATA_LANE_2 +#define DSIM_PLL_OUT_DIV DSIM_PLL_OUT_DIV8 +#define DSIM_BURST_MODE DSIM_BURST +#define DSIM_P 2 +#define DSIM_M 80 +#define DSIM_S 1 +#define DSIM_ESC_CLK 20 * 1000000 /* escape clk : 20MHz */ +#endif + +#if defined(CONFIG_S6E8AA0) +static void lcd_reset(void) +{ + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* 1.8v Level Sequence: H->L->H */ + s5p_gpio_direction_output(&gpio2->x2, 4, 1); + udelay(10000); + s5p_gpio_direction_output(&gpio2->x2, 4, 0); + udelay(10000); + s5p_gpio_direction_output(&gpio2->x2, 4, 1); +} + +static int lcd_power(void) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* power1 GPX2-5 */ + s5p_gpio_direction_output(&gpio2->x2, 5, 0); + s5p_gpio_direction_output(&gpio2->x2, 5, 1); + /* power2 GPD0-0 */ + s5p_gpio_direction_output(&gpio1->d0, 0, 0); + s5p_gpio_direction_output(&gpio1->d0, 0, 1); + + return 0; +} + +static int mipi_power(void) +{ + /* + * MIPI power already enabled on smdk4270 board as default + * LDO7: VDD10 1.0v , LDO8: VDD18 1.8v + */ + return 0; +} + +static void get_logo_info(vidinfo_t *vid) +{ + vid->logo_width = 588; + vid->logo_height = 95; + vid->logo_addr = (ulong)gzip_bmp_logo; +} +#elif defined(CONFIG_HX8369) +static void lcd_reset(void) +{ + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* 1.8v Level Sequence: H->L->H */ + s5p_gpio_direction_output(&gpio2->x2, 4, 1); + udelay(20000); + s5p_gpio_direction_output(&gpio2->x2, 4, 0); + udelay(20000); + s5p_gpio_direction_output(&gpio2->x2, 4, 1); +} + +static int lcd_power(void) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* power1 GPM1-6 */ + s5p_gpio_direction_output(&gpio2->m1, 6, 0); + s5p_gpio_direction_output(&gpio2->m1, 6, 1); + /* power2 GPM4-5 */ + s5p_gpio_direction_output(&gpio2->m4, 5, 0); + s5p_gpio_direction_output(&gpio2->m4, 5, 1); + udelay(20000); + + /* backlight GPD0-1 */ + s5p_gpio_direction_output(&gpio1->d0, 1, 0); + s5p_gpio_direction_output(&gpio1->d0, 1, 1); + + lcd_reset(); + + return 0; +} + +static int mipi_power(void) +{ + /* + * MIPI power already enabled on smdk4270 board as default + * LDO7: VDD10 1.0v , LDO8: VDD18 1.8v + */ + return 0; +} + +static void get_logo_info(vidinfo_t *vid) +{ + vid->logo_width = 305; + vid->logo_height = 50; + vid->logo_addr = (ulong)gzip_bmp_logo; +} + +#elif defined(CONFIG_NT35512) +static void lcd_reset(void) +{ + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* 1.8v Level Sequence: H->L->H */ + s5p_gpio_direction_output(&gpio2->x2, 4, 1); + udelay(20000); + s5p_gpio_direction_output(&gpio2->x2, 4, 0); + udelay(20000); + s5p_gpio_direction_output(&gpio2->x2, 4, 1); +} + +static int lcd_power(void) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); + + /* backlight GPD0-1 */ + s5p_gpio_direction_output(&gpio1->d0, 1, 0); + mdelay(1); + s5p_gpio_direction_output(&gpio1->d0, 1, 1); + + mdelay(150); + lcd_reset(); + mdelay(150); + + return 0; +} + +static int mipi_power(void) +{ + /* + * MIPI power already enabled on smdk4270 board as default + * LDO7: VDD10 1.0v , LDO8: VDD18 1.8v + */ + return 0; +} + +static void get_logo_info(vidinfo_t *vid) +{ + vid->logo_width = 305; + vid->logo_height = 50; + vid->logo_addr = (ulong)gzip_bmp_logo; +} +#endif + +static struct mipi_dsim_config dsim_config = { + .e_interface = DSIM_VIDEO, + .e_pixel_format = DSIM_24BPP_888, + + .auto_flush = 0, + .eot_disable = 1, + .auto_vertical_cnt = 0, + + .hse = 0, + .hfp = 0, + .hbp = 0, + .hsa = 0, + + .e_no_data_lane = DSIM_DATA_LANE, + .e_byte_clk = DSIM_PLL_OUT_DIV, + .e_burst_mode = DSIM_BURST_MODE, + + .e_virtual_ch = DSIM_VIRTUAL_CH_0, + + .p = DSIM_P, + .m = DSIM_M, + .s = DSIM_S, + + .esc_clk = DSIM_ESC_CLK, /* escape clk : 20MHz */ + + /* stop state holding counter after bta change count 0 ~ 0xfff */ + .stop_holding_cnt = 0x0fff, + /* bta timeout 0 ~ 0xff */ + .bta_timeout = 0xff, + /* lp rx timeout 0 ~ 0xffff */ + .rx_timeout = 0xffff, + /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */ + .pll_stable_time = 0xffffff, +}; + +static struct exynos_platform_mipi_dsim dsim_platform_data = { + .lcd_panel_info = NULL, + .dsim_config = &dsim_config, +}; + +static struct mipi_dsim_lcd_device mipi_lcd_device = { + .name = XYREF4415_LCD_TYPE, + .id = -1, + .bus_id = 0, + .platform_data = (void *)&dsim_platform_data, +}; + +vidinfo_t panel_info = { + .vl_col = XYREF4415_XRES, /* Number of columns (i.e. 640) */ + .vl_row = XYREF4415_YRES, /* Number of rows (i.e. 480) */ + .vl_width = XYREF4415_XRES, /* Width of display area in millimeters */ + .vl_height = XYREF4415_YRES, /* Height of display area in millimeters */ + + /* LCD configuration register */ + .vl_freq = XYREF4415_DEFAULT_FREQ, /* Frequency */ + .vl_clkp = CONFIG_SYS_HIGH,/* Clock polarity */ + .vl_hsp = CONFIG_SYS_LOW, /* Horizontal Sync polarity */ + .vl_vsp = CONFIG_SYS_LOW, /* Vertical Sync polarity */ + .vl_dp = CONFIG_SYS_LOW, /* Data polarity */ + .vl_bpix = 5, /* Bits per pixel, 2^5 = 32 */ + + /* Horizontal control register. Timing from data sheet */ + .vl_hspw = XYREF4415_HSP, /* Horizontal sync pulse width */ + .vl_hfpd = XYREF4415_HFP, /* Wait before of line */ + .vl_hbpd = XYREF4415_HBP, /* Wait end of line */ + + /* Vertical control register. */ + .vl_vspw = XYREF4415_VSW, /* Vertical sync pulse width */ + .vl_vfpd = XYREF4415_VFP, /* Wait before of frame */ + .vl_vbpd = XYREF4415_VBP, /* Wait end of frame */ + .vl_stable_vfp = 1, + .vl_cmd_allow_len = 0, /* Wait end of frame */ + + .cfg_gpio = NULL, + .backlight_on = NULL, + .lcd_power_on = NULL, /* lcd_power_on in mipi dsi driver */ + .reset_lcd = NULL, + .dual_lcd_enabled = 0, + + .win_id = 0, + .init_delay = 0, + .power_on_delay = 0, + .reset_delay = 0, + .interface_mode = FIMD_RGB_INTERFACE, + .mipi_enabled = 1, +}; + +#define HD_RESOLUTION 1 +void init_panel_info(vidinfo_t *vid) +{ + vid->logo_on = 1; + vid->resolution = HD_RESOLUTION; + vid->rgb_mode = MODE_BGR_P; +#ifdef CONFIG_TIZEN + get_tizen_logo_info(vid); +#else + get_logo_info(vid); +#endif + + strcpy(dsim_platform_data.lcd_panel_name, mipi_lcd_device.name); + dsim_platform_data.lcd_power = lcd_power; + dsim_platform_data.mipi_power = mipi_power; + dsim_platform_data.phy_enable = set_mipi_phy_ctrl; + dsim_platform_data.lcd_panel_info = (void *)vid; + exynos_mipi_dsi_register_lcd_device(&mipi_lcd_device); + dsim_lcd_init(); + exynos_set_dsim_platform_data(&dsim_platform_data); +} diff --git a/board/samsung/xyref4415/dmc_init.c b/board/samsung/xyref4415/dmc_init.c new file mode 100644 index 000000000..d144dd283 --- /dev/null +++ b/board/samsung/xyref4415/dmc_init.c @@ -0,0 +1,902 @@ +/* + * Memory setup for XYREF4415 board based on EXYNOS4 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/io.h> +#include <asm/arch/dmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include "setup.h" +#include "cmu.h" + +typedef int BOOT_STAT; +#define nRESET 1 +#define true 1 +#define DMC_BASE 0x106F0000 +#define PHY0_BASE 0x10600000 +#define PHY1_BASE 0x10610000 +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) ((*(volatile u32 *)(addr))) +#define SetBits(uAddr, uBaseBit, uMaskValue, uSetValue) \ + Outp32(uAddr, (Inp32(uAddr) & ~((uMaskValue)<<(uBaseBit))) | (((uMaskValue)&(uSetValue))<<(uBaseBit))) + +//---------------------------------------------------------------------------- +// +//- DMC Initialzation Script for LPDDR3 +// +//- Copyright 2013 by Samsung Electronics. All rights reserved. +// +//---------------------------------------------------------------------------- +void DMC_Delay(int msec) +{ + volatile u32 i; + for(;msec > 0; msec--); + for(i=0; i<1000; i++) ; +} + +void InitDMC(u32 MemClk, BOOT_STAT eRstStat) +{ + u32 utemp; + + //Outp32(0x105c0504, 546867200.); + Outp32(0x106F0000+0x0024, 0x00000003); + Outp32(0x10600000+0x0000, 0x17023A00); + Outp32(0x10610000+0x0000, 0x17023A00); + Outp32(0x10600000+0x00AC, 0x809); + Outp32(0x10610000+0x00AC, 0x809); + Outp32(0x10600000+0x0004, 0x09210001); + Outp32(0x10610000+0x0004, 0x09210001); + Outp32(0x10600000+0x000C, 0x00210842); + Outp32(0x10610000+0x000C, 0x00210842); + Outp32(0x10600000+0x0038, 0x001F000F); + Outp32(0x10610000+0x0038, 0x001F000F); + Outp32(0x10600000+0x0040, 0x0F0C0308); + Outp32(0x10610000+0x0040, 0x0F0C0308); + Outp32(0x10600000+0x0040, 0x0F0C030a); + Outp32(0x10610000+0x0040, 0x0F0C030a); + Outp32(0x10600000+0x0048, 0x1E9); + Outp32(0x10610000+0x0048, 0x1E9); + Outp32(0x10600000+0x0040, 0x0F0C0308); + Outp32(0x10610000+0x0040, 0x0F0C0308); + Outp32(0x106F0000+0x0018, 0x00003000); + Outp32(0x106F0000+0x0000, 0x1FFF1008); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0000, 0x0FFF1000); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x10600000+0x0010, 0x7f7f7f7f); + Outp32(0x10610000+0x0010, 0x7f7f7f7f); + Outp32(0x10600000+0x0018, 0x7f7f7f7f); + Outp32(0x10610000+0x0018, 0x7f7f7f7f); + Outp32(0x10600000+0x0028, 0x0000007f); + Outp32(0x10610000+0x0028, 0x0000007f); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0018, 0x00003008); + Outp32(0x106F0000+0x0018, 0x00003000); + Outp32(0x106F0000+0x0004, 0x00302740); + Outp32(0x106F0000+0x0008, 0x00001323); + Outp32(0x106F0000+0x000C, 0x00001323); + Outp32(0x106F0000+0x010C, 0x004007c0); + Outp32(0x106F0000+0x0014, 0xFF000000); + Outp32(0x106F0000+0x0028, 0xFFFF00FF); + + Outp32(0x106F0000+0x0030, 0x5d); // normal = 0x5d, half = 0x2e + + Outp32(0x106F0000+0x0034, 0x2C46450C); + Outp32(0x106F0000+0x0038, 0x3530460A); + Outp32(0x106F0000+0x003C, 0x442F0335); + Outp32(0x106F0000+0x0034, 0x2446648D); + Outp32(0x106F0000+0x0038, 0x35302509); + Outp32(0x106F0000+0x003C, 0x38270335); + Outp32(0x106F0000+0x00F0, 0x00000007); + + if (eRstStat ==nRESET) + { + Outp32(0x106F0000+0x0010, 0x07000000); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x00071C00); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x00010BFC); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x0000050C); + Outp32(0x106F0000+0x0010, 0x0000085C); + Outp32(0x106F0000+0x0010, 0x00000C04); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x17000000); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x10071C00); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x10010BFC); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x1000050C); + Outp32(0x106F0000+0x0010, 0x1000085C); + Outp32(0x106F0000+0x0010, 0x10000C04); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + } + + Outp32(0x10600000+0x0030, 0x10107f10); + Outp32(0x10610000+0x0030, 0x10107f10); + Outp32(0x10600000+0x0030, 0x10107f30); + Outp32(0x10610000+0x0030, 0x10107f30); + Outp32(0x10600000+0x0030, 0x10107f70); + Outp32(0x10610000+0x0030, 0x10107f70); + + while(1) + { + if(Inp32(0x10600034)&0x5==0x5) + break; + } + + #if 0 + utemp = (Inp32(0x10600000+0x0034)>>10)&0x7f; //forcing value + Outp32(0x10600000+0x0030, Inp32(0x10600000+0x0030)&(~(0x7f<<8))|(utemp<<8)); + Outp32(0x10600000+0x0030, Inp32(0x10600000+0x0030)&(~(0x1<<5))); //forcing value + #endif + + Outp32(0x10610000+0x0030, 0x10107f10); + Outp32(0x10610000+0x0030, 0x10107f30); + Outp32(0x10610000+0x0030, 0x10107f70); + + while(1) + { + if(Inp32(0x10610034)&0x5==0x5) + break; + } + + #if 0 + utemp = (Inp32(0x10610000+0x0034)>>10)&0x7f; //forcing value + Outp32(0x10610000+0x0030, Inp32(0x10610000+0x0030)&(~(0x7f<<8))|(utemp<<8)); + Outp32(0x10610000+0x0030, Inp32(0x10610000+0x0030)&(~(0x1<<5))); //forcing value + #endif + + //---------------- clock change + //Outp32(0x105C0504, 142641152.); + //Outp32(0x105C0800, 3.); + //Outp32(0x105C0300, 0x1510); + //Outp32(0x105C0218, 2171208705.); + // DMC_Delay(0x10000); //- GOSUB Waiting 0.3s + //Outp32(0x105C0300, 0x1510); + CMU_InitForMif(MemClk); + + + Outp32(0x10600000+0x0010, 0x08080808); + Outp32(0x10610000+0x0010, 0x08080808); + Outp32(0x10600000+0x0018, 0x08080808); + Outp32(0x10610000+0x0018, 0x08080808); + Outp32(0x10600000+0x0028, 0x00000008); + Outp32(0x10610000+0x0028, 0x00000008); + + while(1) + { + if(Inp32(0x10600000+0x0034)&0x1==0x1) + break; + } + while(1) + { + if(Inp32(0x10610000+0x0034)&0x1==0x1) + break; + } + + Outp32(0x106F0000+0x0000, 0x1FFF1008); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + DMC_Delay(0x10000); //- GOSUB Waiting 0.1s + Outp32(0x106F0000+0x0018, 0x5008); + Outp32(0x106F0000+0x0018, 0x5000); + Outp32(0x10600000+0x0000, 0x17023a00); + Outp32(0x10610000+0x0000, 0x17023a00); + Outp32(0x106F0000+0x0010, 0x01000000); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x01100000); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x11000000); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + Outp32(0x106F0000+0x0010, 0x11100000); + DMC_Delay(0x10000); //- GOSUB Waiting 100ms + + #if 0 + Outp32(0x106F0000+0x0004, 0x00302763); + Outp32(0x106F0000+0x0000, 0x0FFF1028); + #endif + Outp32(0x106F0000+0x001C, 0x17); // MEMIF_CG_EN off + Outp32(0x106F0000+0x0400, 0x00000001); // ALL_INIT_INDI[0]=all_init_done=0x1 + + // LPI handshaking w/a + SetBits(0x105C0700, 0, 0x1, 0); + // Checking Self-Refresh Status + #if 1 //- 1GB size + while(((Inp32(0x106F0048)>>8)&0x1)!=0x1); //- CH0 ChipStatus, chip_sref_state[8] (CS0) + while(((Inp32(0x106F004C)>>8)&0x1)!=0x1); //- CH1 ChipStatus, chip_sref_state[8] (CS0) + #else //- 2GB size + while(((Inp32(0x106F0048)>>8)&0x3)!=0x3); //- CH0 ChipStatus, chip_sref_state[9:8] (CS1,CS0) + while(((Inp32(0x106F004C)>>8)&0x3)!=0x3); //- CH1 ChipStatus, chip_sref_state[9:8] (CS1,CS0) + #endif + + //DMC_Delay(10000); + SetBits(0x105C0700, 0, 0x1, 1); + + // MEMIF_CG_EN off + Outp32(0x106F0000+0x001C, 0x1F); + + //check clockout setting + Outp32(0x10020A00, 0x00000000); + Outp32(0x105C0A00, 0x10004); + + #if 1 + Outp32(0x106F0000+0x0004, 0x00302762); //- Setting Power Down Mode, dynamic self refresh, dynamic power down : Enable + Outp32(0x106F0000+0x0018, 0x5002); //- SDLL dynamic power gating : Enable + Outp32(0x106F0000+0x0000, 0x0FFF1028); //- Auto Refresh : Enable + #endif + +} + +void InitDMC_temp(u32 MemClk, BOOT_STAT eRstStat) +{ + u32 IvSize=0x7; //Interleaved( 128-byte:0x7),Linear(512-Mbyte:0x1D) + u32 DrexCGEn=1; + u32 PhyCgEn=1; + u32 uBits; + u32 uCLK_Pause =true; + u32 uDLL_Lock0,uDLL_Lock1,uTemp; + u32 uIsWakeup; + u32 channel,chip; + + +//;------------------------------------------------------------------------------- +//; 0-0 Clock change to low (about 50Mhz) +//;------------------------------------------------------------------------------- +//; DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/8:19), COREP(1/2:15), CORED(1/2:11), MPLL_PRE(1/1:8) +//&uBits=(4.<<27.)|(1.<<23.)|(3.<<19.)|(1.<<15.)|(1.<<11.)|(0.<<8.);For DMC 40Mhz@800Mhz(BPLL), 53.3Mhz@1066Mhz(BPLL) +//d.s SD:0x105c0504 %LE %LONG &uBits //"rCLK_DIV_CORE_1" + + // DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/8:19), COREP(1/2:15), CORED(1/2:11), MPLL_PRE(1/1:8) + //uBits=(1<<27)|(1<<23)|(0<<19)|(1<<15)|(1<<11)|(0<<8)//For DMC 400Mhz + //uBits=(1<<27)|(1<<23)|(2<<19)|(1<<15)|(1<<11)|(0<<8)//For DMC 266Mhz + uBits=(4<<27)|(1<<23)|(3<<19)|(1<<15)|(1<<11)|(0<<8);//For DMC 40Mhz@BPLL800Mhz, 53.3Mhz@BPLL 1066Mhz + Outp32(0x105c0504, uBits); //"rCLK_DIV_CORE_1" + //Outp32(0x105C0300, 0x1510); //Phy BPLL 400Mhz Sel + + +//;------------------------------------------------------------------------------- +//; 0. Set PLControl to 2'b11 for reducing pipeline cycle +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x0024 0x00000003 + Outp32(DMC_BASE+0x0024 ,0x00000003); + + +//;------------------------------------------------------------------------------- +//; 1. To provide stable power for controller and memory device, +//; the controller must assert and hold CKE to a logic low level. +//;------------------------------------------------------------------------------- + +//;------------------------------------------------------------------------------- +//; 2. Set the right value to PHY control register0 for LPDDR2/3. If read +//; leveling is needed, check LPDDR2/3 IO calibration MRR data and match it +//; to PHY control register1's ctrl_rlvl_rdata_adj field. +//;------------------------------------------------------------------------------- +//;PHY_CON0 reset value 0x17020A40 +//; w_data[13] = 'h1; // [13] byte_rdlvl_en +//; w_data[12:11] = 'h3; // [12:11] 00:DDR2/LPDDR2, 01:DDR3, 10:LPDDR2, 11:LPDDR3 +//; w_data[5] = 'h1; // [5] drive ctrl_read_p* 1: LPDDR2/LPDDR3, 0:normal +//GOSUB write &PHY0_BASE+0x0000 0x17023A60 +//GOSUB write &PHY1_BASE+0x0000 0x17023A60 + + Outp32(PHY0_BASE+0x0000 ,0x17023A60); + Outp32(PHY1_BASE+0x0000 ,0x17023A60); + +//;PHY_CON1 reset value 0x09210100 +//; w_data[15:0] = 'h1; // [15:0] rdlvl_rddata_adj 16'h0100:DDR3(@byte_rdlvl_en=1), 16'h0001:LPDDR3(@byte_rdlvl_en=1) +//GOSUB write &PHY0_BASE+0x0004 0x09210101 +//GOSUB write &PHY1_BASE+0x0004 0x09210101 + Outp32(PHY0_BASE+0x0004 ,0x09210101); + Outp32(PHY1_BASE+0x0004 ,0x09210101); + +//;PHY_CON3 reset value 0x00210842 +//GOSUB write &PHY0_BASE+0x000C 0x00210842 +//GOSUB write &PHY1_BASE+0x000C 0x00210842 + Outp32(PHY0_BASE+0x000C ,0x00210842); + Outp32(PHY1_BASE+0x000C ,0x00210842); + +//;PHY_CON14 reset value 0x001F0000 +//;w_data[3:0] = 'hF; // [3:0] F:LPDDR2/LPDDR3, 0:Gate Leveing in DDR3(not normal) +//GOSUB write &PHY0_BASE+0x0038 0x001F000F +//GOSUB write &PHY1_BASE+0x0038 0x001F000F + Outp32(PHY0_BASE+0x0038 ,0x001F000F); + Outp32(PHY1_BASE+0x0038 ,0x001F000F); + + +//;PHY_CON16 reset value 0x08000304 +//;w_data[19] = 'h1; // [19] zq_mode_noterm. 1:termination disable, 0:termination enable/ +//GOSUB write &PHY0_BASE+0x0040 0x08080304 +//GOSUB write &PHY1_BASE+0x0040 0x08080304 + Outp32(PHY0_BASE+0x0040 ,0x08080304); + Outp32(PHY1_BASE+0x0040 ,0x08080304); + + +//; PHYCONTROL0 reset value 0x00000000 +//; w_data[28:24] = 'h1F; // [28:24] ctrl_pd. +//; w_data[15:12] = 'h9; // [15:12] Recovery Time From PHY Clock Gate. minimum value is 0x3 +//; w_data[0] = 'h1; // [0] Memory Termination between chips. 0:disable, 1:Enable +//GOSUB write &DMC_BASE+0x0018 0x01F09001 +//; fpga - GOSUB write &DMC_BASE+0x0018 0x1f749a05 + Outp32(DMC_BASE+0x0018 ,0x01F09001); + + +//;------------------------------------------------------------------------------- +//; 3. Assert dfi_init_start field to high but the aref_en should be off +//;------------------------------------------------------------------------------- +//;------------------------------------------------------------------------------- +//; 4. Wait dfi_init_complete +//;------------------------------------------------------------------------------- +//; CONCONTROL reset value 0x0FFF1100 +//; w_data[28] = 1'b1; // dfi_init_start +//; w_data[27:16] = 12'hFFF; // timeout_cnt +//; w_data[15] = 1'b0; // Reserved +//; w_data[14:12] = 4'h1; // rd_fetch. 0x2:LPDDR3 800MHz/ 0x1:Other cases +//; w_data[11:9] = 1'b0; // Reserved +//; w_data[8] = 1'b0; // chip_empty, read-only +//; w_data[7:6] = 2'b0; // Reserved +//; w_data[5] = 1'b0; // Auto-Refresh cnt En. ** Auto refresh cont. On +//; w_data[4] = 1'b0; // Reserved +//; w_data[3] = 1'b1; // IO Powerdown Control in Low Power Mode(through LPI) +//; // 0x0 = Use Programmed ctrl_pd and pulldown control +//; // 0x1 = Automatic control for ctrl_pd and pulldown control +//; w_data[2:1] = 2'b0; // clock ratio between aclk and cclk (0 - 1:1, 1 - 1:2) +//; w_data[0] = 1'b0; // Reserved + +//GOSUB write &DMC_BASE+0x0000 0x1FFF1008 ; DFI_INIT_START '1' & aref'0' step 4 +//Wait 100ms ; check DFI_INIT_COMPLETE step 5 + Outp32(DMC_BASE+0x0000 ,0x1FFF1008); + DMC_Delay(100); // + +//;------------------------------------------------------------------------------- +//; 5. Set ConControl. Deassert dfi_init_start field to low +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x0000 0x0FFF1000 ; DFI_INIT_START '0' & aref'0' step 6 +//Wait 100ms + Outp32(DMC_BASE+0x0000 ,0x0FFF1000); + DMC_Delay(100); // + + +//;------------------------------------------------------------------------------- +//; 6. Set PhyControl0.fp_resync to '1' to DLL information +//; 7. Set PhyControl0.fp_resync to '0' +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x0018 0x00000008 ; [3] 1'b1 Force DLL resync step 7 +//GOSUB write &DMC_BASE+0x0018 0x00000000 ; [3] 1'b0 + Outp32(DMC_BASE+0x0018 ,0x00000008); + Outp32(DMC_BASE+0x0018 ,0x00000000); + +//;------------------------------------------------------------------------------- +//; 8. Set MemControl. All power down modes should be off +//;------------------------------------------------------------------------------- +//;MEMCONTROL reset value 0x00202601 +//GOSUB write &DMC_BASE+0x0004 0x00312700 ; Memory Control Register +// ; [22:20] 3'b011 Memory Burst length 8 +// ; [19:16] 4'b0001 2chips +// ; [15:12] 4'b0010 Width of Memory Data Bus 32bit +// ; [11:8]4'b0111 LPDDR3 +// ; [7:6] 2'b00 Additional Latency for PALL in cclk cycle +// ; [5] 1'b0 dynamic self refresh disable +// ; [4] 1'b0 timeout precharge +// ; [3:2] 1'b0 type of dynamic power down , active/precharge power down +// ; [1] 1'b0 dynamic power down disable +// ; [0] 1'b0 always running + Outp32(DMC_BASE+0x0004 ,0x00312700); + +//;------------------------------------------------------------------------------- +//; 9. Set MemConfig0/1 : ADDR/ROW/BANK bits step 10 MembaseConfig0/1 setting (0x010c) +//;------------------------------------------------------------------------------- +//;MEMCONFIG0,1 reset value 0x00001312 +//GOSUB write &DMC_BASE+0x0008 0x00001323 ; MemConfig0 step 11 +// ; [15:12] 4'b0001 address Mapping Method (AXI to Memory) interleaved ({row, bank, column, width}), +// ; [11:8]4'b0011 Number of Column Address Bits 10bit +// ; [7:4] 4'b0010 Number of Row Address Bits 14bit +// ; [3:0] 4'b0011 Number of Banks 8 banks +//GOSUB write &DMC_BASE+0x000C 0x00001323 + Outp32(DMC_BASE+0x0008 ,0x00001323); + Outp32(DMC_BASE+0x000C ,0x00001323); + + +//;------------------------------------------------------------------------------- +//; 10. Set MemBaseConfig0/1 +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x010C 0x004007C0 ; MemBaseConfig0 step 10 +// ; [26:16] AXI Base Address for Chip0 0x40000000 +// ; [10:0] 1GB, then chip_mask is 0x7C0. + +//GOSUB write &DMC_BASE+0x0110 0x008007C0 ; MemBaseConfig1 +// ; [26:16] AXI Base Address for Chip1 0x80000000 +// ; [10:0] 1GB, then chip_mask is 0x7C0. + Outp32(DMC_BASE+0x010C ,0x004007C0); + Outp32(DMC_BASE+0x0110 ,0x008007C0); + +//;------------------------------------------------------------------------------- +//; 11. Set PrechConfig and PwrdnConfig +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x0014 0xFF000000 ; PrechConfig step 12 +// ; [31:24] 0xff Timeout Precharge Cycles +// ; [15:8] Memory Chip1 Precharge Bank Selective Policy +// ; [7:0] Memory Chip0 Precharge Bank Selective Policy +//GOSUB write &DMC_BASE+0x0028 0xFFFF00FF ; PwrdnConfig +// ; [31:16] Number of Cycles for dynamic self refresh entry +// ; [7:0] Number of Cycles for dynamic power down entry + Outp32(DMC_BASE+0x0014 ,0xFF000000); + Outp32(DMC_BASE+0x0028 ,0xFFFF00FF); + +//;------------------------------------------------------------------------------- +//;12. Set the TimingAref, TimingRow, TimingData and TimingPower registers +//; according to memory AC parameters. At this moment, TimingData.wl and TimingData.rl +//; registers must be programmed according to initial clock frequency +//;------------------------------------------------------------------------------- + +//GOSUB write &DMC_BASE+0x0030 0x0000005d ; TimingAref step 13 +// ; [15:0] Average Periodic Refresh Interval +// ; t_refi * T(rclk) should be less than or equal to the minimum value of memory tREFI (all bank), +// ; for example, for the all bank refresh period of 7.8us, and an rclk frequency of 12MHz, +// ; the following value should be programmed into it: 7.8 us * 12 MHz = 93 + Outp32(DMC_BASE+0x0030 ,0x0000005d); + +//if &MCLK==667 +//( +//; TIMINGROW reset value 0x1F233286 +//; w_data[31:24] = 8'h57; //tRFCab 130 /1.5 = 86.7 t_rfc = timing_row[31:24]; +//; w_data[23:20] = 4'h7; //tRRD max(2Tck,10ns) = 10 /1.5 = 6.7 t_rrd = timing_row[23:20]; +//; w_data[19:16] = 4'hE; //tRP 21 /1.5 = 14 t_rp = timing_row[19:16]; +//; w_data[15:12] = 4'hC; //tRCD 18 /1.5 = 12 t_rcd = timing_row[15:12]; +//; w_data[11: 6] = 6'h28; //tRC 60 /1.5 = 40 t_rc = timing_row[11:6]; +//; w_data[ 5: 0] = 6'h1C; //tRAS 42 /1.5 = 28 t_ras = timing_row[5:0]; +// GOSUB write &DMC_BASE+0x0034 0x577ECA1C + +if (MemClk==667) +{ + Outp32(DMC_BASE+0x0034 ,0x577ECA1C); + Outp32(DMC_BASE+0x0038 ,0x5A53360C); + Outp32(DMC_BASE+0x003C ,0x885E05AA); + +} +else if(MemClk==667) +{ + Outp32(DMC_BASE+0x0034 ,0x2336544C); + Outp32(DMC_BASE+0x0038 ,0x24202408); + Outp32(DMC_BASE+0x003C ,0x38260235); + +} +else +{ + Outp32(DMC_BASE+0x0034 ,0x03598691); + Outp32(DMC_BASE+0x0038 ,0x3833060c); + Outp32(DMC_BASE+0x003C ,0x50c80365); +} + + +//; TIMINGDATA reset value 0x1230360C +//; w_data[31:28] = 4'h5; //tWTR max(4Tck,7.5ns) = 7.5 /1.5 = 5 t_wtr = timing_data[31:28]; +//; w_data[27:24] = 4'hA; //tWR max(4Tck,15ns) = 15 /1.5 = 10 t_wr = timing_data[27:24]; +//; w_data[23:20] = 4'h5; //tRTP max(4Tck,7.5ns) = 7.5 /1.5 = 5 t_rtp = timing_data[23:20]; +//; w_data[19:16] = 4'h3; //CL Reset Value. cl = timing_data[19:16]; +//; w_data[11: 8] = 4'h6; //WLmin 6 tCK wl = timing_data[11:8]; +//; w_data[ 3: 0] = 4'hC; //RLmin 12 tCK rl = timing_data[3:0]; +// GOSUB write &DMC_BASE+0x0038 0x5A53360C + +//; TIMINGPOWER reset value 0x381B0422 +//; w_data[31:26] = 6'h22; //tFAW max(8Tck,50ns) = 50 /1.5 = 33.4 t_faw = timing_power[31:26]; +//; w_data[25:16] = 10'h5E; //tXSRD max(2Tck,tRFC+10)= 140 /1.5 = 93.3 t_xsr = timing_power[25:16]; +//; // = tXSDLL @DDR3 +//; w_data[15: 8] = 8'h5; //tXP max(2Tck,7.5ns) = 7.5 /1.5 = 5 t_xp = timing_power[15:8]; +//; // =tXPDLL @DDR3 +//; w_data[ 7: 4] = 4'hA; //tCKESR max(3Tck,15ns) = 15 /1.5 = 10 t_cke = timing_power[7:4]; +//; w_data[ 3: 0] = 4'hA; // max(6Tck,15ns) = 15 /1.5 = 10 t_mrd = timing_power[3:0]; +// // = tMOD @DDR3 +// GOSUB write &DMC_BASE+0x003C 0x885E05AA +//) +//else if &MCLK==533 +//( +// GOSUB write &DMC_BASE+0x0034 0x2336544C +// GOSUB write &DMC_BASE+0x0038 0x24202408 +// GOSUB write &DMC_BASE+0x003C 0x38260235 +//) +//else ;&MCLK==400 +//( +// GOSUB write &DMC_BASE+0x0034 0x03598691 ;0x1A354349 +// GOSUB write &DMC_BASE+0x0038 0x3833060c ;0x23202306 +// GOSUB write &DMC_BASE+0x003C 0x50c80365 +//) + +//GOSUB write &DMC_BASE+0x00F0 0x000000007 ; IVCONTROL step ??? + Outp32(DMC_BASE+0x00F0 ,0x000000007); + +//;------------------------------------------------------------------------------- ; [7:0] Memory Channel Interleaving Size 0x07 = 128-byte, +//; 13. If QoS scheme is required... +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x0060 0x00ff_4b20 +//GOSUB write &DMC_BASE+0x0068 0x00ff_c0c0 +//GOSUB write &DMC_BASE+0x0070 0x00ff_5d10 +//GOSUB write &DMC_BASE+0x0078 0x00ff_b130 +//GOSUB write &DMC_BASE+0x0080 0x00ff_61f0 +//GOSUB write &DMC_BASE+0x0088 0x00ff_0fc0 +//GOSUB write &DMC_BASE+0x0090 0x00ff_f680 +//GOSUB write &DMC_BASE+0x0098 0x00ff_2160 +//GOSUB write &DMC_BASE+0x00A0 0x00ff_6dd0 +//GOSUB write &DMC_BASE+0x00A8 0x00ff_93c0 +//GOSUB write &DMC_BASE+0x00B0 0x00ff_2330 +//GOSUB write &DMC_BASE+0x00B8 0x00ff_fd60 +//GOSUB write &DMC_BASE+0x00C0 0x00ff_48f0 +//GOSUB write &DMC_BASE+0x00C8 0x00ff_d750 +//GOSUB write &DMC_BASE+0x00D0 0x00ff_4580 +//GOSUB write &DMC_BASE+0x00D8 0x000f_6920 + Outp32(DMC_BASE+0x0060 ,0x00ff4b20); + Outp32(DMC_BASE+0x0068 ,0x00ffc0c0); + Outp32(DMC_BASE+0x0070 ,0x00ff5d10); + Outp32(DMC_BASE+0x0078 ,0x00ffb130); + Outp32(DMC_BASE+0x0080 ,0x00ff61f0); + Outp32(DMC_BASE+0x0088 ,0x00ff0fc0); + Outp32(DMC_BASE+0x0090 ,0x00fff680); + Outp32(DMC_BASE+0x0098 ,0x00ff4b20); + Outp32(DMC_BASE+0x00A0 ,0x00ff4b20); + Outp32(DMC_BASE+0x00A8 ,0x00ff4b20); + Outp32(DMC_BASE+0x00B0 ,0x00ff4b20); + Outp32(DMC_BASE+0x00B8 ,0x00ff4b20); + Outp32(DMC_BASE+0x00C0 ,0x00ff4b20); + Outp32(DMC_BASE+0x00C8 ,0x00ff4b20); + Outp32(DMC_BASE+0x00D0 ,0x00ff4b20); + Outp32(DMC_BASE+0x00D8 ,0x00ff4b20); + + +#if 1 +//;------------------------------------------------------------------------------- +//; 14. Set the PHY for LPDDR2/3 intialization +//; If LPDDR2/3 initialization frequency is 20ns, then follow 15 ~21 +//;------------------------------------------------------------------------------- + +//;------------------------------------------------------------------------------- +//; 15. Set ctrl_offsetr0~3 and ctrl_offsetw0~3 to 0x7F +//;------------------------------------------------------------------------------- +//;GOSUB write &PHY0_BASE+0x0010 0x7f7f7f7f ; PHY_CON4 step 16 +// ; ctrl_offset_r=0x7f +//;GOSUB write &PHY1_BASE+0x0010 0x7f7f7f7f ; ctrl_offset_r=0x7f + Outp32(PHY0_BASE+0x0010 ,0x7f7f7f7f); + Outp32(PHY1_BASE+0x0010 ,0x7f7f7f7f); +//;------------------------------------------------------------------------------- +//; 16. Set ctrl_offsetd0~3 to 0x7F +//;------------------------------------------------------------------------------- +//;GOSUB write &PHY0_BASE+0x0018 0x7f7f7f7f ; PHY_CON6 +// ; ctrl_offset_w=0x7f +//;GOSUB write &PHY1_BASE+0x0018 0x7f7f7f7f ; ctrl_offset_w=0x7f + Outp32(PHY0_BASE+0x0018 ,0x7f7f7f7f); + Outp32(PHY1_BASE+0x0018 ,0x7f7f7f7f); +//;------------------------------------------------------------------------------- +//; 17. Set ctrl_force to 0x7F +//;------------------------------------------------------------------------------- +//;GOSUB write &PHY0_BASE+0x0028 0x0000007f ; PHY_CON10 step 17 +// ; ctrl_offset_d=0x7f +//;GOSUB write &PHY1_BASE+0x0028 0x0000007f ; ctrl_offset_d=0x7f + Outp32(PHY0_BASE+0x0028 ,0x0000007f); + Outp32(PHY1_BASE+0x0028 ,0x0000007f); +//;------------------------------------------------------------------------------- +//; 18. Set ctrl_dll_on to low +//;------------------------------------------------------------------------------- +//;GOSUB write &PHY0_BASE+0x0030 0x10107f70 ; PHY_CON12 step 18/step19 +// ; ctrl_force[14:8]=0x7f, ctrl_dll_on[5]=0 +//;GOSUB write &PHY1_BASE+0x0030 0x10107f70 ; ctrl_force[14:8]=0x7f, ctrl_dll_on[5]=0 +//;GOSUB write &PHY0_BASE+0x0030 0x10107f50 ; PHY_CON12 step 18/step19 +// ; ctrl_force[14:8]=0x7f, ctrl_dll_on[5]=0 +//;GOSUB write &PHY1_BASE+0x0030 0x10107f50 ; ctrl_force[14:8]=0x7f, ctrl_dll_on[5]=0 + Outp32(PHY0_BASE+0x0030 ,0x10107f70); + Outp32(PHY1_BASE+0x0030 ,0x10107f70); + Outp32(PHY0_BASE+0x0030 ,0x10107f50); + Outp32(PHY1_BASE+0x0030 ,0x10107f50); + +//;------------------------------------------------------------------------------- +//; 19. Wait for 10 PCLK +//;------------------------------------------------------------------------------- +//;Wait 100ms ; step 20 + DMC_Delay(100); +//;------------------------------------------------------------------------------- +//;20. Set the Phy Control.fp_resync bit '1' +//;------------------------------------------------------------------------------- +//;GOSUB write &DMC_BASE+0x0018 0x00000008 ; PHYCONTROL0 resync step 21 + Outp32(DMC_BASE+0x0018 ,0x00000008); + +//;------------------------------------------------------------------------------- +//;21. Set the Phy Control.fp_resync bit '0' +//;------------------------------------------------------------------------------- +//;GOSUB write &DMC_BASE+0x0018 0x00000000 ; PHYCONTROL0 resync step 22 + Outp32(DMC_BASE+0x0018 ,0x00000000); +#endif + +if ( eRstStat == nRESET ) +{ + for (channel=0; channel<2; channel++) + { + for (chip=0; chip<2; chip++) + { + //;------------------------------------------------------------------------------- + //; 22. Confirm that CKE has been as a logic low level at least 100ns after power on. + //;------------------------------------------------------------------------------- + //;------------------------------------------------------------------------------- + //; 23.Issue a NOP command using the DirectCmd register to assert and to hold CKE to a logic high level. + //;------------------------------------------------------------------------------- + //&mr1_400=0x0000050c + //&mr1_800=0x0000070c + + //; --------------------- + //; Direct Command P0 CH0 + //; --------------------- + //GOSUB write &DMC_BASE+0x0010 0x07000000 ; Direct Command NOP step 24 + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x07000000); + //;------------------------------------------------------------------------------- + //; 24. Wait for minimum 200us. + //;------------------------------------------------------------------------------- + //Wait 100ms ; step 25 + DMC_Delay(100); + //;------------------------------------------------------------------------------- + //;25. Issue a MRS command using the DirectCmd register to reset memory devices and program the + //; operating parameters. + //;------------------------------------------------------------------------------- + //GOSUB write &DMC_BASE+0x0010 0x00071C00 ; Direct Command MRS step 26 + // ; [18:16] ?? Related Bank Address when issuing a direct command + // ; [15:0] ?? Related Address value when issuing a direct command + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x00071C00); + //;------------------------------------------------------------------------------- + //; 26. Wait for minimum 10us. + //; 27. + //;------------------------------------------------------------------------------- + + + //Wait 100ms ; step 27 + //GOSUB write &DMC_BASE+0x0010 0x00010BFC ; Direct Command MRS step ?? + // ; [18:16] ?? Related Bank Address when issuing a direct command + // ; [15:0] ?? Related Address value when issuing a direct command + DMC_Delay(100); + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x00010BFC); + + //Wait 100ms + DMC_Delay(100); + if (MemClk==400) + { + //if &MCLK==400 + //( + // ;- nWR=6, Wrap, Sequential, BL4 + // GOSUB write &DMC_BASE+0x0010 0x00000000+&mr1_400 + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x0000050c); + // Wait 100ms + DMC_Delay(100); + // ;- RL=6, WL=3 + // GOSUB write &DMC_BASE+0x0010 0x00000810 + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x00000810); + // Wait 100ms + DMC_Delay(100); + //) + + } + else if(MemClk==667) + { + //else if &MCLK==667 + //{ + //; // [27:24] cmd_type + //; // [20] cmd_chip + //; // [18:16] cmd_bank + //; // [15:0] cmd_addr + //; // MA[7:0] = {cmd_addr[1:0], cmd_bank[2:0], cmd_addr[12:10]}, + //; // OP[7:0] = cmd_addr[9:2] + //; // MR1 : nWR, WC, BT, BL + //; // MA=0x01 = {cmd_addr[1:0], cmd_bank[2:0], cmd_addr[12:10]} = 00_000_001, + //; // OP=100_0_0_010 (nWR=12, Sequential, BL8) + //; // 0000_0000_0000_0_000_000_001_100_0_0_010_00 + //; // 0000_0000_0000_0000_0000_0110_0000_1000 + // GOSUB write &DMC_BASE+0x0010 0x0000050c + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x0000050c); + + //; // [27:24] cmd_type + //; // [20] cmd_chip + //; // [18:16] cmd_bank + //; // [15:0] cmd_addr + //; // MA[7:0] = {cmd_addr[1:0], cmd_bank[2:0], cmd_addr[12:10]}, + //; // OP[7:0] = cmd_addr[9:2] + //; // MR2 : RL&WL + //; // MA=0x02 = {cmd_addr[1:0], cmd_bank[2:0], cmd_addr[12:10]} = 00_000_010, + //; // OP=0x04 (RL=12, WL=6) + //; // 0000_0000_0000_0_000_000_010_00000100_00 + //; // 0000_0000_0000_0000_0000_1000_0001_0000 + // GOSUB write &DMC_BASE+0x0010 0x00000828 + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x00000828); + } + else + { + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x0000070c); + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x00000818); + + + } + Outp32(DMC_BASE+0x0010 ,(channel<<28)|(chip<<20)|0x00000C08); + //else + //( + // ;- nWR=8, Wrap, Sequential, BL4 + // GOSUB write &DMC_BASE+0x0010 0x00000000+&mr1_800 + // Wait 100ms + // ;- RL=?, WL=? + // GOSUB write &DMC_BASE+0x0010 0x00000818 + // Wait 100ms + // GOSUB write &DMC_BASE+0x0010 0x00000C08 ;DirectCmd chip0 MRS, MA03 40-ohm + // Wait 100ms + //) + } + + } +} + + +//;------------------------------------------------------------------------------- +//; 29. Set ctrl_offsetr0~3 and ctrl_offsetw0~3 to 0x0 +//;------------------------------------------------------------------------------- +//GOSUB write &PHY0_BASE+0x0010 0x00000000 +//GOSUB write &PHY1_BASE+0x0010 0x00000000 + Outp32(PHY0_BASE+0x0010 ,0x00000000); + Outp32(PHY1_BASE+0x0010 ,0x00000000); + +//;------------------------------------------------------------------------------- +//; 30. Set ctrl_offsetd to 0x0 +//;------------------------------------------------------------------------------- +//GOSUB write &PHY0_BASE+0x0028 0x00000000 +//GOSUB write &PHY1_BASE+0x0028 0x00000000 + Outp32(PHY0_BASE+0x0028 ,0x00000000); + Outp32(PHY1_BASE+0x0028 ,0x00000000); + +//;------------------------------------------------------------------------------- +//; 31. Set ctrl_dll_on enable +//;------------------------------------------------------------------------------- +//GOSUB write &PHY0_BASE+0x0030 0x10107f70 +//GOSUB write &PHY1_BASE+0x0030 0x10107f70 + Outp32(PHY0_BASE+0x0030 ,0x10107f70); + Outp32(PHY1_BASE+0x0030 ,0x10107f70); + +//;------------------------------------------------------------------------------- +//; 32. Set ctrl_start to 0 +//;------------------------------------------------------------------------------- +//GOSUB write &PHY0_BASE+0x0030 0x10107f30 +//GOSUB write &PHY1_BASE+0x0030 0x10107f30 + Outp32(PHY0_BASE+0x0030 ,0x10107f30); + Outp32(PHY1_BASE+0x0030 ,0x10107f30); +//;------------------------------------------------------------------------------- +//; 33. Set ctrl_start to 1 +//;------------------------------------------------------------------------------- +//GOSUB write &PHY0_BASE+0x0030 0x10107f70 +//GOSUB write &PHY1_BASE+0x0030 0x10107f70 + Outp32(PHY0_BASE+0x0030 ,0x10107f70); + Outp32(PHY1_BASE+0x0030 ,0x10107f70); + +//;------------------------------------------------------------------------------- +//; 34. Wait for 10 PCLK +//;------------------------------------------------------------------------------- +//; 35. Wait DFI_init complete +//;------------------------------------------------------------------------------- +//print "=== Waiting for 2nd DFI INIT COMPLETE (LPDDR3PHY) ===" +//wait 0.1s + DMC_Delay(100); +//;------------------------------------------------------------------------------- +//; 36. Set the Phy Control.fp_resync bit '1' +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x0018 0x1f749a0c + Outp32(DMC_BASE+0x0018 ,0x1f749a0c); +//;------------------------------------------------------------------------------- +//; 37. Set the Phy Control.fp_resync bit '0' +//;------------------------------------------------------------------------------- +//GOSUB write &DMC_BASE+0x0018 0x1f749a04 + Outp32(DMC_BASE+0x0018 ,0x1f749a04); + +//;------------------------------------------------------------------------------- +//; Skip 38 ~ 42 +//;------------------------------------------------------------------------------- + +//;------------------------------------------------------------------------------ +//; 43. Disable ctrl_atgate +//;------------------------------------------------------------------------------ +//GOSUB write &PHY0_BASE+0x0000 0x00023a00 +//GOSUB write &PHY1_BASE+0x0000 0x00023a00 + Outp32(PHY0_BASE+0x0000 ,0x00023a00); + Outp32(PHY1_BASE+0x0000 ,0x00023a00); + +//;------------------------------------------------------------------------------ +//; 43.-1 PALL command to memory using DirectCmd +//;------------------------------------------------------------------------------ +//GOSUB write &DMC_BASE+0x0010 0x01000000 +//Wait 100ms + Outp32(DMC_BASE+0x0010 ,0x01000000); + DMC_Delay(100); + +//GOSUB write &DMC_BASE+0x0010 0x01100000 +//Wait 100ms + Outp32(DMC_BASE+0x0010 ,0x01100000); + DMC_Delay(100); +//GOSUB write &DMC_BASE+0x0010 0x11000000 +//Wait 100ms + Outp32(DMC_BASE+0x0010 ,0x11000000); + DMC_Delay(100); +//GOSUB write &DMC_BASE+0x0010 0x11100000 +//Wait 100ms + Outp32(DMC_BASE+0x0010 ,0x11100000); + DMC_Delay(100); + +//;------------------------------------------------------------------------------ +//; 43.-2 Clock change to High +//;------------------------------------------------------------------------------ +//;;; DMC CLK Setting ;;; +//; DMC(1/2:27), DPHY(1/2:23), DMC_PRE(1/8:19), COREP(1/2:15), CORED(1/2:11), MPLL_PRE(1/1:8) +//&uBits=(0.<<27.)|(1.<<23.)|(1.<<19.)|(1.<<15.)|(1.<<11.)|(0.<<8.);For DMC 400Mhz~667Mhz +//d.s SD:0x105c0504 %LE %LONG &uBits //"rCLK_DIV_CORE_1" + uBits =(0<<27)|(1<<23)|(1<<19)|(1<<15)|(1<<11)|(0<<8); + Outp32(0x105c0504 ,uBits); + +//;------------------------------------------------------------------------------ +//; 44. If power_down modes are required, set the MemControl register. +//;------------------------------------------------------------------------------ + +// ;0x00312700 +//GOSUB write &DMC_BASE+0x0004 0x00312723 ; Memory Control Register step 9 //Phycon0 setting ϳ? +// ; [22:20] 3'b011 Memory Burst length 8 +// ; [19:16] 4'b0001 2chips +// ; [15:12] 4'b0010 Width of Memory Data Bus 32bit +// ; [11:8]4'b0111 LPDDR3 +// ; [7:6] 2'b00 Additional Latency for PALL in cclk cycle +// ; [5] 1'b1 dynamic self refresh eanble +// ; [4] 1'b0 timeout precharge +// ; [3:2] 1'b0 type of dynamic power down , active/precharge power down +// ; [1] 1'b1 dynamic power down enable +// ; [0] 1'b1 clk stop during idle + Outp32(DMC_BASE+0x0004 ,0x00312723); + +//; Start Auto-refresh +//;just before setting value 0x0FFF1000 ; DFI_INIT_START '0' & aref'0' step 6 +//;gaia setting 0x0FFF10E4 ; [7:6] 0x3 PHY Driving type ->static pull down -> spec out + +//;------------------------------------------------------------------------------ +//; 45. Set ConControl to turn on an auto refresh +//;------------------------------------------------------------------------------ +// ; [2:1] 0x2 ???? +//GOSUB write &DMC_BASE+0x0000 0x0FFF1028 ; [5] 1b'1 Auto Refresh Counter enable +// ; [3] 1b'1 Automatic control for ctrl_pd and pulldown control + Outp32(DMC_BASE+0x0000 ,0x0FFF1028); +//;------------------------------------------------------------------------------ +//; 46. Set the ALL_INIT_INDI register. +//;------------------------------------------------------------------------------ +//GOSUB write &DMC_BASE+0x0400 0x00000001 + Outp32(DMC_BASE+0x0400 ,0x00000001 ); + + +} + +void BTS_DMC_init(void) +{ + Outp32(0x106F0000+0x00B8, 0x00000080); + Outp32(0x106F0000+0x00B0, 0x00000080); + Outp32(0x106F0000+0x00A8, 0x00000080); + Outp32(0x106F0000+0x00A0, 0x00000080); +} + +void mem_ctrl_init (void) +{ + InitDMC(543, 1); + BTS_DMC_init(); +} + diff --git a/board/samsung/xyref4415/logo_305x50.h b/board/samsung/xyref4415/logo_305x50.h new file mode 100644 index 000000000..2b77571a8 --- /dev/null +++ b/board/samsung/xyref4415/logo_305x50.h @@ -0,0 +1,756 @@ +/* +* Image information, +* format: Compressed BMP(gzip), +* size: 305 x 50, +*/ +unsigned char gzip_bmp_logo[] = { +0x1F, 0x8B, 0x08, 0x08, 0x9A, 0xD6, 0x4B, 0x51, 0x00, 0x03, 0x6C, 0x6F, 0x67, 0x6F, 0x5F, 0x33, + 0x30, 0x35, 0x5F, 0x35, 0x30, 0x5F, 0x33, 0x32, 0x62, 0x69, 0x74, 0x2E, 0x62, 0x6D, 0x70, 0x00, + 0xE5, 0x9D, 0x05, 0xD4, 0x76, 0x45, 0xD5, 0x86, 0xC1, 0x4E, 0xEC, 0x2E, 0x6C, 0x6C, 0x41, 0xC5, + 0x16, 0x45, 0x45, 0x0C, 0x54, 0x54, 0xEC, 0x6E, 0x14, 0xBB, 0x51, 0x41, 0x97, 0x89, 0x8A, 0xDD, + 0xDD, 0x09, 0x76, 0x77, 0x60, 0x77, 0x77, 0x77, 0x61, 0x77, 0x9C, 0x9F, 0xEB, 0xFC, 0xEB, 0x3A, + 0xEB, 0x7E, 0xF6, 0x3B, 0x27, 0x9E, 0x4F, 0xE0, 0xD3, 0xF7, 0x9B, 0xB5, 0x66, 0x3D, 0x79, 0x26, + 0xF6, 0xEC, 0xD9, 0x3D, 0x7B, 0x76, 0xDF, 0xEB, 0x80, 0xC3, 0xB7, 0xEB, 0xCB, 0xAE, 0x47, 0xD4, + 0x9D, 0x8E, 0xA8, 0x3B, 0x6F, 0xBF, 0xDD, 0x76, 0xBB, 0x1C, 0xF1, 0xBA, 0xFD, 0x76, 0x3B, 0xF6, + 0xDF, 0xEF, 0x79, 0xC4, 0xEF, 0x87, 0xED, 0xF0, 0xFF, 0x35, 0x4A, 0x37, 0x57, 0xB7, 0xDF, 0x7E, + 0xFB, 0xEE, 0x18, 0xC7, 0x38, 0xC6, 0xCA, 0x77, 0xC7, 0x3E, 0xF6, 0xB1, 0xBB, 0x13, 0x9E, 0xF0, + 0x84, 0xFD, 0x7B, 0x7E, 0xE3, 0x33, 0xB5, 0xFE, 0x8F, 0xFF, 0xD4, 0xEF, 0x6A, 0xDB, 0xD4, 0xA5, + 0xDF, 0x6F, 0xB6, 0x7A, 0x54, 0xCF, 0x7F, 0x69, 0xFB, 0x7E, 0xDE, 0xD2, 0x7E, 0xA7, 0x9E, 0x67, + 0xFD, 0x8F, 0x73, 0x9C, 0xE3, 0x74, 0xC7, 0x3C, 0xE6, 0x31, 0xFB, 0x7A, 0xDC, 0xE3, 0x1E, 0xB7, + 0x3B, 0xD6, 0xB1, 0x8E, 0xD5, 0xFF, 0xC6, 0xF7, 0xBC, 0xAF, 0x38, 0xD2, 0xC2, 0xB9, 0xA3, 0xB2, + 0x32, 0x2E, 0xC6, 0xE2, 0x78, 0xFC, 0xFE, 0x78, 0xC7, 0x3B, 0xDE, 0xCA, 0xE7, 0xAD, 0x8D, 0x27, + 0xFF, 0x6B, 0xFB, 0xE2, 0xBF, 0x65, 0x7F, 0x57, 0x5C, 0x3F, 0xE9, 0x49, 0x4F, 0xDA, 0xED, 0xB4, + 0xD3, 0x4E, 0xDD, 0xA5, 0x2E, 0x75, 0xA9, 0x6E, 0xCF, 0x3D, 0xF7, 0xEC, 0x6E, 0x76, 0xB3, 0x9B, + 0x75, 0xF7, 0xBA, 0xD7, 0xBD, 0xBA, 0xFD, 0xF7, 0xDF, 0xBF, 0xDB, 0x6F, 0xBF, 0xFD, 0xBA, 0xEB, + 0x5D, 0xEF, 0x7A, 0xDD, 0x6E, 0xBB, 0xED, 0xD6, 0x5D, 0xE4, 0x22, 0x17, 0xE9, 0xCE, 0x74, 0xA6, + 0x33, 0x75, 0x27, 0x39, 0xC9, 0x49, 0x06, 0x7C, 0xE4, 0x15, 0x7C, 0xE1, 0x75, 0x6A, 0x4D, 0xFE, + 0xD7, 0xD6, 0xEA, 0xBF, 0x75, 0x8D, 0xB7, 0x36, 0x0D, 0x63, 0xED, 0xCF, 0x78, 0xC6, 0x33, 0x76, + 0xE7, 0x39, 0xCF, 0x79, 0xBA, 0x0B, 0x5E, 0xF0, 0x82, 0xDD, 0xC5, 0x2F, 0x7E, 0xF1, 0xEE, 0x0A, + 0x57, 0xB8, 0x42, 0x5F, 0xC1, 0x9F, 0x0B, 0x5F, 0xF8, 0xC2, 0xDD, 0xB9, 0xCE, 0x75, 0xAE, 0xEE, + 0xD4, 0xA7, 0x3E, 0x75, 0x4F, 0xDB, 0xB2, 0x4D, 0xF0, 0xE4, 0xA8, 0x86, 0x3F, 0x78, 0x78, 0x82, + 0x13, 0x9C, 0xA0, 0xEF, 0xFF, 0xEC, 0x67, 0x3F, 0x7B, 0x77, 0xBE, 0xF3, 0x9D, 0xAF, 0x1F, 0x27, + 0xF5, 0x02, 0x17, 0xB8, 0x40, 0x77, 0xBA, 0xD3, 0x9D, 0xAE, 0x3B, 0xF9, 0xC9, 0x4F, 0xDE, 0xD3, + 0xB2, 0x8A, 0xC3, 0x47, 0xC7, 0xF8, 0x8E, 0xAC, 0xF5, 0xD9, 0x5A, 0xF5, 0xE8, 0xDC, 0xDF, 0x2D, + 0x19, 0x2A, 0x71, 0xEA, 0x64, 0x27, 0x3B, 0x59, 0x77, 0xAD, 0x6B, 0x5D, 0xAB, 0x7B, 0xEA, 0x53, + 0x9F, 0xDA, 0xBD, 0xF7, 0xBD, 0xEF, 0xED, 0xBE, 0xFB, 0xDD, 0xEF, 0x76, 0xB5, 0xFC, 0xEB, 0x5F, + 0xFF, 0x1A, 0xDE, 0xFF, 0xF3, 0x9F, 0xFF, 0xEC, 0x7E, 0xF7, 0xBB, 0xDF, 0x75, 0x5F, 0xF8, 0xC2, + 0x17, 0xFA, 0xFF, 0x3F, 0xFA, 0xD1, 0x8F, 0xEE, 0x2E, 0x7B, 0xD9, 0xCB, 0xF6, 0xF8, 0x32, 0x86, + 0x07, 0xF0, 0x40, 0xDF, 0x2B, 0xE3, 0x39, 0x4F, 0x70, 0xC8, 0x31, 0xF9, 0x9D, 0xE3, 0x65, 0xEC, + 0xF5, 0x7F, 0x75, 0xFC, 0xD9, 0x67, 0x7D, 0x7E, 0x87, 0x1D, 0x76, 0xE8, 0x5F, 0xE5, 0xB7, 0xFC, + 0xEE, 0xB3, 0xD9, 0x86, 0xFF, 0xCB, 0xF6, 0xF2, 0xB3, 0x73, 0x39, 0xFE, 0xF1, 0x8F, 0x3F, 0xFC, + 0x9E, 0x32, 0x06, 0xAF, 0x8E, 0xCF, 0xF9, 0xF9, 0x9C, 0xFF, 0x63, 0x2E, 0xFE, 0x37, 0xFF, 0x33, + 0xB5, 0xEE, 0xD0, 0x09, 0xDF, 0x3B, 0x07, 0xDB, 0xC9, 0x71, 0x02, 0xDF, 0xFC, 0x9E, 0xB6, 0x12, + 0x5E, 0xBC, 0x77, 0xEC, 0xB5, 0x9F, 0xD6, 0xDC, 0x9D, 0xEF, 0x89, 0x4E, 0x74, 0xA2, 0x95, 0xEF, + 0xE9, 0x63, 0xEF, 0xBD, 0xF7, 0xEE, 0x9E, 0xF0, 0x84, 0x27, 0x74, 0xAF, 0x7F, 0xFD, 0xEB, 0xBB, + 0xCF, 0x7D, 0xEE, 0x73, 0xDD, 0xCF, 0x7E, 0xF6, 0xB3, 0xEE, 0x97, 0xBF, 0xFC, 0x65, 0xF7, 0xFB, + 0xDF, 0xFF, 0x7E, 0xC0, 0x91, 0x3F, 0xFD, 0xE9, 0x4F, 0x7D, 0xFD, 0xF6, 0xB7, 0xBF, 0xDD, 0x1D, + 0x76, 0xD8, 0x61, 0xDD, 0xAB, 0x5F, 0xFD, 0xEA, 0xEE, 0x3E, 0xF7, 0xB9, 0x4F, 0xB7, 0xF3, 0xCE, + 0x3B, 0xAF, 0xE0, 0x82, 0x55, 0xDC, 0xB1, 0x5F, 0xE7, 0xCA, 0x1A, 0x2D, 0x91, 0xE3, 0x7C, 0x9E, + 0x0A, 0x8D, 0xBA, 0xDB, 0xDD, 0xEE, 0xD6, 0x3D, 0xF3, 0x99, 0xCF, 0xEC, 0xDE, 0xF4, 0xA6, 0x37, + 0x75, 0x1F, 0xFF, 0xF8, 0xC7, 0xBB, 0xCF, 0x7F, 0xFE, 0xF3, 0xDD, 0xF7, 0xBE, 0xF7, 0xBD, 0x7E, + 0x8C, 0xBF, 0xF9, 0xCD, 0x6F, 0xBA, 0x6F, 0x7D, 0xEB, 0x5B, 0xDD, 0x67, 0x3F, 0xFB, 0xD9, 0xEE, + 0x7D, 0xEF, 0x7B, 0x5F, 0x77, 0xE8, 0xA1, 0x87, 0x76, 0x4F, 0x7A, 0xD2, 0x93, 0xBA, 0x1B, 0xDD, + 0xE8, 0x46, 0xDD, 0xE9, 0x4F, 0x7F, 0xFA, 0x15, 0x9C, 0xB5, 0xDD, 0x84, 0x43, 0xC2, 0x75, 0xAE, + 0x26, 0xDE, 0xE5, 0xDA, 0xA5, 0xFC, 0x27, 0x3C, 0x72, 0xAE, 0xFC, 0x5F, 0x58, 0x28, 0xE7, 0x66, + 0xBF, 0xEB, 0xC8, 0x8F, 0x2D, 0x7A, 0xBC, 0x94, 0xC6, 0x30, 0x9E, 0xDC, 0x8B, 0xB9, 0x67, 0x4E, + 0x7C, 0xE2, 0x13, 0xF7, 0x7C, 0xEA, 0x96, 0xB7, 0xBC, 0x65, 0xF7, 0xD0, 0x87, 0x3E, 0xB4, 0x3B, + 0xF8, 0xE0, 0x83, 0xBB, 0xC7, 0x3F, 0xFE, 0xF1, 0x3D, 0x6E, 0x3C, 0xF9, 0xC9, 0x4F, 0xEE, 0x9E, + 0xF8, 0xC4, 0x27, 0xF6, 0xB4, 0x01, 0xD9, 0x07, 0xBE, 0x86, 0xCC, 0x03, 0x1C, 0x13, 0x67, 0x6D, + 0xD7, 0xF9, 0x30, 0xC7, 0xC4, 0x8F, 0xDC, 0x33, 0x39, 0x76, 0xD7, 0x83, 0xF7, 0xE0, 0xD5, 0x37, + 0xBE, 0xF1, 0x8D, 0xEE, 0x8F, 0x7F, 0xFC, 0x63, 0xF7, 0xD7, 0xBF, 0xFE, 0x75, 0x85, 0x4E, 0xFD, + 0xE5, 0x2F, 0x7F, 0x59, 0xA1, 0x5D, 0x94, 0x7F, 0xFF, 0xFB, 0xDF, 0x2B, 0xAF, 0xFC, 0xC7, 0xF7, + 0xEF, 0x78, 0xC7, 0x3B, 0xBA, 0x3D, 0xF6, 0xD8, 0x63, 0x85, 0x8E, 0x30, 0xCF, 0xA4, 0x17, 0xB9, + 0xD7, 0xF9, 0xDF, 0xB5, 0xAF, 0x7D, 0xED, 0xEE, 0xD3, 0x9F, 0xFE, 0x74, 0xF7, 0xCD, 0x6F, 0x7E, + 0xB3, 0xFB, 0xFE, 0xF7, 0xBF, 0xDF, 0x7D, 0xE5, 0x2B, 0x5F, 0xE9, 0x69, 0x23, 0x9F, 0x19, 0x17, + 0xAF, 0x5F, 0xFE, 0xF2, 0x97, 0xFB, 0x57, 0x70, 0x11, 0xD9, 0x10, 0xBC, 0xAA, 0xEB, 0x52, 0xF1, + 0x9A, 0xF7, 0xB4, 0xFD, 0xA9, 0x4F, 0x7D, 0xAA, 0xA7, 0xC9, 0xEC, 0xA5, 0x2F, 0x7E, 0xF1, 0x8B, + 0x3D, 0x2E, 0xD3, 0x9E, 0xF5, 0xEB, 0x5F, 0xFF, 0xFA, 0xF0, 0x3D, 0xFF, 0x87, 0x37, 0x8B, 0x33, + 0xE2, 0x30, 0x70, 0xE4, 0x95, 0xBE, 0xA1, 0xD9, 0x3C, 0xF3, 0xD5, 0xAF, 0x7E, 0xB5, 0xFB, 0xD2, + 0x97, 0xBE, 0xD4, 0x8F, 0xEB, 0x6B, 0x5F, 0xFB, 0x5A, 0xFF, 0x99, 0x7D, 0x41, 0x7F, 0x9F, 0xF9, + 0xCC, 0x67, 0xBA, 0xE7, 0x3F, 0xFF, 0xF9, 0x2B, 0x34, 0x25, 0xC7, 0xC8, 0x3E, 0x7E, 0xE3, 0x1B, + 0xDF, 0xD8, 0xCF, 0x95, 0xE7, 0xA8, 0xB4, 0x61, 0x3B, 0x54, 0x7E, 0x63, 0xFE, 0xF4, 0x87, 0x5C, + 0x9C, 0x6D, 0x49, 0xEB, 0xD9, 0x6F, 0x8F, 0x79, 0xCC, 0x63, 0x7A, 0x78, 0xF1, 0x5F, 0xE6, 0xC1, + 0x98, 0x80, 0xE3, 0x77, 0xBE, 0xF3, 0x9D, 0xA1, 0x7D, 0xDA, 0xFD, 0xC8, 0x47, 0x3E, 0xD2, 0xE3, + 0x11, 0xCF, 0x52, 0x53, 0x8F, 0x4A, 0xDD, 0x2F, 0xF1, 0x85, 0x3E, 0x85, 0x33, 0x74, 0xEE, 0xBE, + 0xF7, 0xBD, 0x6F, 0x0F, 0xB3, 0x9F, 0xFE, 0xF4, 0xA7, 0x03, 0x8E, 0x8C, 0x15, 0x70, 0x09, 0x5A, + 0x21, 0x6E, 0x88, 0x5B, 0xD0, 0xB5, 0x97, 0xBE, 0xF4, 0xA5, 0xDD, 0x95, 0xAF, 0x7C, 0xE5, 0x0D, + 0xEB, 0x58, 0xF9, 0x52, 0xDD, 0x4B, 0xF2, 0x33, 0xC7, 0x57, 0xF9, 0xCA, 0xEE, 0xBB, 0xEF, 0xDE, + 0xC3, 0x8B, 0xF9, 0x83, 0xCF, 0xD0, 0xAB, 0x7F, 0xFC, 0xE3, 0x1F, 0xC3, 0x58, 0x1D, 0x2F, 0x63, + 0xFA, 0xDB, 0xDF, 0xFE, 0xD6, 0x8F, 0xC5, 0xC2, 0xFF, 0xFF, 0xF0, 0x87, 0x3F, 0xF4, 0x74, 0x8E, + 0xBD, 0xC8, 0xDE, 0xB4, 0xEF, 0x53, 0x9C, 0xE2, 0x14, 0x2B, 0xB0, 0xAA, 0xEB, 0x3A, 0x56, 0x2F, + 0x74, 0xA1, 0x0B, 0x75, 0x77, 0xBC, 0xE3, 0x1D, 0xBB, 0xBB, 0xDC, 0xE5, 0x2E, 0xDD, 0xDD, 0xEF, + 0x7E, 0xF7, 0xFE, 0xF5, 0x9E, 0xF7, 0xBC, 0x67, 0xB7, 0xEF, 0xBE, 0xFB, 0xF6, 0xFB, 0x1A, 0x3A, + 0xCB, 0xEB, 0x9D, 0xEF, 0x7C, 0xE7, 0x5E, 0x1E, 0x4C, 0xBA, 0x94, 0xB4, 0x23, 0xE7, 0x7A, 0xFD, + 0xEB, 0x5F, 0xBF, 0x6F, 0xEB, 0x0E, 0x77, 0xB8, 0x43, 0xDF, 0xDE, 0x54, 0xA5, 0x6F, 0xDA, 0xBE, + 0xEB, 0x5D, 0xEF, 0xDA, 0xF7, 0x83, 0xFE, 0xB4, 0x74, 0xEC, 0xD6, 0xCA, 0xDF, 0xA8, 0x97, 0xBC, + 0xE4, 0x25, 0xBB, 0xD7, 0xBC, 0xE6, 0x35, 0x3D, 0x2E, 0xFC, 0xF0, 0x87, 0x3F, 0xEC, 0x61, 0x97, + 0xF4, 0xC1, 0x35, 0xA7, 0x00, 0x67, 0xE4, 0x1D, 0x2A, 0x7C, 0xEE, 0x5D, 0xEF, 0x7A, 0x57, 0x4F, + 0xF3, 0x90, 0x9B, 0xB2, 0x4D, 0xD6, 0x3E, 0xF9, 0x90, 0xB0, 0x48, 0x18, 0x24, 0x7E, 0x20, 0x03, + 0xB0, 0x46, 0xAC, 0xF7, 0xAF, 0x7F, 0xFD, 0xEB, 0x61, 0x8D, 0x5D, 0xEF, 0x2A, 0x77, 0xF9, 0x99, + 0xF1, 0x80, 0x8B, 0x49, 0xC7, 0xF8, 0xFE, 0xCF, 0x7F, 0xFE, 0x73, 0xFF, 0x1B, 0x05, 0xBC, 0x85, + 0x26, 0x57, 0xF9, 0xC7, 0xFE, 0x2B, 0x0E, 0x5C, 0xF7, 0xBA, 0xD7, 0x1D, 0xFA, 0xE2, 0x35, 0xE7, + 0x2F, 0xCE, 0xFD, 0xFD, 0xEF, 0x7F, 0x1F, 0xBE, 0xBB, 0xC1, 0x0D, 0x6E, 0xD0, 0xE4, 0x25, 0x55, + 0x8E, 0x61, 0xEE, 0xFB, 0xEC, 0xB3, 0xCF, 0x0A, 0x0E, 0xD7, 0x62, 0xBB, 0xF6, 0x99, 0x78, 0x9B, + 0xED, 0xF8, 0xFE, 0x1A, 0xD7, 0xB8, 0x46, 0x77, 0xF8, 0xE1, 0x87, 0x0F, 0xCF, 0x42, 0xBF, 0x5B, + 0xF0, 0x02, 0x46, 0xC8, 0x1D, 0xC9, 0x47, 0x6D, 0x87, 0xF9, 0x5F, 0xF1, 0x8A, 0x57, 0xDC, 0x30, + 0x96, 0xB1, 0xC2, 0xF8, 0x2F, 0x76, 0xB1, 0x8B, 0xF5, 0x34, 0x47, 0xD9, 0x2D, 0x79, 0xF9, 0x2B, + 0x5F, 0xF9, 0xCA, 0x0D, 0xF0, 0xA2, 0xE4, 0xD8, 0x2C, 0xD0, 0xCE, 0x9C, 0x5B, 0xEE, 0x19, 0x60, + 0x97, 0xF2, 0x40, 0xFE, 0x0F, 0xDA, 0xFD, 0x9E, 0xF7, 0xBC, 0x67, 0x85, 0xC7, 0x65, 0x9F, 0xF4, + 0xC5, 0xFA, 0x8B, 0x43, 0xC0, 0x26, 0x71, 0x89, 0x02, 0x8E, 0x50, 0x2D, 0xE0, 0xF3, 0xD3, 0x9E, + 0xF6, 0xB4, 0x61, 0x4C, 0xAE, 0x9D, 0x78, 0x53, 0x79, 0x7E, 0x4B, 0x96, 0x70, 0xBC, 0xE7, 0x3F, + 0xFF, 0xF9, 0xFB, 0xB6, 0x7E, 0xF0, 0x83, 0x1F, 0xF4, 0xFD, 0x8E, 0xD1, 0x56, 0xD6, 0x88, 0xB1, + 0xB9, 0x56, 0x89, 0x6B, 0xCC, 0x2D, 0xF1, 0xEC, 0x27, 0x3F, 0xF9, 0x49, 0xBF, 0xEF, 0xD1, 0x43, + 0x5B, 0xF8, 0xB0, 0x44, 0x0E, 0xBA, 0xFF, 0xFD, 0xEF, 0xDF, 0xEF, 0x07, 0xE9, 0x25, 0x34, 0x12, + 0x18, 0xD0, 0x17, 0x7B, 0x9A, 0xFE, 0x81, 0x1D, 0xFF, 0x81, 0xBE, 0x28, 0x73, 0x2B, 0x97, 0x30, + 0x3F, 0xD6, 0x1D, 0xD8, 0xC0, 0x5B, 0x91, 0x3D, 0xE0, 0x9F, 0x14, 0xE8, 0xB3, 0xB2, 0xEE, 0x54, + 0x65, 0x4E, 0xF4, 0x4B, 0x7F, 0xC8, 0x47, 0xCA, 0x14, 0x4B, 0xEC, 0x91, 0xB9, 0x77, 0xE1, 0x13, + 0xE8, 0x5A, 0xC8, 0x29, 0xC0, 0xF7, 0x57, 0xBF, 0xFA, 0xD5, 0x06, 0xD8, 0xCA, 0x27, 0x78, 0x5F, + 0xE9, 0x47, 0xC5, 0x05, 0x64, 0xF7, 0x07, 0x3C, 0xE0, 0x01, 0xBD, 0x2D, 0xC2, 0xF5, 0x57, 0xB6, + 0x49, 0xFA, 0xE6, 0xBA, 0xA7, 0xDE, 0xC2, 0x7B, 0x6C, 0x14, 0x1F, 0xFD, 0xE8, 0x47, 0x07, 0x1C, + 0x4C, 0xDC, 0x64, 0xCE, 0xF2, 0x27, 0xF9, 0x55, 0xAE, 0xAD, 0x70, 0xE7, 0x3F, 0x49, 0x7F, 0x69, + 0x43, 0xBC, 0x65, 0x4D, 0x3E, 0xF8, 0xC1, 0x0F, 0x76, 0x3B, 0xEE, 0xB8, 0xE3, 0xD0, 0x6F, 0xD5, + 0x63, 0xD4, 0xAF, 0x2E, 0x71, 0x89, 0x4B, 0xF4, 0x74, 0x81, 0x71, 0x48, 0x07, 0x29, 0xB4, 0x6D, + 0xBF, 0xB6, 0xCD, 0x7F, 0x1E, 0xF9, 0xC8, 0x47, 0xF6, 0xF4, 0x9A, 0x3A, 0x25, 0x0F, 0xD3, 0xFE, + 0x63, 0x1F, 0xFB, 0xD8, 0xFE, 0x79, 0xC6, 0xEA, 0x9E, 0x6E, 0xE1, 0x37, 0x7D, 0xD1, 0xFE, 0x69, + 0x4E, 0x73, 0x9A, 0x1E, 0x66, 0xC0, 0x88, 0x4A, 0x1B, 0xCA, 0x2D, 0xD4, 0x1B, 0xDE, 0xF0, 0x86, + 0xC3, 0xDA, 0xB1, 0x0E, 0xD9, 0x66, 0xEE, 0x4F, 0x3E, 0xBF, 0xFC, 0xE5, 0x2F, 0xDF, 0xB0, 0x2F, + 0x5D, 0x13, 0x6C, 0x8C, 0xC0, 0xB1, 0xAE, 0xB9, 0xD5, 0xEF, 0x5D, 0x17, 0xFA, 0xE5, 0x59, 0xD7, + 0x58, 0x79, 0x84, 0xB5, 0x3E, 0xE4, 0x90, 0x43, 0xFA, 0x71, 0x24, 0xCD, 0xB2, 0x4D, 0x8A, 0x6B, + 0x45, 0x5B, 0xD8, 0x80, 0x80, 0x1B, 0x6B, 0x91, 0x3A, 0x4B, 0xE5, 0x07, 0xFE, 0xCE, 0x2B, 0xB2, + 0xA9, 0x73, 0x76, 0xBD, 0x79, 0x15, 0x66, 0x15, 0x9E, 0x95, 0x07, 0xD9, 0x77, 0xE2, 0x6F, 0x8E, + 0x15, 0x3C, 0x41, 0xC7, 0x00, 0x2E, 0xF2, 0x61, 0x64, 0x92, 0xA4, 0x51, 0xCA, 0xC5, 0xB9, 0xBE, + 0xC0, 0x80, 0xF1, 0xF1, 0x2C, 0x6D, 0x88, 0x27, 0x14, 0xE6, 0xCE, 0xF8, 0xC0, 0x27, 0xE9, 0xAB, + 0xFC, 0x31, 0xF9, 0x24, 0xBF, 0xFD, 0xF6, 0xB7, 0xBF, 0x5D, 0x59, 0x3B, 0xE9, 0x1C, 0x85, 0xE7, + 0xD0, 0x89, 0xE8, 0x47, 0xBA, 0xB2, 0x8E, 0x2F, 0x02, 0x19, 0xC8, 0x22, 0xED, 0x4C, 0xBE, 0xC9, + 0x67, 0x60, 0xC8, 0xEB, 0x45, 0x2F, 0x7A, 0xD1, 0xC9, 0xB6, 0xC0, 0xBF, 0xAB, 0x5E, 0xF5, 0xAA, + 0xC3, 0x1A, 0x4C, 0xC9, 0xC0, 0x16, 0xF7, 0xA3, 0xFB, 0x0A, 0x7D, 0xB9, 0xC5, 0x9B, 0xA7, 0x2A, + 0xF6, 0x71, 0x5E, 0x1F, 0xF8, 0xC0, 0x07, 0xF6, 0x6D, 0x40, 0x0B, 0xB5, 0x19, 0x30, 0x07, 0xFA, + 0xA0, 0x7D, 0x79, 0xD8, 0x18, 0x2E, 0xF8, 0x3F, 0xE6, 0xCF, 0x3A, 0x31, 0x0F, 0x60, 0x8F, 0xAE, + 0x0F, 0x3D, 0xB2, 0x3F, 0xE9, 0x78, 0xF2, 0x08, 0xF6, 0xA5, 0xEF, 0x4F, 0x7B, 0xDA, 0xD3, 0xF6, + 0xFB, 0x09, 0xFB, 0x44, 0xF6, 0xA1, 0x8C, 0xD5, 0x2A, 0xFC, 0x87, 0x7E, 0x19, 0x5F, 0x8E, 0xC9, + 0x22, 0x8F, 0x61, 0x8C, 0xCE, 0x89, 0x31, 0xF2, 0x3D, 0x74, 0xDF, 0xFD, 0x20, 0x3E, 0x56, 0x5C, + 0x64, 0x4C, 0xC8, 0xA4, 0x73, 0xEB, 0x42, 0xDB, 0xB4, 0x0B, 0x1F, 0x48, 0xD9, 0xA1, 0x05, 0x77, + 0xF5, 0xD5, 0xD7, 0xBD, 0xEE, 0x75, 0x2B, 0x6B, 0x49, 0x69, 0xC9, 0x12, 0xC0, 0x13, 0xDD, 0x0B, + 0x1E, 0xD5, 0xB2, 0x1D, 0x5A, 0xB1, 0x19, 0xC2, 0x9F, 0x5B, 0x25, 0xF5, 0x14, 0xFA, 0x7B, 0xD5, + 0xAB, 0x5E, 0x35, 0xCC, 0x59, 0xDA, 0xA3, 0xBF, 0xE3, 0x25, 0x2F, 0x79, 0xC9, 0x06, 0x39, 0xA5, + 0x55, 0xA4, 0x43, 0xE8, 0xA5, 0x09, 0x3B, 0x65, 0x26, 0x60, 0x8B, 0x4C, 0xEF, 0xFA, 0xE4, 0x9A, + 0xE4, 0xF3, 0x14, 0xF8, 0x04, 0xBA, 0x4D, 0xE5, 0x6F, 0x2D, 0xDB, 0x94, 0x30, 0xBC, 0xDA, 0xD5, + 0xAE, 0x36, 0xD0, 0x2F, 0x71, 0x34, 0xF5, 0xAF, 0xD6, 0x1A, 0xB9, 0x2F, 0x13, 0xCE, 0xCA, 0xEF, + 0x75, 0x7D, 0xFD, 0xFC, 0xFE, 0xF7, 0xBF, 0xBF, 0x97, 0x31, 0x18, 0x4B, 0xB5, 0x1B, 0xB9, 0x7F, + 0x2B, 0x7D, 0x55, 0x4E, 0x41, 0x87, 0xA6, 0xB0, 0x1F, 0xB2, 0xCD, 0xB9, 0x92, 0xE3, 0x93, 0x9F, + 0xB4, 0x74, 0x00, 0xBE, 0x43, 0xAF, 0x00, 0x4F, 0x1D, 0x4B, 0x4B, 0xBF, 0x6A, 0x55, 0xF4, 0x39, + 0x0A, 0xEB, 0x93, 0xFC, 0xD8, 0x76, 0xDD, 0xD7, 0xBC, 0x5E, 0xEE, 0x72, 0x97, 0xEB, 0xE7, 0xEE, + 0x1E, 0xD6, 0x2E, 0xC4, 0x7C, 0xDD, 0xCF, 0xD8, 0x1F, 0x84, 0xA7, 0xB4, 0x78, 0xAA, 0xDA, 0xA7, + 0x34, 0x1A, 0xFB, 0x94, 0x6D, 0x2B, 0x53, 0x2C, 0xA9, 0xC8, 0xB8, 0xB4, 0x91, 0xB4, 0x0B, 0xFA, + 0x9F, 0xBC, 0x72, 0x0A, 0x27, 0xA4, 0x71, 0x59, 0x7C, 0x8E, 0xBD, 0x87, 0xFD, 0x05, 0x79, 0x47, + 0x19, 0xB1, 0x65, 0x2B, 0x4E, 0xFE, 0xFD, 0x9C, 0xE7, 0x3C, 0x67, 0x68, 0x27, 0xDB, 0xCD, 0xF5, + 0x03, 0x4F, 0x91, 0xA5, 0x52, 0x6F, 0x54, 0xD6, 0x50, 0x6F, 0x9C, 0x92, 0xD9, 0x2D, 0xE0, 0x15, + 0xFB, 0x20, 0xF7, 0x05, 0xB0, 0x13, 0x4F, 0xE1, 0xBB, 0xAC, 0x99, 0xB4, 0xC6, 0xB5, 0xCE, 0x76, + 0x19, 0x4B, 0x8E, 0x0D, 0x9B, 0x93, 0x6D, 0x8D, 0xD1, 0x30, 0xD6, 0x9C, 0x3D, 0x81, 0x9D, 0x2D, + 0x75, 0x87, 0xE4, 0xB7, 0xCA, 0xD9, 0xE2, 0xD1, 0x8B, 0x5F, 0xFC, 0xE2, 0xC1, 0x2E, 0x9E, 0x76, + 0xE5, 0xD4, 0xB1, 0xD0, 0x25, 0xE1, 0x43, 0xC2, 0xC3, 0x31, 0xE7, 0xF8, 0xE4, 0x33, 0xAF, 0x78, + 0xC5, 0x2B, 0x06, 0xB8, 0x6B, 0xDB, 0x70, 0x2F, 0x62, 0xB3, 0x4A, 0x1C, 0x6C, 0xAD, 0x3B, 0x15, + 0x1D, 0x80, 0xF1, 0x61, 0xCB, 0x92, 0xEE, 0xE4, 0xDE, 0x06, 0x7E, 0xE2, 0xB5, 0x76, 0x49, 0xF1, + 0xAB, 0xF2, 0x45, 0x68, 0x18, 0xF6, 0x30, 0x9F, 0x55, 0xBF, 0xAD, 0xF6, 0x53, 0xDB, 0x3F, 0xC3, + 0x19, 0xCE, 0xD0, 0x7D, 0xF2, 0x93, 0x9F, 0xEC, 0x61, 0xE6, 0x7E, 0xB3, 0xFC, 0xE2, 0x17, 0xBF, + 0x18, 0xC6, 0xA9, 0xBC, 0x58, 0x6D, 0xA7, 0x7C, 0xCF, 0xF8, 0x6B, 0x49, 0x5D, 0x33, 0x7D, 0x00, + 0xD8, 0xA0, 0x9C, 0xA3, 0x63, 0x72, 0x7D, 0x73, 0x3D, 0x12, 0xBF, 0xB1, 0x1F, 0x6B, 0x9B, 0xB3, + 0x6D, 0xC6, 0x52, 0xF5, 0x42, 0xC7, 0x53, 0xE5, 0x02, 0x60, 0x92, 0x63, 0x76, 0x9E, 0xFE, 0xCF, + 0xF1, 0xB1, 0xE6, 0x57, 0xB9, 0xCA, 0x55, 0x9A, 0x34, 0x75, 0xAA, 0x62, 0xFB, 0x12, 0x27, 0x2C, + 0xAD, 0x3D, 0x0F, 0x8C, 0x2F, 0x73, 0x99, 0xCB, 0xCC, 0xB6, 0xFD, 0xF3, 0x9F, 0xFF, 0x7C, 0x98, + 0xCB, 0x3A, 0x45, 0x1C, 0x3D, 0xE8, 0xA0, 0x83, 0x16, 0xD3, 0x2D, 0x71, 0x04, 0x3F, 0x87, 0x74, + 0xB7, 0xB5, 0x9E, 0xB5, 0x24, 0x4E, 0x43, 0x9F, 0xEA, 0x7C, 0x5D, 0x7F, 0xE7, 0x20, 0x2D, 0xC4, + 0x1E, 0x5D, 0xF7, 0x9B, 0x7B, 0x27, 0xF7, 0x35, 0xB6, 0x07, 0xF9, 0x68, 0xDA, 0x3B, 0xED, 0x9B, + 0xB6, 0xEB, 0xF7, 0xD9, 0x77, 0xC5, 0x01, 0xE1, 0xC3, 0x58, 0xFD, 0x8D, 0xBD, 0xC3, 0x9A, 0x38, + 0x46, 0x74, 0xAA, 0x84, 0x4B, 0xC6, 0x0F, 0x59, 0x1F, 0xF1, 0x88, 0x47, 0xAC, 0xF4, 0x65, 0x1B, + 0xCE, 0x31, 0xED, 0x6F, 0x3F, 0xFA, 0xD1, 0x8F, 0x7A, 0x3C, 0x4E, 0x7F, 0x65, 0x95, 0xC9, 0xE8, + 0x03, 0x19, 0xD8, 0x36, 0xA4, 0x17, 0xD5, 0x67, 0x91, 0xE5, 0xE6, 0x37, 0xBF, 0xF9, 0x4A, 0x6C, + 0x48, 0xF2, 0x29, 0x61, 0x8A, 0x1C, 0x26, 0xFC, 0x68, 0x6B, 0x4A, 0x7E, 0x45, 0x0E, 0xCB, 0x3D, + 0xA8, 0xDC, 0xC0, 0xB8, 0x99, 0x83, 0xB4, 0x61, 0xAC, 0xE4, 0x6F, 0xD8, 0x40, 0xD4, 0xAF, 0xD2, + 0x0F, 0x8A, 0x2E, 0xF9, 0xDA, 0xD7, 0xBE, 0x76, 0x83, 0xDC, 0x53, 0x0B, 0x73, 0xC5, 0xEE, 0x79, + 0xE9, 0x4B, 0x5F, 0x7A, 0x83, 0xDF, 0x23, 0x3F, 0xA7, 0x0C, 0x8A, 0xDD, 0xD8, 0x22, 0x1C, 0x13, + 0x3F, 0x2B, 0x8D, 0xB0, 0xB0, 0x5E, 0x55, 0xC6, 0xC9, 0x35, 0x74, 0x3C, 0x96, 0x1F, 0xFF, 0xF8, + 0xC7, 0x03, 0x3C, 0xE1, 0x67, 0xA7, 0x3C, 0xE5, 0x29, 0x57, 0x64, 0x56, 0x71, 0xB7, 0xF2, 0x2D, + 0x7C, 0x8F, 0xC0, 0x91, 0x02, 0x8D, 0x71, 0xAF, 0x54, 0xBE, 0x9C, 0xB6, 0x7C, 0xF9, 0x70, 0xC5, + 0xFB, 0xFC, 0xCE, 0x3D, 0x56, 0xCB, 0xCB, 0x5E, 0xF6, 0xB2, 0xDE, 0xB6, 0x9F, 0xB0, 0x9A, 0xA3, + 0x01, 0xF7, 0xB8, 0xC7, 0x3D, 0x26, 0xE7, 0x2E, 0xFE, 0x80, 0x53, 0xE8, 0x92, 0xCC, 0x53, 0xFF, + 0xA3, 0xB8, 0xA2, 0xCE, 0x8C, 0x2C, 0xC0, 0x38, 0x79, 0xA6, 0x45, 0xA3, 0x5B, 0x45, 0xFE, 0x6D, + 0xFF, 0x8F, 0x7B, 0xDC, 0xE3, 0xFA, 0xB6, 0x96, 0xD2, 0xE0, 0x33, 0x9F, 0xF9, 0xCC, 0x43, 0x3B, + 0xE2, 0x00, 0x76, 0x2C, 0x0A, 0xF4, 0x4C, 0xBB, 0x07, 0x30, 0x53, 0xA6, 0x49, 0x9B, 0x88, 0x85, + 0x67, 0xD5, 0xED, 0x5B, 0xB0, 0x90, 0x57, 0x1C, 0x78, 0xE0, 0x81, 0xC3, 0xD8, 0x94, 0x75, 0x95, + 0x03, 0xFC, 0x8C, 0x6E, 0xCF, 0xFC, 0xA5, 0xA7, 0xAE, 0x9B, 0xF2, 0x7F, 0xB6, 0xED, 0x98, 0xF1, + 0x75, 0x21, 0x83, 0xE2, 0x4B, 0x41, 0xA6, 0xC6, 0xF6, 0x80, 0x7C, 0xC5, 0x7F, 0xD2, 0x1E, 0x56, + 0xDB, 0x70, 0x5F, 0xF1, 0x1F, 0xF6, 0x9A, 0x72, 0x62, 0xEE, 0x1F, 0xE3, 0x2F, 0x88, 0x3F, 0x53, + 0x76, 0xC8, 0x52, 0x6D, 0xAE, 0x7C, 0x86, 0xEF, 0x9E, 0xF3, 0x9C, 0xE7, 0x5C, 0x89, 0xA3, 0x48, + 0x1A, 0xC6, 0x2B, 0xEB, 0x04, 0xBE, 0x09, 0xD7, 0xD4, 0x0B, 0x28, 0xEA, 0x1D, 0x29, 0xA3, 0xE9, + 0xF3, 0x4F, 0xDC, 0xF4, 0xBD, 0x34, 0x0C, 0xDB, 0x10, 0x32, 0x48, 0xB5, 0x0F, 0x3A, 0xFF, 0x1C, + 0x3F, 0x72, 0x1D, 0xCF, 0xA4, 0xED, 0x89, 0xD7, 0x73, 0x9F, 0xFB, 0xDC, 0xC3, 0xFF, 0xE6, 0x68, + 0x98, 0x36, 0x42, 0x7C, 0x3F, 0xF8, 0x82, 0xD2, 0x37, 0xA7, 0x7F, 0x19, 0x1F, 0x5F, 0xEE, 0x0B, + 0xF5, 0xF8, 0x5C, 0x17, 0xE9, 0x37, 0xB6, 0xEF, 0x4A, 0x1F, 0x9C, 0x5F, 0x8D, 0xFB, 0xFA, 0xC4, + 0x27, 0x3E, 0x31, 0xC0, 0xC8, 0x76, 0x7D, 0x2F, 0xFE, 0x56, 0x1D, 0x09, 0x5C, 0x81, 0x76, 0xC3, + 0xB7, 0xDE, 0xFD, 0xEE, 0x77, 0x0F, 0x7B, 0xCE, 0xF9, 0x24, 0x5E, 0x27, 0xDD, 0xB5, 0x0D, 0xFC, + 0x74, 0x89, 0x1B, 0x8E, 0x27, 0xE3, 0xAD, 0x1D, 0xDF, 0x83, 0x1E, 0xF4, 0xA0, 0x0D, 0xFA, 0xAA, + 0x25, 0xED, 0x6D, 0xB9, 0xC6, 0x8C, 0x1B, 0xFF, 0x34, 0x7E, 0x6A, 0xDE, 0x57, 0x7A, 0x97, 0xEB, + 0x91, 0x63, 0x55, 0xF6, 0x3E, 0xC7, 0x39, 0xCE, 0xD1, 0xE4, 0x99, 0x63, 0x15, 0xBC, 0x4E, 0xD9, + 0xBF, 0xEA, 0x54, 0xC2, 0x94, 0xF5, 0x3B, 0xEF, 0x79, 0xCF, 0x3B, 0xCC, 0x39, 0xF5, 0x26, 0xE7, + 0x4D, 0x9C, 0x88, 0x7B, 0xC0, 0x7D, 0x36, 0xA7, 0x4B, 0x52, 0x12, 0x37, 0xB0, 0x25, 0xAF, 0x13, + 0xF7, 0xF6, 0xA8, 0x47, 0x3D, 0x6A, 0xE8, 0x47, 0x9A, 0x51, 0x69, 0xA7, 0x74, 0xAC, 0x16, 0xE5, + 0xF3, 0x2A, 0x87, 0xB9, 0x1F, 0xE5, 0x6D, 0xC2, 0x85, 0xFF, 0xA1, 0x9F, 0xB0, 0x6F, 0x33, 0x8E, + 0x45, 0x7C, 0xA5, 0xC2, 0xC7, 0xB1, 0x25, 0xF9, 0x5C, 0xD5, 0x65, 0xB4, 0x57, 0xE4, 0xFE, 0xC2, + 0x0E, 0x83, 0xFF, 0x1E, 0xDA, 0x48, 0x1B, 0xE0, 0x0E, 0x7E, 0x1A, 0x7C, 0xB6, 0xD0, 0x81, 0x6C, + 0xA3, 0xEA, 0xC6, 0xBE, 0x87, 0xC7, 0x20, 0xE3, 0x38, 0x1E, 0xF6, 0x74, 0xC6, 0x85, 0xF0, 0x8A, + 0x9C, 0x5E, 0xE5, 0x54, 0x9F, 0x4F, 0x1B, 0x28, 0x7D, 0xA0, 0xE3, 0xDE, 0xE4, 0x26, 0x37, 0x59, + 0xE1, 0xCF, 0x75, 0x5D, 0x18, 0x2F, 0x32, 0x87, 0x63, 0xAA, 0xF8, 0x99, 0xEB, 0x0C, 0x3E, 0x80, + 0xA3, 0xC4, 0x40, 0xE6, 0x98, 0x94, 0x6B, 0x6D, 0x9F, 0xEF, 0xA1, 0x73, 0xDA, 0x87, 0x94, 0xCF, + 0xD3, 0xA7, 0x9A, 0xED, 0xA3, 0x4B, 0x2A, 0xE7, 0xD8, 0x0E, 0xF3, 0xBE, 0xCE, 0x75, 0xAE, 0x33, + 0xD8, 0x71, 0x5B, 0xFE, 0xD8, 0xB4, 0x37, 0xA5, 0xBC, 0x7D, 0xE3, 0x1B, 0xDF, 0x78, 0x43, 0xEC, + 0x1B, 0x7C, 0x01, 0xFF, 0x67, 0xCE, 0x29, 0xC7, 0x90, 0x6D, 0xD0, 0x2E, 0xFE, 0xCD, 0x9C, 0x5F, + 0xD2, 0xB1, 0x94, 0x3B, 0xB1, 0x9B, 0x41, 0xAB, 0xE7, 0x74, 0x5D, 0x69, 0x08, 0xFE, 0x40, 0x7C, + 0xFE, 0xEC, 0xF1, 0x53, 0x9D, 0xEA, 0x54, 0x43, 0x5C, 0x29, 0xF1, 0x13, 0xDA, 0x3A, 0xB3, 0x48, + 0x13, 0xC4, 0x5F, 0x61, 0xF0, 0xE6, 0x37, 0xBF, 0x79, 0xA0, 0x0F, 0xE9, 0x9B, 0xCB, 0xB5, 0x16, + 0x8E, 0x6F, 0x7F, 0xFB, 0xDB, 0x37, 0xB4, 0x3B, 0x56, 0x98, 0x3B, 0x3C, 0x9E, 0x18, 0x15, 0xFC, + 0x60, 0xD8, 0xB6, 0xF0, 0x6F, 0x40, 0xFF, 0x29, 0x55, 0xAF, 0x75, 0x0D, 0x52, 0xD7, 0xA0, 0x62, + 0xA3, 0x6F, 0xC5, 0x77, 0xCD, 0xC9, 0x61, 0xCE, 0x6F, 0x6A, 0x7C, 0xD5, 0x36, 0x92, 0x3C, 0x19, + 0x98, 0xEA, 0xB7, 0xA0, 0xE4, 0x5E, 0xAB, 0xFB, 0x66, 0xCC, 0xCE, 0xCA, 0x7A, 0x69, 0xD3, 0xCF, + 0xFD, 0x92, 0x3E, 0xB6, 0x94, 0xC3, 0x91, 0x87, 0x59, 0xBB, 0x6C, 0xBF, 0xF2, 0x46, 0x63, 0x12, + 0xFC, 0x8C, 0x5D, 0x13, 0x3E, 0x04, 0x8E, 0xB3, 0x47, 0xE1, 0x65, 0xCA, 0xD9, 0x8C, 0xB9, 0xE5, + 0xAF, 0x4E, 0xFB, 0x20, 0xEF, 0xAF, 0x79, 0xCD, 0x6B, 0x36, 0xF9, 0x2A, 0xF5, 0x2C, 0x67, 0x39, + 0x4B, 0xCF, 0x27, 0x2D, 0xF6, 0xED, 0x7E, 0x4A, 0xFA, 0xCA, 0x77, 0xC4, 0x62, 0x21, 0x3F, 0x31, + 0x5F, 0xF6, 0x4A, 0xCE, 0x1B, 0x3A, 0x89, 0x2D, 0x79, 0x4A, 0x8E, 0xC8, 0xFD, 0x89, 0x0C, 0xAB, + 0x9C, 0x9C, 0xFB, 0x47, 0x78, 0x11, 0x3F, 0x8D, 0x8C, 0x9A, 0x7E, 0xBE, 0x4A, 0x1B, 0x72, 0x8F, + 0xE3, 0x93, 0x4D, 0x1A, 0x53, 0x7D, 0x9D, 0x8C, 0x17, 0x7C, 0x5B, 0x42, 0xC3, 0xA8, 0xAC, 0x15, + 0x78, 0x52, 0x79, 0x5F, 0xC5, 0x49, 0xE2, 0xD1, 0x5D, 0x13, 0x75, 0xEB, 0x39, 0x1A, 0x96, 0x7C, + 0x84, 0xF7, 0xD8, 0x47, 0x1D, 0x4B, 0xEE, 0x91, 0x16, 0xDC, 0xF2, 0x7F, 0xF7, 0xBB, 0xDF, 0xFD, + 0x06, 0x5B, 0x9D, 0x72, 0xD4, 0x12, 0x1A, 0xE6, 0x2B, 0xB4, 0x1F, 0xDA, 0x94, 0x74, 0xBF, 0xC5, + 0x93, 0xE9, 0x83, 0xB3, 0x18, 0xE0, 0x6E, 0xE5, 0xE9, 0x15, 0x76, 0x14, 0xFE, 0xF7, 0xE0, 0x07, + 0x3F, 0x78, 0xF0, 0x5F, 0x65, 0x3B, 0xB4, 0x8F, 0x2F, 0x4D, 0xDB, 0xDC, 0x58, 0x6C, 0x86, 0xE5, + 0xC3, 0x1F, 0xFE, 0x70, 0x3F, 0xA7, 0x8C, 0x93, 0x49, 0x18, 0x6A, 0x53, 0x44, 0xC7, 0x81, 0x67, + 0xCF, 0x15, 0xF5, 0x89, 0x87, 0x3F, 0xFC, 0xE1, 0x2B, 0x7A, 0xA0, 0xF4, 0x02, 0x5A, 0xF6, 0xD6, + 0xB7, 0xBE, 0xB5, 0xFF, 0x6F, 0xF5, 0x39, 0xB4, 0x74, 0x35, 0x62, 0xC0, 0x8D, 0xB5, 0x38, 0x3A, + 0x68, 0x98, 0x9F, 0x77, 0xD9, 0x65, 0x97, 0xDE, 0xE7, 0x94, 0x25, 0xF7, 0x45, 0xC6, 0x0F, 0xB5, + 0x70, 0xCA, 0xFF, 0x55, 0x1A, 0xA6, 0x6F, 0xA4, 0xD2, 0x4C, 0x63, 0x18, 0x89, 0x7F, 0x49, 0x98, + 0x54, 0x3D, 0xD8, 0xBE, 0x18, 0x3F, 0xFB, 0x0D, 0x1F, 0x71, 0x9E, 0xD1, 0xA1, 0x1F, 0xEC, 0x2F, + 0xD0, 0x36, 0xCB, 0x94, 0x0E, 0x42, 0x7B, 0xF0, 0x1A, 0xC7, 0xA8, 0x6D, 0x4C, 0x5C, 0xE2, 0x6C, + 0x10, 0x78, 0xDC, 0x9A, 0x9F, 0x76, 0x35, 0xDB, 0x06, 0x2F, 0xA1, 0x3B, 0xB9, 0x56, 0xCA, 0x62, + 0xF2, 0x6B, 0xE2, 0xD4, 0x2A, 0x4E, 0xB6, 0xF6, 0x10, 0x05, 0x3C, 0xC9, 0x33, 0x98, 0x49, 0xCF, + 0xA4, 0x89, 0xE0, 0xA4, 0xBA, 0x69, 0x4B, 0x57, 0x13, 0x5E, 0xF4, 0x89, 0x5F, 0x4F, 0x9B, 0x74, + 0xB6, 0x23, 0x9E, 0xD3, 0xD7, 0x0B, 0x5E, 0xF0, 0x82, 0x59, 0x1A, 0x26, 0x1E, 0x40, 0x8F, 0x93, + 0xDF, 0x8F, 0xC9, 0xDB, 0x67, 0x3B, 0xDB, 0xD9, 0x7A, 0x3D, 0x44, 0x1E, 0xB4, 0x94, 0x86, 0xA5, + 0xAD, 0x9C, 0xF8, 0xCB, 0xB1, 0x38, 0xBC, 0x6A, 0x13, 0x4F, 0xDF, 0x38, 0x32, 0x71, 0x3D, 0xEF, + 0x37, 0x47, 0xC3, 0xF2, 0x33, 0xB4, 0x17, 0x1D, 0xBC, 0xE2, 0x6C, 0xDD, 0x3B, 0xD8, 0x1D, 0xD0, + 0x39, 0x5A, 0x6D, 0xD4, 0xB6, 0x19, 0x17, 0x7E, 0x41, 0x6C, 0x53, 0x29, 0xCB, 0xA5, 0x3E, 0xCE, + 0x77, 0xF2, 0xF2, 0x84, 0x57, 0xCB, 0x36, 0x49, 0x5B, 0xF0, 0xDA, 0xAA, 0x47, 0xE4, 0x78, 0x69, + 0x1B, 0x19, 0x0A, 0xFD, 0x7A, 0x49, 0xC1, 0x66, 0x76, 0xD6, 0xB3, 0x9E, 0x75, 0x03, 0xDD, 0xB1, + 0x5D, 0xE4, 0x05, 0x75, 0x0A, 0x4A, 0xDA, 0x57, 0x6A, 0x21, 0x46, 0xCE, 0x78, 0xA6, 0x25, 0x75, + 0x09, 0x0D, 0x03, 0x26, 0x63, 0x34, 0x4C, 0x38, 0x1A, 0xA3, 0xA1, 0x2E, 0x42, 0x49, 0x1D, 0x59, + 0x58, 0x4C, 0xC5, 0x77, 0xB6, 0x68, 0x58, 0xF6, 0x51, 0xED, 0xC9, 0xD8, 0xDF, 0xA6, 0x64, 0x14, + 0x0B, 0x38, 0x80, 0xFC, 0x9C, 0x3C, 0x22, 0x79, 0x0F, 0x7B, 0x1E, 0xD9, 0x4C, 0xDD, 0xB1, 0xC5, + 0x1B, 0xA4, 0x6B, 0xCC, 0x0D, 0xF9, 0xBA, 0x35, 0x26, 0x65, 0x1D, 0xFD, 0x1A, 0x29, 0x83, 0xE5, + 0x7C, 0x95, 0xE7, 0xF8, 0x8C, 0xBD, 0x21, 0xF1, 0x12, 0x1D, 0x3D, 0xE3, 0xCD, 0xB0, 0xCF, 0xE8, + 0xBB, 0xF4, 0xD9, 0x1A, 0xA3, 0x6A, 0x1F, 0x1F, 0xF8, 0xC0, 0x07, 0x86, 0x3D, 0x97, 0xF3, 0xCB, + 0x75, 0x23, 0x4E, 0xC4, 0xF9, 0x25, 0x3E, 0x55, 0x9C, 0x67, 0xEC, 0xC4, 0x86, 0x28, 0xF7, 0xA6, + 0x7D, 0x32, 0x65, 0x27, 0x7C, 0x92, 0x4B, 0x69, 0x18, 0x76, 0xBE, 0x6C, 0xA3, 0xC2, 0xD0, 0x79, + 0x43, 0xC3, 0xE0, 0x87, 0x29, 0xE3, 0x2C, 0x95, 0xC3, 0x94, 0xD5, 0x13, 0xFE, 0x14, 0x71, 0x1C, + 0x3C, 0x66, 0x7D, 0x52, 0x87, 0x16, 0x1E, 0xFC, 0x07, 0x19, 0x05, 0xFA, 0xB2, 0x0E, 0x0D, 0xCB, + 0x75, 0xE5, 0x3C, 0x01, 0xBE, 0xC6, 0x4A, 0x9F, 0xF3, 0x8C, 0x96, 0x38, 0x0D, 0xFD, 0x4F, 0x5B, + 0xE2, 0x58, 0xFC, 0x1A, 0x85, 0x58, 0x13, 0xE0, 0x92, 0xB4, 0x4B, 0x5E, 0xCE, 0x67, 0xC6, 0x8C, + 0xEF, 0xDC, 0xF5, 0x4B, 0xDA, 0x55, 0xED, 0x05, 0xC8, 0xE2, 0xC8, 0xBA, 0x49, 0x67, 0xAA, 0x8F, + 0x92, 0x57, 0x62, 0x0A, 0x91, 0x11, 0xE6, 0x0A, 0x30, 0xA5, 0x6F, 0x9F, 0x43, 0xD6, 0xCE, 0x73, + 0x6B, 0xF0, 0x4E, 0xF6, 0x05, 0x3E, 0x93, 0x8C, 0xA7, 0xAB, 0x76, 0x67, 0x6D, 0x77, 0x9C, 0x7B, + 0x50, 0x5E, 0x5F, 0x62, 0x0F, 0xDB, 0x12, 0x1A, 0x96, 0xBC, 0x45, 0xDC, 0xE6, 0x4C, 0x97, 0x6D, + 0xB8, 0xDF, 0xD5, 0xCB, 0x80, 0x03, 0xE7, 0xA5, 0x28, 0x53, 0xF1, 0x3A, 0x63, 0xBA, 0x64, 0xF2, + 0xFD, 0xA4, 0x9F, 0xC4, 0x9E, 0xDB, 0x67, 0xEE, 0xC3, 0x5A, 0xE8, 0xFF, 0x4E, 0x77, 0xBA, 0xD3, + 0x10, 0xDF, 0x07, 0x4C, 0x95, 0x9F, 0xB4, 0x6B, 0x21, 0xD3, 0x81, 0x27, 0x69, 0xA7, 0x4C, 0xDA, + 0x93, 0x38, 0x81, 0x4E, 0x54, 0xC7, 0x47, 0x3B, 0xAC, 0x17, 0x31, 0xE8, 0x19, 0x9F, 0xE9, 0x1A, + 0xBB, 0x4E, 0xB6, 0x27, 0x3E, 0xA5, 0x4C, 0x97, 0xEB, 0xC2, 0x1E, 0x82, 0xAE, 0x81, 0x47, 0x4B, + 0x68, 0x98, 0x7A, 0x32, 0xF3, 0xAA, 0x31, 0xFA, 0xAE, 0x1B, 0xDF, 0x3D, 0xEC, 0x61, 0x0F, 0x1B, + 0xD6, 0xC6, 0x92, 0xBC, 0xC6, 0xEF, 0x19, 0x33, 0xFC, 0x5A, 0x7A, 0x98, 0x38, 0xAE, 0x6C, 0x86, + 0xDD, 0x0E, 0xDE, 0xBF, 0x84, 0x86, 0x51, 0xB1, 0xD7, 0xE5, 0x3C, 0xAB, 0x9E, 0xA0, 0x6E, 0x8E, + 0xBD, 0x67, 0x1D, 0x1A, 0x56, 0xE9, 0x20, 0x36, 0x75, 0xFE, 0x57, 0x6D, 0xCE, 0xAE, 0x09, 0xF2, + 0xA0, 0xF6, 0xCE, 0x8C, 0xD9, 0x00, 0x6F, 0x91, 0xA3, 0xE8, 0x3F, 0xED, 0x31, 0x73, 0x34, 0x2C, + 0xD7, 0x95, 0xFD, 0x87, 0x1E, 0x94, 0x7C, 0x23, 0xF7, 0x61, 0xCE, 0x1F, 0x1F, 0xDC, 0x98, 0xBF, + 0x35, 0x0B, 0x63, 0x44, 0x2E, 0xC5, 0x1E, 0x5D, 0xDB, 0x51, 0xD7, 0x67, 0xCF, 0x73, 0xF6, 0xCA, + 0xF6, 0xD2, 0x0F, 0x94, 0xBE, 0x40, 0x0A, 0x34, 0x5C, 0x1A, 0x66, 0x3B, 0xD2, 0x57, 0xED, 0x04, + 0xAC, 0x05, 0x31, 0x2E, 0x4B, 0xC6, 0x07, 0x6E, 0x12, 0x97, 0x32, 0x16, 0x03, 0x47, 0x25, 0x2E, + 0x09, 0xDB, 0x9F, 0xB4, 0x2A, 0x7D, 0x98, 0xC2, 0x4E, 0x99, 0x93, 0xFD, 0xA3, 0xBC, 0x31, 0xD5, + 0xE6, 0x52, 0x1A, 0x26, 0xFE, 0x00, 0x93, 0x16, 0x0D, 0xD3, 0x8E, 0x63, 0x4C, 0x62, 0xC5, 0x0B, + 0xC6, 0xF8, 0x96, 0xB7, 0xBC, 0xA5, 0xB7, 0xEB, 0xE9, 0x4F, 0x1D, 0xF3, 0x95, 0x8F, 0xD1, 0x30, + 0xFB, 0xAA, 0xF6, 0x51, 0xF4, 0x2C, 0xD7, 0xA6, 0xFA, 0x71, 0xEB, 0x7B, 0xCE, 0x78, 0x4D, 0xC1, + 0x01, 0x5B, 0x33, 0x3C, 0x34, 0xE9, 0x6F, 0xAE, 0x51, 0xB6, 0x09, 0x9E, 0x56, 0xF8, 0x0A, 0x1B, + 0xE4, 0xFD, 0x3C, 0x57, 0x94, 0x7C, 0x3E, 0x7D, 0xE7, 0xFA, 0x08, 0xB0, 0xBF, 0xD4, 0xB3, 0xCB, + 0x29, 0x4B, 0x61, 0x63, 0x98, 0xD3, 0x25, 0x5D, 0xB7, 0x0F, 0x7D, 0xE8, 0x43, 0x1B, 0x62, 0xEA, + 0x6A, 0x9C, 0x13, 0x78, 0x49, 0x7B, 0x79, 0x46, 0xA0, 0x25, 0xCB, 0x82, 0x13, 0xF0, 0x6B, 0xFC, + 0x7B, 0x95, 0xF7, 0xFB, 0x1E, 0xDD, 0x41, 0x79, 0x61, 0x8A, 0x86, 0x51, 0xC0, 0x4B, 0xCE, 0x50, + 0xC8, 0xF3, 0x5A, 0xE7, 0x89, 0xDD, 0x8F, 0xD0, 0x90, 0x75, 0x74, 0xC9, 0xA4, 0x87, 0xB4, 0x79, + 0xDB, 0xDB, 0xDE, 0x76, 0x45, 0x6F, 0xCF, 0x39, 0x51, 0x6E, 0x7A, 0xD3, 0x9B, 0xAE, 0x7C, 0x4E, + 0x1A, 0xC6, 0x1A, 0x11, 0xDF, 0x95, 0xB2, 0xDD, 0x96, 0xD0, 0xB0, 0xDC, 0x27, 0x49, 0xC3, 0x92, + 0x6E, 0x67, 0x6C, 0x70, 0xCA, 0x63, 0x56, 0xBF, 0x67, 0x5C, 0xF0, 0x4D, 0x7C, 0x05, 0xEE, 0x39, + 0xED, 0x62, 0xB6, 0xCD, 0x5A, 0xA4, 0xDC, 0xE9, 0xFB, 0xB4, 0xEF, 0x4A, 0xB7, 0xA1, 0xD3, 0xC6, + 0x6C, 0xB7, 0x64, 0x61, 0x6D, 0xA8, 0xC8, 0x08, 0xAD, 0xB3, 0x54, 0xAD, 0xC2, 0x79, 0x3A, 0xE3, + 0xEC, 0x6D, 0x2F, 0xF7, 0x30, 0xE3, 0x43, 0x96, 0xA8, 0xF1, 0x29, 0xC6, 0x07, 0x55, 0x5D, 0xDF, + 0xD8, 0x8F, 0x23, 0xC3, 0x1E, 0x36, 0x46, 0xC3, 0x72, 0x8C, 0xD8, 0xB8, 0xD3, 0x7F, 0x92, 0x71, + 0x6E, 0x3C, 0x8B, 0x6D, 0x18, 0xDB, 0xF9, 0x98, 0x9E, 0x9E, 0x7D, 0x55, 0x1A, 0xD6, 0x3A, 0x73, + 0xEC, 0x3E, 0x62, 0xFF, 0xB7, 0x4A, 0xE2, 0x99, 0x6B, 0x09, 0xDF, 0xC9, 0xF3, 0xE8, 0xFA, 0xE2, + 0xF9, 0x0E, 0x7C, 0x80, 0xC7, 0x61, 0x2B, 0x12, 0x9E, 0x89, 0x0F, 0x55, 0x17, 0xE4, 0xEC, 0xAF, + 0x34, 0x21, 0xC7, 0x46, 0x5B, 0xBB, 0xEE, 0xBA, 0x6B, 0xAF, 0x37, 0x67, 0x7C, 0x89, 0x63, 0x51, + 0x7E, 0xE6, 0x37, 0xCF, 0xE5, 0x10, 0x0F, 0x97, 0x3C, 0x21, 0xDB, 0xC4, 0xC6, 0xA8, 0xDF, 0x6A, + 0xAC, 0xA4, 0xCF, 0x55, 0x3C, 0x1A, 0xDB, 0x33, 0x8C, 0x0F, 0x7B, 0x20, 0x71, 0x13, 0x8E, 0x2B, + 0xED, 0x73, 0xD9, 0x0F, 0x73, 0xC6, 0x7E, 0xC1, 0x19, 0xBE, 0x3C, 0xEF, 0xEE, 0x38, 0x79, 0xC5, + 0x27, 0xB9, 0x94, 0x86, 0xB1, 0x07, 0xB1, 0xC1, 0x8C, 0x9D, 0x23, 0xC8, 0x76, 0xA1, 0x61, 0x9C, + 0x09, 0x4E, 0xBB, 0xF6, 0x1C, 0x0D, 0x4B, 0x39, 0x11, 0x9B, 0x70, 0xAE, 0x9B, 0xC5, 0x78, 0x17, + 0xF6, 0x13, 0x71, 0x97, 0x69, 0x1F, 0xC8, 0xD7, 0x5B, 0xDD, 0xEA, 0x56, 0x2B, 0xFB, 0x7A, 0xA9, + 0x2E, 0xC9, 0xF3, 0xE8, 0x4B, 0x9C, 0xB9, 0x1B, 0xD3, 0x81, 0xF2, 0x5C, 0x0F, 0xF6, 0x46, 0xE3, + 0x4F, 0xE6, 0x0A, 0xF0, 0x03, 0x1F, 0x2A, 0xBC, 0x58, 0x1B, 0x64, 0x16, 0xE2, 0x0B, 0x98, 0xCF, + 0xD4, 0x19, 0x19, 0xBF, 0xC3, 0xBF, 0x69, 0xFC, 0x82, 0x7B, 0xBA, 0xB5, 0x1E, 0xF8, 0x1C, 0x96, + 0x8E, 0x0F, 0x5B, 0x2C, 0xCF, 0x78, 0x5E, 0x2C, 0xDB, 0x46, 0x47, 0x81, 0x66, 0x22, 0xD7, 0x57, + 0x5A, 0x25, 0x9F, 0xAF, 0xE3, 0x85, 0x86, 0x2D, 0x3D, 0xA7, 0x33, 0x47, 0xC3, 0xE4, 0x85, 0x63, + 0x34, 0x8C, 0xEF, 0xE0, 0x27, 0x49, 0x5F, 0x6B, 0x0C, 0x2E, 0xF1, 0xFD, 0xC4, 0x1B, 0x50, 0xC6, + 0xEC, 0xD1, 0x7E, 0x6E, 0xD9, 0xF4, 0x13, 0x9F, 0xEC, 0x1B, 0x1C, 0x30, 0xAE, 0x62, 0xAC, 0x24, + 0x7F, 0x64, 0xCD, 0xB0, 0x19, 0x48, 0x23, 0x2A, 0x8E, 0x21, 0xEB, 0xA6, 0x7F, 0x9A, 0x39, 0x54, + 0x9D, 0x5D, 0xF8, 0x28, 0x87, 0xD5, 0xB8, 0x26, 0x2A, 0xF8, 0x44, 0x9C, 0x17, 0x79, 0x0E, 0xB0, + 0xD9, 0x9A, 0x17, 0x03, 0xDB, 0x3D, 0xE7, 0x0A, 0x39, 0x17, 0x44, 0xAC, 0x34, 0xB4, 0x0B, 0xDF, + 0x19, 0x7E, 0x71, 0xD7, 0xDE, 0x36, 0x58, 0x73, 0xF0, 0xD5, 0xB3, 0x96, 0x73, 0xB1, 0x15, 0xE2, + 0x02, 0xB6, 0x2E, 0xE0, 0xA5, 0x7E, 0x5C, 0xE5, 0x70, 0xE8, 0x10, 0xD5, 0x73, 0x23, 0x75, 0xFF, + 0x29, 0x2F, 0xCA, 0x83, 0xD8, 0xEF, 0xC8, 0xBA, 0x2D, 0x9D, 0x8F, 0x57, 0x62, 0x8B, 0xFD, 0xFF, + 0x1C, 0x0D, 0xC3, 0xCE, 0xC4, 0xB8, 0x6A, 0x5E, 0x9B, 0x96, 0xBC, 0x82, 0x4D, 0x9C, 0x7D, 0x96, + 0xED, 0x2C, 0xA5, 0x61, 0x54, 0xE2, 0x51, 0x29, 0x19, 0x37, 0x25, 0x8E, 0xB3, 0x76, 0x8C, 0x81, + 0x5C, 0x36, 0xE2, 0x69, 0xC5, 0x43, 0xCE, 0xAC, 0x19, 0x6F, 0xC0, 0x98, 0x96, 0xDA, 0xF4, 0x81, + 0x03, 0xE7, 0x1B, 0xB0, 0x47, 0x57, 0x7C, 0x6D, 0xE1, 0xCA, 0x43, 0x1E, 0xF2, 0x90, 0x9E, 0xEF, + 0x10, 0xE3, 0x45, 0xC5, 0x96, 0x9D, 0x35, 0xBF, 0xC7, 0x76, 0x66, 0xFC, 0x8D, 0xB2, 0x36, 0xF0, + 0xA4, 0x5D, 0x62, 0x70, 0xEC, 0x3F, 0x65, 0x83, 0x2A, 0x27, 0xB8, 0x1F, 0xF0, 0x77, 0x00, 0xE3, + 0x6A, 0x47, 0x74, 0xAC, 0x7E, 0xCF, 0x79, 0xD3, 0xE4, 0xE5, 0x63, 0x85, 0x7E, 0x80, 0x67, 0xF5, + 0x35, 0xE7, 0x59, 0x21, 0xFC, 0x03, 0xD5, 0xE7, 0x97, 0xB2, 0x4E, 0xC2, 0x91, 0x75, 0x41, 0x37, + 0x5E, 0x1A, 0x23, 0xFA, 0x9F, 0xD2, 0x30, 0xE0, 0xE9, 0x99, 0xED, 0x94, 0xB1, 0xD4, 0x29, 0x19, + 0x37, 0x34, 0x15, 0x1C, 0xAE, 0x36, 0x8A, 0x96, 0x8E, 0x34, 0xA6, 0x4B, 0x6A, 0x5B, 0x4E, 0x3B, + 0x35, 0x74, 0x40, 0x38, 0xB8, 0x07, 0x13, 0xBF, 0x72, 0x4F, 0x62, 0x57, 0xAA, 0xED, 0x25, 0x4E, + 0x41, 0xE3, 0x3C, 0x9B, 0xD2, 0xC2, 0x03, 0x75, 0x60, 0xE0, 0xCB, 0x9C, 0x96, 0xC0, 0xB6, 0xCA, + 0x8F, 0x55, 0x96, 0xF4, 0x7D, 0xC6, 0x7C, 0xF2, 0x0A, 0xEE, 0x18, 0x9F, 0x91, 0xFB, 0xA3, 0xC6, + 0x58, 0xD6, 0x38, 0x6D, 0xE4, 0x52, 0xCF, 0xDF, 0xA7, 0xDD, 0x2A, 0xE1, 0x06, 0x5C, 0xB5, 0x5D, + 0x8A, 0x2F, 0xF9, 0x5A, 0xFD, 0x19, 0xEE, 0x67, 0xC7, 0x9E, 0x72, 0x22, 0x34, 0xB9, 0x9E, 0x29, + 0xCB, 0xF1, 0x24, 0xED, 0x81, 0xD6, 0xD4, 0xFD, 0x2C, 0xAD, 0xAD, 0x79, 0x61, 0xD8, 0xAB, 0xC6, + 0x86, 0x57, 0x1F, 0x71, 0xE5, 0x29, 0xC8, 0xF7, 0x39, 0x3E, 0x70, 0x0D, 0xFB, 0x72, 0xD5, 0x13, + 0x85, 0x15, 0xB4, 0x88, 0x3E, 0xA4, 0x49, 0xEE, 0x51, 0x7F, 0xE7, 0xB9, 0x77, 0xBE, 0xF3, 0x9D, + 0x83, 0x6F, 0x9F, 0xB1, 0xAE, 0x23, 0x87, 0xB1, 0x6E, 0xC4, 0x24, 0xB4, 0x78, 0xC8, 0x1C, 0x6E, + 0x54, 0xFD, 0x3A, 0x71, 0x22, 0xE1, 0x2F, 0xBC, 0xB0, 0xFB, 0xC1, 0x23, 0x3D, 0xE3, 0x3B, 0xE7, + 0xDF, 0xD2, 0x6F, 0x89, 0xCD, 0x21, 0xF3, 0x4B, 0xD5, 0x7E, 0x7D, 0x4F, 0xFC, 0xD1, 0x52, 0x5D, + 0x12, 0xFF, 0x4F, 0x9D, 0x4F, 0xB6, 0x89, 0x1E, 0x24, 0x0D, 0x4B, 0x9C, 0xAE, 0xEB, 0x2A, 0x2C, + 0x59, 0xC7, 0x25, 0xF6, 0xFC, 0x25, 0x34, 0xCC, 0x75, 0x85, 0x86, 0x65, 0x4E, 0x64, 0xF7, 0x0A, + 0xF6, 0x15, 0xC6, 0x52, 0xE7, 0x2A, 0x0D, 0x23, 0x8F, 0x0D, 0xCF, 0x10, 0x3B, 0x96, 0xFE, 0x9B, + 0x96, 0xAC, 0x3B, 0x45, 0xC3, 0x2A, 0x7C, 0x59, 0xD7, 0x7A, 0x76, 0x66, 0xAC, 0xD0, 0x2E, 0x76, + 0x2A, 0x9E, 0x49, 0xBC, 0x4A, 0xDB, 0x0C, 0x7C, 0x82, 0x5C, 0x6D, 0x35, 0x8E, 0xBE, 0xC2, 0x85, + 0xF7, 0xC8, 0x6B, 0xEB, 0xD0, 0xAF, 0xCC, 0x15, 0x20, 0xEC, 0x9C, 0x5F, 0xE6, 0xDE, 0x63, 0x9D, + 0x9F, 0xFE, 0xF4, 0xA7, 0x0F, 0xBE, 0xA0, 0x3C, 0x8B, 0x97, 0x32, 0x61, 0xC2, 0x2E, 0xCF, 0xB7, + 0x73, 0x8E, 0x62, 0x49, 0xDE, 0x38, 0xE4, 0x40, 0xDB, 0x92, 0x66, 0xF9, 0x9A, 0xB1, 0xC9, 0x14, + 0xF6, 0x08, 0x63, 0xAF, 0xEB, 0xCE, 0xF8, 0x89, 0x91, 0x17, 0x26, 0x53, 0x34, 0x8C, 0x57, 0x64, + 0x0E, 0x69, 0x58, 0xCD, 0x13, 0x94, 0x7B, 0x98, 0xDF, 0x88, 0x97, 0xC3, 0x36, 0x99, 0xB0, 0x9F, + 0xA2, 0x61, 0x89, 0x1B, 0xC0, 0x30, 0x65, 0xB8, 0x8C, 0x9B, 0x80, 0x5E, 0x71, 0xB6, 0x8E, 0xFF, + 0x3E, 0xE5, 0x29, 0x4F, 0x59, 0xB1, 0xB5, 0x25, 0x4C, 0xD9, 0x6B, 0xF8, 0x16, 0x97, 0xEA, 0x92, + 0xA9, 0x8F, 0x43, 0xC3, 0xD0, 0xD7, 0xD7, 0xA1, 0x61, 0x35, 0xE7, 0x64, 0x3D, 0x5F, 0x93, 0x39, + 0x3D, 0xA4, 0x63, 0xD8, 0x6F, 0x8C, 0x3F, 0x4D, 0xD8, 0x68, 0x43, 0x73, 0x9C, 0xEA, 0x69, 0xDA, + 0x3F, 0xD1, 0xA1, 0x3D, 0xDB, 0x20, 0x1F, 0xD9, 0x16, 0x68, 0x98, 0xF1, 0xB5, 0x19, 0xFB, 0x27, + 0x9C, 0xCD, 0xBB, 0x92, 0xBE, 0x36, 0xC6, 0x66, 0x8C, 0xF0, 0xBD, 0xEF, 0x7D, 0xEF, 0xFE, 0x7F, + 0xF8, 0x2D, 0x72, 0xDD, 0x93, 0x7F, 0xE5, 0xF7, 0x47, 0x36, 0x0D, 0xD3, 0x3E, 0xC0, 0xFE, 0x06, + 0x26, 0xE0, 0x41, 0x3D, 0xAF, 0x4D, 0xC5, 0x76, 0x4D, 0x0E, 0x3B, 0xC7, 0x51, 0x63, 0x65, 0xF3, + 0xFD, 0xBA, 0x34, 0x2C, 0x71, 0xB5, 0x85, 0xD7, 0xEC, 0x11, 0xF2, 0xDE, 0x61, 0xC7, 0xA6, 0x98, + 0x7F, 0x60, 0xAC, 0x00, 0x67, 0xE0, 0x9B, 0x32, 0x13, 0xF4, 0x57, 0xFC, 0x4E, 0x3C, 0x6A, 0x55, + 0xFC, 0x83, 0x9E, 0xA9, 0xAA, 0xF2, 0x57, 0x8D, 0xDF, 0x79, 0xC3, 0x1B, 0xDE, 0xD0, 0xDB, 0x0B, + 0x6B, 0x0E, 0x2C, 0xE6, 0x02, 0x7F, 0xF2, 0x99, 0x29, 0x1A, 0x46, 0x5B, 0x57, 0xBF, 0xFA, 0xD5, + 0x57, 0x64, 0xC1, 0xD6, 0x18, 0xFD, 0x9D, 0x35, 0xE2, 0x6C, 0x6A, 0xD5, 0x1B, 0xF3, 0xD5, 0x7E, + 0x93, 0x86, 0x81, 0x13, 0xD8, 0xE3, 0x6B, 0x7E, 0x1E, 0x0B, 0x73, 0x26, 0x77, 0x33, 0xFF, 0x45, + 0x66, 0x4D, 0xBC, 0xAF, 0x6B, 0xCC, 0x9E, 0x73, 0xAD, 0x96, 0xCA, 0x61, 0x14, 0x7C, 0x83, 0xD8, + 0xC3, 0x1C, 0xCF, 0x52, 0xDC, 0x68, 0xE5, 0xA4, 0x4D, 0x3A, 0xAF, 0xFD, 0x16, 0x7D, 0x81, 0x18, + 0x36, 0x4B, 0x3D, 0x67, 0x52, 0xCF, 0xDB, 0xE6, 0xFC, 0x3D, 0x83, 0x87, 0x6D, 0xA7, 0xAE, 0xC3, + 0xB6, 0x40, 0xC3, 0x90, 0x0D, 0x5C, 0x17, 0xF3, 0x62, 0x03, 0x57, 0xE4, 0x76, 0x4B, 0xCD, 0x57, + 0x40, 0xD1, 0x1F, 0xEC, 0xB9, 0x30, 0xDB, 0xA3, 0x2C, 0x89, 0x71, 0xFD, 0x4F, 0x69, 0x98, 0x63, + 0xAA, 0xBA, 0x24, 0x73, 0x00, 0x1F, 0xB0, 0x5D, 0xC0, 0xF7, 0xB1, 0x4F, 0xAB, 0xBF, 0xD5, 0xD8, + 0x85, 0xFF, 0x94, 0x86, 0xB9, 0xE7, 0xFD, 0x2C, 0x9D, 0x81, 0x36, 0xE0, 0x23, 0x23, 0xEE, 0xC4, + 0xBC, 0x00, 0x49, 0x57, 0x28, 0xC8, 0xFF, 0x69, 0x57, 0xCD, 0xF3, 0x23, 0xE6, 0x79, 0xE3, 0x19, + 0x73, 0x16, 0xBA, 0x36, 0x69, 0x9B, 0xA8, 0xBE, 0x64, 0xF2, 0xB1, 0x4B, 0xDB, 0x2B, 0xCD, 0x4A, + 0x1F, 0x1D, 0x05, 0x98, 0x10, 0x67, 0x5D, 0xF7, 0x23, 0x63, 0xC7, 0xB7, 0xB1, 0x24, 0xAE, 0x82, + 0xB6, 0xB1, 0xA3, 0xB7, 0xCE, 0x14, 0xB7, 0xF6, 0x0E, 0x6B, 0x5F, 0x65, 0xE2, 0x29, 0x1A, 0x96, + 0x71, 0x57, 0x9C, 0x15, 0x9A, 0xCA, 0x37, 0x80, 0x5F, 0x81, 0xFF, 0x93, 0x2B, 0x2C, 0xED, 0x1F, + 0xD2, 0x74, 0xE7, 0x0D, 0xCD, 0x15, 0xCF, 0x96, 0xDA, 0xC3, 0x78, 0x85, 0x57, 0xEB, 0x33, 0x5C, + 0x7A, 0x66, 0x2E, 0xFD, 0x1C, 0x29, 0x97, 0xFB, 0x3D, 0xFB, 0x0C, 0x7B, 0x2D, 0xB1, 0x84, 0xF8, + 0x3A, 0x28, 0xDA, 0x4E, 0xCC, 0x63, 0x31, 0xA6, 0x47, 0xFA, 0xBD, 0x38, 0x04, 0xBC, 0x3C, 0x7B, + 0x90, 0xF8, 0xB9, 0x99, 0x69, 0x18, 0x6D, 0xF3, 0x3B, 0x76, 0x40, 0xF9, 0x82, 0xF8, 0x8C, 0x7E, + 0x66, 0x5E, 0x3D, 0x4A, 0xF5, 0x03, 0x91, 0x53, 0xC4, 0xFD, 0xFA, 0xB1, 0x8F, 0x7D, 0x6C, 0xE0, + 0x11, 0xD5, 0x56, 0x91, 0x7D, 0x1D, 0xD9, 0x34, 0x4C, 0x3A, 0x89, 0x1C, 0x66, 0x3E, 0x3F, 0x2A, + 0xB6, 0x74, 0x7C, 0x29, 0xF0, 0x4D, 0xF0, 0x8E, 0x5A, 0xF7, 0x47, 0x0B, 0x2E, 0x5B, 0x42, 0xC3, + 0xB4, 0x97, 0x82, 0x8B, 0xCE, 0x0B, 0x79, 0x81, 0x7C, 0x2E, 0xAD, 0x78, 0x5A, 0xFD, 0x23, 0x69, + 0xE3, 0x14, 0x3E, 0xAD, 0x7D, 0xFD, 0xAC, 0x67, 0x3D, 0x6B, 0x03, 0x1E, 0xD6, 0xF8, 0x21, 0xF1, + 0x81, 0xCF, 0xD8, 0x6B, 0xD4, 0xB7, 0xD2, 0x96, 0x93, 0x9F, 0x1D, 0x17, 0xEB, 0x8B, 0x8C, 0x9A, + 0xB2, 0x37, 0x6D, 0xE1, 0x67, 0x32, 0x96, 0x77, 0x8E, 0x86, 0x11, 0x57, 0x61, 0xDE, 0x2A, 0x9F, + 0x6F, 0xF9, 0x9D, 0x33, 0x7F, 0x02, 0xB4, 0x53, 0xFA, 0x97, 0x73, 0x1D, 0xA3, 0x61, 0xD2, 0x45, + 0xE3, 0xDF, 0x2A, 0x1D, 0x83, 0xA7, 0xA2, 0x4B, 0x18, 0x77, 0xC4, 0x79, 0x0A, 0xC6, 0xE5, 0x1A, + 0x1B, 0xE7, 0xA6, 0xEE, 0x65, 0x3C, 0x2E, 0x38, 0xB3, 0xE4, 0xAC, 0x91, 0xB2, 0x1C, 0x36, 0xF8, + 0xCC, 0x35, 0xBD, 0x74, 0x1F, 0xD2, 0x87, 0x32, 0x57, 0xC2, 0x06, 0xBD, 0x94, 0xF8, 0x71, 0x7C, + 0x11, 0x14, 0xED, 0x8F, 0x94, 0x6A, 0x0F, 0x4D, 0x3C, 0xCD, 0x33, 0xE9, 0xF2, 0x2B, 0xFC, 0x0D, + 0xE6, 0x9F, 0xB4, 0x5F, 0xFD, 0xD8, 0x9B, 0x99, 0x86, 0xB9, 0xFE, 0xD8, 0x27, 0x9C, 0xB3, 0xCF, + 0x92, 0x6B, 0x5A, 0x7B, 0x80, 0x38, 0x93, 0x30, 0xA6, 0x6D, 0xF5, 0x27, 0xE2, 0x2F, 0x85, 0xE9, + 0x54, 0x1E, 0xC0, 0xA3, 0xC2, 0x1E, 0xC6, 0x78, 0x88, 0x3D, 0x4D, 0x3B, 0xE6, 0xED, 0x6E, 0x77, + 0xBB, 0x61, 0x2C, 0xF4, 0xCB, 0x1C, 0xD3, 0x6E, 0x50, 0x9F, 0xCF, 0xF7, 0x5B, 0xA2, 0x4B, 0xDA, + 0x2F, 0x32, 0x0D, 0xB9, 0xC5, 0xD2, 0x0E, 0x55, 0xF3, 0x50, 0xB4, 0xFC, 0x12, 0x79, 0x56, 0x96, + 0xF7, 0xEA, 0x9B, 0xD0, 0x5E, 0xF7, 0x65, 0x2B, 0x96, 0xB2, 0xE5, 0xDB, 0x41, 0xEE, 0xC4, 0x1F, + 0x46, 0xA9, 0x7E, 0xCE, 0x1A, 0x6B, 0xC1, 0x67, 0xE2, 0xBA, 0x72, 0x4F, 0x52, 0x89, 0xB7, 0xAB, + 0x39, 0x77, 0xC6, 0x68, 0x18, 0x7D, 0xE5, 0x39, 0xA0, 0xDC, 0x33, 0x49, 0x7F, 0x1C, 0x3F, 0xF8, + 0xE2, 0x9E, 0xAD, 0x79, 0xAC, 0xC7, 0x74, 0x49, 0xE8, 0x1E, 0xB8, 0x86, 0x3D, 0x3E, 0xC7, 0xE4, + 0x7C, 0xA0, 0x51, 0xE8, 0x02, 0xEA, 0x6C, 0xEC, 0x65, 0x74, 0x77, 0xDB, 0xCB, 0x33, 0xB7, 0xF4, + 0x49, 0x4C, 0xA3, 0x63, 0x59, 0x4A, 0xC3, 0x28, 0xC6, 0x18, 0x38, 0xCF, 0x25, 0xFB, 0xB0, 0x9E, + 0x6D, 0x32, 0xE7, 0x3B, 0x79, 0x93, 0xE1, 0xB1, 0x14, 0xF0, 0xB2, 0xB5, 0x6F, 0x92, 0x56, 0x27, + 0xEE, 0x24, 0x7D, 0x10, 0x67, 0xB0, 0xF9, 0x02, 0xA3, 0xCC, 0xB7, 0xA6, 0x0C, 0xBB, 0xD9, 0x69, + 0x18, 0x6B, 0x0A, 0x0D, 0xD3, 0x9E, 0xE4, 0xDE, 0x20, 0xFF, 0x47, 0xC2, 0x8F, 0x92, 0x73, 0x46, + 0x7F, 0x33, 0xBF, 0x2D, 0xFC, 0xA9, 0xC2, 0xBB, 0x96, 0xA3, 0x8A, 0x86, 0x51, 0x38, 0x87, 0x9B, + 0x30, 0x41, 0xF7, 0x6A, 0xD1, 0xAB, 0x96, 0xAD, 0xEE, 0xC8, 0xA0, 0x61, 0xD0, 0x19, 0x62, 0x2F, + 0x91, 0x4D, 0xED, 0xC3, 0x3C, 0x38, 0xAD, 0x5C, 0x4A, 0x99, 0xF7, 0x38, 0xF3, 0x01, 0x29, 0x9B, + 0x50, 0x89, 0x1B, 0xF6, 0x7E, 0x98, 0xC4, 0x4B, 0xF7, 0x74, 0xBE, 0xE6, 0xDC, 0x91, 0x2D, 0x88, + 0xA1, 0x12, 0x87, 0x2A, 0x0D, 0xB5, 0x38, 0xA6, 0xCC, 0x87, 0x61, 0x3B, 0xB7, 0xB8, 0xC5, 0x2D, + 0x56, 0x72, 0x19, 0x4D, 0xD1, 0x30, 0x7C, 0x9B, 0xE9, 0x1B, 0xAD, 0xB4, 0xB6, 0xFA, 0x4E, 0x19, + 0xB3, 0x34, 0x6C, 0xA9, 0x4D, 0x9F, 0xF9, 0xE3, 0xCB, 0xD7, 0xE6, 0x53, 0x69, 0x18, 0xEF, 0x9F, + 0xFD, 0xEC, 0x67, 0xAF, 0xF8, 0xA3, 0xF1, 0x95, 0xFB, 0xDF, 0x7A, 0x16, 0x1F, 0x3D, 0x59, 0x9D, + 0x70, 0x9D, 0xBC, 0x15, 0xD2, 0xB0, 0xD4, 0x6F, 0x97, 0xE2, 0x08, 0xBC, 0x85, 0x71, 0xC1, 0xE7, + 0x88, 0xC1, 0x91, 0x66, 0xE5, 0x79, 0x9F, 0xF4, 0x23, 0x27, 0x0F, 0x71, 0x2C, 0xF5, 0x2C, 0x1F, + 0xF1, 0xD6, 0x9C, 0x07, 0x23, 0x9F, 0x91, 0xB0, 0x4D, 0x1F, 0x4D, 0xE5, 0x29, 0x9B, 0x95, 0x86, + 0x51, 0xC8, 0x07, 0x24, 0xED, 0xE0, 0x15, 0xBB, 0x82, 0xFE, 0xEF, 0x5C, 0x43, 0x0B, 0x38, 0x80, + 0x1C, 0xEC, 0x1E, 0xE2, 0x2C, 0x5F, 0xAE, 0xFD, 0xBA, 0x71, 0xFA, 0x5B, 0x4A, 0xC3, 0x9C, 0x1B, + 0x34, 0x4C, 0xBE, 0x03, 0xFD, 0xBD, 0xF5, 0xAD, 0x6F, 0x3D, 0xC4, 0xD3, 0xB4, 0xEC, 0x72, 0xAD, + 0xF3, 0x66, 0xBE, 0x5F, 0x97, 0x86, 0xC1, 0xF3, 0xC9, 0x85, 0xE9, 0x59, 0x70, 0xE1, 0x55, 0xF5, + 0x38, 0xE1, 0x32, 0x46, 0xEB, 0x8D, 0x69, 0x46, 0xBF, 0x23, 0x87, 0x81, 0x36, 0x8D, 0xB4, 0xBF, + 0xD4, 0x33, 0x14, 0x8E, 0xC1, 0xD8, 0x30, 0xF7, 0x3B, 0x71, 0xC7, 0xAD, 0x33, 0x09, 0xAD, 0xFC, + 0x50, 0x07, 0x1C, 0x70, 0xC0, 0xCA, 0xDE, 0xA7, 0x5D, 0x7C, 0x35, 0xFA, 0xBD, 0xE6, 0x68, 0x18, + 0x39, 0x15, 0x5A, 0x6B, 0xE8, 0x7B, 0x75, 0xCB, 0x1C, 0x6F, 0xE6, 0xFE, 0xB0, 0xBD, 0x7C, 0x75, + 0x2D, 0x8C, 0xAD, 0x40, 0xBE, 0xC2, 0x96, 0x94, 0xBE, 0x39, 0x8B, 0xF3, 0xE3, 0xEE, 0x88, 0xA4, + 0xF7, 0xF2, 0xE0, 0x6A, 0x13, 0xE4, 0x15, 0xFF, 0x0E, 0x31, 0x54, 0xEB, 0xD2, 0x30, 0x7C, 0x85, + 0x9E, 0xD5, 0x59, 0xBA, 0x07, 0xF3, 0xBC, 0x22, 0x36, 0x06, 0xFC, 0x19, 0x94, 0xCA, 0x63, 0x2B, + 0xAE, 0xCA, 0xCF, 0xF2, 0x7F, 0xF9, 0x3B, 0xF4, 0x1C, 0x19, 0xD8, 0x98, 0xFC, 0xEA, 0x07, 0x4E, + 0xFE, 0xB6, 0x99, 0x69, 0x98, 0x6B, 0x63, 0x4C, 0x94, 0x67, 0x03, 0x39, 0xF7, 0x90, 0xEB, 0x9E, + 0xFB, 0x0E, 0xB9, 0x9C, 0x18, 0x81, 0x8C, 0x65, 0xC0, 0x1E, 0x96, 0x36, 0xD3, 0xA3, 0x8B, 0x86, + 0x39, 0x2E, 0x6C, 0x77, 0x09, 0x53, 0x6C, 0xBA, 0xB5, 0x80, 0x0B, 0xAD, 0x58, 0xCA, 0x39, 0x1A, + 0x96, 0xE7, 0x46, 0x53, 0x27, 0x40, 0x2E, 0x40, 0x2F, 0x20, 0x76, 0xBB, 0xC6, 0x3B, 0xBB, 0xBF, + 0xF3, 0xDE, 0x9E, 0x94, 0x1B, 0x1C, 0x4F, 0xC2, 0x94, 0x02, 0x2F, 0xD1, 0x3F, 0x51, 0x73, 0x30, + 0xD7, 0x35, 0x4F, 0xBB, 0x53, 0xCA, 0x65, 0x8C, 0x95, 0x5C, 0x62, 0x99, 0xB7, 0x7B, 0xAC, 0xF0, + 0x9B, 0x76, 0xE0, 0xA4, 0x87, 0xE4, 0x79, 0x6C, 0xC1, 0xC7, 0x67, 0xA8, 0xE6, 0x50, 0x45, 0xAE, + 0x18, 0xBB, 0x3B, 0xA7, 0x9E, 0x2B, 0x94, 0xF6, 0xBA, 0x8F, 0x13, 0x26, 0xF5, 0x15, 0xDC, 0x23, + 0xD6, 0xDD, 0x36, 0x91, 0x35, 0x2C, 0x69, 0x47, 0x13, 0xCE, 0xC4, 0xDD, 0xE5, 0x79, 0x7A, 0xEE, + 0xCB, 0xF3, 0xBF, 0x79, 0x27, 0x8B, 0xF1, 0xEE, 0xFA, 0x49, 0xE0, 0x11, 0xCF, 0x7B, 0xDE, 0xF3, + 0x56, 0xFA, 0xAE, 0x3A, 0xAE, 0xB2, 0x32, 0xBA, 0x6C, 0xC5, 0xD5, 0x2A, 0x03, 0xFB, 0xB9, 0xEA, + 0xF9, 0xC8, 0xE9, 0xCA, 0x91, 0xC0, 0x2E, 0xCF, 0xAE, 0x56, 0x5F, 0x4B, 0xDA, 0x4A, 0xF3, 0x3B, + 0xC7, 0xC7, 0x79, 0x22, 0xEE, 0x0A, 0x6B, 0xDD, 0xAF, 0x21, 0x8C, 0xB7, 0xA5, 0xF8, 0x30, 0x60, + 0x88, 0x4D, 0x3F, 0x63, 0x7B, 0xA0, 0xEF, 0xDA, 0x72, 0xEC, 0x3F, 0xE3, 0xF4, 0x59, 0x0F, 0x71, + 0x0B, 0xFE, 0xC8, 0xFD, 0x7B, 0x55, 0x2F, 0xA8, 0xE5, 0xA8, 0xA0, 0x61, 0x8E, 0x89, 0x33, 0xDD, + 0x09, 0x53, 0x72, 0x81, 0xB4, 0xE6, 0x5C, 0x63, 0x0C, 0x28, 0x15, 0x6F, 0x90, 0x31, 0xEB, 0xFD, + 0x41, 0xDA, 0x7B, 0x84, 0x8F, 0x79, 0x12, 0xF1, 0x39, 0xE6, 0xF9, 0xDB, 0xB1, 0xF9, 0x27, 0xED, + 0xCA, 0xFF, 0xBB, 0xB7, 0x90, 0xE1, 0x38, 0x3B, 0x99, 0xF2, 0x50, 0xFA, 0x1E, 0xC5, 0x4B, 0xCF, + 0x7B, 0xB7, 0x62, 0x84, 0x85, 0x2B, 0xFF, 0xE5, 0x1C, 0x00, 0xBE, 0xD0, 0x2A, 0x57, 0xB4, 0xD6, + 0x04, 0xFC, 0xCC, 0xFB, 0x75, 0xD9, 0xD3, 0x9E, 0xF5, 0x4B, 0x58, 0x55, 0x59, 0x9C, 0xEF, 0x91, + 0xD5, 0x81, 0xC5, 0x58, 0xEE, 0xEE, 0xAA, 0xD3, 0x58, 0xD1, 0xB9, 0xED, 0xDF, 0x76, 0x5D, 0x4B, + 0xE9, 0x05, 0xED, 0x13, 0xFB, 0xE1, 0x1E, 0x44, 0x36, 0xB5, 0xDF, 0xBA, 0x4F, 0xF0, 0xE7, 0xE6, + 0x99, 0x59, 0xFE, 0x4F, 0x8C, 0x95, 0xF9, 0xBD, 0xD3, 0x7E, 0x60, 0x9C, 0x33, 0x34, 0x8E, 0xB6, + 0xE1, 0x43, 0xD0, 0xCA, 0x5C, 0xBB, 0x7A, 0xFE, 0x4C, 0xBC, 0x81, 0x86, 0xD5, 0xF3, 0x3B, 0x63, + 0x7A, 0x74, 0xDA, 0x96, 0xB1, 0xDB, 0xC3, 0x9F, 0x2A, 0x8E, 0x24, 0x4C, 0xFD, 0x2E, 0x7D, 0xD3, + 0xD9, 0x37, 0x05, 0x5E, 0xC9, 0x3D, 0x72, 0xCC, 0x75, 0xC9, 0x59, 0xC3, 0x1A, 0x9B, 0xBF, 0x59, + 0x69, 0x18, 0xED, 0x63, 0xFF, 0x74, 0xEF, 0x10, 0x8F, 0x00, 0x4D, 0xF3, 0xB7, 0xCC, 0x19, 0xC1, + 0x67, 0xF0, 0xD6, 0x3B, 0x04, 0xB7, 0x36, 0x0D, 0x13, 0x07, 0xB0, 0x67, 0x66, 0xDE, 0x0A, 0x62, + 0x29, 0xF0, 0xE7, 0x11, 0xEF, 0xC7, 0x39, 0x0E, 0xF8, 0xEC, 0x0B, 0x5F, 0xF8, 0xC2, 0xFE, 0x15, + 0x3B, 0x13, 0x31, 0x38, 0x2F, 0x7A, 0xD1, 0x8B, 0xFA, 0xDC, 0xB4, 0xD8, 0x51, 0xC8, 0x75, 0x80, + 0x3E, 0x41, 0xAE, 0x01, 0xFA, 0x95, 0x56, 0x08, 0xE7, 0x1C, 0xAF, 0x77, 0x1C, 0x99, 0xF7, 0x2D, + 0x4B, 0x9E, 0xD9, 0x77, 0xCE, 0xE9, 0x0F, 0x71, 0xCC, 0xCA, 0x60, 0xE0, 0xEB, 0x33, 0x9E, 0xF1, + 0x8C, 0x3E, 0xE6, 0x92, 0x36, 0xD3, 0xBF, 0xC7, 0x5C, 0x6A, 0xBC, 0x99, 0x7C, 0xA6, 0xF2, 0xDF, + 0xA4, 0x61, 0x8E, 0x11, 0x7D, 0xAD, 0xFA, 0x10, 0x5A, 0x6B, 0xC2, 0xF9, 0x4F, 0xF5, 0x55, 0x68, + 0x18, 0x31, 0xEC, 0xD0, 0x71, 0x4A, 0xF5, 0x85, 0xD5, 0x02, 0x0C, 0x18, 0x73, 0xC6, 0x22, 0x25, + 0x6E, 0x8E, 0xD1, 0xB3, 0xCC, 0xA7, 0x69, 0x69, 0xDD, 0x23, 0x84, 0x9D, 0xDE, 0xF6, 0xB4, 0xE7, + 0xD7, 0xFB, 0xD3, 0x98, 0x03, 0x72, 0x49, 0xDE, 0x61, 0x47, 0x25, 0x97, 0xCD, 0x58, 0x6E, 0x19, + 0xE0, 0xE2, 0xFD, 0xBB, 0xC8, 0xD3, 0xC8, 0xA2, 0xC2, 0xC3, 0x76, 0xF3, 0xB3, 0x34, 0xED, 0x6D, + 0x6F, 0x7B, 0xDB, 0x70, 0xA6, 0x24, 0x71, 0xA2, 0x15, 0xB7, 0xEA, 0x7F, 0x90, 0x1F, 0xD9, 0x1F, + 0xCE, 0xAD, 0x95, 0x3B, 0xC5, 0xBB, 0xDF, 0xB2, 0xBF, 0xD4, 0x1B, 0x80, 0x0D, 0xB0, 0xE6, 0x7C, + 0x6B, 0x85, 0xA7, 0x3E, 0xE5, 0x16, 0x6F, 0xDB, 0x16, 0xE4, 0x30, 0xDB, 0xD6, 0x2F, 0xC9, 0xDE, + 0x80, 0x7F, 0xE5, 0x3A, 0xD6, 0x31, 0xE0, 0x83, 0x74, 0x1F, 0x6D, 0x6D, 0x1A, 0x66, 0x31, 0xC7, + 0x79, 0x56, 0xEC, 0x1C, 0xF5, 0x9C, 0x58, 0x9E, 0x69, 0x32, 0xAE, 0xAB, 0xE6, 0xEB, 0x13, 0x1F, + 0xC5, 0xC3, 0x9A, 0x8B, 0x8E, 0x57, 0xCF, 0xA3, 0xA7, 0xDD, 0xAB, 0xEA, 0x8A, 0x94, 0xA4, 0x5B, + 0x29, 0x07, 0xA0, 0x4B, 0x60, 0x5B, 0x69, 0xE5, 0x82, 0x13, 0x17, 0xE7, 0x62, 0x28, 0xAB, 0xFF, + 0x2F, 0xE9, 0x07, 0xCF, 0x72, 0x86, 0x75, 0x09, 0x0D, 0x43, 0xE7, 0xD4, 0x36, 0xC4, 0xF3, 0xF8, + 0x11, 0xBC, 0xC3, 0x36, 0xE7, 0x93, 0xF9, 0x61, 0x95, 0x0D, 0x38, 0x2B, 0x9A, 0xB4, 0xBE, 0xA5, + 0xD7, 0xD8, 0x6E, 0xC2, 0xB8, 0x95, 0x03, 0xB9, 0xE5, 0x07, 0x22, 0x5E, 0xC0, 0xF5, 0x32, 0xD6, + 0xA3, 0xE6, 0x1E, 0x00, 0x9E, 0xE0, 0x9F, 0x3E, 0x49, 0xE5, 0x55, 0x78, 0x00, 0xFC, 0x36, 0x65, + 0x2A, 0x9F, 0x61, 0x5D, 0xCC, 0x03, 0x02, 0x0E, 0x60, 0x3B, 0xCB, 0xB3, 0xC9, 0x75, 0x1D, 0x6D, + 0x83, 0xB3, 0x9A, 0xAD, 0x1C, 0xB5, 0x55, 0x7F, 0xF6, 0x3F, 0xC4, 0xB9, 0x70, 0xD6, 0xD0, 0xB5, + 0xCF, 0x3C, 0x81, 0xD5, 0x5E, 0xA9, 0xFF, 0xBF, 0xE6, 0xC7, 0x87, 0x36, 0x98, 0x37, 0x5C, 0x3E, + 0xE7, 0x1D, 0xE5, 0x53, 0xF8, 0x91, 0xE7, 0x24, 0x37, 0x33, 0x0D, 0x33, 0x4E, 0x09, 0x1A, 0xC6, + 0x98, 0x98, 0x33, 0x3E, 0x13, 0x7F, 0x4B, 0xBC, 0x52, 0x76, 0x00, 0x6F, 0x69, 0x5B, 0xFB, 0xEF, + 0xD6, 0xA4, 0x61, 0xCA, 0x88, 0xC4, 0x03, 0xD9, 0xC6, 0x94, 0x8C, 0x9D, 0xED, 0xFB, 0xB9, 0x05, + 0x4B, 0x65, 0xA0, 0x5C, 0x27, 0xF6, 0x88, 0x67, 0x72, 0xD1, 0xFD, 0xB4, 0x37, 0x4D, 0xC5, 0x5C, + 0xAA, 0xB7, 0x50, 0xA0, 0x5B, 0xF8, 0x91, 0xD8, 0x3B, 0x7B, 0xEF, 0xBD, 0xF7, 0xCA, 0x38, 0xBD, + 0x77, 0x4F, 0x1C, 0x55, 0xFE, 0x32, 0x8F, 0xB5, 0x7C, 0xB6, 0xD2, 0x88, 0x96, 0x6F, 0x4C, 0x7A, + 0x86, 0x6F, 0xB2, 0xDE, 0x81, 0xD2, 0x5A, 0x13, 0xD6, 0x75, 0xAF, 0xBD, 0xF6, 0x1A, 0xC6, 0x43, + 0xDC, 0x72, 0x2B, 0x86, 0x3E, 0x6D, 0xA3, 0xEE, 0x2F, 0xCE, 0x23, 0x8F, 0xF1, 0xFB, 0xC4, 0xF7, + 0xFA, 0x9B, 0xBA, 0x6A, 0xB6, 0x9D, 0x36, 0x2E, 0xFA, 0x60, 0xEC, 0xE8, 0x07, 0x3C, 0x07, 0x7C, + 0xAA, 0x7E, 0x97, 0xB4, 0x0C, 0x9F, 0x52, 0xCA, 0xAC, 0x9E, 0x3B, 0xC4, 0x67, 0x97, 0xFF, 0x33, + 0xCE, 0x8B, 0xB6, 0xD1, 0xED, 0x68, 0x97, 0xFF, 0x92, 0x43, 0x33, 0xE3, 0x86, 0xEA, 0x9A, 0xFA, + 0x2C, 0x3A, 0x67, 0xCD, 0x57, 0x50, 0xF1, 0x2B, 0xD7, 0xD5, 0xFC, 0x51, 0x99, 0xA3, 0xC9, 0xB1, + 0xA7, 0x5C, 0xAB, 0x3D, 0xD5, 0x39, 0xA2, 0x03, 0x63, 0x67, 0x25, 0x5F, 0x45, 0xCA, 0xD8, 0x39, + 0xC7, 0x3C, 0x5F, 0x2F, 0x1F, 0x4E, 0x1F, 0xF0, 0x18, 0xEC, 0x37, 0x1B, 0x0D, 0xB3, 0x6D, 0xE0, + 0x05, 0x7C, 0xB0, 0x0D, 0x64, 0x6C, 0xBE, 0x7C, 0x9C, 0xF1, 0x68, 0x77, 0xE6, 0x8E, 0x78, 0xE7, + 0xB0, 0xB5, 0x69, 0x98, 0xF3, 0x22, 0x36, 0x5D, 0x1B, 0xAA, 0xF7, 0x30, 0xB9, 0xC6, 0xD0, 0x9E, + 0xBA, 0xD7, 0xEB, 0xB9, 0xC3, 0x94, 0xD1, 0xEA, 0xF7, 0xE2, 0x80, 0xCF, 0xE3, 0xC7, 0x53, 0x4E, + 0x19, 0x8B, 0xE9, 0xC9, 0xF5, 0xF3, 0x33, 0x70, 0x25, 0x66, 0x21, 0x65, 0xA7, 0x9A, 0x0F, 0x2C, + 0xED, 0x52, 0xAD, 0xD8, 0xAF, 0x16, 0x6E, 0x56, 0x5C, 0x30, 0xDF, 0x35, 0x36, 0x4B, 0xF3, 0xB9, + 0x8F, 0x15, 0xE5, 0x30, 0x73, 0xEB, 0xF3, 0x3C, 0x31, 0xEC, 0xD5, 0x3F, 0xD8, 0x82, 0x39, 0x73, + 0xF2, 0xEE, 0x81, 0x31, 0x7A, 0xDA, 0xFA, 0x8D, 0x31, 0xEB, 0x07, 0x6C, 0xF9, 0x58, 0x2C, 0xDA, + 0x69, 0x79, 0x06, 0x1F, 0x45, 0x8D, 0x57, 0xCF, 0xBC, 0x91, 0xC4, 0xE4, 0xA5, 0xAF, 0xD0, 0x73, + 0x9F, 0xD8, 0x0F, 0x52, 0xCE, 0xF1, 0x95, 0x67, 0xE0, 0x43, 0xF8, 0x4F, 0xD0, 0x9D, 0xC9, 0x21, + 0x32, 0xE6, 0xE7, 0xC9, 0xF9, 0x62, 0x77, 0x48, 0x1A, 0x96, 0x36, 0xE4, 0xDC, 0xDF, 0x54, 0xD6, + 0x96, 0x5C, 0x23, 0xE9, 0xEB, 0x12, 0x67, 0x92, 0x76, 0xA7, 0xFD, 0xCB, 0x3B, 0xFD, 0xC8, 0x8B, + 0x82, 0x8C, 0x4E, 0x1F, 0x89, 0xAB, 0x2D, 0x9F, 0xEF, 0x1C, 0x0D, 0xD8, 0xEC, 0x34, 0xCC, 0xC2, + 0xDD, 0x15, 0xFC, 0x1F, 0x5A, 0x80, 0xAC, 0x50, 0xF3, 0x80, 0xCA, 0x1F, 0xD8, 0xBB, 0xDA, 0x4E, + 0xFE, 0x5B, 0x68, 0x18, 0xB0, 0xC2, 0x3E, 0xD7, 0xE2, 0x8B, 0x09, 0x73, 0xF8, 0xAD, 0xB2, 0x75, + 0xC6, 0x21, 0x54, 0x5D, 0x52, 0x9C, 0xF1, 0xBC, 0x6C, 0x9E, 0x0F, 0xE1, 0xBF, 0xD8, 0xCC, 0x2C, + 0x55, 0xFF, 0xD1, 0x1F, 0x2E, 0xCC, 0x84, 0x09, 0xF3, 0xCE, 0x7C, 0x83, 0xE6, 0x4D, 0x10, 0x16, + 0x8E, 0xA1, 0xFA, 0xEC, 0xD5, 0x89, 0xAA, 0x6C, 0x69, 0xAC, 0x42, 0x6B, 0xCE, 0xCA, 0x8F, 0xD8, + 0xF5, 0xD1, 0xBF, 0xE6, 0x68, 0x18, 0xF2, 0x21, 0xB6, 0x41, 0xFB, 0x23, 0xDE, 0x2B, 0x65, 0x2D, + 0xE7, 0x95, 0x6B, 0xCB, 0xEF, 0xD8, 0xA0, 0xF0, 0x07, 0x2F, 0x89, 0x93, 0xCA, 0xDF, 0x19, 0x1F, + 0x76, 0xE9, 0x16, 0xFC, 0xB2, 0x30, 0x2E, 0x74, 0x41, 0x9E, 0x01, 0x17, 0x5A, 0x7C, 0xC1, 0xB2, + 0xDF, 0x7E, 0xFB, 0xAD, 0xEC, 0x55, 0xDF, 0x73, 0xBF, 0x63, 0xF5, 0xF9, 0xE5, 0x2B, 0xBE, 0x4C, + 0xF4, 0xBD, 0x1A, 0xEB, 0x91, 0x6D, 0x4B, 0x3B, 0x79, 0xC5, 0x1F, 0x9F, 0x71, 0xFA, 0x63, 0xB4, + 0x84, 0xEF, 0x58, 0x63, 0xF2, 0xC3, 0x25, 0xED, 0xF5, 0x1E, 0x44, 0x4B, 0xD2, 0x10, 0x68, 0x2A, + 0x7B, 0x8F, 0x75, 0x33, 0xAF, 0x4D, 0xE6, 0xB6, 0x98, 0x3B, 0xDB, 0xD4, 0xFA, 0x8F, 0x3A, 0xE7, + 0x66, 0xA7, 0x61, 0xF4, 0x65, 0xDC, 0x32, 0x76, 0x1E, 0x65, 0xEA, 0x56, 0x1C, 0x93, 0xF7, 0xBD, + 0x4B, 0xBF, 0xB6, 0x36, 0x0D, 0x73, 0xAF, 0x19, 0x5B, 0x61, 0x8E, 0x67, 0xF0, 0x4C, 0x5D, 0x17, + 0xBB, 0x18, 0xB2, 0x18, 0x77, 0x9E, 0xB3, 0x3F, 0xA9, 0xE4, 0x37, 0x20, 0x9E, 0x68, 0xFF, 0xFD, + 0xF7, 0xEF, 0xFD, 0x53, 0xF8, 0xBC, 0xF8, 0x8C, 0x3C, 0xC2, 0xF9, 0x84, 0xBA, 0xEF, 0x8C, 0x1B, + 0xA4, 0xCD, 0x43, 0x0F, 0x3D, 0x74, 0xF0, 0x75, 0x29, 0xA3, 0xD6, 0xB8, 0xE9, 0x1C, 0x1B, 0x79, + 0xC6, 0xA4, 0x41, 0x79, 0x96, 0x80, 0xB1, 0x11, 0xC3, 0x82, 0x1E, 0x8C, 0x4F, 0x82, 0xF3, 0x52, + 0xE8, 0x71, 0xE4, 0x59, 0x04, 0x8F, 0xC9, 0xB5, 0x4F, 0x9E, 0x72, 0x7E, 0xC7, 0x5E, 0x9D, 0x32, + 0x5B, 0xDD, 0x37, 0xD5, 0x36, 0xC6, 0x2B, 0x7A, 0x28, 0x72, 0xCC, 0x1C, 0x0D, 0xA3, 0x90, 0xC3, + 0xCA, 0x67, 0xA4, 0xD1, 0x29, 0x3B, 0x64, 0x7E, 0x08, 0x0A, 0x32, 0x10, 0x67, 0x1E, 0xF1, 0x49, + 0xB6, 0x68, 0xE9, 0x94, 0x8C, 0xC0, 0x3C, 0xA4, 0x61, 0xAD, 0x7C, 0x4A, 0xE2, 0x11, 0xFA, 0x14, + 0xFE, 0x06, 0x9E, 0xC1, 0x3F, 0x99, 0x30, 0xAE, 0xFE, 0x65, 0xEF, 0x41, 0x4F, 0x5A, 0xCF, 0x7B, + 0xF3, 0x99, 0x4B, 0xAB, 0x29, 0xD2, 0x10, 0x9E, 0x65, 0xED, 0xA1, 0x61, 0xC4, 0xDC, 0xB6, 0xCE, + 0x33, 0xF8, 0xDE, 0xB5, 0xC6, 0xFF, 0xE2, 0xF9, 0xBA, 0x4A, 0x17, 0xAA, 0x4D, 0x15, 0x3D, 0x75, + 0x2C, 0x67, 0x8E, 0xBE, 0xB2, 0x84, 0x29, 0xFE, 0x0B, 0xCE, 0xF8, 0x3A, 0x07, 0xEF, 0xF3, 0xA5, + 0x12, 0xFF, 0x48, 0x1C, 0xDE, 0x1E, 0x7B, 0xEC, 0xD1, 0xCF, 0x15, 0xDD, 0x9F, 0xCF, 0xC8, 0xCC, + 0xC8, 0xA8, 0xE4, 0x97, 0xC1, 0xDE, 0x0F, 0x0E, 0x99, 0x67, 0x36, 0xD7, 0x61, 0x33, 0xD3, 0x30, + 0x71, 0x86, 0x7D, 0xC9, 0xFF, 0xBD, 0xB3, 0xDD, 0xB5, 0x4E, 0x7F, 0x37, 0xFF, 0xD5, 0x2F, 0x92, + 0xFB, 0x65, 0x6B, 0xD2, 0x30, 0xFB, 0x44, 0x7E, 0x1C, 0x83, 0x09, 0xF4, 0x0B, 0x9B, 0x35, 0xE7, + 0x3A, 0xD2, 0xDE, 0x60, 0xD1, 0xFF, 0xAE, 0xDE, 0x8C, 0x4F, 0x2E, 0x73, 0xE9, 0xE4, 0x3D, 0x8E, + 0xC8, 0xF7, 0xC8, 0xAC, 0x75, 0xED, 0x6D, 0xAF, 0xDE, 0x53, 0x81, 0x0F, 0xB4, 0xDE, 0xD5, 0x69, + 0x05, 0xDF, 0xB0, 0x43, 0xC2, 0x7F, 0xA9, 0xD8, 0x44, 0xB2, 0xFA, 0x3D, 0xFA, 0x20, 0x7E, 0xD3, + 0x3C, 0x67, 0x57, 0xE3, 0xC2, 0x5A, 0xF9, 0x53, 0x99, 0x43, 0xD5, 0x91, 0xF2, 0x2C, 0x78, 0xD2, + 0x23, 0xF6, 0x30, 0xBC, 0x1F, 0x9A, 0xC4, 0x5A, 0x26, 0xCE, 0x55, 0xBF, 0xAA, 0x73, 0xE7, 0x6C, + 0x86, 0x38, 0xDD, 0x82, 0x7D, 0xEB, 0x7B, 0xD7, 0xD7, 0x1C, 0x67, 0x55, 0xDE, 0xB3, 0x4F, 0xE5, + 0x1E, 0x68, 0x30, 0xCF, 0x98, 0x53, 0xC0, 0x31, 0x54, 0xF9, 0x8D, 0x3D, 0x91, 0xF7, 0xDE, 0x3A, + 0x7F, 0x78, 0x81, 0xF2, 0xB0, 0x6D, 0x26, 0x4E, 0x63, 0xCB, 0xF7, 0x5C, 0x52, 0xA5, 0x61, 0xAD, + 0xD8, 0x64, 0x7C, 0xDC, 0x75, 0x8E, 0xC2, 0xDD, 0xB9, 0x19, 0x9B, 0x8C, 0x9F, 0xA9, 0xFA, 0x13, + 0xC6, 0xE4, 0x08, 0x72, 0xBD, 0x43, 0x9F, 0xF2, 0xCC, 0x56, 0x56, 0x7C, 0xEC, 0xC2, 0x3E, 0xE1, + 0xD5, 0x3A, 0xCB, 0xAC, 0x9F, 0x48, 0x3B, 0xEA, 0xD1, 0x41, 0xC3, 0xE0, 0xBD, 0xC0, 0xB0, 0xAE, + 0x63, 0x7D, 0x9F, 0x34, 0x6C, 0x4C, 0x6F, 0xDA, 0x12, 0x39, 0x0C, 0x1D, 0x1C, 0xDA, 0xC5, 0x9A, + 0x7B, 0xAE, 0xB0, 0xE2, 0x08, 0xEB, 0x4F, 0x7C, 0x1E, 0x31, 0x00, 0x09, 0x17, 0xE0, 0x54, 0x6D, + 0x68, 0xE2, 0x4A, 0x2B, 0x36, 0xB2, 0x75, 0xAF, 0x51, 0x85, 0xAD, 0x7B, 0x93, 0x7B, 0x3E, 0x2C, + 0xB9, 0x6E, 0xF5, 0x4C, 0x39, 0xAF, 0xD0, 0xA8, 0xB4, 0x21, 0xA5, 0xBC, 0x4F, 0x45, 0x9E, 0x31, + 0x3F, 0x50, 0xDE, 0xD1, 0x4D, 0x91, 0x2F, 0xDB, 0x07, 0x31, 0xDC, 0xB6, 0x51, 0xF7, 0x21, 0xBC, + 0x35, 0xEF, 0xE4, 0xAB, 0x31, 0xC0, 0x75, 0x9C, 0xE4, 0x42, 0xE5, 0x39, 0xED, 0x33, 0xEE, 0x2D, + 0x6D, 0x8F, 0xFC, 0xA7, 0x75, 0xF7, 0x8D, 0x9F, 0x8D, 0x71, 0xC4, 0xAF, 0x9E, 0xB4, 0xB4, 0xC2, + 0xAF, 0x75, 0xC6, 0x1A, 0x18, 0x62, 0x0F, 0xCA, 0xB5, 0xC8, 0x18, 0xBF, 0xB4, 0xA1, 0x93, 0x2F, + 0x01, 0x5D, 0x17, 0xDC, 0x22, 0x1E, 0x21, 0x61, 0xEB, 0xF3, 0x69, 0x0F, 0xE7, 0x7B, 0xF4, 0xAA, + 0x8C, 0xF9, 0x1A, 0xA3, 0x61, 0x39, 0x26, 0xDF, 0x23, 0x57, 0x59, 0x6A, 0x1C, 0x43, 0xF2, 0x71, + 0xF6, 0x05, 0xB2, 0xA1, 0xB9, 0x69, 0xAB, 0x6D, 0x8B, 0xFF, 0x42, 0x97, 0x81, 0x65, 0xF5, 0xD1, + 0x02, 0x2F, 0xE4, 0x1A, 0x73, 0x87, 0xD7, 0x35, 0xA3, 0xC0, 0x8F, 0xF0, 0xC3, 0xE6, 0x9D, 0x3C, + 0x39, 0x86, 0x8A, 0x7F, 0xD2, 0xB0, 0xCA, 0x83, 0x53, 0x87, 0x95, 0x67, 0x91, 0x07, 0xA8, 0xC6, + 0x0E, 0x66, 0xFB, 0xF6, 0x01, 0xDF, 0x23, 0xD6, 0x24, 0xF3, 0xA2, 0xD2, 0x0E, 0x36, 0x1B, 0x73, + 0xD8, 0x63, 0x87, 0x6B, 0xC5, 0xE7, 0xE5, 0x9A, 0xCA, 0x3F, 0xC1, 0xD1, 0xB4, 0xFD, 0x6F, 0x0B, + 0x34, 0x8C, 0x35, 0x45, 0x7F, 0xC0, 0x3E, 0x5B, 0x75, 0x22, 0x65, 0x13, 0xD6, 0x10, 0xFB, 0x64, + 0xBD, 0xFF, 0x9A, 0xCA, 0x78, 0xD0, 0x2B, 0xB2, 0x8F, 0x56, 0x6C, 0x65, 0x8B, 0x86, 0xB5, 0xF2, + 0x1A, 0x58, 0x39, 0xC7, 0x97, 0x7B, 0x9B, 0xC2, 0x38, 0x52, 0xC7, 0xD1, 0xDF, 0x8E, 0x2C, 0x2D, + 0xDD, 0xA9, 0x79, 0xF0, 0xD9, 0x03, 0xC8, 0xBA, 0xD0, 0xE0, 0x4A, 0x63, 0x92, 0x5E, 0xDB, 0x8F, + 0x71, 0xFA, 0xD5, 0x7E, 0xCE, 0x58, 0xBD, 0xB7, 0xB7, 0x05, 0xCF, 0x3C, 0xE7, 0xAD, 0x8E, 0x49, + 0x8C, 0x92, 0x3A, 0xA0, 0xB6, 0x2D, 0x79, 0x35, 0xF7, 0x25, 0x2F, 0xC9, 0x05, 0x4C, 0x3F, 0xC8, + 0x3C, 0xFA, 0x1C, 0xAA, 0xDD, 0xA3, 0xDA, 0xCF, 0xF2, 0x3B, 0x62, 0x2B, 0x6B, 0x7C, 0xA7, 0xEB, + 0xEA, 0x9A, 0x50, 0xC8, 0xF1, 0x80, 0xAF, 0x06, 0xFC, 0x4F, 0x98, 0x54, 0x9D, 0x2D, 0xD7, 0x81, + 0xBC, 0xF4, 0x2D, 0x3A, 0xBF, 0x84, 0x86, 0xE5, 0x59, 0xDC, 0x56, 0xBC, 0xA7, 0x7D, 0x10, 0x5B, + 0x01, 0x6D, 0xD5, 0x6F, 0x57, 0xE9, 0x1D, 0xE3, 0x41, 0x6E, 0x4E, 0x9B, 0xA5, 0xF0, 0xA1, 0x6F, + 0xE4, 0x4A, 0xE2, 0x90, 0xC7, 0x70, 0x1F, 0xFB, 0x13, 0xFB, 0xAF, 0xDA, 0xC3, 0xB2, 0xA4, 0xDE, + 0xF7, 0xDC, 0xE7, 0x3E, 0x77, 0x45, 0xBE, 0xA9, 0xB8, 0x9B, 0xFA, 0x3E, 0x31, 0x8A, 0xC8, 0xD1, + 0x2D, 0xBF, 0x75, 0xDD, 0x1F, 0xC4, 0x9D, 0xF1, 0x0C, 0x74, 0xAB, 0xB5, 0xB7, 0x91, 0xE7, 0x2B, + 0xAE, 0xF8, 0xBC, 0x34, 0x4C, 0x5E, 0x0C, 0x4D, 0x4E, 0x3F, 0xC0, 0x66, 0xA7, 0x61, 0x7E, 0xC7, + 0xDA, 0xE4, 0xBD, 0x1E, 0x95, 0x16, 0xF1, 0x99, 0x3B, 0x1A, 0x5B, 0xF2, 0x13, 0x67, 0x2B, 0xE1, + 0x63, 0x94, 0xB1, 0xFB, 0x87, 0xFC, 0x3C, 0x45, 0xC3, 0xEA, 0xBE, 0xE4, 0x6E, 0xDB, 0x3A, 0xEE, + 0xF4, 0x45, 0xD9, 0x3E, 0x6B, 0xC7, 0xD8, 0xAA, 0x1F, 0xCF, 0xD8, 0x1F, 0xDE, 0x63, 0x77, 0xAA, + 0xB2, 0x61, 0xD5, 0x63, 0xC4, 0x35, 0x78, 0x73, 0xC6, 0xD6, 0x48, 0x1B, 0xBD, 0xEB, 0x8D, 0x3D, + 0x91, 0x71, 0x3C, 0x15, 0x97, 0xB2, 0x0F, 0xF4, 0x03, 0x63, 0xE9, 0x6A, 0xBC, 0x2A, 0x36, 0x0E, + 0xE3, 0x18, 0xD3, 0xBE, 0x96, 0xD5, 0xDF, 0xCC, 0xA5, 0xDF, 0xF2, 0x45, 0x26, 0x9D, 0xAD, 0x77, + 0xC0, 0x5F, 0xFE, 0xF2, 0x97, 0xDF, 0xB0, 0xEF, 0x73, 0x8C, 0x99, 0x2F, 0x89, 0x5C, 0x67, 0xD8, + 0xE5, 0x84, 0x45, 0xE6, 0x0C, 0xAD, 0x30, 0xA7, 0xE0, 0x47, 0xA9, 0xFA, 0x5B, 0x8B, 0x86, 0xB5, + 0xE4, 0x15, 0x74, 0xA3, 0xDA, 0x5E, 0xC5, 0x1D, 0x78, 0x15, 0x34, 0x8C, 0x39, 0x64, 0xEC, 0x5D, + 0x3E, 0xC7, 0x2B, 0xFE, 0x88, 0xCC, 0x0D, 0x99, 0xFE, 0x65, 0xD6, 0x1F, 0x59, 0xB4, 0xE2, 0x64, + 0xF2, 0x6A, 0xF8, 0x9F, 0x31, 0xBD, 0xB5, 0xFD, 0xD4, 0x41, 0x29, 0xE4, 0x87, 0x6D, 0xF9, 0xB0, + 0x13, 0x4F, 0xFC, 0x8E, 0xBB, 0xB4, 0xCC, 0x65, 0x59, 0xD7, 0xB8, 0xCE, 0x13, 0x39, 0x5B, 0x3A, + 0x5C, 0xF7, 0x04, 0xFD, 0xE4, 0x1D, 0xCF, 0x19, 0x93, 0xD1, 0xF2, 0x29, 0x99, 0xA3, 0x31, 0xCF, + 0x9A, 0x6C, 0x66, 0x1A, 0x26, 0x5E, 0xA0, 0x4B, 0x7A, 0xB7, 0x52, 0xDA, 0x86, 0x12, 0x6E, 0xD8, + 0x9C, 0xD2, 0x5E, 0x25, 0xAF, 0x63, 0x2F, 0x7A, 0x77, 0x5B, 0x3D, 0x57, 0x9F, 0x65, 0x4E, 0x97, + 0xCC, 0xFB, 0xDF, 0xCD, 0x4D, 0x92, 0x76, 0x9B, 0x1C, 0xAF, 0xFA, 0x97, 0x3A, 0x21, 0x38, 0xC8, + 0x73, 0xFA, 0xFB, 0xD4, 0x21, 0x6D, 0x9B, 0x73, 0x3C, 0xC2, 0xA1, 0xDE, 0x1F, 0x65, 0x91, 0xCF, + 0x91, 0x1B, 0xDE, 0x9C, 0x42, 0x55, 0x57, 0xF3, 0xEE, 0x53, 0x65, 0xD3, 0x1C, 0x53, 0x9D, 0x2F, + 0xDF, 0x23, 0x6F, 0x54, 0xDC, 0x81, 0x0E, 0xC2, 0x2B, 0xC9, 0x61, 0xE5, 0x99, 0xC3, 0x31, 0xBB, + 0xAF, 0xDF, 0xCB, 0xFF, 0x2B, 0xCD, 0xCA, 0xB5, 0xCE, 0x7B, 0x27, 0x8D, 0x19, 0x42, 0xD6, 0xF3, + 0x2E, 0xB9, 0x56, 0xBC, 0x6B, 0xFA, 0xF9, 0xF1, 0xE7, 0xA0, 0xFB, 0x8E, 0xF9, 0xF1, 0xF2, 0x1E, + 0x4D, 0xDA, 0xD2, 0xE6, 0xBC, 0x94, 0x86, 0xA5, 0xCD, 0x88, 0x18, 0xC3, 0x6A, 0x07, 0xAB, 0xB8, + 0xC3, 0xEF, 0xE8, 0xB8, 0xC4, 0xA3, 0x24, 0x7C, 0xAB, 0xAE, 0xB0, 0xEF, 0xBE, 0xFB, 0xAE, 0xE0, + 0x4E, 0xB5, 0x49, 0x78, 0xB7, 0x4C, 0x9E, 0xA1, 0x48, 0xBC, 0xC2, 0x8F, 0xE3, 0xF9, 0xCD, 0xDA, + 0x7E, 0xD2, 0x4D, 0xDE, 0x83, 0x47, 0xAE, 0xE5, 0xD8, 0x79, 0x2F, 0xE7, 0x0E, 0x4F, 0x4D, 0xBD, + 0x5C, 0x9F, 0x75, 0x8B, 0x6E, 0xE3, 0xBF, 0xCC, 0x58, 0xBB, 0xCC, 0x35, 0xC6, 0xFD, 0x43, 0xEE, + 0x2F, 0x8A, 0x38, 0x93, 0xCF, 0xA7, 0x9D, 0x53, 0x5D, 0x69, 0xEC, 0x9E, 0xBC, 0xCD, 0x46, 0xC3, + 0x2C, 0xE6, 0x8F, 0x1C, 0xBB, 0xCF, 0x0A, 0x3B, 0x2F, 0x72, 0x79, 0xDD, 0xD3, 0x7C, 0xC6, 0x8F, + 0xE6, 0x99, 0x8E, 0xD4, 0x51, 0x96, 0xC8, 0x61, 0x09, 0x93, 0x8A, 0x87, 0xEC, 0x3F, 0xDA, 0xF5, + 0x1C, 0x46, 0x8E, 0xA7, 0xC6, 0x65, 0xF1, 0x3B, 0xE7, 0x86, 0x92, 0xFF, 0xC8, 0x87, 0x91, 0xE7, + 0xD0, 0x39, 0xF3, 0x4E, 0xBE, 0x84, 0x85, 0xBA, 0x9F, 0xBF, 0xE3, 0xAB, 0xAA, 0x77, 0xC6, 0x3A, + 0x46, 0xF0, 0x02, 0xFF, 0xA5, 0xA5, 0xFA, 0x70, 0xF3, 0x95, 0x31, 0xD1, 0xE6, 0x81, 0x07, 0x1E, + 0xD8, 0xEB, 0x43, 0xE6, 0x91, 0xC2, 0xE6, 0x8A, 0x9E, 0x9C, 0x77, 0xCF, 0x8F, 0x15, 0x7F, 0xCB, + 0x31, 0xB5, 0x64, 0x58, 0xF7, 0x90, 0x78, 0xA1, 0xDC, 0x07, 0x4F, 0xD6, 0x1E, 0x9E, 0xB6, 0xED, + 0x9C, 0xBB, 0x63, 0xE6, 0x9C, 0x37, 0xF7, 0x33, 0x55, 0xDA, 0xE5, 0xEF, 0x19, 0xA7, 0x4F, 0x7C, + 0x68, 0xF2, 0xF9, 0x39, 0x1A, 0xA6, 0xFE, 0xE5, 0x1A, 0x03, 0x93, 0x2A, 0x43, 0x54, 0x5F, 0x20, + 0x63, 0x45, 0xFF, 0x67, 0x4C, 0x63, 0xF6, 0x2C, 0xBE, 0x27, 0xC6, 0xAB, 0xE2, 0x90, 0xFD, 0xD3, + 0xAF, 0x77, 0xD4, 0x57, 0x1F, 0xA1, 0x6B, 0x77, 0xC8, 0x21, 0x87, 0xAC, 0x9C, 0x41, 0x1F, 0xDB, + 0x27, 0xFC, 0xDF, 0xDC, 0x18, 0x2D, 0xF8, 0xA7, 0xEF, 0x46, 0x7A, 0x86, 0xBF, 0x37, 0x4B, 0xCB, + 0xFE, 0xE0, 0x77, 0xD8, 0x94, 0xF7, 0xD9, 0x67, 0x9F, 0xDE, 0x0F, 0x81, 0xDD, 0x99, 0x4A, 0xEE, + 0x02, 0xD7, 0xAF, 0xD2, 0x84, 0xDC, 0x63, 0xAE, 0x0D, 0xB9, 0x2F, 0xE9, 0x37, 0xED, 0x29, 0xDB, + 0x02, 0x0D, 0x4B, 0xBC, 0x4E, 0x3C, 0xA5, 0xA4, 0x1D, 0x20, 0xE3, 0xA8, 0x72, 0xFD, 0xF0, 0xAF, + 0x71, 0xBE, 0xB8, 0xDA, 0x96, 0x6A, 0x19, 0xA3, 0x61, 0x63, 0x71, 0xCF, 0xD8, 0x38, 0xC9, 0x87, + 0x41, 0x31, 0xAF, 0x78, 0xFA, 0xD2, 0x1C, 0xBB, 0x3C, 0x8A, 0xF7, 0xC4, 0x6B, 0xC3, 0xCF, 0xD0, + 0x3F, 0x58, 0x23, 0xF0, 0x5F, 0x7B, 0xB0, 0xA5, 0xEA, 0x7C, 0x49, 0x0F, 0xF9, 0x0D, 0xFD, 0x2F, + 0x6D, 0xB4, 0xA9, 0x2F, 0x41, 0x17, 0xD8, 0x33, 0xDA, 0xE1, 0xAA, 0x5D, 0xC9, 0xF7, 0xC6, 0x99, + 0x53, 0xA0, 0x63, 0xEC, 0x11, 0x6C, 0x1A, 0x9C, 0xDF, 0x44, 0x3F, 0x92, 0xE6, 0x57, 0x9B, 0x79, + 0xEA, 0x90, 0x56, 0xF4, 0x11, 0x6C, 0x55, 0xD5, 0x07, 0x59, 0xFD, 0x57, 0xF5, 0xEC, 0x8B, 0x39, + 0x48, 0x38, 0x23, 0x5A, 0xDB, 0xCD, 0xBE, 0xD5, 0x8B, 0xF1, 0x15, 0x7A, 0x3E, 0x69, 0xCA, 0x8F, + 0xC6, 0xF7, 0xCC, 0xC3, 0x58, 0xDA, 0x25, 0x34, 0x4C, 0xFD, 0xD7, 0xB5, 0x86, 0x86, 0xB5, 0xDA, + 0xB5, 0x08, 0x57, 0xEC, 0x60, 0xE4, 0x1F, 0x68, 0xE9, 0x4F, 0xEA, 0xC0, 0x79, 0xC6, 0xA1, 0xFA, + 0x34, 0xE8, 0x93, 0xF5, 0x34, 0x97, 0x5B, 0xED, 0x8F, 0x36, 0x58, 0x0F, 0x6D, 0x9C, 0x63, 0x32, + 0xB1, 0xB8, 0xC1, 0x7E, 0xCA, 0xF6, 0x5B, 0x7B, 0xDA, 0x98, 0x2C, 0xEA, 0xED, 0x6F, 0x7F, 0xFB, + 0x95, 0xF3, 0x45, 0x15, 0x57, 0x84, 0xBD, 0xDF, 0x21, 0x4F, 0x71, 0x36, 0x89, 0x58, 0x27, 0x6C, + 0x1A, 0x59, 0x2A, 0xAF, 0xAC, 0xBC, 0x88, 0x42, 0x6C, 0x2C, 0x63, 0xD0, 0x37, 0x7A, 0x74, 0xC5, + 0x56, 0x6C, 0x4D, 0x1A, 0x96, 0xF2, 0xBC, 0xBA, 0x79, 0x85, 0x17, 0x38, 0x63, 0x9E, 0x92, 0x7A, + 0x97, 0x01, 0x95, 0xF8, 0x25, 0x7C, 0x3F, 0xC9, 0x53, 0xD6, 0xC9, 0xBD, 0x53, 0xCF, 0x2B, 0xE7, + 0xDC, 0x52, 0xE6, 0xA1, 0x8C, 0xDD, 0x71, 0x69, 0xFB, 0xC8, 0x3E, 0xCA, 0x6C, 0xE9, 0x13, 0xCA, + 0x3C, 0xA9, 0xAD, 0xB8, 0x4A, 0xC7, 0x0D, 0xDE, 0xA4, 0x6F, 0xBA, 0xC6, 0x66, 0xFA, 0x9E, 0x7D, + 0x95, 0xF7, 0x1B, 0xDA, 0x7F, 0xBE, 0x26, 0x7C, 0x33, 0xB7, 0x7B, 0xCD, 0xC7, 0x59, 0xE9, 0x57, + 0xA5, 0x37, 0xE0, 0x86, 0x77, 0xE9, 0x24, 0xEC, 0xC7, 0x72, 0x22, 0xE7, 0x67, 0xDE, 0x13, 0x0F, + 0x57, 0xEF, 0x40, 0x51, 0x57, 0xB3, 0x00, 0x33, 0x72, 0x49, 0x78, 0x6F, 0x4A, 0xD5, 0x8F, 0xF3, + 0x0E, 0x73, 0xFE, 0x8B, 0x6C, 0x93, 0x74, 0x6A, 0x8A, 0x86, 0xB5, 0x6C, 0x62, 0xDC, 0x83, 0x34, + 0xB6, 0x06, 0x69, 0x43, 0xA7, 0x5F, 0xE2, 0x2B, 0xEC, 0xBF, 0xEA, 0x83, 0xD0, 0xF7, 0xBC, 0x37, + 0x38, 0xE3, 0x4E, 0x85, 0x0F, 0xFE, 0x1C, 0x78, 0x46, 0x0B, 0x77, 0x9C, 0xAB, 0xF7, 0x2C, 0x55, + 0xDB, 0x5F, 0xD2, 0x0A, 0x9E, 0x27, 0xDF, 0x8D, 0x73, 0x4B, 0xBD, 0x21, 0xE7, 0x2C, 0x3E, 0x33, + 0x2E, 0x64, 0x29, 0xE2, 0xA6, 0xD2, 0x0F, 0x5E, 0xCF, 0xD8, 0x8A, 0x27, 0x8E, 0x2F, 0xF1, 0x56, + 0x5C, 0xF6, 0xB5, 0xF2, 0xDF, 0xA4, 0x7D, 0xB4, 0xEB, 0xFD, 0x16, 0x75, 0x0D, 0xB6, 0x05, 0x1A, + 0x56, 0x73, 0xF3, 0xE5, 0xFF, 0x81, 0x9F, 0xF7, 0x06, 0x5B, 0x33, 0xB7, 0x15, 0x76, 0x32, 0xE2, + 0xA9, 0x5B, 0xE7, 0x83, 0xB3, 0x8C, 0xD1, 0xB0, 0xBC, 0x1B, 0xD9, 0x3D, 0xEA, 0xFC, 0xBC, 0xB7, + 0xDA, 0xB6, 0x6B, 0x8E, 0xF1, 0xC4, 0xCB, 0xD4, 0x81, 0xD2, 0x5E, 0x90, 0x3A, 0x84, 0xB8, 0x54, + 0x75, 0x52, 0x68, 0x1C, 0x6D, 0x71, 0xAF, 0x6D, 0x8E, 0x2B, 0xD7, 0x9F, 0x57, 0x79, 0x2C, 0x79, + 0xE7, 0x90, 0xFF, 0xB2, 0x9F, 0x29, 0x5D, 0x3D, 0xE9, 0x7B, 0xEA, 0x6F, 0x7E, 0x47, 0xFF, 0x2D, + 0x3D, 0x99, 0xF1, 0x12, 0x8F, 0xEB, 0xD9, 0x88, 0xD4, 0x93, 0xD3, 0xE7, 0x30, 0x55, 0xB1, 0x71, + 0xA5, 0xFC, 0x55, 0xE3, 0x40, 0xC6, 0xFC, 0x09, 0xD5, 0x06, 0x9D, 0x7B, 0x8B, 0xF9, 0xE7, 0xBD, + 0x13, 0x53, 0xB5, 0xFA, 0xF0, 0xA8, 0x9C, 0x03, 0x14, 0x6E, 0x73, 0x25, 0xE9, 0x8D, 0xE7, 0x72, + 0xDC, 0xF3, 0x9C, 0x1D, 0x1F, 0x3B, 0xAF, 0xA0, 0xCD, 0x8A, 0x71, 0x22, 0x67, 0x55, 0x7E, 0x6D, + 0xFF, 0x4B, 0xE6, 0x6E, 0xCE, 0x31, 0xEF, 0x7E, 0x6B, 0xE5, 0xED, 0x1A, 0xAB, 0x9C, 0x15, 0xC0, + 0xEF, 0x5B, 0xD7, 0xB9, 0x15, 0x77, 0xA1, 0x9F, 0xC9, 0xFD, 0x98, 0x34, 0xB5, 0xE2, 0x97, 0xB8, + 0xCD, 0x7F, 0xA9, 0xE8, 0xC4, 0xEA, 0x90, 0xDA, 0xC4, 0x52, 0xB7, 0x4E, 0xB9, 0x03, 0xDC, 0x26, + 0x9F, 0x86, 0x7B, 0x65, 0x6E, 0xFE, 0x9E, 0xE3, 0x49, 0x1B, 0x92, 0x31, 0xE5, 0xBC, 0x87, 0xEF, + 0x7B, 0xFE, 0x2E, 0x61, 0x9C, 0x79, 0xFF, 0x13, 0xEF, 0xA7, 0xEE, 0x4A, 0xAF, 0x15, 0x98, 0xD3, + 0x56, 0x85, 0x57, 0xC6, 0x2A, 0x4F, 0x55, 0x0A, 0xFA, 0x05, 0x78, 0x90, 0x72, 0x88, 0x31, 0xF0, + 0xBC, 0xC7, 0xE7, 0xE7, 0x1A, 0x59, 0xCC, 0xC1, 0x6C, 0x1F, 0xBE, 0x47, 0xB7, 0x33, 0xE6, 0x65, + 0xC9, 0xF8, 0xA9, 0xD8, 0x8E, 0xCC, 0x91, 0xEA, 0xB8, 0xD3, 0xA6, 0x9E, 0x30, 0x6B, 0xE9, 0x3F, + 0xAD, 0xF5, 0xF7, 0x7F, 0xFA, 0x05, 0xF8, 0x0F, 0xBC, 0xD8, 0xB5, 0xD7, 0x47, 0x94, 0x6B, 0x55, + 0x71, 0x17, 0x59, 0x04, 0x3D, 0x21, 0x75, 0x9B, 0xF4, 0x55, 0x02, 0xF3, 0x25, 0x7A, 0x7C, 0x16, + 0xE5, 0x0C, 0x9E, 0xC7, 0x16, 0xC4, 0xF9, 0x70, 0x73, 0xFD, 0x54, 0x1A, 0xB6, 0xE4, 0xAE, 0x49, + 0x2A, 0xF1, 0xFE, 0xC6, 0x95, 0x24, 0xAD, 0x4F, 0x1B, 0xF3, 0x54, 0xCD, 0x38, 0x75, 0x0A, 0xF0, + 0x82, 0x8F, 0x2E, 0xED, 0x3F, 0x71, 0x86, 0xCA, 0x1C, 0xB8, 0xC3, 0x87, 0x32, 0x16, 0x3F, 0x95, + 0x25, 0x73, 0x0F, 0x54, 0x5B, 0x05, 0xFE, 0x95, 0x39, 0x1A, 0xC6, 0x2B, 0xBE, 0x64, 0xF3, 0x51, + 0x52, 0x2B, 0x2F, 0x9C, 0xAA, 0x79, 0x66, 0x58, 0x1A, 0x36, 0x26, 0x7B, 0x8E, 0x55, 0xEE, 0xF1, + 0x44, 0x16, 0xAC, 0x77, 0x83, 0x29, 0x9F, 0x4F, 0xD9, 0x44, 0x73, 0x3F, 0x66, 0xAC, 0x51, 0xAE, + 0x89, 0xF7, 0x5E, 0xA6, 0x1D, 0x4C, 0x9F, 0x4B, 0xF5, 0xC3, 0xB9, 0x6F, 0xD1, 0xB1, 0xD9, 0x57, + 0x73, 0xF3, 0xF7, 0x5E, 0x07, 0x70, 0xDF, 0x18, 0xB6, 0xAA, 0x9F, 0x70, 0xD6, 0x01, 0x39, 0x2C, + 0xE3, 0xE2, 0x6B, 0x01, 0x8E, 0xAE, 0x37, 0xED, 0xA4, 0xAC, 0x3C, 0x55, 0x39, 0x47, 0x26, 0x1C, + 0x5C, 0x07, 0x4A, 0xC6, 0xFD, 0x4C, 0x55, 0xFE, 0xC7, 0xFD, 0x1A, 0x35, 0x77, 0x42, 0xDA, 0x8E, + 0xB1, 0xE9, 0x2B, 0x2F, 0xB7, 0xC6, 0x9F, 0xFC, 0x84, 0xFB, 0x2A, 0x1D, 0xDB, 0xDC, 0xF9, 0xAF, + 0xDC, 0xA7, 0xE8, 0xF9, 0xE2, 0x33, 0xBC, 0x2C, 0x65, 0xF0, 0xA9, 0xFC, 0x32, 0xFC, 0xDF, 0xFE, + 0xE5, 0x71, 0xAD, 0xBB, 0x86, 0x88, 0x6F, 0x63, 0x1E, 0x79, 0x0F, 0x60, 0xCA, 0x0F, 0xF9, 0xBD, + 0x7A, 0x04, 0xE3, 0xE7, 0xDE, 0x48, 0xFA, 0x48, 0x9B, 0x47, 0x2B, 0x27, 0x62, 0xE6, 0x44, 0x48, + 0x99, 0xAD, 0x15, 0x67, 0x6D, 0xC1, 0x3E, 0xA5, 0x9F, 0x5C, 0x3E, 0x9A, 0x30, 0x5B, 0x7A, 0xD7, + 0x3B, 0x31, 0x6A, 0xEA, 0x4A, 0xAE, 0xB9, 0xA5, 0x05, 0x8B, 0x5A, 0xAA, 0xDE, 0xC9, 0x7E, 0xA9, + 0x7A, 0xF6, 0x5C, 0x4D, 0x7F, 0x03, 0xCF, 0xA1, 0xDF, 0x2E, 0x2D, 0x95, 0x07, 0xA5, 0x3E, 0x09, + 0x7E, 0x8F, 0x9D, 0x6B, 0x4A, 0x19, 0xDA, 0x1C, 0x87, 0x15, 0x06, 0x4B, 0xE6, 0x9F, 0x6B, 0x83, + 0xFC, 0x68, 0xDB, 0xEB, 0xF0, 0x61, 0x78, 0x23, 0x73, 0x56, 0x8E, 0x9C, 0xA2, 0xDD, 0x89, 0xAB, + 0x53, 0x77, 0x1B, 0x51, 0xC0, 0x2B, 0xFC, 0x06, 0xD8, 0xA4, 0x93, 0x1E, 0xC8, 0xEB, 0xA0, 0x69, + 0x89, 0x27, 0x09, 0x27, 0xFC, 0x07, 0x4B, 0x0A, 0xFD, 0xC2, 0x03, 0x6A, 0x2C, 0xA7, 0x7B, 0x80, + 0x36, 0xD1, 0x25, 0x39, 0x3F, 0x9B, 0xCF, 0x50, 0xC6, 0xE0, 0xEC, 0x3D, 0x37, 0x4B, 0x64, 0x59, + 0x64, 0x85, 0x9C, 0xF7, 0xD8, 0x9D, 0x43, 0x63, 0x85, 0xBE, 0x39, 0xAB, 0xD7, 0xD2, 0xA7, 0xAD, + 0xDC, 0xC9, 0x99, 0xB9, 0xF7, 0x29, 0xA9, 0x57, 0xE6, 0xF8, 0x93, 0x86, 0x2D, 0xC1, 0x01, 0xD7, + 0x02, 0x5D, 0x4A, 0xDE, 0x4D, 0xC9, 0xBB, 0x9E, 0x85, 0x99, 0x72, 0xB5, 0x74, 0xAD, 0x15, 0x33, + 0x99, 0xF6, 0x53, 0x7E, 0x87, 0x2F, 0xC2, 0x63, 0x88, 0x47, 0xAC, 0x7B, 0xAE, 0xAE, 0x79, 0xFA, + 0xD3, 0xA5, 0x2D, 0x7C, 0x26, 0x1E, 0xDB, 0xFB, 0x64, 0x33, 0xE7, 0x31, 0x7D, 0x29, 0x5F, 0xB7, + 0x6C, 0x03, 0xF9, 0x59, 0x7F, 0x85, 0x31, 0x51, 0xD8, 0x8B, 0xCC, 0xE9, 0x57, 0x69, 0x57, 0xB5, + 0x5B, 0xCF, 0xC1, 0x10, 0xD8, 0x11, 0x43, 0xA9, 0x1E, 0xC3, 0x3E, 0x32, 0x17, 0xB2, 0x76, 0xF1, + 0xA9, 0xAA, 0xDD, 0x19, 0x1E, 0x4B, 0x9C, 0x06, 0xBE, 0x09, 0xEF, 0xA1, 0x5B, 0x82, 0x83, 0x35, + 0xCE, 0x05, 0xD8, 0x42, 0x0B, 0x8C, 0x5B, 0x35, 0x0F, 0xCD, 0x58, 0x75, 0x3F, 0xB3, 0xEF, 0x81, + 0x8F, 0xF7, 0xD2, 0x03, 0x5B, 0xF6, 0xE1, 0x9C, 0x3D, 0x8E, 0xBE, 0xE1, 0x35, 0xF8, 0x61, 0x98, + 0x03, 0xB8, 0xE1, 0xBC, 0x80, 0xC3, 0xDC, 0xFC, 0xF9, 0x0F, 0xCF, 0xA0, 0x6B, 0x64, 0xFE, 0xE7, + 0xA5, 0xBA, 0x64, 0xFA, 0x93, 0xF1, 0x91, 0x13, 0x0B, 0xC6, 0x1A, 0x8C, 0xC5, 0x8A, 0x4C, 0xED, + 0x45, 0xE1, 0xA1, 0xED, 0x9F, 0xD8, 0x1D, 0xEC, 0x7D, 0xE2, 0x82, 0x7E, 0xA7, 0xC4, 0x93, 0xB1, + 0x58, 0x1C, 0x62, 0x36, 0xBC, 0xBF, 0x6E, 0xAA, 0x32, 0x36, 0x74, 0xF6, 0x1A, 0x47, 0x9C, 0xFB, + 0x97, 0xF8, 0x2A, 0x6C, 0xA9, 0xCA, 0xCC, 0xE0, 0x9A, 0xF7, 0xA3, 0x32, 0x6E, 0x6D, 0xC7, 0x7C, + 0xA6, 0xCF, 0x3C, 0x17, 0x3A, 0x57, 0x89, 0x7D, 0x41, 0x5E, 0x74, 0xDD, 0xB4, 0xFD, 0x79, 0xDE, + 0x66, 0x6E, 0xFC, 0xF8, 0x75, 0x33, 0x6F, 0x7E, 0xC2, 0xC6, 0x31, 0x10, 0xC7, 0xC5, 0x79, 0x3B, + 0xFD, 0x92, 0xCA, 0xC8, 0xEE, 0x67, 0x63, 0x0C, 0xE8, 0x9B, 0xB8, 0xA0, 0xD6, 0x99, 0xD9, 0xB9, + 0xEA, 0xFD, 0x7C, 0xC8, 0x4A, 0xF0, 0x04, 0x0A, 0x38, 0x5C, 0xE3, 0x24, 0x5A, 0xEB, 0x9E, 0x79, + 0x24, 0x2C, 0xCC, 0x8D, 0xF8, 0x00, 0x62, 0x16, 0xA1, 0x47, 0xDA, 0x76, 0xCC, 0xD3, 0x93, 0xF0, + 0xCD, 0xB5, 0xAA, 0x79, 0x50, 0x3C, 0x5B, 0xC2, 0xFF, 0x39, 0x87, 0x4B, 0x9C, 0x1D, 0xED, 0xE6, + 0xFD, 0x20, 0x63, 0x74, 0xCB, 0xF8, 0x0B, 0x0A, 0x38, 0x8D, 0xAC, 0x84, 0x3D, 0x0E, 0xDF, 0x3A, + 0x7C, 0x5B, 0x38, 0xD5, 0xB8, 0x23, 0xE4, 0xF0, 0x25, 0x32, 0x6C, 0x56, 0xEE, 0x96, 0xC5, 0x3F, + 0x82, 0x3F, 0x10, 0x9C, 0x60, 0x4F, 0xF3, 0x19, 0xBE, 0xC0, 0xE7, 0xA9, 0xCA, 0xFF, 0x38, 0x13, + 0xCF, 0x3D, 0x21, 0xE4, 0x1D, 0xC2, 0x47, 0xEA, 0xDC, 0x97, 0xC8, 0x62, 0xB9, 0x87, 0xDC, 0xFB, + 0xF8, 0x81, 0x68, 0x0F, 0xD9, 0x64, 0xAE, 0x7F, 0x2A, 0x34, 0x9D, 0x38, 0x66, 0x62, 0xD8, 0x88, + 0xAB, 0xF3, 0x39, 0x74, 0x98, 0x25, 0xFD, 0x23, 0x27, 0x60, 0x1B, 0xA6, 0x4F, 0xDA, 0x80, 0x86, + 0x32, 0x77, 0xE1, 0x31, 0x55, 0xED, 0x8B, 0xF8, 0x16, 0xE4, 0x9D, 0x9C, 0xCB, 0xD2, 0xF9, 0xD7, + 0xFB, 0xE7, 0x39, 0x13, 0x43, 0x4C, 0x39, 0xE7, 0x2F, 0xE0, 0x0B, 0x69, 0x3F, 0x96, 0x1F, 0x6B, + 0x3F, 0xCA, 0xFB, 0x7D, 0xF1, 0x9D, 0xE1, 0x4F, 0xE2, 0x9E, 0xCD, 0xCC, 0x99, 0xC7, 0x59, 0x14, + 0xF7, 0x49, 0xEE, 0x99, 0x1C, 0x87, 0x72, 0x93, 0xB4, 0x0E, 0x3A, 0x82, 0x6E, 0xBC, 0x04, 0xF6, + 0xD8, 0x73, 0x52, 0x8E, 0xAE, 0xF4, 0x07, 0xDB, 0x02, 0xF0, 0x05, 0xAF, 0x84, 0x15, 0x38, 0xC3, + 0x5A, 0x01, 0x67, 0xAA, 0x7D, 0xC1, 0x07, 0xA0, 0x87, 0x49, 0x6F, 0xA7, 0x2A, 0x30, 0x67, 0xCD, + 0xA8, 0xE2, 0xAC, 0x39, 0x1A, 0xE8, 0x67, 0x6E, 0xFC, 0x9C, 0xFB, 0x77, 0xDC, 0xE9, 0x6F, 0xC9, + 0x3E, 0xD0, 0xC3, 0xC9, 0x09, 0x41, 0xDB, 0xF4, 0x43, 0xBB, 0xAC, 0x3B, 0xF8, 0x61, 0xBF, 0xE4, + 0x87, 0xA0, 0x5F, 0xEE, 0xAE, 0x5D, 0x67, 0xFF, 0x55, 0x7B, 0xB0, 0xE7, 0x0C, 0x39, 0xAB, 0x0F, + 0x0E, 0x60, 0xAB, 0xC5, 0xB6, 0x5E, 0x63, 0x86, 0xA0, 0x99, 0xF0, 0x82, 0xAA, 0x37, 0x81, 0x03, + 0xF0, 0x41, 0xE0, 0x0D, 0x3D, 0x4C, 0x7F, 0x3F, 0x7D, 0x69, 0x3B, 0x4F, 0x7C, 0xAB, 0xFB, 0x35, + 0xE3, 0x4B, 0x94, 0xD3, 0x93, 0xAE, 0x70, 0x76, 0x93, 0xD8, 0x6F, 0x64, 0xE0, 0x83, 0x0F, 0x3E, + 0xB8, 0x3F, 0x4F, 0x4F, 0xFE, 0x4F, 0xEC, 0x8A, 0xE0, 0x1F, 0xFD, 0xF3, 0x99, 0xF1, 0x13, 0xAF, + 0x4E, 0x0C, 0xE7, 0x95, 0xAE, 0x74, 0xA5, 0x41, 0xBE, 0x4E, 0x9A, 0x95, 0x31, 0xBB, 0xB9, 0x27, + 0xD6, 0xD1, 0xE3, 0x1C, 0x9F, 0xF4, 0x63, 0x1D, 0x1D, 0xA8, 0xD2, 0xA1, 0xE4, 0xC5, 0xEB, 0x3E, + 0x9B, 0x31, 0xB8, 0x09, 0xC7, 0x25, 0xB5, 0xA5, 0x37, 0x2F, 0xE5, 0xE3, 0x56, 0xF3, 0x9F, 0xAE, + 0x3B, 0x7E, 0x2B, 0x78, 0x9F, 0xFB, 0xB8, 0xB5, 0x97, 0xC7, 0xAA, 0xBC, 0x8F, 0x67, 0xF0, 0x55, + 0x3A, 0x0E, 0xDE, 0xE3, 0x13, 0x23, 0x07, 0xC5, 0x6D, 0x6E, 0x73, 0x9B, 0x9E, 0x06, 0xB0, 0xEF, + 0xC9, 0x75, 0x82, 0xCE, 0x82, 0x1D, 0x0D, 0x9F, 0x00, 0x31, 0x1A, 0xE0, 0x14, 0x32, 0x57, 0xE5, + 0x61, 0xCA, 0x85, 0xB9, 0x2F, 0xD3, 0x9E, 0x5B, 0x61, 0x65, 0x5E, 0x97, 0x1C, 0xD7, 0x92, 0x7D, + 0x58, 0x71, 0x4F, 0x9A, 0xE0, 0x6F, 0xDA, 0x92, 0x13, 0x46, 0xB5, 0x9D, 0xBC, 0x27, 0x62, 0x9D, + 0x35, 0xAC, 0x67, 0xA7, 0xB6, 0x74, 0x0D, 0xF3, 0xEE, 0xC9, 0xDA, 0x5E, 0xCB, 0xF7, 0x34, 0x85, + 0x87, 0xEB, 0xE0, 0x6F, 0xE6, 0x95, 0xAF, 0xCF, 0x41, 0x2F, 0xD0, 0x03, 0xF1, 0xBD, 0x41, 0x97, + 0x90, 0x13, 0xC8, 0x77, 0x71, 0xD0, 0x41, 0x07, 0xF5, 0xF4, 0x03, 0x7E, 0x05, 0xFD, 0xE4, 0xAE, + 0x36, 0xEE, 0xC5, 0x22, 0x6E, 0x16, 0xB9, 0x2B, 0x73, 0xE0, 0x48, 0xA3, 0xC4, 0x01, 0x69, 0x49, + 0xDA, 0x47, 0xEB, 0x79, 0xF2, 0x5C, 0x87, 0xFA, 0x5E, 0xDC, 0xF6, 0x7B, 0xE8, 0x22, 0x38, 0x85, + 0x6D, 0x1E, 0xFF, 0x0D, 0x3C, 0x8B, 0xEF, 0x94, 0xF9, 0x5C, 0xCB, 0xE4, 0x49, 0xF5, 0xAE, 0xD3, + 0xBC, 0x7F, 0x7D, 0xDD, 0xB5, 0x6C, 0x9D, 0xED, 0xD3, 0xBE, 0x99, 0xF1, 0x5D, 0x63, 0x35, 0xF3, + 0x9B, 0xA5, 0x3E, 0xBD, 0x2E, 0x2E, 0x69, 0x43, 0x91, 0x8E, 0xA6, 0x4E, 0xB6, 0xA4, 0xD6, 0xB5, + 0xA7, 0xFF, 0xE4, 0x35, 0x4B, 0x6A, 0xFA, 0x66, 0x72, 0x1E, 0x73, 0xD5, 0xFF, 0xB5, 0xEE, 0x32, + 0x58, 0xDA, 0x67, 0xAD, 0x69, 0x5F, 0x4F, 0x59, 0xAD, 0x75, 0x8F, 0x42, 0xFA, 0x00, 0xB3, 0xDD, + 0xC4, 0x21, 0xF1, 0xA5, 0xE6, 0x49, 0xA1, 0x8F, 0xA4, 0x01, 0x55, 0xAF, 0x5A, 0x32, 0x77, 0x9E, + 0x11, 0x27, 0xAB, 0x8E, 0x52, 0xF1, 0x32, 0xE5, 0xBD, 0x3A, 0x4F, 0x7D, 0xFD, 0xEB, 0xC0, 0x90, + 0x7D, 0x59, 0x65, 0x8A, 0xC4, 0xE3, 0x25, 0xE3, 0x77, 0xFE, 0xAD, 0xB3, 0xFA, 0x2D, 0xDB, 0x6E, + 0xCA, 0x88, 0xBC, 0xB6, 0x72, 0x7F, 0x67, 0xFC, 0xC4, 0x96, 0xE0, 0x02, 0x34, 0xA8, 0xEA, 0x58, + 0xC2, 0x4A, 0xF8, 0xD5, 0xFB, 0xCA, 0x5A, 0xF2, 0x87, 0x72, 0x57, 0x8E, 0x8B, 0xD7, 0x94, 0xC3, + 0x9D, 0x37, 0xBF, 0x65, 0xFE, 0xDF, 0x94, 0x69, 0x32, 0x96, 0x30, 0xC7, 0x09, 0xEC, 0xC6, 0xE8, + 0x75, 0xE6, 0xBA, 0x4E, 0x58, 0x24, 0xAD, 0xAF, 0x7C, 0x72, 0x49, 0x2E, 0xBC, 0x56, 0x4D, 0x1F, + 0x5D, 0xEB, 0x9C, 0xDF, 0x92, 0xEA, 0x9A, 0x26, 0x6C, 0x96, 0x3C, 0x2F, 0xBE, 0x26, 0x5C, 0x96, + 0xE8, 0x10, 0x15, 0x1E, 0x09, 0xEF, 0x75, 0x7D, 0xA2, 0x35, 0x57, 0x01, 0x6D, 0x2E, 0x1D, 0x43, + 0x0B, 0x4F, 0x5B, 0x31, 0x52, 0x4B, 0xE0, 0xD0, 0xB2, 0xC9, 0x68, 0x5B, 0xAC, 0xFF, 0x95, 0x16, + 0x24, 0xDE, 0xEA, 0xCB, 0x1B, 0xB3, 0x89, 0xA6, 0xDF, 0x30, 0x9F, 0x13, 0x77, 0x53, 0xEF, 0x68, + 0xF1, 0x85, 0x56, 0x6D, 0xC5, 0xF7, 0xD5, 0xEF, 0x68, 0xC7, 0xB9, 0x65, 0xEC, 0x6F, 0xE5, 0x01, + 0x15, 0x97, 0xD7, 0x59, 0xC3, 0x2D, 0x95, 0xBF, 0xD2, 0x6E, 0x5B, 0xE5, 0x0F, 0xDB, 0xAC, 0x63, + 0x77, 0x7C, 0x53, 0xEB, 0xBB, 0x74, 0xED, 0xAB, 0xFC, 0x50, 0x79, 0x5A, 0xA5, 0x03, 0xF2, 0x98, + 0xE4, 0x1F, 0xAD, 0xF9, 0x54, 0x1D, 0x32, 0xF9, 0x42, 0xA5, 0xD9, 0xFF, 0x07, 0x11, 0xC4, 0xE0, + 0xBF, 0x7E, 0xEE, 0x00, 0x00 + }; diff --git a/board/samsung/xyref4415/logo_588x95.h b/board/samsung/xyref4415/logo_588x95.h new file mode 100644 index 000000000..0af04a52d --- /dev/null +++ b/board/samsung/xyref4415/logo_588x95.h @@ -0,0 +1,1913 @@ +/* + * Image information, + * format: Compressed BMP(gzip), + * size: 588 x 95, + */ +unsigned char gzip_bmp_logo[] = { + 0x1F, 0x8B, 0x08, 0x08, 0xBB, 0x04, 0x24, 0x51, 0x00, 0x03, 0x6C, 0x6F, 0x67, 0x6F, 0x5F, 0x35, + 0x38, 0x38, 0x5F, 0x39, 0x35, 0x2E, 0x62, 0x6D, 0x70, 0x00, 0xED, 0x9D, 0x09, 0xBC, 0x75, 0xD7, + 0x78, 0xFF, 0xA9, 0x56, 0xAB, 0xAD, 0xA8, 0x21, 0x29, 0xAD, 0xFE, 0x5B, 0x55, 0x29, 0x21, 0x69, + 0x69, 0xE9, 0x80, 0x9A, 0x83, 0x2A, 0x1D, 0x48, 0x08, 0x21, 0xA9, 0x18, 0x12, 0x44, 0x05, 0x11, + 0x45, 0x47, 0x53, 0x8C, 0x89, 0x20, 0x4D, 0xC8, 0x40, 0x50, 0xC4, 0xD4, 0x89, 0x06, 0xE9, 0x40, + 0xB5, 0x4A, 0xA9, 0x29, 0x66, 0x7D, 0xDF, 0x96, 0x4E, 0x5A, 0x4A, 0xAB, 0xDA, 0x92, 0xE1, 0xFC, + 0xF3, 0xDD, 0xC9, 0xEF, 0xE6, 0x77, 0x9F, 0xF7, 0x59, 0x6B, 0xAF, 0xB5, 0xF7, 0x3E, 0x37, 0x37, + 0xED, 0x5D, 0x9F, 0xCF, 0xBA, 0x67, 0x9F, 0x73, 0xCF, 0xD9, 0x7B, 0xAD, 0x67, 0xAD, 0xF5, 0xAC, + 0xDF, 0x33, 0xAE, 0x3B, 0xDE, 0xF3, 0xAA, 0x47, 0x5D, 0xE5, 0x4A, 0x94, 0x5B, 0x5D, 0x5C, 0x6F, + 0x7C, 0x71, 0xFD, 0x99, 0x6F, 0xB8, 0xD2, 0x95, 0x0E, 0xBB, 0xF8, 0xF5, 0xCA, 0x57, 0xFA, 0xBE, + 0xE1, 0xF3, 0x0F, 0x1E, 0x79, 0x95, 0x2B, 0xBD, 0x6B, 0xAF, 0x2B, 0x0D, 0xD5, 0xCA, 0x6A, 0xAC, + 0x5E, 0xF9, 0xCA, 0x57, 0xDE, 0xA8, 0xA5, 0xFF, 0xF3, 0xFA, 0x0D, 0xDF, 0xF0, 0x0D, 0xAB, 0xAB, + 0x5C, 0xE5, 0x2A, 0xE9, 0x77, 0xBE, 0xF9, 0x9B, 0xBF, 0x79, 0xF5, 0x5D, 0xDF, 0xF5, 0x5D, 0xAB, + 0xEF, 0xFE, 0xEE, 0xEF, 0x1E, 0xEA, 0xF7, 0x7C, 0xCF, 0xF7, 0x0C, 0xAF, 0xFF, 0xEF, 0xFF, 0xFD, + 0xBF, 0xE1, 0x9A, 0xFF, 0xEB, 0xBB, 0xDC, 0x23, 0x3E, 0xAB, 0x74, 0x5F, 0x3D, 0xB7, 0xA5, 0x1F, + 0xAD, 0xD5, 0xFB, 0x5B, 0xEA, 0xF3, 0x76, 0xAB, 0xD0, 0x60, 0x9D, 0x6D, 0xED, 0xA5, 0x49, 0xFC, + 0xFE, 0x56, 0xB4, 0x2D, 0xBE, 0x5F, 0x37, 0x4D, 0x5A, 0xFA, 0xDE, 0x4A, 0x93, 0x75, 0xB4, 0xD3, + 0x9F, 0x23, 0x5A, 0x6C, 0x87, 0xF9, 0x9C, 0xF5, 0xFF, 0x1B, 0xBF, 0xF1, 0x1B, 0x37, 0xFD, 0xBF, + 0xB4, 0xA6, 0x4B, 0xE3, 0xAA, 0xEF, 0xF3, 0xB9, 0x78, 0x85, 0x5F, 0x4F, 0x1D, 0xB3, 0xCB, 0x83, + 0x36, 0x59, 0xBB, 0x6A, 0xF3, 0x24, 0xA3, 0x89, 0xFA, 0xEE, 0x74, 0x9C, 0xDA, 0xBF, 0xB1, 0xB9, + 0xBC, 0xD5, 0x73, 0xA6, 0xE7, 0xB9, 0xBD, 0x6D, 0x2C, 0xF1, 0x92, 0x25, 0x68, 0xD8, 0xF2, 0xD9, + 0x56, 0xCC, 0xA9, 0x39, 0xF4, 0x99, 0x33, 0x77, 0x4A, 0x7C, 0xAF, 0x65, 0x7E, 0xD7, 0xE6, 0xDC, + 0x9C, 0xF1, 0x9D, 0x4B, 0xBF, 0x29, 0xF7, 0xE7, 0xFF, 0x7B, 0xED, 0xB5, 0xD7, 0xEA, 0xFA, 0xD7, + 0xBF, 0xFE, 0x6A, 0xFF, 0xFD, 0xF7, 0x5F, 0xFD, 0xE4, 0x4F, 0xFE, 0xE4, 0xEA, 0xCE, 0x77, 0xBE, + 0xF3, 0xEA, 0x67, 0x7E, 0xE6, 0x67, 0x56, 0x3F, 0xFF, 0xF3, 0x3F, 0xBF, 0xBA, 0xF7, 0xBD, 0xEF, + 0xBD, 0x7A, 0xC8, 0x43, 0x1E, 0xB2, 0xFA, 0xB5, 0x5F, 0xFB, 0xB5, 0xD5, 0x53, 0x9F, 0xFA, 0xD4, + 0xD5, 0x6F, 0xFC, 0xC6, 0x6F, 0xAC, 0x7E, 0xFD, 0xD7, 0x7F, 0x7D, 0x78, 0xFF, 0xB4, 0xA7, 0x3D, + 0x6D, 0x78, 0xFF, 0xE0, 0x07, 0x3F, 0x78, 0xF8, 0xDE, 0xBD, 0xEE, 0x75, 0xAF, 0xD5, 0x3D, 0xEF, + 0x79, 0xCF, 0xD5, 0x1D, 0xEE, 0x70, 0x87, 0xD5, 0xAD, 0x6E, 0x75, 0xAB, 0xE1, 0x7E, 0xDF, 0xFF, + 0xFD, 0xDF, 0xBF, 0xFA, 0x8E, 0xEF, 0xF8, 0x8E, 0x4D, 0x98, 0x0A, 0x3E, 0x50, 0xDB, 0x03, 0x7C, + 0x9F, 0x98, 0x82, 0xA7, 0xB6, 0x0B, 0x66, 0x9A, 0xF3, 0xFC, 0xB1, 0xFE, 0x4F, 0xE5, 0x3D, 0x4E, + 0xF7, 0xD2, 0xDE, 0xB6, 0x2E, 0xDA, 0xC5, 0x7B, 0x0A, 0xA3, 0xC7, 0x35, 0xE7, 0xF3, 0x63, 0xCE, + 0x78, 0x4E, 0x5D, 0x5F, 0xF1, 0xF9, 0xA5, 0x79, 0xB5, 0xAE, 0xF9, 0x35, 0x36, 0x3E, 0xDE, 0xCE, + 0x56, 0x4C, 0xB1, 0x15, 0xF5, 0x9B, 0xBE, 0xE9, 0x9B, 0x56, 0xD7, 0xBA, 0xD6, 0xB5, 0x56, 0xDF, + 0xF7, 0x7D, 0xDF, 0xB7, 0xBA, 0xE9, 0x4D, 0x6F, 0xBA, 0xFA, 0xD1, 0x1F, 0xFD, 0xD1, 0xD5, 0x4F, + 0xFC, 0xC4, 0x4F, 0xAC, 0x6E, 0x79, 0xCB, 0x5B, 0xAE, 0x6E, 0x7D, 0xEB, 0x5B, 0xAF, 0xEE, 0x72, + 0x97, 0xBB, 0x0C, 0x7C, 0xE5, 0x67, 0x7F, 0xF6, 0x67, 0x87, 0xFA, 0x73, 0x3F, 0xF7, 0x73, 0x03, + 0x8F, 0x39, 0xF0, 0xC0, 0x03, 0x57, 0xB7, 0xB9, 0xCD, 0x6D, 0x86, 0xEF, 0xFE, 0xD8, 0x8F, 0xFD, + 0xD8, 0xEA, 0x87, 0x7F, 0xF8, 0x87, 0x57, 0xFB, 0xED, 0xB7, 0xDF, 0xEA, 0x06, 0x37, 0xB8, 0xC1, + 0xEA, 0xDA, 0xD7, 0xBE, 0xF6, 0x2C, 0x3A, 0x2E, 0x2D, 0x8F, 0x4D, 0x19, 0xC7, 0xB1, 0xEF, 0x44, + 0x1A, 0x5E, 0xF3, 0x9A, 0xD7, 0x1C, 0xE4, 0xD0, 0x1B, 0xDE, 0xF0, 0x86, 0xAB, 0x1F, 0xF8, 0x81, + 0x1F, 0x58, 0xFD, 0xE0, 0x0F, 0xFE, 0xE0, 0xEA, 0xE6, 0x37, 0xBF, 0xF9, 0x40, 0x1F, 0xEA, 0x8F, + 0xFF, 0xF8, 0x8F, 0x6F, 0xD0, 0xEA, 0x47, 0x7E, 0xE4, 0x47, 0x86, 0xEF, 0xF0, 0x5D, 0xE8, 0x05, + 0x1F, 0xE7, 0xF7, 0xF0, 0x5B, 0x5F, 0x3F, 0xB5, 0x79, 0x7C, 0x79, 0xCF, 0x9B, 0x52, 0xBB, 0x7A, + 0xC7, 0xAF, 0x15, 0x2F, 0x4D, 0xBD, 0xFF, 0xE5, 0x3D, 0x7F, 0xB6, 0xBA, 0xFD, 0x63, 0x78, 0x68, + 0xEC, 0xF9, 0xFE, 0xFF, 0xB9, 0x78, 0x89, 0xEF, 0x45, 0x19, 0x22, 0xFE, 0xBE, 0x95, 0x3E, 0xD9, + 0x3E, 0xC4, 0xAB, 0xCB, 0x6A, 0x54, 0x97, 0x03, 0xF9, 0xCE, 0x55, 0xAF, 0x7A, 0xD5, 0x61, 0x8D, + 0xFD, 0xC2, 0x2F, 0xFC, 0xC2, 0xEA, 0x57, 0x7E, 0xE5, 0x57, 0x56, 0x67, 0x9D, 0x75, 0xD6, 0xEA, + 0x4F, 0xFE, 0xE4, 0x4F, 0x56, 0x9F, 0xFD, 0xEC, 0x67, 0x57, 0xFF, 0xF3, 0x3F, 0xFF, 0xB3, 0xBA, + 0xE0, 0x82, 0x0B, 0x56, 0x63, 0xE5, 0xA2, 0x8B, 0x2E, 0xDA, 0xA8, 0x17, 0x5E, 0x78, 0xE1, 0xEA, + 0xBF, 0xFE, 0xEB, 0xBF, 0x86, 0xDF, 0xFF, 0xE9, 0x9F, 0xFE, 0xE9, 0xEA, 0x25, 0x2F, 0x79, 0xC9, + 0x80, 0xAD, 0x0E, 0x3F, 0xFC, 0xF0, 0x81, 0x77, 0x82, 0x9B, 0xC6, 0xE8, 0xE7, 0xFD, 0x6B, 0xDD, + 0x0B, 0xFC, 0x7B, 0xBA, 0x5F, 0xFC, 0x6D, 0xFC, 0x4E, 0xEF, 0x3E, 0xA3, 0x76, 0x79, 0xFB, 0xE3, + 0x67, 0xDE, 0x2F, 0xFF, 0x5E, 0xCB, 0xBD, 0xB5, 0x3F, 0x7B, 0xBB, 0x22, 0xAD, 0x6A, 0x63, 0xDE, + 0x3A, 0xEF, 0xE3, 0xFC, 0x89, 0x74, 0x28, 0xCD, 0x39, 0xE7, 0xBD, 0x3D, 0x7D, 0x6B, 0x69, 0x7F, + 0x36, 0x77, 0xBD, 0x6D, 0x19, 0x76, 0x89, 0x73, 0xBB, 0xB7, 0x4D, 0xF1, 0x5E, 0xFA, 0xBD, 0xAF, + 0x11, 0x1F, 0x9B, 0x88, 0xF1, 0xE3, 0x38, 0xCD, 0xA1, 0x4F, 0x8D, 0x66, 0xF1, 0xD9, 0xDE, 0xA6, + 0xA9, 0xF7, 0x2E, 0xF5, 0xDF, 0xDB, 0x2D, 0x3A, 0xE8, 0x99, 0xEC, 0xE3, 0x3E, 0x66, 0x3E, 0x36, + 0x5C, 0xB3, 0x47, 0x83, 0x91, 0x0E, 0x3E, 0xF8, 0xE0, 0x41, 0x86, 0x7A, 0xF1, 0x8B, 0x5F, 0xBC, + 0x7A, 0xCD, 0x6B, 0x5E, 0xB3, 0xFA, 0xF3, 0x3F, 0xFF, 0xF3, 0x81, 0xA7, 0xBC, 0xF7, 0xBD, 0xEF, + 0x5D, 0xFD, 0xED, 0xDF, 0xFE, 0xED, 0xEA, 0xBF, 0xFF, 0xFB, 0xBF, 0x37, 0x78, 0x07, 0xFC, 0x82, + 0xF2, 0xA5, 0x2F, 0x7D, 0x69, 0xF5, 0xFE, 0xF7, 0xBF, 0x7F, 0xF5, 0x47, 0x7F, 0xF4, 0x47, 0xC3, + 0x77, 0xDF, 0xF0, 0x86, 0x37, 0xAC, 0x4E, 0x3E, 0xF9, 0xE4, 0x81, 0x27, 0xDD, 0xF7, 0xBE, 0xF7, + 0x1D, 0xE4, 0x2E, 0x78, 0x47, 0x36, 0x1F, 0x4A, 0xE3, 0x96, 0xCD, 0xF5, 0xDA, 0xFA, 0xAB, 0xED, + 0xB3, 0x2D, 0xF4, 0xF3, 0xB6, 0xC5, 0x71, 0x8C, 0xB4, 0x8A, 0xF3, 0x8A, 0xF7, 0xDF, 0xFA, 0xAD, + 0xDF, 0x3A, 0xF0, 0x62, 0xB0, 0xE2, 0x41, 0x07, 0x1D, 0x34, 0xD0, 0xF0, 0xE9, 0x4F, 0x7F, 0xFA, + 0x20, 0x97, 0x9E, 0x74, 0xD2, 0x49, 0xAB, 0xDF, 0xF9, 0x9D, 0xDF, 0x59, 0xBD, 0xEB, 0x5D, 0xEF, + 0x1A, 0xF8, 0x2A, 0x74, 0xFA, 0xB3, 0x3F, 0xFB, 0xB3, 0xD5, 0xB9, 0xE7, 0x9E, 0xBB, 0x7A, 0xFD, + 0xEB, 0x5F, 0xBF, 0x7A, 0xC1, 0x0B, 0x5E, 0xB0, 0xFA, 0xCD, 0xDF, 0xFC, 0xCD, 0xE1, 0x37, 0x8F, + 0x7B, 0xDC, 0xE3, 0x06, 0x1C, 0x0A, 0x96, 0x02, 0xB7, 0xC6, 0xB6, 0xC4, 0x76, 0x65, 0xBC, 0xD0, + 0xFB, 0x00, 0x5D, 0x4B, 0x7B, 0xD2, 0x52, 0xF3, 0x2F, 0xD2, 0xA2, 0xF7, 0xDE, 0x19, 0x4F, 0x6E, + 0xE1, 0xEF, 0x91, 0x2F, 0x66, 0xB2, 0x9B, 0xAF, 0x8F, 0xF8, 0x0C, 0x7F, 0x3F, 0xA6, 0x03, 0x18, + 0xAB, 0x71, 0xFE, 0xC6, 0xE7, 0x64, 0xFB, 0x42, 0xEB, 0xFC, 0x1E, 0x6B, 0x53, 0xEC, 0x5F, 0xE9, + 0x39, 0x4E, 0x1F, 0x9F, 0x17, 0x99, 0x4D, 0xA9, 0xF4, 0xCC, 0x6C, 0xFE, 0x44, 0xBE, 0x96, 0xF1, + 0x99, 0xF8, 0xDB, 0xB8, 0x37, 0xF1, 0xEA, 0x34, 0xD4, 0x75, 0x6D, 0x4C, 0xF8, 0x1F, 0x7C, 0xCD, + 0xE9, 0x10, 0xF7, 0x24, 0xE4, 0x0F, 0x74, 0x40, 0xAC, 0xAB, 0x57, 0xBC, 0xE2, 0x15, 0x03, 0x7F, + 0xFA, 0xAB, 0xBF, 0xFA, 0xAB, 0xD5, 0x67, 0x3E, 0xF3, 0x99, 0xD5, 0xE7, 0x3F, 0xFF, 0xF9, 0xD5, + 0x7F, 0xFE, 0xE7, 0x7F, 0xEE, 0xC1, 0xCF, 0x7A, 0x0B, 0x38, 0xEB, 0x2B, 0x5F, 0xF9, 0xCA, 0xEA, + 0x9F, 0xFE, 0xE9, 0x9F, 0x56, 0xBB, 0x76, 0xED, 0x5A, 0x9D, 0x77, 0xDE, 0x79, 0xAB, 0x77, 0xBF, + 0xFB, 0xDD, 0xAB, 0xD7, 0xBD, 0xEE, 0x75, 0xAB, 0xE7, 0x3C, 0xE7, 0x39, 0xAB, 0xC3, 0x0E, 0x3B, + 0x6C, 0x90, 0x89, 0x6A, 0xED, 0xEC, 0x95, 0x2B, 0xE2, 0x1E, 0x52, 0x9A, 0xDF, 0xD9, 0xFA, 0x1F, + 0xBB, 0x7F, 0x9C, 0x0F, 0x25, 0x8C, 0xD1, 0xBB, 0x46, 0x6A, 0xEB, 0xC3, 0xC7, 0xBB, 0xB5, 0x9D, + 0x63, 0xEB, 0xC5, 0xF7, 0x85, 0x6C, 0x7F, 0xA9, 0xF5, 0x3F, 0xD2, 0xB5, 0x77, 0x8C, 0xC6, 0xDA, + 0x56, 0x5A, 0x4B, 0xB1, 0xEF, 0xD9, 0xFC, 0x28, 0x61, 0xAF, 0x6C, 0xAC, 0x4A, 0x6D, 0xF0, 0xF7, + 0xD0, 0x26, 0xC3, 0xE0, 0xD9, 0x6F, 0x4A, 0x18, 0x77, 0x29, 0xFA, 0xD4, 0x68, 0xE0, 0x6B, 0x7D, + 0xA9, 0xEA, 0x7B, 0xBA, 0xFA, 0x16, 0xED, 0x6D, 0xBC, 0xEE, 0xBD, 0xF7, 0xDE, 0xAB, 0xDB, 0xDF, + 0xFE, 0xF6, 0xAB, 0x63, 0x8F, 0x3D, 0x76, 0x75, 0xC6, 0x19, 0x67, 0xAC, 0xFE, 0xE0, 0x0F, 0xFE, + 0x60, 0xD8, 0xC3, 0xFF, 0xFA, 0xAF, 0xFF, 0x7A, 0x58, 0xF3, 0xFF, 0xFC, 0xCF, 0xFF, 0xBC, 0xFA, + 0xE2, 0x17, 0xBF, 0xB8, 0xFA, 0xEA, 0x57, 0xBF, 0x3A, 0xC8, 0x50, 0x51, 0xFE, 0x92, 0x7C, 0xC5, + 0x2B, 0x05, 0x1C, 0x05, 0xCF, 0xE0, 0x15, 0xFC, 0xF4, 0x8F, 0xFF, 0xF8, 0x8F, 0xAB, 0xBF, 0xFB, + 0xBB, 0xBF, 0x5B, 0x7D, 0xF8, 0xC3, 0x1F, 0x5E, 0xBD, 0xF3, 0x9D, 0xEF, 0x1C, 0xEE, 0xFF, 0xB2, + 0x97, 0xBD, 0x6C, 0x78, 0xDE, 0x1D, 0xEF, 0x78, 0xC7, 0x0D, 0xBD, 0x53, 0x86, 0x4F, 0x9D, 0x77, + 0x66, 0xF3, 0x64, 0xE9, 0xFD, 0x5E, 0x73, 0xC6, 0x69, 0x18, 0xDB, 0x15, 0xE7, 0x09, 0x7A, 0xF7, + 0xBB, 0xDF, 0xFD, 0xEE, 0xAB, 0xC7, 0x3E, 0xF6, 0xB1, 0xAB, 0x33, 0xCF, 0x3C, 0x73, 0xC0, 0x3D, + 0x7F, 0xFC, 0xC7, 0x7F, 0x3C, 0xD0, 0xF0, 0x03, 0x1F, 0xF8, 0xC0, 0x80, 0x2D, 0xA9, 0xBB, 0x77, + 0xEF, 0x5E, 0xFD, 0xFD, 0xDF, 0xFF, 0xFD, 0xEA, 0xCB, 0x5F, 0xFE, 0xF2, 0x40, 0x43, 0xE8, 0x09, + 0x9D, 0xA0, 0x29, 0xD7, 0x7C, 0xFE, 0x0F, 0xFF, 0xF0, 0x0F, 0xC3, 0xF7, 0xF8, 0xFE, 0xA7, 0x3F, + 0xFD, 0xE9, 0x01, 0x7B, 0x82, 0x53, 0xC1, 0x55, 0x6F, 0x7C, 0xE3, 0x1B, 0x57, 0x2F, 0x7A, 0xD1, + 0x8B, 0x56, 0x8F, 0x79, 0xCC, 0x63, 0x56, 0xB7, 0xBB, 0xDD, 0xED, 0x56, 0xDF, 0xF9, 0x9D, 0xDF, + 0x99, 0xCE, 0xCB, 0x28, 0xBB, 0x67, 0xB2, 0x7C, 0xB6, 0xDE, 0xD6, 0x59, 0x33, 0xBE, 0x50, 0xAB, + 0xA5, 0xF9, 0xDC, 0xBB, 0xBE, 0x6A, 0x7D, 0xAF, 0xFD, 0xAE, 0xD4, 0xD6, 0x9E, 0x7B, 0xF8, 0x3C, + 0x2A, 0xB5, 0xA3, 0x57, 0xD6, 0xEF, 0xC5, 0xFE, 0x19, 0x4E, 0x8A, 0xF3, 0x5B, 0xD7, 0xC8, 0x49, + 0xE8, 0x82, 0xE1, 0x05, 0xBF, 0xF8, 0x8B, 0xBF, 0xB8, 0xFA, 0xD5, 0x5F, 0xFD, 0xD5, 0xD5, 0x0B, + 0x5F, 0xF8, 0xC2, 0xD5, 0xCB, 0x5F, 0xFE, 0xF2, 0x41, 0xEE, 0x79, 0xF3, 0x9B, 0xDF, 0xBC, 0x7A, + 0xD3, 0x9B, 0xDE, 0xB4, 0x51, 0xC1, 0xFD, 0xBF, 0xFB, 0xBB, 0xBF, 0xBB, 0xA9, 0xFE, 0xDE, 0xEF, + 0xFD, 0xDE, 0xA0, 0xAB, 0xE1, 0xB7, 0xAC, 0xEF, 0x47, 0x3C, 0xE2, 0x11, 0x83, 0x1E, 0xFA, 0x87, + 0x7E, 0xE8, 0x87, 0x56, 0x57, 0xBB, 0xDA, 0xD5, 0x86, 0x67, 0xB7, 0xDA, 0xFC, 0xE3, 0x7A, 0x2F, + 0xF5, 0x3F, 0xEE, 0xB5, 0xBE, 0x56, 0x79, 0x26, 0xF6, 0xB1, 0x7B, 0xDC, 0xE3, 0x1E, 0xAB, 0x27, + 0x3E, 0xF1, 0x89, 0x43, 0x3F, 0x3E, 0xFA, 0xD1, 0x8F, 0x6E, 0xF0, 0xAA, 0xAC, 0xC0, 0xCB, 0xCE, + 0x3F, 0xFF, 0xFC, 0x0D, 0xDE, 0x96, 0xE9, 0x93, 0xE2, 0xEF, 0x4B, 0xF7, 0xD3, 0x7D, 0x28, 0xFF, + 0xF6, 0x6F, 0xFF, 0x36, 0xF0, 0x85, 0xE3, 0x8F, 0x3F, 0x7E, 0x75, 0xFF, 0xFB, 0xDF, 0x7F, 0xD0, + 0x33, 0x5F, 0xE3, 0x1A, 0xD7, 0xD8, 0x83, 0x16, 0x19, 0xBF, 0x6B, 0x19, 0xE7, 0x28, 0x13, 0x7C, + 0xFB, 0xB7, 0x7F, 0xFB, 0xA0, 0xCF, 0xC6, 0x5E, 0x88, 0x0D, 0x40, 0xF6, 0x00, 0x64, 0x30, 0x70, + 0x23, 0xD7, 0xD8, 0x11, 0x6B, 0x15, 0xBA, 0x61, 0x37, 0xE0, 0x37, 0x3F, 0xFD, 0xD3, 0x3F, 0x3D, + 0xBC, 0xF2, 0x3B, 0xF4, 0x72, 0x92, 0xE1, 0x4A, 0xF6, 0x9B, 0xD6, 0xF9, 0x1C, 0xBF, 0xBB, 0xCF, + 0x3E, 0xFB, 0x0C, 0x76, 0x4D, 0xDA, 0x48, 0x1B, 0xD4, 0x66, 0xD9, 0x32, 0xF4, 0x9E, 0x3A, 0xD6, + 0x7E, 0xBE, 0x43, 0xBF, 0xF5, 0x1E, 0x9B, 0x2B, 0xB8, 0x99, 0xE7, 0xA0, 0x63, 0x1C, 0x5B, 0xDB, + 0xCE, 0xEF, 0xA9, 0xDF, 0xF2, 0x2D, 0xDF, 0xB2, 0xDA, 0x77, 0xDF, 0x7D, 0x57, 0x77, 0xBB, 0xDB, + 0xDD, 0x36, 0xEE, 0x5F, 0xAB, 0xDE, 0x56, 0xAE, 0xE9, 0x93, 0xFA, 0xA5, 0xCF, 0xA0, 0x31, 0x36, + 0x19, 0x6C, 0xC3, 0xDE, 0x9E, 0x88, 0x6F, 0x33, 0x3D, 0x1F, 0xBA, 0x07, 0x6C, 0x3E, 0x8C, 0x8D, + 0xEE, 0xCF, 0x78, 0xB5, 0x8E, 0xAF, 0x7E, 0xA3, 0x57, 0xD1, 0x8B, 0xD7, 0xEB, 0x5D, 0xEF, 0x7A, + 0xD5, 0x75, 0x27, 0x2C, 0x3D, 0x87, 0x3E, 0x91, 0x56, 0xB1, 0xD2, 0x17, 0xF6, 0x56, 0x74, 0x2D, + 0xF8, 0x11, 0x3A, 0x2D, 0x96, 0xB4, 0xC7, 0x65, 0x7A, 0x16, 0x5F, 0x7F, 0xDF, 0xF6, 0x6D, 0xDF, + 0x36, 0xF0, 0x46, 0x74, 0x48, 0xC7, 0x1D, 0x77, 0xDC, 0x20, 0x6F, 0xB1, 0x3F, 0xB3, 0x8F, 0x67, + 0x45, 0x98, 0x28, 0xFB, 0x3C, 0xF2, 0x94, 0xEC, 0x73, 0xF1, 0x21, 0xC7, 0x59, 0x9F, 0xFA, 0xD4, + 0xA7, 0x06, 0x5E, 0x0C, 0x1F, 0xBB, 0xDF, 0xFD, 0xEE, 0x37, 0xB4, 0x07, 0xFE, 0x26, 0xBE, 0xB7, + 0x55, 0x7B, 0x79, 0xB6, 0xCE, 0x33, 0x5C, 0x04, 0xA6, 0x15, 0x0D, 0xAF, 0x7B, 0xDD, 0xEB, 0x0E, + 0x76, 0xC9, 0xFB, 0xDC, 0xE7, 0x3E, 0x83, 0xDE, 0x5D, 0x7C, 0x18, 0x8C, 0x98, 0xE9, 0xF2, 0x33, + 0x7A, 0x94, 0xE8, 0x5C, 0xFB, 0x0D, 0x32, 0x30, 0x38, 0x16, 0xBC, 0xF9, 0xA4, 0x27, 0x3D, 0x69, + 0xD0, 0x5F, 0xC1, 0x77, 0xAF, 0x73, 0x9D, 0xEB, 0xEC, 0xC1, 0x5F, 0x2F, 0x0F, 0xFB, 0x14, 0xE3, + 0x87, 0x3F, 0x2C, 0x18, 0x92, 0x0A, 0x4F, 0xFD, 0xDE, 0xEF, 0xFD, 0xDE, 0x41, 0xDF, 0xC6, 0xF5, + 0x58, 0xC5, 0x76, 0xC9, 0x2B, 0xFE, 0xB4, 0xFC, 0xE6, 0xC6, 0x37, 0xBE, 0xF1, 0x80, 0x0B, 0xB9, + 0xAF, 0xAF, 0xCF, 0xDA, 0xBC, 0x88, 0x78, 0x29, 0xAE, 0x03, 0xF8, 0x12, 0xCF, 0xA1, 0x7D, 0xB2, + 0x93, 0xF2, 0x2C, 0xDA, 0xA9, 0x76, 0xF0, 0x3E, 0x6B, 0xB3, 0x3E, 0xAF, 0x55, 0xDA, 0xCE, 0xBD, + 0x6E, 0x74, 0xA3, 0x1B, 0x6D, 0xF4, 0x9F, 0xE7, 0x20, 0x97, 0xA0, 0x7B, 0xCC, 0x78, 0x5F, 0xCF, + 0x1E, 0x33, 0x56, 0x4B, 0x7E, 0xC7, 0x91, 0x0E, 0xF0, 0x5A, 0xE8, 0xFB, 0x53, 0x3F, 0xF5, 0x53, + 0xC3, 0xFE, 0x0D, 0xDE, 0x7F, 0xF6, 0xB3, 0x9F, 0x3D, 0xAC, 0x49, 0xB0, 0x3E, 0xB6, 0x25, 0xB0, + 0x7C, 0x49, 0xD7, 0x12, 0xD7, 0xBA, 0x2A, 0x18, 0x01, 0xBC, 0xFF, 0x37, 0x7F, 0xF3, 0x37, 0x83, + 0x8C, 0x04, 0xAE, 0x02, 0xE7, 0x83, 0x9D, 0xE0, 0xC9, 0xE8, 0x4B, 0xD9, 0xC7, 0x99, 0x27, 0x59, + 0xFB, 0xA2, 0x9C, 0x57, 0xE3, 0xD9, 0xFA, 0x3C, 0xEA, 0x96, 0x74, 0x9F, 0x3B, 0xDD, 0xE9, 0x4E, + 0x43, 0x7F, 0xFE, 0xF5, 0x5F, 0xFF, 0x75, 0x8F, 0x76, 0xB3, 0x4E, 0xE9, 0x9B, 0x64, 0xBD, 0x12, + 0x0E, 0x72, 0x9B, 0x5B, 0xF6, 0xFD, 0xB8, 0x66, 0xC5, 0xE7, 0xC4, 0x07, 0xBE, 0xF6, 0xB5, 0xAF, + 0xED, 0x81, 0xBF, 0xBE, 0xF0, 0x85, 0x2F, 0x0C, 0x3A, 0x27, 0xB0, 0x0C, 0xF3, 0x22, 0xF6, 0xA9, + 0x55, 0x7E, 0xCE, 0x6C, 0x15, 0xE2, 0xF5, 0xF0, 0x04, 0xF4, 0xD4, 0x8E, 0xD9, 0x32, 0x3E, 0x33, + 0x56, 0x7C, 0xFC, 0xE9, 0x93, 0x7E, 0xFB, 0xF0, 0x87, 0x3F, 0x3C, 0xE5, 0x9B, 0xBD, 0xBC, 0x27, + 0xEA, 0xA4, 0x91, 0xA1, 0x99, 0x3F, 0x94, 0xAF, 0x7F, 0xFD, 0xEB, 0xA3, 0xF3, 0x6F, 0xAC, 0xED, + 0x1A, 0x2F, 0xDA, 0x7E, 0xCE, 0x39, 0xE7, 0x0C, 0xD8, 0x22, 0x3E, 0x3B, 0xD3, 0x93, 0x66, 0xF3, + 0x8E, 0xF5, 0x8C, 0x9D, 0x40, 0xED, 0x8B, 0xF3, 0xA0, 0xC6, 0xE7, 0xD5, 0x06, 0xCD, 0x3B, 0x7D, + 0x8F, 0xF9, 0x01, 0x8E, 0x06, 0xCB, 0x45, 0xEC, 0x9B, 0xCD, 0x79, 0xB7, 0x17, 0x61, 0xC3, 0x40, + 0x76, 0xF9, 0xF7, 0x7F, 0xFF, 0xF7, 0xE6, 0xF1, 0xCC, 0x68, 0xA4, 0xE2, 0x7B, 0x17, 0x38, 0x4E, + 0x63, 0xA2, 0xF9, 0x98, 0xE9, 0x1A, 0x97, 0xA4, 0x4F, 0xED, 0xFB, 0xF0, 0x0E, 0x7F, 0xEE, 0x52, + 0xD5, 0xF1, 0x67, 0xB4, 0x2D, 0x69, 0xBF, 0x60, 0x4E, 0xA2, 0x0B, 0x41, 0x0F, 0x5D, 0x1A, 0x57, + 0xE7, 0x13, 0x6A, 0x33, 0x6B, 0xCF, 0xD7, 0x4C, 0xA4, 0xBB, 0x3E, 0x8F, 0xD8, 0x48, 0xF7, 0x8D, + 0xDF, 0xD7, 0x58, 0xA1, 0x83, 0xA2, 0x3D, 0x77, 0xBD, 0xEB, 0x5D, 0x37, 0xF9, 0x47, 0xAA, 0x82, + 0x5B, 0xB7, 0x62, 0xFF, 0xCF, 0xF0, 0x3C, 0x73, 0xC5, 0xE7, 0x0B, 0xF8, 0xF9, 0x98, 0x63, 0x8E, + 0x19, 0xF6, 0x14, 0xF8, 0x5E, 0x86, 0x8F, 0xA2, 0xFE, 0xAD, 0x44, 0x83, 0x12, 0xFD, 0xFC, 0x7D, + 0x09, 0x93, 0x52, 0x78, 0x3E, 0x72, 0x3D, 0xFA, 0x00, 0xF6, 0xE7, 0xC8, 0xAF, 0x4A, 0x7B, 0xCF, + 0xBA, 0x2A, 0xB2, 0x1B, 0x3E, 0x1B, 0xE8, 0x17, 0xE4, 0x1F, 0x4B, 0xE5, 0x1A, 0x3B, 0xA3, 0xDE, + 0x97, 0x2A, 0x6B, 0x8D, 0x57, 0xEC, 0xB7, 0xBC, 0x3E, 0xF3, 0x99, 0xCF, 0x1C, 0x7C, 0x6E, 0xC1, + 0x36, 0xCE, 0xD7, 0x4A, 0x7A, 0x9F, 0x9A, 0x5E, 0x5B, 0x9F, 0xA1, 0x9B, 0x63, 0xFC, 0x78, 0x16, + 0x6D, 0xC2, 0x77, 0x97, 0xF6, 0xF2, 0x3C, 0xDE, 0xCB, 0x1E, 0xAA, 0x1A, 0xDB, 0xD6, 0xD2, 0x07, + 0xDD, 0x5B, 0xBE, 0xC2, 0xD4, 0x43, 0x0E, 0x39, 0x64, 0xC0, 0x09, 0xA5, 0x35, 0xBF, 0xC4, 0xFC, + 0x8E, 0xF7, 0x70, 0x7D, 0x8B, 0x3F, 0x17, 0x1E, 0x80, 0xDC, 0x86, 0xAD, 0x1C, 0x1D, 0x28, 0x7A, + 0xCE, 0xB8, 0xFE, 0x7D, 0x9D, 0x8F, 0xC9, 0x4B, 0x25, 0x3E, 0x18, 0xE7, 0x34, 0xF7, 0x7C, 0xDF, + 0xFB, 0xDE, 0x37, 0x3C, 0xF7, 0x41, 0x0F, 0x7A, 0xD0, 0x20, 0x77, 0xF8, 0xBA, 0x43, 0xE6, 0xF7, + 0xBE, 0x64, 0x7A, 0xF1, 0x52, 0x75, 0x5E, 0x87, 0xCC, 0x8D, 0xFD, 0xEB, 0x2F, 0xFE, 0xE2, 0x2F, + 0x06, 0xDB, 0x98, 0x0A, 0xFC, 0xCB, 0x79, 0x5A, 0xE4, 0x65, 0xFE, 0xDE, 0x71, 0x86, 0xFF, 0x66, + 0x8C, 0xEF, 0x7B, 0x11, 0x1F, 0xD0, 0xF7, 0xB5, 0x57, 0x52, 0xD0, 0x37, 0x21, 0xFB, 0xBC, 0xF4, + 0xA5, 0x2F, 0x5D, 0xDD, 0xF6, 0xB6, 0xB7, 0x2D, 0xEA, 0xFD, 0xC6, 0xFA, 0xEC, 0x7B, 0xAB, 0xFF, + 0x8E, 0x31, 0x46, 0xA6, 0x8A, 0xFD, 0x8E, 0x6D, 0xAB, 0x15, 0xF6, 0x72, 0xEF, 0xBF, 0xFF, 0x8E, + 0x7B, 0xF3, 0x8C, 0xC8, 0x37, 0x7B, 0xDA, 0xEF, 0x38, 0x49, 0xE3, 0xCD, 0x3E, 0xED, 0x74, 0x9F, + 0x53, 0xE2, 0xF8, 0x9E, 0x76, 0xDA, 0x69, 0x83, 0x4F, 0x88, 0x3F, 0xBB, 0x85, 0x87, 0xE8, 0x1A, + 0xB9, 0xE7, 0x59, 0xCF, 0x7A, 0xD6, 0xEA, 0x5F, 0xFE, 0xE5, 0x5F, 0x66, 0xB5, 0xCB, 0xDB, 0x47, + 0xC1, 0xC7, 0x05, 0x3D, 0xA8, 0xF6, 0x1B, 0xD7, 0x17, 0x44, 0xDD, 0x87, 0xF4, 0x62, 0xE2, 0x65, + 0xE8, 0x1D, 0xB2, 0xF9, 0xA8, 0xB1, 0x6B, 0x79, 0x7E, 0xC4, 0x6F, 0x14, 0xE4, 0x1B, 0xAD, 0x47, + 0xBD, 0x96, 0x70, 0xE4, 0xBA, 0xE9, 0x83, 0x5D, 0x86, 0xBE, 0x8A, 0x1E, 0xCE, 0x27, 0xE6, 0xD6, + 0x92, 0xCE, 0x1D, 0xCC, 0x81, 0x8E, 0xEC, 0xF4, 0xD3, 0x4F, 0x1F, 0x6C, 0xEA, 0xEC, 0xB5, 0x14, + 0xC9, 0x84, 0xBA, 0x8E, 0xED, 0x75, 0x9E, 0x99, 0x95, 0xC8, 0x4B, 0x4A, 0x58, 0xC1, 0xFB, 0x4F, + 0x71, 0x7E, 0xC4, 0x35, 0xD8, 0x0D, 0x7F, 0x02, 0xDA, 0xF7, 0xC0, 0x07, 0x3E, 0x70, 0xD0, 0x27, + 0x8B, 0xE7, 0x3B, 0x3F, 0x88, 0xF3, 0x7C, 0x49, 0x0C, 0x90, 0xF1, 0x67, 0xDD, 0x1F, 0x3C, 0x02, + 0x8F, 0xF8, 0xC3, 0x3F, 0xFC, 0xC3, 0x61, 0x8E, 0x62, 0x43, 0xF3, 0xFE, 0x53, 0xE2, 0x6B, 0xEC, + 0x73, 0xA4, 0x5B, 0x26, 0xCF, 0x46, 0xDC, 0x19, 0xF7, 0xAC, 0x28, 0xF3, 0xB2, 0xD7, 0x7D, 0xE4, + 0x23, 0x1F, 0x19, 0xEC, 0x75, 0x0F, 0x7B, 0xD8, 0xC3, 0x06, 0x79, 0xB5, 0x44, 0x97, 0x75, 0x63, + 0x26, 0xE4, 0x9D, 0xDF, 0xFE, 0xED, 0xDF, 0x1E, 0x7C, 0x42, 0xB0, 0x2B, 0x62, 0x87, 0xA5, 0xA2, + 0x6B, 0x90, 0x9D, 0xB1, 0x56, 0xF9, 0x0E, 0x36, 0x60, 0xBE, 0xCF, 0x2B, 0x9F, 0xFD, 0xFE, 0xEF, + 0xFF, 0xFE, 0xA0, 0xCB, 0x73, 0x99, 0x7B, 0xCC, 0x96, 0xE7, 0x7C, 0x98, 0xF1, 0x74, 0x0C, 0xFE, + 0x8C, 0x67, 0x3C, 0x63, 0xF5, 0x89, 0x4F, 0x7C, 0x62, 0x43, 0x07, 0xC2, 0x33, 0x19, 0x4F, 0xDA, + 0xC9, 0xB5, 0x6A, 0xD6, 0xB6, 0xB1, 0x4A, 0x9B, 0xFD, 0x1A, 0x3A, 0xA0, 0xA7, 0xE1, 0x3D, 0x7A, + 0x0E, 0xE2, 0xAF, 0xB2, 0x71, 0x58, 0x72, 0x4C, 0xB2, 0x3D, 0x48, 0xD7, 0x37, 0xBB, 0xD9, 0xCD, + 0x56, 0x8F, 0x7F, 0xFC, 0xE3, 0x57, 0x67, 0x9F, 0x7D, 0xF6, 0xB0, 0xD6, 0xE0, 0x6B, 0xE8, 0x94, + 0x35, 0x5F, 0xC7, 0xF6, 0xA7, 0x31, 0x79, 0x91, 0x6B, 0x74, 0x02, 0xB1, 0xF8, 0x1A, 0x40, 0x07, + 0xFB, 0xB9, 0xCF, 0x7D, 0x6E, 0xF5, 0xC1, 0x0F, 0x7E, 0x70, 0xD0, 0x3D, 0x81, 0x8D, 0xC1, 0x37, + 0x35, 0x7F, 0xB5, 0x92, 0x4C, 0x29, 0xBB, 0x85, 0xFA, 0x87, 0x1E, 0x12, 0x59, 0xF0, 0x94, 0x53, + 0x4E, 0x59, 0xFD, 0xC7, 0x7F, 0xFC, 0xC7, 0x28, 0xCF, 0x2A, 0xFD, 0xAF, 0xD4, 0xEF, 0x16, 0x5A, + 0xF8, 0xDA, 0x14, 0x8F, 0x8B, 0xB8, 0xD1, 0xAF, 0xD9, 0x9F, 0xD8, 0xC7, 0xB1, 0x61, 0x60, 0x8B, + 0xEA, 0xF5, 0xCD, 0xC8, 0x30, 0xB2, 0x3E, 0x47, 0x6F, 0xE8, 0x6D, 0x17, 0xAF, 0xEF, 0xC1, 0x21, + 0x8C, 0x67, 0xF6, 0xFD, 0xE7, 0x3F, 0xFF, 0xF9, 0x1B, 0xF8, 0x3F, 0x1B, 0x97, 0x9E, 0xF6, 0x6B, + 0x7D, 0xD2, 0x77, 0xE4, 0x8A, 0x88, 0x73, 0x32, 0xFD, 0x5E, 0xAB, 0x8F, 0x19, 0xF3, 0x5B, 0xF7, + 0xFA, 0xA5, 0x5F, 0xFA, 0xA5, 0x61, 0x5F, 0x69, 0xD1, 0x51, 0x67, 0x6B, 0x14, 0x5D, 0x31, 0x32, + 0x11, 0xFC, 0x00, 0x3A, 0x66, 0x18, 0x3A, 0xAE, 0x8B, 0xDA, 0x67, 0x14, 0xFA, 0x8A, 0xEC, 0xCD, + 0x1A, 0x70, 0xDA, 0xF9, 0x1A, 0xF6, 0x75, 0xEC, 0xF3, 0x83, 0x39, 0x83, 0x1F, 0x87, 0xE6, 0x98, + 0xCF, 0xB9, 0xD6, 0xE2, 0x7B, 0x96, 0xD3, 0x9C, 0x75, 0x49, 0xCC, 0xD7, 0xD8, 0xFA, 0x9B, 0x43, + 0x9F, 0x31, 0x7A, 0x51, 0xE0, 0x17, 0x6F, 0x79, 0xCB, 0x5B, 0x06, 0x3C, 0xB9, 0xA4, 0x6E, 0x29, + 0x8E, 0xBF, 0xEF, 0xF9, 0xCC, 0x6B, 0xE4, 0x39, 0x7C, 0x87, 0xB2, 0xBD, 0xB8, 0x54, 0xA2, 0xEC, + 0xA5, 0xCF, 0x4A, 0x7B, 0x3A, 0xC5, 0xC7, 0xCB, 0xE7, 0xBD, 0xCF, 0x73, 0x97, 0xB3, 0xFC, 0x5A, + 0xAF, 0xF8, 0xEB, 0x1C, 0x71, 0xC4, 0x11, 0x83, 0xDF, 0x79, 0xDC, 0x03, 0xE7, 0xF8, 0xE2, 0x8E, + 0xD5, 0xCC, 0xCF, 0x94, 0xF5, 0x85, 0xCD, 0x02, 0x79, 0xF5, 0x63, 0x1F, 0xFB, 0x58, 0x15, 0x03, + 0x66, 0xFB, 0x4E, 0x86, 0xA1, 0x7C, 0x6E, 0x78, 0xFF, 0x45, 0x3F, 0x5F, 0x4B, 0xB5, 0x12, 0xEF, + 0x89, 0xBC, 0x8A, 0xEE, 0x04, 0x1B, 0x9D, 0xD6, 0x55, 0xA6, 0x63, 0x5A, 0x17, 0x66, 0x22, 0xDE, + 0x0F, 0x7F, 0xAB, 0xB8, 0xBF, 0xB4, 0xCC, 0x35, 0xA7, 0x87, 0x17, 0xF4, 0x1F, 0xEC, 0x81, 0x99, + 0xDE, 0x31, 0xF6, 0x29, 0xFA, 0x99, 0x69, 0xAD, 0x8B, 0x16, 0xD8, 0xA1, 0xD1, 0xC7, 0xA9, 0xB8, + 0x7C, 0xB5, 0x8E, 0xA2, 0xF9, 0xCF, 0xFD, 0xDF, 0xF6, 0xB6, 0xB7, 0x0D, 0xF6, 0xF8, 0x6C, 0x9F, + 0x5B, 0x6A, 0x3C, 0x32, 0x0C, 0x46, 0xFF, 0x91, 0xFB, 0xB0, 0xFD, 0xB0, 0xC7, 0x81, 0xAD, 0x55, + 0xE2, 0x5C, 0xCB, 0xF6, 0xF5, 0x88, 0xD9, 0x6B, 0xFB, 0x80, 0xFF, 0xC6, 0x4B, 0x4D, 0xE6, 0x82, + 0xB7, 0xFE, 0xD6, 0x6F, 0xFD, 0xD6, 0x60, 0xDB, 0x46, 0x26, 0x71, 0xFA, 0xB8, 0xEC, 0xE2, 0x32, + 0xAE, 0xF7, 0x59, 0x74, 0xE4, 0xFF, 0xD8, 0xDF, 0xDE, 0xFE, 0xF6, 0xB7, 0x0F, 0xF7, 0x65, 0x9F, + 0x8F, 0x6B, 0x33, 0xAE, 0x35, 0x7D, 0x1E, 0xE7, 0xAA, 0xAF, 0xE3, 0x9A, 0x2E, 0x29, 0xBB, 0x5F, + 0xEC, 0xB3, 0xBF, 0x8F, 0x58, 0xC5, 0x75, 0x00, 0x1F, 0xFF, 0xF8, 0xC7, 0x87, 0xFC, 0x04, 0x57, + 0xBF, 0xFA, 0xD5, 0xBB, 0xE6, 0x44, 0x5C, 0xCF, 0xAC, 0x13, 0xD1, 0x04, 0xDB, 0x93, 0xF6, 0x53, + 0xC5, 0xE7, 0xB4, 0xAE, 0x45, 0xA7, 0x87, 0xFA, 0x2A, 0x6C, 0xCD, 0x35, 0xF6, 0x44, 0xC9, 0xFC, + 0x59, 0x7B, 0x7B, 0xE6, 0xB4, 0xBE, 0x4B, 0xDF, 0xC1, 0xF3, 0xA5, 0xF9, 0x32, 0x45, 0xDF, 0x84, + 0x5C, 0xAB, 0xDF, 0xE1, 0xF7, 0xA1, 0x67, 0xF5, 0xF8, 0x7D, 0xAB, 0x62, 0xC7, 0x07, 0x47, 0x20, + 0x03, 0xCD, 0x2D, 0x5A, 0x27, 0xD8, 0xBC, 0xD9, 0xEF, 0x88, 0x93, 0xAE, 0xF1, 0x04, 0xFD, 0x4F, + 0xBA, 0x27, 0x5E, 0xD1, 0x2B, 0x30, 0x87, 0xB2, 0x7D, 0xA2, 0x95, 0xA7, 0x65, 0xBA, 0x47, 0xC6, + 0xF9, 0x84, 0x13, 0x4E, 0xD8, 0x03, 0x0F, 0x8F, 0xF9, 0xE0, 0x2F, 0x49, 0x1F, 0x0A, 0x7D, 0x63, + 0x1D, 0xE3, 0xF7, 0x0C, 0x7D, 0xB2, 0xB6, 0x4C, 0xE5, 0x93, 0xEA, 0x83, 0xF6, 0x15, 0xF9, 0x02, + 0xE1, 0x53, 0x88, 0xFF, 0x80, 0xF4, 0x21, 0xD0, 0x47, 0xEB, 0xD4, 0x69, 0xC4, 0xB8, 0xE9, 0x33, + 0xD9, 0xDD, 0x62, 0xA9, 0xF1, 0x0E, 0x15, 0xE7, 0x09, 0x99, 0x4C, 0x15, 0x71, 0x57, 0x89, 0xB7, + 0xD2, 0x9E, 0xE7, 0x3D, 0xEF, 0x79, 0x83, 0x1D, 0xBE, 0xC7, 0x6F, 0x77, 0xEE, 0x7E, 0x13, 0xE7, + 0x04, 0x3A, 0x01, 0xF6, 0x98, 0xA8, 0x0F, 0x8B, 0xF4, 0x8B, 0xD7, 0x35, 0xD9, 0xD6, 0x4B, 0xA4, + 0x41, 0x09, 0x67, 0x38, 0xFD, 0xE2, 0x3E, 0x10, 0xB1, 0x28, 0xF1, 0x8C, 0xB7, 0xB8, 0xC5, 0x2D, + 0xAA, 0xFA, 0xD3, 0x75, 0x60, 0x26, 0x64, 0xA4, 0x77, 0xBC, 0xE3, 0x1D, 0xC3, 0xFC, 0xCA, 0x6C, + 0xB2, 0x2D, 0x25, 0xCE, 0x19, 0x74, 0xD5, 0xF0, 0xE5, 0x16, 0xB9, 0xBB, 0xE6, 0x3B, 0x0C, 0x7F, + 0x01, 0x47, 0x12, 0x9B, 0xC8, 0xF8, 0x49, 0xFE, 0x29, 0x8D, 0x4B, 0xA9, 0x6D, 0x63, 0xF2, 0x51, + 0xE9, 0x77, 0xF8, 0x4E, 0xE0, 0xC3, 0x38, 0x65, 0x3F, 0x99, 0x3A, 0x77, 0x79, 0x05, 0x2B, 0x11, + 0x9F, 0x29, 0x9B, 0x5B, 0xB4, 0x33, 0x65, 0xC5, 0xE7, 0x54, 0x2F, 0x4D, 0xE2, 0x7D, 0xA2, 0xBC, + 0xAB, 0x39, 0xE1, 0xB2, 0x14, 0xD7, 0xE8, 0x9C, 0xF0, 0x9F, 0xC2, 0x07, 0xCC, 0xC7, 0x32, 0x8E, + 0x69, 0xA6, 0x4F, 0x64, 0x6C, 0xB1, 0xE5, 0x63, 0x7F, 0xA3, 0x9F, 0x2E, 0xA3, 0x49, 0xDF, 0x95, + 0xC9, 0x30, 0x2E, 0x03, 0x67, 0x73, 0xC1, 0x31, 0x64, 0xD6, 0x47, 0xEE, 0x5D, 0x92, 0xA3, 0x75, + 0x1F, 0xD7, 0xB7, 0x39, 0xBE, 0x92, 0x6C, 0x20, 0x5E, 0xCC, 0xF7, 0xF0, 0x81, 0x7C, 0xE4, 0x23, + 0x1F, 0x39, 0xEC, 0x3B, 0x2D, 0xFC, 0x2E, 0xDB, 0x5F, 0xDD, 0x5E, 0xC3, 0x1E, 0x83, 0xBC, 0xE1, + 0x7D, 0x76, 0xFA, 0xB7, 0x14, 0xE7, 0x4F, 0x4E, 0x23, 0x64, 0x7E, 0x7C, 0x4A, 0x1C, 0x97, 0x47, + 0xDD, 0x66, 0xCF, 0xFC, 0x65, 0x0C, 0xF1, 0xA9, 0xC3, 0x36, 0x2E, 0x7A, 0xB6, 0xE6, 0x76, 0x28, + 0x15, 0x68, 0x2A, 0x9F, 0x5C, 0xF0, 0x22, 0xF6, 0x15, 0xB5, 0x2B, 0x93, 0xBF, 0x4A, 0x6B, 0x52, + 0x73, 0x0D, 0xFF, 0x1C, 0xE9, 0x4F, 0xDC, 0x67, 0xA5, 0xB4, 0xFE, 0x33, 0x1E, 0xE3, 0xDF, 0xE5, + 0xFF, 0xB4, 0x4F, 0x78, 0xC9, 0xDB, 0x10, 0x7D, 0x0E, 0xA3, 0x8F, 0x05, 0xD8, 0x92, 0xD8, 0x1F, + 0xBF, 0x77, 0x2F, 0x16, 0x66, 0xEE, 0x65, 0xB2, 0x2D, 0xE5, 0x55, 0xAF, 0x7A, 0xD5, 0xD0, 0xA6, + 0x2C, 0x8F, 0x62, 0xC9, 0x86, 0xD9, 0x4B, 0x9F, 0xB1, 0xCF, 0x35, 0x07, 0x88, 0x65, 0x25, 0x2F, + 0x87, 0xEB, 0xA0, 0xE7, 0xF0, 0xCF, 0xD8, 0x7E, 0xDD, 0x17, 0x7C, 0x48, 0x8C, 0x3A, 0x71, 0x57, + 0xA5, 0xF1, 0xF3, 0xF5, 0x10, 0x6D, 0x9E, 0xB1, 0x2F, 0x11, 0x0B, 0xC5, 0xBD, 0x4D, 0xFB, 0x90, + 0xE8, 0xEE, 0x7C, 0x4B, 0xDF, 0xD1, 0xFC, 0x77, 0x3E, 0xEA, 0xFC, 0xC6, 0x3F, 0xA7, 0xDD, 0xD2, + 0xFB, 0xD6, 0xD6, 0x5F, 0x69, 0xFC, 0xB2, 0xBD, 0xA4, 0x85, 0x96, 0x9A, 0x17, 0x87, 0x1E, 0x7A, + 0xE8, 0xA0, 0x2F, 0x11, 0xCF, 0xF3, 0xFE, 0x79, 0x1F, 0xF4, 0x1A, 0xE5, 0xCD, 0x4C, 0x17, 0x17, + 0xF5, 0xCA, 0x5E, 0x24, 0x13, 0x97, 0xE4, 0x2A, 0xD7, 0x8D, 0x47, 0x5D, 0x8C, 0xDF, 0x97, 0x78, + 0x46, 0xF6, 0x67, 0xE2, 0x4C, 0x4A, 0xBE, 0xC5, 0x25, 0x5B, 0xD6, 0x9C, 0xCA, 0x9C, 0x26, 0x37, + 0x82, 0xCB, 0xB2, 0x91, 0x4F, 0x8F, 0x15, 0xD7, 0xC9, 0x50, 0xD8, 0x03, 0xD1, 0x1B, 0x80, 0xFF, + 0x5B, 0xDA, 0x19, 0x63, 0xE5, 0xF5, 0x19, 0x76, 0x4A, 0x6C, 0xF2, 0xD8, 0xC9, 0xA2, 0xBD, 0xD4, + 0xF7, 0x90, 0xB8, 0x47, 0xF6, 0x94, 0x0C, 0x0B, 0xA8, 0x10, 0x3B, 0x26, 0x5F, 0xD3, 0x0C, 0xC3, + 0x2E, 0x25, 0x2F, 0x29, 0x5F, 0x08, 0x7D, 0x46, 0x2F, 0xF7, 0xCA, 0x57, 0xBE, 0x72, 0xC0, 0x22, + 0x71, 0xAD, 0x47, 0x9D, 0xA6, 0xDA, 0x5D, 0xE3, 0xB9, 0x35, 0x7D, 0x8A, 0xEE, 0x53, 0xD2, 0xEF, + 0xEB, 0xD9, 0xE2, 0x31, 0x91, 0x0F, 0xF0, 0xBF, 0xDD, 0xBB, 0x77, 0x0F, 0xB1, 0x13, 0xC4, 0xE8, + 0x39, 0x3D, 0x32, 0xAC, 0xEC, 0xFE, 0x85, 0xE8, 0x35, 0xB1, 0x31, 0xB6, 0xDA, 0x15, 0x4B, 0xC5, + 0xF9, 0x74, 0xC6, 0xBF, 0xBC, 0xDD, 0x99, 0x9C, 0x93, 0xED, 0x3B, 0xA5, 0x67, 0x78, 0x71, 0x9E, + 0x02, 0x9E, 0xC7, 0x16, 0x00, 0xEE, 0x89, 0xB9, 0x60, 0x32, 0x3E, 0x16, 0xD7, 0xB0, 0xEB, 0xDF, + 0xB1, 0x8F, 0xBF, 0xF6, 0xB5, 0xAF, 0x1D, 0x64, 0xE5, 0x48, 0x9B, 0x56, 0x2C, 0x9C, 0xB5, 0x99, + 0xF6, 0xA2, 0xCB, 0x3E, 0xF2, 0xC8, 0x23, 0x37, 0xED, 0xE1, 0x63, 0xB8, 0xA3, 0x34, 0x86, 0xBE, + 0x5F, 0x11, 0x93, 0xE9, 0xF4, 0x8D, 0x7B, 0xCC, 0xD4, 0x35, 0x89, 0xCE, 0x83, 0xBC, 0x81, 0x7A, + 0x76, 0x8B, 0x0F, 0x4C, 0xEC, 0x07, 0xF6, 0x26, 0xF9, 0x33, 0x47, 0xF9, 0xBF, 0x95, 0xA6, 0xB1, + 0xC0, 0xD3, 0xF1, 0xF7, 0x26, 0x0E, 0x22, 0xA3, 0x8F, 0x8F, 0xBD, 0xFB, 0xE8, 0x11, 0xA7, 0x72, + 0xE2, 0x89, 0x27, 0x16, 0xE5, 0xEB, 0x56, 0xFD, 0x52, 0xDC, 0x47, 0xD4, 0x27, 0x74, 0x3A, 0xE8, + 0xAF, 0x1C, 0xBF, 0x39, 0x8F, 0xCD, 0xE8, 0x25, 0xFA, 0xE0, 0xDB, 0x10, 0xE9, 0xBF, 0x0E, 0xFA, + 0xCC, 0xE1, 0x93, 0xEA, 0x87, 0xFA, 0x82, 0x5C, 0xF9, 0xE4, 0x27, 0x3F, 0x79, 0x88, 0xE9, 0xA7, + 0xB8, 0x8F, 0xD2, 0x9C, 0x39, 0x38, 0xF6, 0xFD, 0xD2, 0x3C, 0xF7, 0x7D, 0xB0, 0xC4, 0x67, 0x32, + 0xD9, 0x07, 0x3F, 0x2B, 0xFC, 0x86, 0x24, 0x77, 0x4A, 0x2E, 0x98, 0xA2, 0x37, 0x89, 0xFE, 0xA4, + 0xD9, 0x3E, 0x05, 0xFF, 0xC5, 0xD7, 0x0B, 0xBD, 0x12, 0xE3, 0xA4, 0x3E, 0xC5, 0x71, 0x9F, 0xB2, + 0x76, 0xFD, 0xF7, 0xB5, 0xF7, 0x73, 0x8A, 0xF3, 0x73, 0xF4, 0x4C, 0xE4, 0xC1, 0x8C, 0x58, 0x22, + 0x8B, 0x6D, 0x58, 0x02, 0x2F, 0x31, 0xA7, 0x91, 0x05, 0xC6, 0x70, 0x77, 0x6B, 0x1F, 0x28, 0xD2, + 0x2F, 0x31, 0x26, 0xA5, 0xF9, 0x5F, 0xB2, 0x05, 0x38, 0x76, 0x3A, 0xE0, 0x80, 0x03, 0x86, 0xBD, + 0x98, 0xBD, 0x23, 0xC3, 0x33, 0x25, 0x39, 0xD0, 0xF7, 0xCF, 0x29, 0x45, 0xCF, 0xC1, 0x0F, 0x8B, + 0x58, 0xDD, 0x39, 0xF4, 0x8D, 0xFE, 0x48, 0x71, 0x2C, 0x35, 0x97, 0x91, 0x3D, 0xA1, 0x19, 0x71, + 0xAF, 0x9E, 0x27, 0x6D, 0x4C, 0x07, 0x76, 0x79, 0x94, 0x48, 0x5F, 0xAE, 0x91, 0x6D, 0x69, 0xBF, + 0xAF, 0xD7, 0x0C, 0x0F, 0x50, 0x89, 0x47, 0xC4, 0x0F, 0xCA, 0x65, 0xF6, 0xD6, 0xBE, 0x8C, 0xAD, + 0xE3, 0x28, 0xE7, 0xB5, 0xC8, 0xC8, 0x99, 0x4E, 0xB8, 0xF4, 0x3C, 0xBF, 0x76, 0x3D, 0x14, 0x73, + 0x05, 0x5D, 0x68, 0x86, 0x83, 0x7D, 0xBF, 0xCA, 0xE6, 0xBD, 0xFB, 0x2C, 0x20, 0xEF, 0x13, 0x77, + 0x80, 0xBF, 0xAC, 0xF7, 0xA7, 0xB5, 0x94, 0xF0, 0x12, 0x85, 0x7B, 0x62, 0x7B, 0x89, 0xB6, 0xF0, + 0x1E, 0x5E, 0x22, 0xBB, 0x92, 0xEE, 0x81, 0xAF, 0x37, 0x63, 0xB9, 0x74, 0x61, 0xCD, 0x93, 0xEF, + 0x0E, 0x5C, 0x9D, 0xED, 0x05, 0x63, 0xFB, 0x6A, 0x86, 0x07, 0xB6, 0x02, 0x2F, 0x45, 0x7C, 0xE2, + 0x63, 0x8B, 0x8F, 0x08, 0xFC, 0xBD, 0xD4, 0x86, 0x5E, 0x3C, 0xAC, 0x57, 0x5D, 0x83, 0x2F, 0xC1, + 0x0F, 0x7A, 0x76, 0xE6, 0xD3, 0x5B, 0xA3, 0x8F, 0xCA, 0x76, 0xC2, 0x4B, 0xB1, 0xED, 0x3E, 0x07, + 0x68, 0x37, 0xFE, 0x9C, 0x51, 0x67, 0x13, 0xDB, 0x5D, 0xC2, 0x4F, 0xF1, 0xB3, 0x92, 0xEF, 0x96, + 0xEB, 0x35, 0xBC, 0x94, 0xFC, 0x05, 0xC6, 0xF0, 0x5A, 0x76, 0xCD, 0xD8, 0x69, 0x6D, 0xAA, 0x9F, + 0x51, 0x36, 0xF7, 0x7C, 0x1A, 0x63, 0xFB, 0x69, 0xF6, 0x3F, 0xE5, 0xEA, 0xE2, 0x3D, 0x63, 0xC3, + 0x18, 0xC9, 0xAE, 0xE4, 0x71, 0x22, 0x73, 0x4A, 0x89, 0x1E, 0xA2, 0xD5, 0x5C, 0x1C, 0xA6, 0xB9, + 0x29, 0x3F, 0x03, 0xEE, 0x43, 0xAE, 0x61, 0xE5, 0xB8, 0xCA, 0x6C, 0xF6, 0x3D, 0xBA, 0xB7, 0xAD, + 0xC2, 0x4B, 0x3E, 0xB7, 0xFE, 0xF2, 0x2F, 0xFF, 0x72, 0xD0, 0x93, 0x45, 0x1D, 0xC3, 0x18, 0x4F, + 0xF6, 0xBD, 0x95, 0xF7, 0xE8, 0xA8, 0xF0, 0xBF, 0xE6, 0xBE, 0x31, 0xEE, 0xA7, 0xB4, 0xAF, 0x2D, + 0x51, 0x96, 0xC4, 0x4B, 0x35, 0xBD, 0x94, 0xCB, 0x7C, 0xF0, 0x52, 0xF4, 0x0A, 0x7A, 0xB6, 0x6C, + 0xF1, 0x53, 0xF5, 0x66, 0xEB, 0x2E, 0x6A, 0x93, 0xDB, 0xCE, 0xF0, 0xB5, 0x24, 0x6F, 0x53, 0x66, + 0xE3, 0xD1, 0x3C, 0x26, 0x6E, 0xF2, 0xB9, 0xCF, 0x7D, 0xEE, 0x90, 0x2F, 0xC0, 0xF5, 0x5A, 0xD1, + 0xE7, 0x3C, 0xF2, 0xAC, 0xD6, 0x36, 0x65, 0xBE, 0x89, 0xBA, 0xD6, 0x7A, 0x2D, 0xE9, 0xDC, 0x5A, + 0xF8, 0x2A, 0xC5, 0xDB, 0xAA, 0xFF, 0x11, 0xFB, 0x82, 0x2F, 0x82, 0xDB, 0xE5, 0x62, 0x3E, 0xAF, + 0x6C, 0x0D, 0x38, 0xAD, 0xA8, 0xE8, 0x54, 0x89, 0x01, 0xC1, 0xCE, 0xE7, 0xF7, 0x8F, 0xD7, 0x63, + 0x74, 0xF0, 0xA2, 0xBE, 0xC2, 0x63, 0xD0, 0x05, 0xA9, 0x1D, 0xA5, 0x36, 0xF5, 0xAC, 0x51, 0xFC, + 0x8B, 0xB0, 0x4D, 0x95, 0xB0, 0x69, 0x6F, 0xD1, 0x3D, 0x88, 0x91, 0xC4, 0x27, 0x45, 0xFE, 0x38, + 0xB5, 0xFC, 0x3D, 0xB5, 0x3D, 0x43, 0xFE, 0xCC, 0x5B, 0x85, 0x07, 0x22, 0x06, 0xF5, 0x36, 0xE3, + 0xCB, 0x8F, 0x2E, 0x92, 0x32, 0x55, 0x96, 0xCB, 0x64, 0x44, 0xCD, 0x47, 0x5E, 0xA1, 0x59, 0xA6, + 0x5F, 0x2A, 0xD5, 0x2B, 0x02, 0x5E, 0x8A, 0x73, 0x14, 0x9F, 0x76, 0xF4, 0x8E, 0xE8, 0xD3, 0x28, + 0x99, 0xAF, 0x8D, 0x97, 0x16, 0x3E, 0x52, 0xFB, 0x8E, 0xEF, 0xF7, 0x35, 0x19, 0x2C, 0xFA, 0x50, + 0x66, 0xF7, 0x76, 0x3E, 0x14, 0x0B, 0xFB, 0x30, 0xFD, 0x42, 0x76, 0x8E, 0x79, 0x91, 0x6A, 0x74, + 0x89, 0xF3, 0xBF, 0x64, 0x03, 0xD1, 0x35, 0xF9, 0x02, 0x88, 0x23, 0x77, 0xB9, 0x5C, 0xE3, 0xD6, + 0x6B, 0x1F, 0x8E, 0xA5, 0xE4, 0xAB, 0x95, 0xD1, 0x62, 0xEA, 0x73, 0xA2, 0x7C, 0x4D, 0x5E, 0xAD, + 0x47, 0x3F, 0xFA, 0xD1, 0x43, 0xEC, 0x76, 0xA9, 0xEF, 0x4B, 0xC5, 0x1D, 0xCC, 0xC5, 0x4B, 0xFA, + 0x9E, 0xEF, 0x7D, 0xE0, 0x25, 0xB0, 0x8E, 0xE7, 0x74, 0x88, 0x31, 0x23, 0x3E, 0xAE, 0x25, 0xBE, + 0xAD, 0xB8, 0x1B, 0x4A, 0xDC, 0xA3, 0xAE, 0x68, 0x78, 0xA9, 0x94, 0x23, 0x9C, 0xCF, 0x6F, 0x72, + 0x93, 0x9B, 0x0C, 0x39, 0x23, 0x4B, 0xB9, 0x2E, 0xB2, 0xF6, 0x6D, 0x37, 0xFC, 0x44, 0xC1, 0x7F, + 0x11, 0x1F, 0x19, 0xE9, 0x47, 0xDD, 0x87, 0x51, 0x72, 0x0D, 0xF4, 0x44, 0x96, 0xCA, 0x7C, 0x94, + 0xB4, 0x7E, 0xA3, 0x5C, 0xD7, 0xCA, 0xEB, 0xA2, 0xED, 0xD2, 0x65, 0xF0, 0x12, 0x3E, 0x1A, 0xF3, + 0x87, 0xCB, 0x9E, 0xED, 0xF6, 0x6A, 0xC7, 0x7A, 0xD8, 0x7C, 0xF0, 0xB7, 0x89, 0x32, 0x4E, 0x89, + 0xDF, 0x65, 0x72, 0x0F, 0xF1, 0x0D, 0xE4, 0x68, 0x23, 0xEF, 0x6D, 0xD4, 0x87, 0xB4, 0x8E, 0x79, + 0xEC, 0xAB, 0xF3, 0x67, 0xF2, 0xC0, 0x95, 0xDA, 0xD5, 0x82, 0x9B, 0xE4, 0xCF, 0xAF, 0x76, 0xE3, + 0xEF, 0x4E, 0xBE, 0x89, 0x5A, 0x3E, 0xE4, 0xD6, 0xE2, 0x78, 0x17, 0x39, 0x89, 0xBC, 0xEE, 0xCA, + 0x79, 0x38, 0x26, 0x23, 0xB6, 0xE8, 0x97, 0x9C, 0x1E, 0xFE, 0xCC, 0xDE, 0x52, 0xC3, 0x03, 0xA5, + 0x9C, 0xB7, 0xBC, 0x3E, 0xEA, 0x51, 0x8F, 0xDA, 0x23, 0xFE, 0x68, 0xAA, 0x5C, 0xEA, 0xBF, 0xF5, + 0xFD, 0x03, 0xFD, 0x74, 0xD4, 0x63, 0xD7, 0xE8, 0x76, 0x45, 0xC0, 0x4B, 0xD1, 0x76, 0x8D, 0xCC, + 0xC5, 0x3C, 0x26, 0xBF, 0x47, 0x94, 0x91, 0xC6, 0x68, 0x36, 0x56, 0x32, 0xFD, 0x52, 0x89, 0x2F, + 0x64, 0xBF, 0xA9, 0xBD, 0x2F, 0xF9, 0x4B, 0x0B, 0x87, 0xC1, 0xFF, 0xD9, 0x07, 0x88, 0x99, 0xCB, + 0xE6, 0x74, 0xAB, 0x8E, 0xC4, 0xF3, 0xA6, 0xC6, 0x57, 0xFE, 0xC7, 0x9A, 0x7D, 0xCF, 0x7B, 0xDE, + 0xB3, 0xD1, 0xB6, 0x56, 0x3F, 0xEE, 0x96, 0x52, 0x93, 0x45, 0x6B, 0x7E, 0xA5, 0xAD, 0xC5, 0x71, + 0x80, 0xEE, 0x27, 0x5B, 0x34, 0x3E, 0x21, 0x4E, 0xAB, 0x52, 0x2E, 0xFB, 0x39, 0x75, 0x29, 0xBC, + 0xE4, 0xFA, 0x50, 0xFC, 0x97, 0xF0, 0xC3, 0xC9, 0xF2, 0x4A, 0x64, 0x3C, 0x2D, 0x3B, 0x13, 0x06, + 0x3F, 0x52, 0xF2, 0xA2, 0xC6, 0x52, 0xDA, 0xDF, 0xE6, 0x62, 0xD6, 0xAC, 0x4F, 0x4B, 0xE0, 0xA5, + 0xD8, 0x47, 0xF1, 0x31, 0xD1, 0x01, 0xDB, 0x14, 0xF9, 0x4F, 0xE4, 0xAF, 0xA8, 0x52, 0xCA, 0xC5, + 0xB2, 0x04, 0x3E, 0x9F, 0x53, 0xE2, 0x73, 0xC5, 0xAB, 0x1C, 0xEB, 0x20, 0xCF, 0xE3, 0x5B, 0xE0, + 0xFD, 0xE5, 0x9A, 0x7C, 0x97, 0xFC, 0xCF, 0x8B, 0xCF, 0xF9, 0xEC, 0x39, 0x53, 0xFB, 0x99, 0xAD, + 0x4F, 0x4A, 0x94, 0x4D, 0xC6, 0x30, 0x55, 0x2C, 0x99, 0x0F, 0x99, 0x8F, 0xD5, 0x53, 0x2F, 0x96, + 0xDB, 0xBE, 0xEB, 0x62, 0x39, 0xE7, 0x9B, 0xF0, 0xB3, 0x60, 0xDE, 0xC3, 0xA3, 0x98, 0xFB, 0xCC, + 0x81, 0x4B, 0xDF, 0xEB, 0x5A, 0xD5, 0x3F, 0x83, 0x4E, 0xC4, 0x7D, 0x10, 0xAF, 0x3E, 0x26, 0x37, + 0x97, 0x4A, 0x8C, 0x21, 0xF5, 0xFE, 0x93, 0xC3, 0x44, 0x36, 0x8D, 0xEC, 0xAC, 0x94, 0x96, 0xB9, + 0xEC, 0x76, 0x76, 0x7C, 0xBD, 0x65, 0x13, 0xC9, 0x68, 0x5F, 0x2B, 0x19, 0x0E, 0xD5, 0x67, 0xE8, + 0xD7, 0xF0, 0xC5, 0x21, 0x87, 0x7D, 0xB4, 0x67, 0xF7, 0xE8, 0xC3, 0xB6, 0xDA, 0x7F, 0x29, 0xF2, + 0x67, 0xE7, 0xDB, 0xCC, 0x7D, 0xCE, 0xDE, 0xA8, 0xF9, 0xD0, 0xB5, 0x94, 0xB8, 0x56, 0x7C, 0x9C, + 0xD1, 0xF1, 0x42, 0x33, 0x8F, 0x53, 0xAD, 0xE9, 0x11, 0xB7, 0x1B, 0x5E, 0xAA, 0xD9, 0x95, 0x44, + 0x53, 0x72, 0x76, 0x2B, 0x46, 0x24, 0xC6, 0xC1, 0x65, 0x72, 0x74, 0x7C, 0xDF, 0xD2, 0xA7, 0x12, + 0xFF, 0x89, 0x72, 0x99, 0x78, 0x57, 0x8B, 0x4D, 0xAE, 0x64, 0xA7, 0xF2, 0x76, 0xE2, 0xC7, 0xAC, + 0x98, 0x6C, 0xDF, 0x2B, 0x5A, 0xFD, 0xE5, 0xA3, 0xFF, 0x83, 0xE6, 0x20, 0xB2, 0x11, 0xF7, 0x20, + 0x16, 0x0F, 0xBF, 0x51, 0xD1, 0xAC, 0x27, 0x77, 0x52, 0x4F, 0x89, 0xF2, 0xEA, 0x92, 0x7B, 0x15, + 0xF7, 0x72, 0x9D, 0x2A, 0x85, 0x7E, 0x80, 0x17, 0x98, 0xFB, 0xD9, 0x3C, 0x5A, 0xCA, 0x26, 0xB7, + 0x0E, 0xFF, 0x25, 0x72, 0x85, 0x61, 0x8F, 0x8B, 0xF9, 0xBD, 0xA3, 0x2E, 0x3F, 0x5B, 0x27, 0xF2, + 0xE7, 0x23, 0x77, 0xAE, 0xDB, 0xA7, 0xF4, 0x0C, 0xD1, 0xA7, 0xC7, 0x37, 0xB7, 0xB7, 0x2C, 0x8D, + 0x97, 0xA2, 0xAE, 0x54, 0x95, 0x7E, 0x92, 0x33, 0x40, 0x79, 0x87, 0x4A, 0xB9, 0xFA, 0xBD, 0x5F, + 0x97, 0x97, 0x5E, 0x69, 0x4C, 0xEE, 0x12, 0xCF, 0xA0, 0xA2, 0x1F, 0x25, 0x47, 0x86, 0xFA, 0x2F, + 0x3D, 0x06, 0x67, 0x28, 0x30, 0xD7, 0xB2, 0x35, 0x5A, 0x8A, 0xEF, 0x9D, 0xDA, 0xD6, 0x58, 0x6A, + 0xBC, 0x41, 0xBF, 0x99, 0xFA, 0x7C, 0xC6, 0x4D, 0xD8, 0xE6, 0x8F, 0xCF, 0x3D, 0x77, 0xF5, 0x73, + 0xF7, 0xBA, 0xD7, 0x06, 0x0E, 0xBA, 0x2A, 0xBA, 0x98, 0x4B, 0xF1, 0x50, 0xC4, 0x4C, 0x5E, 0xC1, + 0x57, 0x57, 0xBB, 0xD4, 0xCF, 0x13, 0x7D, 0x3C, 0x39, 0xE3, 0x62, 0xFB, 0x5B, 0x8B, 0xFA, 0x9F, + 0xFD, 0x06, 0xFA, 0xEB, 0x7C, 0x11, 0xE7, 0xA7, 0x3D, 0xF3, 0xD9, 0xF5, 0xC6, 0xF8, 0x2F, 0x8B, + 0x77, 0xD4, 0xF2, 0x08, 0x95, 0xF6, 0x1E, 0x2F, 0xD1, 0x07, 0x12, 0x79, 0xD1, 0xF3, 0x1E, 0x67, + 0xB6, 0x87, 0xB1, 0xFD, 0xF6, 0xF2, 0xC2, 0x4B, 0xA2, 0x91, 0x9F, 0xBD, 0x4E, 0x3E, 0x37, 0xE5, + 0x12, 0xC8, 0x72, 0xAB, 0xB6, 0x96, 0xA8, 0x0F, 0xF0, 0x7B, 0x11, 0xEB, 0x44, 0xCE, 0xB6, 0x98, + 0xCB, 0xE7, 0x8A, 0x82, 0x97, 0xE2, 0x38, 0xC7, 0xF7, 0xC4, 0x43, 0x60, 0x73, 0x54, 0xBF, 0x5D, + 0x9F, 0x9C, 0xF9, 0x18, 0xF5, 0xE2, 0xA5, 0xA9, 0x76, 0xE5, 0x12, 0x1E, 0x8A, 0xEF, 0xB3, 0x58, + 0x67, 0xCD, 0x07, 0xFD, 0x0F, 0xFF, 0x45, 0xE4, 0xE8, 0x2C, 0x1E, 0xA3, 0x65, 0x0D, 0xA8, 0xC6, + 0x7C, 0x60, 0xE4, 0xAA, 0x25, 0x7E, 0xE9, 0x43, 0x1F, 0xFA, 0xD0, 0xA6, 0x36, 0xD4, 0xF0, 0xDE, + 0x54, 0x5A, 0xD4, 0xD6, 0xF9, 0x9C, 0x92, 0xF9, 0xA9, 0x09, 0x13, 0x10, 0x9F, 0x85, 0x0F, 0x7B, + 0xD4, 0xC9, 0xD5, 0xE6, 0xFF, 0x56, 0xE3, 0x25, 0xC7, 0xC7, 0xC2, 0x94, 0xE4, 0x55, 0x84, 0xD7, + 0x45, 0x9F, 0xB5, 0x6C, 0x9C, 0x23, 0x2F, 0xD4, 0x7B, 0xE2, 0x78, 0xE4, 0xC3, 0xE1, 0xCF, 0xCA, + 0x78, 0xDE, 0xD2, 0x65, 0x49, 0xBC, 0x54, 0xD3, 0xA9, 0x72, 0x9E, 0x90, 0x62, 0x8B, 0xBC, 0x8F, + 0x53, 0xF5, 0x0A, 0xEB, 0x28, 0x25, 0x9C, 0xA4, 0x1A, 0x73, 0x8D, 0x50, 0x98, 0x4B, 0xE8, 0x31, + 0x38, 0xBB, 0x45, 0xF3, 0x15, 0x59, 0x97, 0xB8, 0x59, 0xE5, 0x16, 0xA2, 0x44, 0x0C, 0x33, 0x67, + 0x4C, 0x7D, 0x8D, 0xE2, 0xFB, 0xF2, 0xC9, 0x4F, 0x7E, 0x72, 0x88, 0xCB, 0xC7, 0x36, 0x4C, 0xC5, + 0x66, 0x44, 0x8E, 0x11, 0xE2, 0x0E, 0x75, 0x4E, 0xAF, 0xF8, 0x57, 0xD4, 0x31, 0xB5, 0xE8, 0x45, + 0xA2, 0x9C, 0xA9, 0xFE, 0x7C, 0xE9, 0x62, 0xF9, 0xF0, 0x05, 0x27, 0x9C, 0xB0, 0xFA, 0x66, 0xCE, + 0x62, 0xBA, 0x78, 0x8C, 0xBF, 0xE5, 0xE2, 0x35, 0xE0, 0x3A, 0x26, 0xBD, 0x96, 0xF0, 0x92, 0xE6, + 0x07, 0x7A, 0x79, 0x6F, 0xC7, 0xD4, 0xFD, 0x94, 0xE2, 0x63, 0x84, 0x2C, 0x83, 0xBD, 0x74, 0xAA, + 0xAE, 0x5A, 0xB9, 0xD1, 0xA4, 0xBF, 0x38, 0xF3, 0xCC, 0x33, 0x37, 0xE9, 0xD9, 0x4A, 0xB4, 0x6B, + 0xC5, 0x4B, 0xA2, 0x2B, 0x39, 0xB9, 0x84, 0xEB, 0xA2, 0xDF, 0xF2, 0x76, 0xD6, 0x2F, 0x39, 0x3F, + 0xF3, 0xBC, 0x9E, 0xE8, 0xCB, 0x95, 0x67, 0xCC, 0xF5, 0x22, 0xBD, 0xED, 0x88, 0xF3, 0xCD, 0x7D, + 0x75, 0x29, 0xE4, 0x94, 0x45, 0x2E, 0xC1, 0xAE, 0x1B, 0xF7, 0x88, 0x2B, 0x0A, 0x5E, 0xAA, 0x8D, + 0x33, 0x67, 0xFA, 0xD0, 0x47, 0x7F, 0x96, 0xF7, 0x7F, 0x2E, 0x5E, 0x52, 0x41, 0x06, 0xC2, 0x27, + 0x51, 0xB9, 0x8F, 0x95, 0x1B, 0x19, 0x5F, 0x02, 0xE4, 0xDB, 0xEC, 0xFE, 0xA5, 0xB8, 0x38, 0xE7, + 0x2F, 0x59, 0x3B, 0x63, 0xCE, 0x12, 0x78, 0xE7, 0x81, 0x07, 0x1E, 0xB8, 0x41, 0x07, 0x64, 0x86, + 0xD2, 0xD9, 0xE7, 0x19, 0xBD, 0x4A, 0x72, 0x10, 0x7E, 0x4B, 0x27, 0x9D, 0x74, 0xD2, 0xA0, 0xE3, + 0xCC, 0x72, 0x14, 0x47, 0x7D, 0xF4, 0x54, 0xAC, 0xA4, 0x82, 0xCD, 0x01, 0x5E, 0xCB, 0xEB, 0x5C, + 0x9D, 0x6A, 0x76, 0x7F, 0xD1, 0x4D, 0xF3, 0x15, 0xDE, 0xCE, 0x5C, 0x8E, 0xD8, 0x72, 0x2E, 0x46, + 0x5A, 0x12, 0x2F, 0x79, 0x3C, 0xBB, 0x68, 0x82, 0x3D, 0x8E, 0xBC, 0x4E, 0x59, 0x3C, 0x4B, 0x0D, + 0x2F, 0xF9, 0xF8, 0xBE, 0xF8, 0xC5, 0x2F, 0x1E, 0xE2, 0x44, 0xA5, 0x53, 0xCA, 0x62, 0x13, 0x7A, + 0xDA, 0xD9, 0x53, 0xD6, 0x89, 0x97, 0x3C, 0x87, 0x0C, 0xB9, 0x8B, 0xF1, 0x67, 0x90, 0x7C, 0x11, + 0x73, 0xC2, 0xD6, 0xDA, 0xB7, 0x55, 0xBA, 0xA6, 0x9A, 0x0F, 0x91, 0xF3, 0x01, 0xCF, 0xF1, 0x40, + 0x5F, 0xC8, 0xBF, 0x4E, 0x6E, 0x0F, 0xF4, 0xBF, 0xF4, 0x15, 0xFE, 0x4D, 0xBE, 0x8C, 0x2C, 0x7F, + 0x47, 0xE4, 0x17, 0x63, 0xF8, 0xAC, 0x96, 0x3F, 0x02, 0xDE, 0x86, 0x0F, 0x07, 0xFA, 0x2D, 0xCE, + 0x98, 0x25, 0xCF, 0x3C, 0x31, 0x56, 0x9C, 0x25, 0xC3, 0x19, 0x44, 0xC8, 0x6E, 0xD8, 0xBA, 0x3D, + 0xDF, 0x48, 0x94, 0xF3, 0x6A, 0x32, 0x66, 0xC4, 0x58, 0x6A, 0x8F, 0xFC, 0xF3, 0x2F, 0x6E, 0xD8, + 0xEA, 0x9C, 0xB7, 0xBC, 0x65, 0x75, 0xAD, 0x8B, 0xF7, 0x47, 0x74, 0x49, 0x60, 0x20, 0xB0, 0x90, + 0x74, 0x4D, 0x99, 0x4D, 0xCE, 0x31, 0x93, 0xF0, 0x01, 0xB9, 0x76, 0xFD, 0x3C, 0x82, 0xD6, 0x42, + 0xBF, 0x62, 0x0E, 0x13, 0x5F, 0xDB, 0xAC, 0x4D, 0x64, 0x19, 0xD7, 0x7B, 0xD4, 0xF6, 0xD3, 0xAC, + 0xFA, 0x1C, 0x66, 0x8D, 0x88, 0x8E, 0x3E, 0x36, 0xA5, 0x52, 0xC2, 0x4B, 0xA2, 0xAB, 0x2A, 0x31, + 0x77, 0xE2, 0x07, 0xCA, 0x4B, 0x32, 0x65, 0xFD, 0x6D, 0xB5, 0xBF, 0xB7, 0xD3, 0xD1, 0xF7, 0x38, + 0x30, 0x2A, 0x36, 0xD6, 0x98, 0x93, 0xA3, 0x57, 0x46, 0x10, 0x26, 0x75, 0xDD, 0x8A, 0xCB, 0xDC, + 0xE4, 0x50, 0x65, 0xEE, 0xFB, 0x59, 0x8F, 0xCA, 0x65, 0x77, 0x45, 0xC3, 0x4B, 0xD9, 0xE7, 0xE4, + 0xC9, 0x75, 0xDF, 0xC7, 0x28, 0x6F, 0x8D, 0xE1, 0xA3, 0xC8, 0xCF, 0xE2, 0x7B, 0x2A, 0x78, 0x08, + 0x4C, 0x06, 0x1F, 0x21, 0x0F, 0x1E, 0xBE, 0xD1, 0x9C, 0x8F, 0xC5, 0x2B, 0xB1, 0x2A, 0xC4, 0x6D, + 0xEA, 0xFC, 0xBF, 0x78, 0xFF, 0x28, 0x7F, 0xB9, 0x8F, 0xB8, 0xAA, 0xAF, 0x47, 0xB7, 0x97, 0xF0, + 0x3F, 0x70, 0xDA, 0x79, 0xE7, 0x9D, 0x37, 0x8C, 0xA1, 0xFB, 0x1C, 0xC5, 0xF9, 0x54, 0xDB, 0x67, + 0x4A, 0xF9, 0x88, 0x58, 0xF7, 0xE8, 0x32, 0x9C, 0x7E, 0xE2, 0x15, 0x6A, 0xF3, 0x5C, 0xFF, 0x25, + 0xEE, 0x87, 0xAD, 0x94, 0x73, 0x38, 0xA0, 0x13, 0x7A, 0x72, 0x74, 0xC5, 0xF8, 0x9B, 0x28, 0x0F, + 0xED, 0x9C, 0xFD, 0x4B, 0xF9, 0xD9, 0x5C, 0xA7, 0xE0, 0xD8, 0x0F, 0x39, 0x53, 0xFD, 0x75, 0x7D, + 0x4D, 0xC9, 0xAE, 0xB5, 0xD5, 0x78, 0x89, 0xF6, 0x82, 0x1F, 0x7D, 0xCD, 0x22, 0x47, 0xC9, 0x7F, + 0xA5, 0x36, 0xFF, 0x23, 0x0E, 0x94, 0xFD, 0x0E, 0xBD, 0x21, 0xB9, 0xB5, 0x35, 0x9E, 0xF8, 0x11, + 0x67, 0x39, 0x74, 0xD6, 0xA1, 0x4B, 0xF4, 0xBE, 0x2F, 0xE9, 0xBF, 0xA4, 0xB9, 0x0B, 0x6E, 0x10, + 0x36, 0xE4, 0x1C, 0x1A, 0xF5, 0x49, 0xCF, 0xE5, 0x5A, 0x76, 0x39, 0xD7, 0x77, 0x6C, 0x05, 0x36, + 0xCA, 0xCA, 0x58, 0x7E, 0xA7, 0xA8, 0x63, 0xD2, 0x35, 0xF1, 0x6F, 0xE8, 0x1E, 0xF0, 0x65, 0xA7, + 0xBF, 0xD8, 0x57, 0xD1, 0x6D, 0xE8, 0x7B, 0x73, 0xFB, 0x23, 0x9A, 0xB9, 0xEC, 0xC2, 0x5A, 0xC1, + 0xF6, 0x0F, 0x56, 0xC7, 0x4F, 0x98, 0xBC, 0xBF, 0x9C, 0x97, 0xCC, 0xBA, 0x81, 0xEE, 0x9C, 0x03, + 0xCD, 0xBC, 0x24, 0xEF, 0x01, 0xB8, 0x09, 0x1D, 0x94, 0xEE, 0x35, 0x95, 0x4F, 0x48, 0x1F, 0xE8, + 0xFB, 0x17, 0xFD, 0x8C, 0x71, 0x82, 0x9A, 0xE7, 0x31, 0xB7, 0x42, 0x9C, 0x23, 0xAA, 0x9C, 0xA5, + 0xCC, 0xDE, 0xA7, 0xD2, 0x7B, 0x26, 0x8A, 0x4A, 0xDC, 0x13, 0xC0, 0xB1, 0xC8, 0xE8, 0x3A, 0x83, + 0x49, 0x7C, 0xB8, 0x95, 0x97, 0x28, 0xAE, 0x99, 0x6B, 0x6C, 0x06, 0xF0, 0x44, 0xB7, 0x89, 0x8C, + 0xB5, 0xA3, 0xF6, 0x3F, 0xCD, 0x35, 0xFA, 0xCA, 0xF9, 0x38, 0xCE, 0x1F, 0x22, 0xDD, 0x4A, 0xB2, + 0xA3, 0x7F, 0x4E, 0xBF, 0xC0, 0x0D, 0xE4, 0xB6, 0x01, 0x0F, 0x8C, 0xF9, 0xF6, 0xB7, 0x96, 0x1A, + 0x1E, 0x10, 0x1F, 0xF3, 0xB1, 0x47, 0x3F, 0x40, 0xDC, 0x13, 0x7B, 0x95, 0x4A, 0x16, 0x27, 0x15, + 0xDB, 0xE4, 0xDF, 0xF1, 0xF9, 0x99, 0xC5, 0x32, 0xE8, 0x3D, 0xE7, 0xBA, 0x92, 0xE7, 0x1B, 0xDD, + 0x6E, 0xE4, 0xB1, 0x25, 0x3C, 0xB9, 0x24, 0x5E, 0xD2, 0xF8, 0x91, 0x03, 0x59, 0xB9, 0x20, 0x78, + 0x76, 0xCF, 0x99, 0x41, 0xB1, 0xAD, 0xFA, 0x2D, 0xBE, 0x29, 0xC4, 0x93, 0x68, 0x1C, 0x5D, 0x2E, + 0xE8, 0x39, 0x53, 0x26, 0x62, 0x2C, 0xD7, 0x51, 0x20, 0xD3, 0x91, 0xF3, 0x0F, 0x6C, 0x01, 0xEF, + 0x82, 0x5F, 0xE0, 0x5F, 0xAE, 0x33, 0xD8, 0x39, 0xCF, 0x00, 0xFE, 0x81, 0xEC, 0x85, 0xFD, 0x47, + 0x67, 0xF7, 0xB8, 0x1C, 0x55, 0xE2, 0x6F, 0xAD, 0xB4, 0x84, 0xA7, 0x79, 0x5C, 0x86, 0x64, 0x9B, + 0xCC, 0x07, 0x27, 0x5B, 0x0B, 0xD9, 0x59, 0xE6, 0xFC, 0x1F, 0xBD, 0x23, 0xFA, 0x9E, 0x4C, 0xB7, + 0xD4, 0xD3, 0x3E, 0x4A, 0xCC, 0xE9, 0x4B, 0x01, 0xE7, 0x81, 0x2B, 0x91, 0x53, 0xD1, 0x8F, 0xC1, + 0xF3, 0x91, 0x13, 0xA0, 0x17, 0x76, 0x32, 0xE2, 0xB7, 0x58, 0xD7, 0x9A, 0x6B, 0xFE, 0xBC, 0x52, + 0x7C, 0x74, 0xA9, 0x7D, 0x11, 0x03, 0xE8, 0xFB, 0xF0, 0x23, 0xE6, 0xBE, 0xC7, 0xA5, 0x2C, 0xA9, + 0x63, 0x5A, 0x3A, 0x9F, 0x00, 0x05, 0x9F, 0x43, 0x78, 0xAA, 0xF3, 0x8D, 0x52, 0x9B, 0xC5, 0xAB, + 0xF5, 0x1D, 0xCE, 0xB2, 0x81, 0xB6, 0xF8, 0xEF, 0xF7, 0xE2, 0x9E, 0x88, 0x9D, 0x6A, 0x3A, 0xC0, + 0x31, 0xFE, 0x4D, 0x59, 0x0A, 0x2F, 0xB9, 0x7F, 0x2C, 0xD7, 0x8C, 0xA3, 0xE4, 0x4D, 0xB5, 0x33, + 0xEA, 0x4C, 0x7A, 0xF0, 0x6A, 0xD6, 0x7F, 0xD6, 0x2E, 0xB6, 0x2F, 0xFC, 0x19, 0xF0, 0x03, 0xE3, + 0x0C, 0x3E, 0xF8, 0x22, 0xBC, 0x14, 0x3F, 0x0A, 0x6C, 0x54, 0x59, 0xCC, 0xE1, 0x1C, 0xBD, 0x9D, + 0xF3, 0x70, 0x64, 0x09, 0x30, 0x13, 0x7E, 0xFF, 0x8C, 0x2B, 0xF9, 0x1C, 0xD1, 0xA5, 0xF9, 0xB3, + 0xA6, 0x94, 0x6C, 0xCC, 0xE0, 0x59, 0x9C, 0xF9, 0x8E, 0xCF, 0x5C, 0x6D, 0xFF, 0x74, 0x5E, 0x4C, + 0x6E, 0x38, 0x7C, 0x6F, 0x74, 0xB6, 0xEF, 0x1C, 0xDB, 0x67, 0x94, 0x51, 0xE9, 0x27, 0x3E, 0xA9, + 0xD8, 0x60, 0x1C, 0x2B, 0xB7, 0x62, 0x6A, 0x2A, 0xFC, 0x98, 0x31, 0xEA, 0xC5, 0xCB, 0x25, 0xF9, + 0x5A, 0x9F, 0x93, 0x83, 0x89, 0xBC, 0x07, 0x3A, 0x0F, 0xBB, 0x44, 0xA7, 0xB1, 0xCA, 0xFA, 0xE6, + 0x7C, 0x30, 0xF4, 0x55, 0x3E, 0xEE, 0x63, 0x6D, 0x6B, 0x99, 0xDF, 0x8C, 0x09, 0x3A, 0xA1, 0xA9, + 0xEB, 0xCD, 0xF7, 0x10, 0x64, 0xAF, 0xC3, 0x0E, 0x3B, 0x6C, 0xD3, 0x99, 0x42, 0x73, 0xF1, 0xFA, + 0x98, 0xFE, 0x24, 0xF2, 0x3B, 0xE2, 0xDF, 0xD1, 0xB5, 0xAA, 0x0D, 0x11, 0xC3, 0x66, 0x74, 0x8A, + 0xEF, 0x6B, 0x71, 0x2E, 0xFE, 0x3F, 0x74, 0x23, 0xAF, 0x7E, 0xF5, 0xAB, 0x07, 0xBC, 0xDE, 0x32, + 0x9E, 0xEB, 0xD0, 0x2F, 0x29, 0xBF, 0xB7, 0xD3, 0xA7, 0x75, 0x6E, 0x39, 0x76, 0x77, 0x7D, 0x0A, + 0x98, 0x01, 0x39, 0x88, 0xF9, 0xA6, 0x76, 0x39, 0x5E, 0x6A, 0x95, 0x77, 0x32, 0xFF, 0x11, 0x2A, + 0x32, 0x39, 0x58, 0x89, 0x75, 0x8B, 0x9C, 0x15, 0xD7, 0x84, 0xF6, 0x31, 0xB5, 0x89, 0xF9, 0xCF, + 0xDE, 0xF0, 0xD6, 0xB7, 0xBE, 0x75, 0xD0, 0x35, 0x2D, 0xED, 0x4F, 0xCB, 0xDE, 0x43, 0x4E, 0x21, + 0xF9, 0x32, 0x8C, 0xCD, 0xF7, 0xD2, 0x1C, 0x14, 0x66, 0xA0, 0xBD, 0x87, 0x1F, 0x7E, 0x78, 0x1A, + 0x2B, 0xD0, 0xBA, 0x7E, 0x63, 0x7F, 0xFC, 0xB7, 0xEC, 0x65, 0xC7, 0x1E, 0x7B, 0xEC, 0x1E, 0x7E, + 0x57, 0x3E, 0xA6, 0xBC, 0x32, 0x2F, 0xC9, 0x33, 0xF5, 0xE1, 0x0F, 0x7F, 0x78, 0x8F, 0x31, 0x69, + 0x89, 0x73, 0x8C, 0xBF, 0x89, 0x3A, 0x46, 0xD6, 0x18, 0x3E, 0xC1, 0x3A, 0x57, 0x7C, 0x2A, 0x7F, + 0x2B, 0xD5, 0xA5, 0xF0, 0x92, 0xFF, 0x86, 0xF3, 0xDE, 0x7A, 0x7C, 0x22, 0x5C, 0x06, 0x42, 0x1E, + 0x24, 0x8E, 0x78, 0xD7, 0xAE, 0x5D, 0xD5, 0xE7, 0x44, 0xBE, 0xDB, 0xE2, 0xCF, 0x5B, 0xC3, 0xAB, + 0xD9, 0xE7, 0x4B, 0xFA, 0x7B, 0x3B, 0x76, 0xC4, 0x46, 0xC5, 0x59, 0x8B, 0x9E, 0x63, 0xC7, 0xDB, + 0xD7, 0xBB, 0xC6, 0xA2, 0x6C, 0x45, 0xBC, 0x12, 0x79, 0x5E, 0xB0, 0xE9, 0xB0, 0x57, 0x20, 0xDB, + 0x92, 0x5B, 0x98, 0xFC, 0x14, 0xE4, 0xB3, 0x41, 0x76, 0x42, 0x86, 0x3A, 0xF9, 0xE4, 0x93, 0x07, + 0x3C, 0xA5, 0xB3, 0xC9, 0xE3, 0x7C, 0x6C, 0x39, 0x2F, 0xBD, 0x26, 0x1F, 0xF3, 0x7B, 0x64, 0x0A, + 0x74, 0x3C, 0xE0, 0xB5, 0xDD, 0xBB, 0x77, 0x4F, 0xEA, 0x5F, 0x56, 0x1C, 0xEB, 0x61, 0x5F, 0x23, + 0x4F, 0xBD, 0xAF, 0x4F, 0xB7, 0x3F, 0xC4, 0x9C, 0xA1, 0xFA, 0x1E, 0x98, 0x15, 0x1A, 0xF4, 0x9E, + 0x77, 0x5A, 0x2B, 0xF4, 0x0B, 0x3B, 0x3A, 0xFB, 0x3D, 0x7B, 0x51, 0x7C, 0xE6, 0xD8, 0x1C, 0xD1, + 0x35, 0x79, 0x20, 0x99, 0x7F, 0x71, 0x5E, 0xD4, 0x9E, 0x5B, 0xC3, 0x4A, 0xAA, 0xC4, 0xDF, 0x90, + 0x5B, 0xD4, 0xF3, 0x1A, 0xB5, 0xB6, 0x91, 0xEA, 0x67, 0x74, 0x72, 0x7E, 0x20, 0x39, 0xC3, 0x55, + 0x96, 0xF0, 0x29, 0x64, 0xDE, 0xE1, 0x6B, 0xC6, 0xFA, 0x70, 0x3E, 0x57, 0xB2, 0x27, 0x95, 0x68, + 0xE9, 0x39, 0xB0, 0x90, 0xBF, 0x5C, 0xB7, 0x39, 0x47, 0x9F, 0x48, 0x19, 0xD3, 0x2F, 0x45, 0x7F, + 0x03, 0xE6, 0x01, 0xB6, 0x1C, 0x6C, 0xC5, 0xDE, 0x86, 0xDA, 0x3A, 0x68, 0xD5, 0x85, 0xC5, 0xFD, + 0x8E, 0x35, 0xC7, 0xDA, 0xF7, 0x9C, 0xC7, 0xDA, 0xE7, 0xB3, 0x31, 0x5E, 0x87, 0x7E, 0x09, 0xEC, + 0x81, 0x7E, 0x09, 0xFA, 0x38, 0xF6, 0xE9, 0xCD, 0x81, 0xE3, 0xD8, 0x89, 0x73, 0xAD, 0xD9, 0xEF, + 0x9D, 0x67, 0x66, 0x31, 0xB5, 0x3D, 0xED, 0x14, 0xDE, 0xE2, 0x3E, 0xD8, 0x8C, 0xC8, 0x81, 0x23, + 0xDD, 0x69, 0xA6, 0x17, 0xD6, 0x7B, 0xD9, 0x79, 0x98, 0x5B, 0xE8, 0x52, 0xE8, 0x2B, 0xC5, 0x75, + 0x4D, 0xDE, 0xA6, 0xDE, 0x76, 0x51, 0xE0, 0x69, 0xF2, 0xDB, 0xEF, 0xF1, 0x57, 0x8E, 0x3C, 0x4F, + 0xAF, 0xEC, 0xAB, 0xCC, 0xC1, 0x48, 0xAF, 0x56, 0x39, 0x31, 0x93, 0x73, 0xC4, 0x37, 0xB1, 0xBD, + 0x41, 0x07, 0x8D, 0x99, 0x8F, 0x9F, 0xFB, 0xDB, 0x38, 0xFF, 0x40, 0xBF, 0x8F, 0x3C, 0xED, 0x76, + 0xA3, 0x1E, 0xFE, 0x91, 0x61, 0x27, 0x0A, 0xFE, 0x65, 0xE8, 0xB8, 0xC8, 0x83, 0xE7, 0xE3, 0xB8, + 0x94, 0x8E, 0x69, 0xA9, 0x7C, 0x02, 0x5E, 0x90, 0xF5, 0x5B, 0xC6, 0x55, 0x7D, 0x70, 0x3F, 0x27, + 0x74, 0x69, 0xF0, 0xF3, 0x2C, 0x17, 0x51, 0xC6, 0xFF, 0x4B, 0x7B, 0xC9, 0x98, 0xDF, 0x5F, 0x4B, + 0x9F, 0x96, 0xCC, 0xBF, 0xE4, 0xFC, 0x1E, 0xBD, 0x2E, 0x7E, 0xDE, 0xD2, 0x6D, 0x2C, 0x51, 0xD4, + 0x5F, 0xF6, 0x43, 0x6C, 0xFC, 0x8C, 0x6B, 0xF4, 0xA5, 0xF7, 0x18, 0x63, 0x7D, 0x4E, 0x9E, 0x4C, + 0xE8, 0xED, 0xBE, 0xDA, 0x3D, 0xBA, 0x96, 0x31, 0x9D, 0x01, 0xB2, 0x04, 0x7E, 0xBB, 0xCC, 0x89, + 0x92, 0xCD, 0xBF, 0xA7, 0xC4, 0x33, 0x99, 0xF0, 0x5D, 0xC4, 0xA7, 0xA0, 0xB6, 0x2E, 0x9C, 0x6F, + 0xF8, 0x3A, 0x46, 0x66, 0x25, 0x17, 0x49, 0x96, 0xE3, 0xAB, 0xA5, 0xCF, 0xA5, 0x82, 0x9F, 0xE8, + 0xA9, 0xA7, 0x9E, 0x3A, 0xE8, 0xF3, 0x4B, 0xFB, 0x68, 0xFC, 0xCC, 0xF1, 0x12, 0x63, 0xB4, 0xFF, + 0xFE, 0xFB, 0x0F, 0xBE, 0x99, 0x5E, 0xA6, 0xC8, 0x03, 0x91, 0x77, 0xA3, 0x8F, 0x47, 0x9E, 0x91, + 0xFE, 0xA1, 0x66, 0xDB, 0xCA, 0xE8, 0x28, 0x5D, 0xFF, 0xF5, 0xAE, 0x77, 0xBD, 0xC1, 0xC7, 0x02, + 0x9B, 0xA6, 0x9E, 0xD1, 0x8B, 0x3B, 0x4B, 0x6B, 0x99, 0xFC, 0x97, 0xF0, 0x5F, 0xDF, 0x2F, 0x7B, + 0xB0, 0x92, 0xBF, 0xA7, 0xBD, 0xF8, 0xB0, 0x81, 0x21, 0x9C, 0x57, 0xCC, 0xD1, 0x27, 0x8E, 0xE1, + 0xA5, 0xB8, 0xE7, 0x73, 0x4E, 0x01, 0x31, 0xDC, 0x3E, 0xFF, 0xA3, 0x0F, 0x8D, 0xCB, 0x7D, 0xD9, + 0xD8, 0xF9, 0xFF, 0x9C, 0x7E, 0xFE, 0x99, 0xE6, 0x2F, 0x6B, 0xC2, 0xFD, 0x85, 0x6B, 0xF4, 0x5A, + 0x87, 0x7E, 0x89, 0xDF, 0x43, 0x6F, 0xF4, 0x8F, 0x99, 0xAE, 0x68, 0xAC, 0x66, 0x67, 0xDE, 0xB1, + 0xDF, 0x3F, 0xE1, 0x09, 0x4F, 0x18, 0xF6, 0xE6, 0x48, 0x83, 0x29, 0x98, 0xCE, 0x5F, 0xD1, 0x85, + 0xE3, 0x2F, 0xAB, 0x7D, 0x48, 0xF1, 0x0C, 0x91, 0x7E, 0x51, 0xC7, 0xA4, 0x75, 0xE0, 0x39, 0x52, + 0xE2, 0x99, 0xE1, 0xDE, 0xCE, 0x9E, 0xB6, 0x61, 0x5F, 0x41, 0xCE, 0x75, 0x3F, 0xC3, 0x56, 0x7D, + 0x70, 0xC6, 0x0B, 0x6F, 0x73, 0x9B, 0xDB, 0x0C, 0xB9, 0xE5, 0x6B, 0xFA, 0xA4, 0x56, 0x79, 0x4C, + 0xAF, 0xF4, 0x13, 0xFB, 0xAF, 0xF2, 0xF4, 0x66, 0x7B, 0x9D, 0xB7, 0xC9, 0x3F, 0x43, 0x0F, 0x45, + 0xFC, 0x8F, 0xEE, 0xD3, 0x2B, 0x6B, 0x95, 0xF0, 0x12, 0xB8, 0x01, 0x3F, 0x17, 0x62, 0xA9, 0x7C, + 0xAC, 0xB6, 0x3B, 0x5E, 0x2A, 0xB5, 0xAF, 0xE4, 0xB7, 0xA1, 0xEB, 0xDB, 0xDE, 0xF6, 0xB6, 0x83, + 0x3D, 0x23, 0xFA, 0x78, 0x8F, 0xED, 0xCB, 0x71, 0x2C, 0xE7, 0xC8, 0x8F, 0xEB, 0xD0, 0x2F, 0x79, + 0x5F, 0xD9, 0xAB, 0xD8, 0xB3, 0x74, 0x9E, 0xEE, 0x9C, 0xE2, 0x71, 0xA8, 0xD0, 0x8C, 0x5C, 0x4E, + 0xCA, 0x77, 0x56, 0xD3, 0x19, 0x68, 0xED, 0x63, 0x1F, 0xC4, 0x66, 0xA6, 0x7C, 0x99, 0x73, 0xE8, + 0xA5, 0x6B, 0x97, 0xDF, 0x59, 0xA3, 0x9C, 0x01, 0x8A, 0xBC, 0x54, 0x3A, 0xDF, 0xA9, 0xB7, 0xBF, + 0x3E, 0x2F, 0xD0, 0xCF, 0x3F, 0xE4, 0x21, 0x0F, 0x19, 0x78, 0x5C, 0x96, 0xA3, 0x2C, 0xAE, 0x5D, + 0xBE, 0x47, 0x15, 0x6E, 0x04, 0x2F, 0xC2, 0x83, 0x5B, 0xCF, 0x89, 0x2D, 0xCD, 0x43, 0x7F, 0x8F, + 0x1D, 0x94, 0xFD, 0x51, 0xE7, 0xA3, 0xE8, 0xB9, 0xB5, 0xB5, 0x10, 0x7D, 0x74, 0xD0, 0xDF, 0x10, + 0x0F, 0xE0, 0xFD, 0x6E, 0x29, 0x63, 0x36, 0x5D, 0xEE, 0x43, 0x3C, 0x31, 0x3A, 0xC6, 0xA8, 0xE7, + 0xCF, 0xF0, 0x5C, 0x69, 0x9D, 0xA2, 0x9F, 0x02, 0xA7, 0xC2, 0x2F, 0x5B, 0xFC, 0x97, 0x4A, 0xF4, + 0xCB, 0xDA, 0xA8, 0x73, 0x63, 0xA7, 0xE8, 0xD0, 0xE3, 0x6F, 0x98, 0xDF, 0xF0, 0x14, 0xF4, 0x4B, + 0x53, 0xF5, 0xB7, 0xB1, 0xB4, 0xE6, 0xF7, 0xD6, 0x7B, 0xF0, 0x1A, 0xF9, 0x47, 0x4B, 0xF4, 0x68, + 0xB5, 0x89, 0x94, 0xFC, 0x34, 0x75, 0xED, 0xF9, 0x9A, 0xD1, 0xC5, 0x94, 0xF2, 0x03, 0x7B, 0x5D, + 0x07, 0x5E, 0x02, 0x7F, 0xC0, 0x3B, 0xC1, 0x89, 0x25, 0xBF, 0x9B, 0x5A, 0xCD, 0xCE, 0x71, 0x41, + 0x3F, 0x8E, 0x2F, 0x01, 0x32, 0x66, 0x16, 0x2F, 0xD2, 0x5A, 0xFC, 0xFB, 0xE2, 0x53, 0xF8, 0xDD, + 0xE0, 0xD3, 0xA7, 0xD8, 0xCF, 0x6C, 0x2C, 0x33, 0x0C, 0xA7, 0x57, 0xF2, 0xCB, 0x82, 0x85, 0x15, + 0x6B, 0x31, 0x07, 0x8B, 0xAB, 0xD0, 0x26, 0x74, 0xAC, 0xD8, 0xE4, 0x22, 0xFE, 0x11, 0x3D, 0x4B, + 0x34, 0xCD, 0x7C, 0x9C, 0xC8, 0xA3, 0x8B, 0xED, 0xB0, 0x34, 0x9E, 0x3D, 0x74, 0x44, 0x7F, 0x28, + 0x6C, 0xCE, 0xBA, 0xC2, 0x4F, 0xCD, 0x73, 0x2D, 0xC6, 0x39, 0x97, 0xE5, 0x2A, 0xE7, 0x33, 0xCE, + 0xB2, 0x87, 0x7F, 0xA8, 0x4C, 0xA5, 0x9B, 0xF7, 0x09, 0x1C, 0x83, 0x5D, 0x15, 0xFD, 0xAA, 0xD3, + 0x6B, 0xBB, 0xD9, 0xE3, 0x7C, 0xED, 0x2A, 0xB6, 0x25, 0xD2, 0x6D, 0xAC, 0xBD, 0xD0, 0x1C, 0x3B, + 0xBF, 0xC6, 0xA2, 0x96, 0x8F, 0x28, 0x3E, 0x5B, 0x3C, 0xC7, 0xCF, 0x29, 0x9D, 0x6A, 0x67, 0x59, + 0x1A, 0x2F, 0xF9, 0xFC, 0xA5, 0x8F, 0xEC, 0xD1, 0xC4, 0x5F, 0xCC, 0xB5, 0x0B, 0xA8, 0x30, 0x76, + 0xCC, 0x61, 0x6C, 0x23, 0xC8, 0x11, 0x9A, 0x9F, 0x11, 0x3B, 0xC4, 0x7C, 0x58, 0xFA, 0x1F, 0xBE, + 0xD0, 0xEC, 0x9F, 0x3A, 0xAB, 0x41, 0x34, 0x98, 0x8A, 0x99, 0xFD, 0xB7, 0xE8, 0xAA, 0x95, 0x77, + 0x89, 0x36, 0xF6, 0xDE, 0x3B, 0x2B, 0xEE, 0xA7, 0x85, 0xFF, 0xE7, 0xDD, 0xEE, 0x76, 0xB7, 0x51, + 0xFA, 0xBB, 0x3D, 0xC0, 0xDF, 0xA3, 0xC7, 0x01, 0xBB, 0x2A, 0xC7, 0xC0, 0x94, 0xBE, 0xC6, 0x7E, + 0x33, 0x7F, 0x89, 0x79, 0x70, 0x7B, 0x84, 0xC7, 0x94, 0xD5, 0xAA, 0xF3, 0x6B, 0xF2, 0x35, 0xAA, + 0x6C, 0xC4, 0xDF, 0x75, 0x94, 0xB8, 0x9F, 0x0A, 0x6B, 0x82, 0xD3, 0x45, 0xB3, 0xC8, 0xFB, 0x6B, + 0xFB, 0xAB, 0xCF, 0x27, 0xE4, 0xB7, 0xD3, 0x4F, 0x3F, 0x7D, 0xC8, 0xB1, 0xEC, 0xE3, 0x32, 0xB7, + 0xD0, 0x4E, 0xE4, 0x75, 0xE4, 0xF6, 0xF8, 0xCC, 0x56, 0x1D, 0x85, 0xCF, 0x6F, 0xE8, 0x8E, 0xBF, + 0x29, 0xBE, 0x60, 0xF1, 0x39, 0x53, 0x4B, 0x0D, 0x2F, 0x65, 0xF2, 0x2C, 0x7A, 0x02, 0xEC, 0x04, + 0x99, 0x5E, 0xAB, 0xA4, 0x17, 0xD4, 0x6B, 0xE6, 0x4F, 0x58, 0xFA, 0x8D, 0xC7, 0x3E, 0xA0, 0xFB, + 0x8B, 0x7E, 0xC2, 0x5B, 0x61, 0x8F, 0xE3, 0xFB, 0xF8, 0xC8, 0xA1, 0x3F, 0xC7, 0x47, 0xCE, 0x75, + 0xDB, 0x73, 0xF2, 0x05, 0x92, 0x77, 0xC9, 0x65, 0xCC, 0x48, 0x8F, 0x9E, 0xB6, 0xBA, 0x7E, 0x84, + 0xC2, 0x7D, 0x75, 0xAE, 0xBA, 0xC6, 0xB0, 0x64, 0xC3, 0x57, 0x45, 0x17, 0xA5, 0xB5, 0x0A, 0x1E, + 0x07, 0xDF, 0x94, 0xDA, 0x30, 0x65, 0xAE, 0x61, 0xBB, 0x7D, 0xCA, 0x53, 0x9E, 0x32, 0xE8, 0x61, + 0xB2, 0x7D, 0xBF, 0x94, 0xBB, 0x35, 0x6B, 0x33, 0xD7, 0xF7, 0xBC, 0xE7, 0x3D, 0x37, 0x62, 0x59, + 0xBD, 0x5D, 0x19, 0x1D, 0x6B, 0x25, 0xE6, 0xBC, 0x42, 0xB6, 0xD1, 0xDC, 0x22, 0x6F, 0x5C, 0x7C, + 0x7E, 0x9C, 0x77, 0xBE, 0x3E, 0x90, 0x89, 0xF0, 0x7B, 0xF2, 0x5C, 0xC7, 0x63, 0x65, 0x8C, 0xBE, + 0xB4, 0xEF, 0xDC, 0x73, 0xCF, 0xDD, 0xA4, 0xDB, 0x5C, 0xD2, 0x26, 0xB7, 0x0E, 0xBC, 0xE4, 0xFA, + 0xA5, 0x31, 0x9C, 0xE4, 0xB6, 0x75, 0xFC, 0x6B, 0x98, 0x23, 0x2A, 0xF1, 0x7C, 0x9B, 0xAC, 0xF8, + 0xDA, 0x66, 0x2D, 0xB1, 0xEE, 0x3D, 0x3F, 0x46, 0xA9, 0xAD, 0x2D, 0xFF, 0x5F, 0xD2, 0x1E, 0xE7, + 0xD7, 0xC4, 0xB6, 0xEB, 0x4C, 0xED, 0xB9, 0x78, 0x49, 0xBF, 0x65, 0x7D, 0xB1, 0xCF, 0x78, 0x1C, + 0xB1, 0xEB, 0x95, 0xB3, 0xB6, 0x44, 0xB9, 0xEF, 0xB4, 0xD3, 0x4E, 0x9B, 0x65, 0x5B, 0xC9, 0xAE, + 0xC1, 0x70, 0xD8, 0xBC, 0xC0, 0x4D, 0x1E, 0xC7, 0x3A, 0x47, 0xBF, 0xA4, 0x7B, 0x70, 0x3F, 0x62, + 0x0B, 0xE0, 0x75, 0xBE, 0x2E, 0x6B, 0xBE, 0x12, 0x7E, 0x06, 0x2E, 0xD8, 0x15, 0xDB, 0xE8, 0xF1, + 0xC7, 0x1F, 0x3F, 0xF0, 0xF8, 0x56, 0xFD, 0xC8, 0xD8, 0x7B, 0xDA, 0x88, 0x3E, 0xAD, 0xF5, 0xAC, + 0xD8, 0xC8, 0x87, 0xD5, 0x0F, 0x70, 0xA6, 0xD6, 0x00, 0x58, 0xB3, 0x97, 0x6E, 0xFE, 0x7D, 0xD6, + 0x89, 0x9F, 0x51, 0x89, 0xBC, 0xA9, 0x79, 0x20, 0xDD, 0x5C, 0x69, 0xBE, 0x3A, 0xAF, 0x93, 0xBE, + 0x8E, 0xFD, 0x0B, 0xDA, 0x3B, 0xCE, 0x9C, 0x93, 0xEB, 0xCF, 0xDB, 0xCA, 0x7C, 0x29, 0xE5, 0x20, + 0x6F, 0x5D, 0x73, 0xEA, 0x0F, 0x7D, 0x43, 0x16, 0x90, 0xFF, 0x52, 0xA4, 0xCB, 0x94, 0xD2, 0xA2, + 0x5F, 0xF2, 0x75, 0xA5, 0x9C, 0xB4, 0xCC, 0x0B, 0xCF, 0x51, 0x55, 0xC2, 0x4F, 0xFA, 0x0C, 0x9D, + 0x05, 0xBA, 0xCA, 0x88, 0x7B, 0x33, 0x9E, 0xA1, 0xF5, 0x40, 0x61, 0x1C, 0xF0, 0x17, 0xD4, 0x59, + 0x32, 0x35, 0x9C, 0xD2, 0x8B, 0x97, 0x32, 0xFD, 0x60, 0x1C, 0x3F, 0x78, 0x91, 0x72, 0x2E, 0xF6, + 0xEE, 0x51, 0xBE, 0x8E, 0xFD, 0xB7, 0xF8, 0x27, 0xFA, 0x3E, 0x95, 0xE9, 0xE4, 0x5A, 0xC7, 0x34, + 0xD2, 0x8F, 0x33, 0xDD, 0x25, 0x3F, 0x30, 0xDF, 0x5C, 0xB6, 0x71, 0xFD, 0x48, 0xB6, 0xEF, 0x53, + 0xD9, 0x9B, 0x4B, 0x7B, 0x68, 0xEF, 0x5C, 0x93, 0x1F, 0x0F, 0xFC, 0x88, 0x5C, 0x06, 0x9C, 0xBF, + 0x1D, 0xE7, 0x56, 0xB6, 0xAF, 0x46, 0x7E, 0x1E, 0xC7, 0x1C, 0x5F, 0x43, 0xF4, 0x4B, 0x63, 0x6D, + 0x1B, 0x6B, 0xAB, 0xC7, 0xF1, 0xE3, 0x7F, 0x84, 0x2D, 0x2E, 0xF2, 0x38, 0xDA, 0xE1, 0x67, 0x26, + 0x45, 0x5A, 0xEA, 0x73, 0xE6, 0x1E, 0x31, 0x37, 0x3A, 0xDB, 0xA2, 0x85, 0x56, 0x19, 0x8F, 0xF6, + 0xF1, 0x87, 0x4F, 0xB2, 0x36, 0xE1, 0xBD, 0xBD, 0xB6, 0xFC, 0x96, 0xBA, 0x04, 0x5E, 0x8A, 0xFD, + 0x14, 0x5E, 0x6A, 0x6D, 0xA7, 0xE8, 0x87, 0xBF, 0x1D, 0x76, 0x8C, 0x1E, 0xBD, 0x9C, 0xD6, 0x36, + 0x7E, 0x3B, 0xF8, 0xC6, 0xE3, 0xB7, 0xC7, 0x38, 0x96, 0xD6, 0x50, 0xCB, 0x98, 0x2C, 0x89, 0x97, + 0xDC, 0xEF, 0x54, 0x9F, 0x71, 0x4F, 0xB5, 0x63, 0x09, 0xFD, 0x12, 0xF7, 0x50, 0x9E, 0x3A, 0x62, + 0xB2, 0xC6, 0x62, 0x12, 0x63, 0x55, 0xFC, 0xDE, 0x51, 0x47, 0x1D, 0x95, 0xC6, 0x2D, 0xB4, 0xD0, + 0x4A, 0xD7, 0x91, 0xBE, 0xF0, 0xCE, 0xE3, 0x8E, 0x3B, 0x6E, 0x31, 0xBC, 0xE4, 0x7E, 0x9A, 0x94, + 0x37, 0xBF, 0xF9, 0xCD, 0x1B, 0x63, 0x94, 0xE9, 0xFD, 0x1D, 0x8F, 0xBB, 0xBC, 0xA1, 0x6B, 0xF4, + 0x18, 0x8A, 0x37, 0x6F, 0x29, 0x25, 0x9F, 0x3A, 0x7F, 0xCF, 0x9A, 0x65, 0x4D, 0xC9, 0x07, 0xDD, + 0xF3, 0x04, 0x44, 0xFE, 0x11, 0xC7, 0x48, 0x67, 0x88, 0x73, 0x4D, 0xBC, 0x1F, 0x7C, 0x53, 0xBA, + 0xF2, 0x96, 0x58, 0xB9, 0x92, 0x3D, 0x8E, 0x6B, 0xCF, 0xDD, 0x83, 0x1E, 0x57, 0xE3, 0xEE, 0x3E, + 0xAE, 0x25, 0xBC, 0x24, 0x1E, 0xA8, 0xEF, 0xA1, 0xB3, 0x61, 0xCE, 0x45, 0x9F, 0xAF, 0xB1, 0xF9, + 0x3C, 0x96, 0x9F, 0x89, 0xB6, 0x09, 0xCB, 0xC9, 0x9E, 0xCA, 0x6B, 0xED, 0x0C, 0xBE, 0x4C, 0x67, + 0xEA, 0x98, 0x18, 0x7B, 0xB3, 0xC7, 0x55, 0x49, 0xAF, 0x3B, 0xB5, 0xB4, 0xE4, 0x17, 0xD2, 0x9C, + 0xA3, 0xDD, 0xD8, 0x55, 0x54, 0x62, 0x6E, 0x94, 0x88, 0x4D, 0x5C, 0x4E, 0x41, 0x27, 0x95, 0xE5, + 0x41, 0x28, 0xD9, 0xEF, 0xF4, 0x39, 0xE3, 0x8C, 0xEC, 0xC3, 0xB9, 0x3A, 0x4E, 0x8F, 0x25, 0xF4, + 0x4B, 0x63, 0x78, 0x89, 0xF6, 0xB3, 0xE6, 0xB9, 0x27, 0x7B, 0xBD, 0xFB, 0x2F, 0x4D, 0xDD, 0xB7, + 0x68, 0x37, 0xFB, 0x1F, 0x32, 0x08, 0xF2, 0x83, 0xF3, 0x4E, 0x6F, 0x6F, 0x0F, 0x5E, 0xF2, 0xBE, + 0xC2, 0xE7, 0x89, 0xAF, 0xC8, 0xCE, 0xE5, 0xF2, 0xB6, 0x67, 0xF3, 0x8C, 0xF9, 0x45, 0xDC, 0x1E, + 0x3E, 0x77, 0xF2, 0xFD, 0xCC, 0xEC, 0x06, 0x19, 0x36, 0x2E, 0x15, 0xDA, 0xC4, 0x78, 0x80, 0x39, + 0xDD, 0x6F, 0xB9, 0xF5, 0xBC, 0x69, 0x9F, 0xFB, 0xFA, 0x0E, 0xF6, 0x46, 0x64, 0xD7, 0x31, 0xFD, + 0xCC, 0x18, 0x7F, 0x71, 0x5F, 0x23, 0x6C, 0xA3, 0xF0, 0x76, 0xD1, 0x08, 0x7E, 0x92, 0xB5, 0x43, + 0xFF, 0x8F, 0x3C, 0x8F, 0xBE, 0x3D, 0xF9, 0xC9, 0x4F, 0xDE, 0x14, 0x07, 0x31, 0xB6, 0x5F, 0x8F, + 0xE1, 0x25, 0x64, 0x42, 0x62, 0x98, 0xC8, 0x65, 0x10, 0x69, 0x34, 0x47, 0xBF, 0xA9, 0xBA, 0x44, + 0xFE, 0xA5, 0xD8, 0x07, 0xE1, 0xA5, 0x52, 0xFB, 0x5C, 0x3F, 0xEC, 0xF8, 0xFD, 0x31, 0x8F, 0x79, + 0xCC, 0x90, 0x1F, 0xC6, 0xE9, 0xD2, 0x62, 0xB3, 0x62, 0x8D, 0x32, 0x17, 0x78, 0x2E, 0xF3, 0x16, + 0xDD, 0x8D, 0xBE, 0x9F, 0xCD, 0xDB, 0xCB, 0x43, 0xBF, 0xE4, 0xF2, 0x32, 0x6B, 0xB3, 0x44, 0xE7, + 0x29, 0x7A, 0x3D, 0x9D, 0x37, 0x88, 0xBF, 0x40, 0x96, 0xA7, 0xA6, 0xB4, 0x4F, 0xFB, 0x3E, 0x24, + 0x9D, 0xAD, 0xCE, 0xE1, 0x68, 0xC5, 0x71, 0x63, 0x36, 0x18, 0xD6, 0x14, 0xBC, 0x93, 0x39, 0x96, + 0xE9, 0x0B, 0x33, 0xF9, 0xB4, 0xB5, 0xDF, 0x14, 0x6C, 0xBF, 0x8E, 0x97, 0xC6, 0x7C, 0x70, 0x7C, + 0x2D, 0x2B, 0x3F, 0x0F, 0xF1, 0x14, 0x9E, 0xFF, 0xB9, 0xE5, 0xB9, 0xA5, 0xF6, 0x6B, 0xBF, 0xA2, + 0xBF, 0xE8, 0x9B, 0xB3, 0xE7, 0xD6, 0xEC, 0xE9, 0xAE, 0x87, 0x62, 0x8F, 0x20, 0x9F, 0x88, 0xEB, + 0x85, 0xB2, 0x76, 0x94, 0x68, 0x18, 0xF9, 0x8C, 0xFB, 0xF2, 0x13, 0x2B, 0x43, 0xCC, 0x51, 0xF4, + 0xA9, 0xAE, 0xD9, 0xD0, 0x35, 0x67, 0xF8, 0x0D, 0x3A, 0x52, 0xF4, 0xB9, 0xDC, 0x4F, 0x71, 0x41, + 0xB5, 0xFC, 0x1D, 0xB5, 0xC2, 0xEF, 0x94, 0xBB, 0x86, 0xB5, 0xCB, 0xBD, 0x85, 0xCF, 0xC4, 0x1B, + 0x5A, 0xF3, 0xF7, 0x44, 0xDA, 0x42, 0x4F, 0x70, 0xA7, 0xF2, 0x93, 0xE8, 0x79, 0x91, 0x46, 0x3D, + 0xED, 0xED, 0xF1, 0x5F, 0x42, 0xC7, 0x83, 0xDE, 0x57, 0x7C, 0x6C, 0x2C, 0x8F, 0x96, 0xB7, 0x87, + 0x7C, 0x4D, 0x54, 0xAD, 0xB1, 0x98, 0x4B, 0x3F, 0xDB, 0x8F, 0xF5, 0x39, 0x76, 0x6A, 0xE4, 0x27, + 0xDF, 0xAF, 0xB2, 0xF9, 0x36, 0x05, 0x2F, 0xD5, 0x0A, 0xFF, 0xE7, 0x5E, 0x1E, 0x1F, 0xDA, 0xE3, + 0x3F, 0x52, 0xF2, 0xCF, 0x05, 0x93, 0x40, 0xF3, 0xCC, 0x47, 0xA3, 0x57, 0xBF, 0x14, 0x7F, 0x87, + 0xCC, 0x25, 0x7B, 0x5C, 0x94, 0xAD, 0x4A, 0xFC, 0xDC, 0x7D, 0x1E, 0xD0, 0x2F, 0x21, 0x0F, 0xC6, + 0xFC, 0xF6, 0x3D, 0x73, 0x2A, 0xAE, 0x5F, 0xD9, 0x0B, 0xC8, 0x7B, 0x92, 0xAD, 0xC9, 0x68, 0x67, + 0xF5, 0x76, 0xE9, 0xBD, 0xEB, 0xC9, 0x88, 0xBB, 0x59, 0x2A, 0xBE, 0x48, 0x6D, 0x24, 0xAE, 0x85, + 0xB9, 0xA3, 0x67, 0xB4, 0xE4, 0x3B, 0xF2, 0xFF, 0x81, 0xA7, 0x3D, 0x97, 0x6C, 0x26, 0x17, 0xC4, + 0xB8, 0x88, 0xD8, 0x06, 0x7F, 0xAF, 0xB5, 0xC5, 0xFD, 0x88, 0x89, 0xF5, 0x71, 0x5A, 0x02, 0x2B, + 0x2D, 0x81, 0x97, 0x54, 0xDC, 0xCE, 0x4E, 0x1E, 0x2F, 0xE7, 0xC1, 0x51, 0x8F, 0xE9, 0x38, 0xD9, + 0x75, 0x78, 0xC4, 0x75, 0xE9, 0x1E, 0x59, 0x9E, 0xB6, 0x0C, 0xA3, 0x4B, 0xBE, 0x25, 0xBF, 0x17, + 0x63, 0x87, 0x3D, 0x54, 0x71, 0x28, 0x53, 0xFD, 0x29, 0x96, 0xC4, 0x4B, 0xEA, 0xB3, 0x9F, 0xB9, + 0xC5, 0xDA, 0xD4, 0x73, 0x4A, 0xFB, 0x5B, 0xED, 0xB3, 0xAC, 0xC0, 0x1F, 0xA5, 0x5B, 0x1A, 0x8B, + 0xBD, 0xF6, 0xF5, 0x26, 0xFB, 0x14, 0x15, 0x1C, 0x87, 0x8D, 0x45, 0xCF, 0x9C, 0x42, 0xBF, 0xD8, + 0x27, 0xD6, 0x14, 0x67, 0xB2, 0x82, 0x63, 0x5B, 0xEC, 0xAB, 0x2D, 0xC5, 0x65, 0x70, 0xF0, 0x9D, + 0xF4, 0x11, 0x5A, 0x17, 0x63, 0xF6, 0x5F, 0x9F, 0x77, 0xC4, 0xEC, 0x12, 0x4F, 0x21, 0xBB, 0x47, + 0x4B, 0xFF, 0xB2, 0xFE, 0xFA, 0x5E, 0xCC, 0x5A, 0x82, 0xB7, 0xC3, 0x47, 0xB3, 0x39, 0xDF, 0xB2, + 0x5F, 0xD0, 0x4E, 0x7C, 0x5C, 0xF1, 0x03, 0x41, 0xC7, 0x44, 0x29, 0xE5, 0x0E, 0xD5, 0xBA, 0x88, + 0x3A, 0xA8, 0xC8, 0x5F, 0x3C, 0x97, 0x2F, 0xF1, 0x40, 0xF4, 0x7D, 0x6C, 0x9F, 0x72, 0xBA, 0xB9, + 0xDD, 0x8E, 0xB9, 0xA2, 0xBD, 0x8B, 0x71, 0xAD, 0x9D, 0xDB, 0x99, 0xD1, 0x2B, 0xDB, 0xEF, 0xB9, + 0x07, 0x3A, 0x62, 0x7C, 0xF0, 0xF4, 0x4C, 0xE7, 0x0F, 0x59, 0xCD, 0xDA, 0x19, 0xF1, 0x12, 0xF6, + 0x38, 0xCF, 0xE7, 0xE6, 0x98, 0x25, 0xF3, 0x0F, 0x1A, 0x2B, 0x63, 0xFA, 0x25, 0xAD, 0x3F, 0xDA, + 0x42, 0x5F, 0xC8, 0x13, 0xED, 0x7D, 0x2F, 0xCD, 0x1D, 0x61, 0x6D, 0xF1, 0x34, 0xEC, 0x31, 0xD8, + 0xD5, 0x34, 0xF6, 0x2D, 0xB2, 0x85, 0x3E, 0x27, 0x66, 0xE6, 0xD1, 0x8F, 0x7E, 0x74, 0xEA, 0x3B, + 0xED, 0x75, 0x1D, 0xFE, 0x4B, 0x11, 0x2F, 0xF5, 0x56, 0x97, 0xA1, 0xB5, 0xFF, 0x83, 0x97, 0x84, + 0x49, 0x4A, 0x7D, 0x6E, 0x95, 0xEF, 0xB4, 0x56, 0xF4, 0x7D, 0xD9, 0xF4, 0xC7, 0xF2, 0x1C, 0x39, + 0xFF, 0xF0, 0x9C, 0x7A, 0xAC, 0x73, 0xCF, 0x57, 0xE1, 0xED, 0xEA, 0xC5, 0x4B, 0xA2, 0x3D, 0xBA, + 0x45, 0xC6, 0x05, 0x9B, 0xA6, 0x9E, 0x9B, 0xB5, 0x2F, 0xAE, 0x05, 0x9F, 0xFF, 0xEE, 0xBF, 0x06, + 0x0F, 0x26, 0x6E, 0x72, 0x4A, 0x29, 0xAD, 0x61, 0xEE, 0xC7, 0x7D, 0x9D, 0x87, 0x8C, 0x61, 0x62, + 0xFF, 0x7F, 0x36, 0xF7, 0x32, 0xF9, 0x53, 0x65, 0x4C, 0x2F, 0xAD, 0xFD, 0x05, 0x39, 0xCE, 0x65, + 0x68, 0xF7, 0xC1, 0x98, 0x5B, 0x97, 0xF4, 0x5F, 0xD2, 0x2B, 0xFE, 0x73, 0xB5, 0xF9, 0xE6, 0x6D, + 0xD7, 0x39, 0x47, 0xBC, 0x82, 0xB3, 0xC6, 0xF8, 0x97, 0x7F, 0xAE, 0x7D, 0x93, 0x57, 0xCE, 0x26, + 0x26, 0x06, 0x19, 0xDC, 0x30, 0x77, 0x5F, 0x5E, 0x1A, 0x2F, 0x45, 0x1B, 0xF8, 0x03, 0x1E, 0xF0, + 0x80, 0x8D, 0xFD, 0x22, 0x3B, 0x7F, 0xB1, 0xB5, 0x8D, 0x6E, 0xDB, 0x80, 0x76, 0x92, 0x27, 0xA6, + 0xC6, 0xA2, 0x44, 0xBC, 0x34, 0xC5, 0x66, 0x11, 0xE7, 0xB8, 0xD6, 0x94, 0xF4, 0xD5, 0x73, 0x8B, + 0xF3, 0x14, 0x68, 0x87, 0x6C, 0x88, 0x3E, 0xC2, 0xF7, 0xF4, 0xD2, 0xBA, 0xD5, 0x1E, 0xE6, 0x76, + 0x25, 0x7C, 0xEF, 0x3F, 0xF1, 0x89, 0x4F, 0x6C, 0xDC, 0xBB, 0xE5, 0xF9, 0x59, 0x7F, 0x7D, 0xFE, + 0xB3, 0xDF, 0xA1, 0x17, 0xF2, 0xFC, 0xC6, 0x3D, 0x63, 0xA2, 0xEF, 0xA2, 0x9B, 0x40, 0xE7, 0xBA, + 0x7B, 0xF7, 0xEE, 0xE1, 0xDE, 0x35, 0x5D, 0x6B, 0x26, 0x8F, 0x65, 0x78, 0x44, 0x05, 0x3F, 0x4D, + 0xE2, 0xB6, 0xE2, 0x33, 0x6B, 0x6D, 0x12, 0xDF, 0x61, 0x9E, 0x91, 0x4F, 0x33, 0xC6, 0x55, 0xD4, + 0xB0, 0x5C, 0xFC, 0x3C, 0xF3, 0xDB, 0x41, 0xCE, 0x21, 0xD7, 0xA2, 0xE2, 0x3B, 0xA9, 0xCE, 0xEB, + 0x6A, 0x76, 0x91, 0xC8, 0x5F, 0xF4, 0x3F, 0xF9, 0x2F, 0xE1, 0xEF, 0xAD, 0x36, 0x4C, 0x5D, 0x73, + 0x2A, 0x63, 0x78, 0xC9, 0xB1, 0x31, 0xB1, 0x53, 0x7C, 0x37, 0x2B, 0xD9, 0xDE, 0xE0, 0xFE, 0x79, + 0xF7, 0xBB, 0xDF, 0xFD, 0x86, 0xFC, 0x89, 0xD2, 0x2F, 0x96, 0x68, 0x9C, 0x15, 0xFC, 0xCA, 0x88, + 0x5F, 0x2C, 0xF9, 0x2F, 0xD6, 0xF6, 0xAC, 0x1E, 0xBC, 0x94, 0xCD, 0x7F, 0xEE, 0xE5, 0x7B, 0xBD, + 0xEF, 0xEB, 0x2D, 0xBC, 0x32, 0x7B, 0x4F, 0xBC, 0x13, 0x7E, 0xBC, 0x7E, 0xF6, 0x81, 0xF3, 0x29, + 0x9F, 0x67, 0xB5, 0xAA, 0xE2, 0xF3, 0x0F, 0x3E, 0x1F, 0x63, 0x46, 0x5C, 0x7F, 0x13, 0xE7, 0x9B, + 0xF3, 0x72, 0xE6, 0x17, 0xF6, 0x5E, 0xEC, 0x22, 0x3A, 0x4F, 0x69, 0x0A, 0x66, 0xD2, 0xF7, 0x24, + 0xD3, 0x88, 0x86, 0xB2, 0xC7, 0x8D, 0xD1, 0x2C, 0xA3, 0x9B, 0xF2, 0x44, 0x51, 0xB9, 0x57, 0x2F, + 0x5E, 0x2A, 0xD1, 0xCE, 0xF1, 0x12, 0x7A, 0xAB, 0x6C, 0xDE, 0x97, 0x6A, 0xF4, 0x5F, 0x62, 0x6F, + 0x10, 0x7F, 0x8B, 0x63, 0x58, 0x6A, 0x4F, 0xB6, 0x06, 0xA0, 0xBD, 0xEF, 0x2F, 0xAE, 0x5B, 0x25, + 0xFF, 0xDF, 0xDC, 0x3D, 0x5C, 0x75, 0xC9, 0x7C, 0x95, 0xFA, 0x1D, 0x36, 0x92, 0x96, 0xF1, 0xD5, + 0x7C, 0x54, 0xAE, 0x60, 0xF1, 0x34, 0xB7, 0xEF, 0xC7, 0xB6, 0xF8, 0x1A, 0x51, 0x3C, 0x08, 0x9F, + 0xB1, 0xD7, 0xD3, 0x17, 0xF6, 0x3E, 0x3F, 0x57, 0x61, 0x6A, 0x1F, 0x28, 0xEB, 0x3A, 0x0F, 0x85, + 0x7C, 0x9C, 0x7A, 0x46, 0x3C, 0x8B, 0x30, 0xB6, 0xC1, 0xDF, 0xC7, 0xF5, 0xAE, 0xB3, 0xCE, 0x29, + 0xD8, 0x22, 0x33, 0x5F, 0xA9, 0x31, 0x5D, 0x78, 0x0D, 0x2F, 0x4D, 0xC1, 0xCC, 0x71, 0x4F, 0x27, + 0x5E, 0x94, 0x35, 0xC5, 0x9E, 0xE1, 0x73, 0x2C, 0xAE, 0xC5, 0x56, 0x9F, 0x12, 0xF8, 0x89, 0xEF, + 0xCF, 0xC4, 0x8E, 0x62, 0x47, 0x54, 0x1F, 0x65, 0xC3, 0xA9, 0xE9, 0x23, 0x5C, 0xFE, 0x7F, 0xD8, + 0xC3, 0x1E, 0xD6, 0x85, 0xE3, 0xE2, 0x5C, 0x8C, 0x18, 0x85, 0xA2, 0xFC, 0xC6, 0xD8, 0xD0, 0xA3, + 0x2E, 0xBD, 0x65, 0xAE, 0x88, 0xEF, 0x10, 0x4B, 0x4C, 0x5C, 0x38, 0x73, 0xDA, 0x7D, 0xBF, 0x7A, + 0xDA, 0xE7, 0xD7, 0xAE, 0xA3, 0x40, 0xAE, 0x60, 0xBC, 0x7D, 0x6E, 0xB6, 0xF0, 0x60, 0x5E, 0x39, + 0x57, 0x86, 0x31, 0xD5, 0x18, 0xE8, 0x39, 0xA5, 0xBC, 0x33, 0x63, 0x3A, 0x11, 0xFD, 0x16, 0x99, + 0x1A, 0xFE, 0xC9, 0x1E, 0xE1, 0x3E, 0xBF, 0x2E, 0x3B, 0xD7, 0x78, 0x89, 0x7F, 0xB7, 0x86, 0x97, + 0xE6, 0xC6, 0x7B, 0xB7, 0x9E, 0xB7, 0xCB, 0xEB, 0x43, 0x1F, 0xFA, 0xD0, 0xC1, 0x57, 0xC0, 0x79, + 0x59, 0x6D, 0x2F, 0x70, 0x1A, 0xC2, 0x7B, 0xB0, 0x25, 0x2A, 0xB6, 0xCE, 0xCF, 0xDB, 0x28, 0x15, + 0xCD, 0x49, 0x0A, 0x79, 0xFC, 0x6B, 0xB4, 0xD3, 0x9E, 0x35, 0x15, 0x2F, 0xF9, 0xFC, 0xF7, 0x35, + 0xA0, 0xBD, 0xDE, 0xED, 0x71, 0xB5, 0xF8, 0xF7, 0x12, 0xBF, 0xF4, 0xB1, 0x44, 0xAE, 0xC1, 0x76, + 0xB0, 0x84, 0xCC, 0xE5, 0xFA, 0x25, 0x5E, 0x91, 0xEF, 0x25, 0x73, 0xC5, 0xF6, 0xC6, 0x2A, 0xFE, + 0xE1, 0xF1, 0xF3, 0xF0, 0x10, 0x95, 0x5A, 0x5E, 0x92, 0x31, 0x5A, 0xFA, 0xFF, 0xDD, 0x07, 0x2C, + 0xF3, 0xB1, 0x18, 0x5B, 0xAF, 0xE2, 0x85, 0xFA, 0x6C, 0x2A, 0x5E, 0x2A, 0xF9, 0x62, 0x09, 0x2F, + 0xB1, 0x5E, 0x9D, 0xF7, 0x8E, 0x8D, 0xAB, 0xDB, 0xEC, 0x1C, 0x2F, 0xB5, 0xF0, 0x89, 0xB8, 0x57, + 0xD4, 0xE8, 0x49, 0xAE, 0x02, 0xF5, 0x5D, 0xBA, 0xC0, 0x29, 0xB1, 0x23, 0xEB, 0xC2, 0x4B, 0xBE, + 0xC7, 0x32, 0xFF, 0xB2, 0xB1, 0x8D, 0x36, 0x3A, 0x97, 0xA3, 0xC9, 0x35, 0xE3, 0xE7, 0x79, 0xE9, + 0x35, 0xEA, 0x4E, 0x9D, 0xE7, 0x49, 0xD6, 0x40, 0x2E, 0x25, 0xA7, 0x11, 0xFE, 0xB5, 0x4B, 0x94, + 0xA5, 0xF1, 0x92, 0xF7, 0x17, 0x9F, 0x11, 0xCF, 0xB3, 0x2A, 0xDF, 0x8F, 0xF8, 0xFC, 0x29, 0x78, + 0xC9, 0xF1, 0x67, 0x5C, 0xF3, 0xA5, 0x75, 0xE6, 0xEB, 0x5E, 0x78, 0x69, 0x0E, 0xDD, 0xE2, 0x5C, + 0x26, 0xF6, 0x81, 0xBD, 0x15, 0x7F, 0x5B, 0xF7, 0xBF, 0x98, 0x8A, 0xC7, 0xD5, 0x77, 0x15, 0xCE, + 0x19, 0x64, 0x6D, 0x64, 0x98, 0x24, 0xEB, 0xB3, 0x78, 0x1D, 0x95, 0xB3, 0xE6, 0x14, 0x67, 0x1E, + 0xE5, 0x93, 0xD6, 0xFE, 0x66, 0xEB, 0x5C, 0xF6, 0x38, 0xC5, 0x68, 0xF4, 0xF8, 0xDE, 0xFB, 0x7E, + 0xE1, 0xBE, 0xCA, 0xD1, 0xB7, 0xB5, 0xB7, 0xF8, 0x3E, 0xCA, 0x35, 0xBE, 0xDA, 0x47, 0x1E, 0x79, + 0x64, 0x75, 0x2F, 0x2D, 0x55, 0xF8, 0x1C, 0xB9, 0xE3, 0x55, 0x5A, 0xE5, 0x92, 0xB1, 0x71, 0x07, + 0x17, 0xD2, 0x26, 0xF2, 0xDF, 0xD7, 0x62, 0x81, 0x4A, 0x78, 0x29, 0xF2, 0x18, 0x5E, 0x59, 0x0B, + 0x31, 0x9F, 0x40, 0x86, 0x07, 0x7A, 0xE6, 0xE3, 0x18, 0x5E, 0x72, 0xDF, 0x5C, 0xEC, 0x52, 0x8A, + 0xFF, 0xA1, 0xB4, 0xC8, 0xCF, 0xFA, 0x1F, 0x18, 0x81, 0x3C, 0x57, 0xE4, 0x6E, 0x6A, 0x95, 0x27, + 0x9C, 0x57, 0xA2, 0x73, 0x96, 0x6C, 0x5D, 0xF2, 0xFF, 0x9A, 0x8B, 0x97, 0x62, 0x9B, 0x85, 0x97, + 0xA2, 0xFF, 0x52, 0xCF, 0x1A, 0xF0, 0xEF, 0xEB, 0x95, 0xB5, 0xC4, 0x5A, 0xCF, 0x62, 0x46, 0xE6, + 0xF0, 0x12, 0xE6, 0xAE, 0xF3, 0xF9, 0x12, 0x2E, 0xD1, 0x7B, 0xD9, 0xA4, 0x55, 0xE1, 0x99, 0xEC, + 0x9F, 0xA2, 0x5B, 0x29, 0x6F, 0xE0, 0x58, 0x89, 0xFD, 0xD9, 0xB5, 0x6B, 0xD7, 0x80, 0x25, 0x14, + 0x1F, 0x27, 0x1B, 0xC5, 0x98, 0xFC, 0x5B, 0x92, 0xCF, 0x18, 0x8F, 0x5E, 0xFF, 0xA5, 0x1A, 0x86, + 0xE1, 0x3D, 0xF7, 0x73, 0xBC, 0xD4, 0x8B, 0x47, 0x34, 0xF7, 0xE4, 0xEF, 0x5D, 0x6B, 0x47, 0xAD, + 0x6D, 0xD9, 0xFF, 0xD0, 0x2F, 0x45, 0x5E, 0xB0, 0x44, 0x5D, 0x2A, 0x5F, 0x65, 0xF4, 0x5F, 0xD2, + 0x3C, 0xCF, 0xF2, 0x58, 0x89, 0x9F, 0x88, 0xC6, 0x60, 0x1D, 0x6C, 0xFC, 0x8A, 0xB1, 0xA7, 0xF8, + 0xBA, 0x28, 0xC5, 0x8E, 0x32, 0xD7, 0xF9, 0x1E, 0x7A, 0x5A, 0xE2, 0x9C, 0xE8, 0x8B, 0xCA, 0x1C, + 0x19, 0x72, 0x1D, 0xFA, 0x25, 0xF5, 0x9B, 0x5C, 0xD7, 0xCA, 0x07, 0x1B, 0xE5, 0xC9, 0xAC, 0x0D, + 0xFE, 0x3E, 0xD3, 0x17, 0xA8, 0x9F, 0x6F, 0x7C, 0xE3, 0x1B, 0x37, 0xF1, 0x6B, 0xAE, 0xDD, 0xF7, + 0xAF, 0xA6, 0x6B, 0xD1, 0xF8, 0xD0, 0xD7, 0xB9, 0xFA, 0xA5, 0xD8, 0x4E, 0xF4, 0x4B, 0xAC, 0x09, + 0xF4, 0x19, 0x8C, 0x2F, 0xF1, 0x41, 0xE4, 0x12, 0x52, 0xE5, 0xBD, 0x6A, 0x7C, 0x5F, 0xAA, 0xE0, + 0x63, 0x5E, 0xC1, 0x9A, 0xE8, 0x32, 0xE5, 0x1F, 0x1C, 0xD7, 0x6B, 0xC6, 0xA7, 0x45, 0x1B, 0x6C, + 0x3E, 0xE8, 0xA6, 0x62, 0x8C, 0xD2, 0xDC, 0xA2, 0xFE, 0x93, 0xCB, 0xCA, 0xFD, 0xBD, 0x7B, 0x30, + 0x89, 0xB7, 0x17, 0x7F, 0x74, 0xD9, 0x73, 0xB8, 0xEF, 0x94, 0x7C, 0x78, 0xD9, 0xB8, 0x90, 0xA3, + 0x53, 0xB1, 0x2D, 0x1E, 0x77, 0x51, 0xB2, 0x71, 0x39, 0x1D, 0xC9, 0x25, 0xF0, 0xD2, 0x97, 0xBE, + 0x74, 0x54, 0xAF, 0x34, 0xF6, 0x99, 0x63, 0x38, 0x0A, 0xB8, 0x80, 0xD8, 0x7B, 0x72, 0x75, 0x66, + 0x3C, 0xA3, 0xC4, 0xFB, 0x6A, 0xFC, 0x30, 0xC3, 0x4B, 0xEB, 0xB4, 0xC7, 0xD1, 0x16, 0xD7, 0xFF, + 0x43, 0x27, 0xE5, 0xAC, 0x89, 0xF2, 0x42, 0x8D, 0xE7, 0x93, 0x7F, 0x00, 0x9F, 0x1D, 0x74, 0x8C, + 0x9C, 0xFF, 0xD8, 0xEA, 0x63, 0xE0, 0x63, 0x82, 0x0D, 0x5C, 0xF6, 0x9C, 0x2C, 0xBE, 0x7B, 0x2E, + 0x5E, 0x2A, 0x95, 0xB9, 0xFE, 0x4B, 0xEE, 0x4B, 0x27, 0x9C, 0x07, 0xAD, 0x5D, 0x4F, 0x97, 0xF5, + 0xB9, 0xB5, 0x44, 0x19, 0x1C, 0x3A, 0x11, 0x6F, 0x1F, 0xE5, 0xCB, 0xD2, 0x3C, 0xD3, 0xFE, 0x85, + 0xFF, 0x1F, 0x76, 0x6D, 0xC6, 0xB7, 0xB4, 0x06, 0x5A, 0xED, 0xA7, 0x71, 0x2E, 0xA0, 0x53, 0x24, + 0x3E, 0x0E, 0x7F, 0xEF, 0xD8, 0x86, 0x1A, 0x5E, 0x2A, 0xAD, 0x93, 0x29, 0x78, 0xC9, 0xDB, 0x95, + 0x15, 0xEE, 0xE7, 0xF6, 0xB8, 0xDE, 0x2A, 0x7F, 0xEF, 0x1A, 0x5E, 0x1A, 0xD3, 0x39, 0xC5, 0xEF, + 0x52, 0xA0, 0xB9, 0xCE, 0x67, 0x89, 0x73, 0x6A, 0x6E, 0x5D, 0x02, 0x2F, 0xF9, 0xBE, 0x5F, 0xC3, + 0x4B, 0x3E, 0x96, 0xDE, 0x7E, 0x74, 0xCE, 0x3A, 0x57, 0x21, 0x9E, 0x01, 0x1B, 0xDB, 0x12, 0x71, + 0x38, 0xB9, 0x03, 0xB0, 0xD3, 0x2B, 0x0E, 0xC6, 0x7D, 0x5B, 0x5A, 0xCF, 0xB7, 0x28, 0xD1, 0x7D, + 0x1D, 0xF9, 0xBD, 0xC1, 0x4B, 0x9E, 0x63, 0x2A, 0x7B, 0x6E, 0xBC, 0xCE, 0xFA, 0x1E, 0xBF, 0x23, + 0xBC, 0x14, 0xB1, 0x41, 0x16, 0x23, 0xEE, 0xEB, 0xCD, 0x79, 0x93, 0xF0, 0x92, 0xEB, 0xF7, 0xE6, + 0x16, 0x74, 0xB6, 0xE8, 0xD3, 0xC8, 0x7D, 0xCF, 0x1E, 0x83, 0x5F, 0x0F, 0xF3, 0x8D, 0x6B, 0x2A, + 0xD7, 0xFE, 0x9E, 0xFF, 0xD7, 0x2A, 0xDF, 0x05, 0x1F, 0x13, 0x33, 0x8A, 0xFF, 0x27, 0xFE, 0xB0, + 0xF1, 0xEC, 0x17, 0xEF, 0xAB, 0xD3, 0x40, 0xDF, 0x21, 0xD7, 0x22, 0xB6, 0x0A, 0xE5, 0x33, 0x8F, + 0x67, 0x94, 0xCF, 0x29, 0x8C, 0x09, 0x7B, 0x1B, 0x6D, 0x64, 0xBF, 0xF3, 0xB1, 0x68, 0x5D, 0xB3, + 0x8E, 0x77, 0x99, 0xD7, 0x8C, 0x2D, 0x25, 0xE6, 0x52, 0xD0, 0xF3, 0xFC, 0x7A, 0x4C, 0x37, 0xA9, + 0x7D, 0x02, 0x1F, 0x72, 0xC6, 0xA5, 0x85, 0xD7, 0xAA, 0xED, 0xFA, 0x3F, 0xF3, 0x04, 0xBF, 0xB1, + 0x68, 0x2F, 0x8F, 0x3E, 0xC9, 0x63, 0x74, 0x8A, 0xDF, 0x63, 0x3C, 0x91, 0x9D, 0x32, 0x9E, 0xD1, + 0x8A, 0x37, 0xE3, 0xF8, 0xB7, 0xEA, 0x97, 0x7A, 0xCA, 0x18, 0x5E, 0xBA, 0xDA, 0xD5, 0xAE, 0x36, + 0x5C, 0xB3, 0xD7, 0x6B, 0xEC, 0x94, 0xFF, 0x4A, 0xCF, 0xCC, 0x7C, 0x6D, 0xF4, 0x3D, 0xFE, 0xF7, + 0x81, 0x0F, 0x7C, 0x60, 0xC8, 0x0F, 0xCF, 0xBD, 0xC0, 0x33, 0xC8, 0x1D, 0x3D, 0xFB, 0x06, 0xF7, + 0x20, 0xB7, 0x0A, 0xFA, 0x49, 0xFC, 0xCD, 0x4A, 0xF6, 0xB0, 0xAD, 0xF0, 0xF7, 0xEE, 0x95, 0xEF, + 0x1D, 0x97, 0xE8, 0x1A, 0xD9, 0x83, 0xB5, 0x9F, 0xE5, 0x0E, 0xE8, 0xE1, 0x53, 0x11, 0xBF, 0x30, + 0x96, 0xD8, 0x43, 0xDC, 0x36, 0x5D, 0xE2, 0x9B, 0xBE, 0x86, 0xC1, 0x4A, 0x67, 0x9E, 0x79, 0x66, + 0xF1, 0x8C, 0xA7, 0x0C, 0x2B, 0xB5, 0xE8, 0xEA, 0x54, 0xE4, 0xEF, 0x0D, 0x0D, 0x33, 0xFC, 0x56, + 0xB2, 0x97, 0x97, 0x74, 0x2A, 0xAC, 0xF5, 0x16, 0xBC, 0xD4, 0xB2, 0x6E, 0xF5, 0xEA, 0xFA, 0xA5, + 0xD6, 0x71, 0xF5, 0x0A, 0x5E, 0x72, 0xFD, 0x52, 0x49, 0x4E, 0x8F, 0x7B, 0xFE, 0x18, 0x1D, 0xA1, + 0xBB, 0xFC, 0x97, 0xE2, 0x3E, 0x37, 0xB7, 0x2E, 0x91, 0x4F, 0x20, 0xE2, 0x25, 0xB7, 0xC7, 0xF9, + 0x7E, 0xEC, 0xFC, 0x58, 0xB6, 0x55, 0x2A, 0x67, 0xD7, 0x6B, 0xCE, 0xBB, 0xFD, 0xB7, 0xB4, 0x36, + 0xFC, 0xFD, 0xA7, 0x3F, 0xFD, 0xE9, 0xC1, 0xC7, 0x83, 0xFB, 0x2A, 0xEE, 0x6C, 0xEE, 0x3E, 0xBF, + 0x24, 0x5E, 0x8A, 0x73, 0x09, 0xDB, 0x23, 0x73, 0xAC, 0xF6, 0x5C, 0xBF, 0xAE, 0x8D, 0x83, 0xD3, + 0x42, 0x3E, 0x63, 0x71, 0xCD, 0x94, 0xF4, 0xCA, 0xD9, 0x1E, 0xE9, 0x78, 0xA9, 0xA6, 0xFB, 0x8A, + 0x6D, 0xAE, 0xB5, 0x11, 0x3E, 0xCF, 0x5A, 0x25, 0x8F, 0x36, 0x3E, 0x6A, 0xCC, 0x37, 0x5E, 0x55, + 0xD1, 0xB3, 0xAB, 0xF2, 0xBF, 0x96, 0x4A, 0x5E, 0x19, 0x7C, 0x83, 0xE0, 0xA1, 0x9C, 0xD1, 0x76, + 0xCD, 0x6B, 0x5E, 0xB3, 0x18, 0xDF, 0xE5, 0x34, 0xA0, 0xAF, 0xC4, 0xD2, 0x91, 0xE3, 0x8B, 0xB5, + 0xDE, 0xCA, 0xCB, 0x22, 0xCD, 0x4B, 0xF6, 0x73, 0xD1, 0x82, 0x7B, 0x23, 0x77, 0xC2, 0x53, 0xB5, + 0x06, 0x4A, 0x78, 0xA9, 0xA4, 0xFF, 0xF7, 0xFC, 0x13, 0xE4, 0x84, 0x93, 0xEE, 0xB5, 0x76, 0xBE, + 0xB8, 0xFE, 0x5F, 0x8B, 0xA5, 0xD2, 0x7B, 0xF6, 0x89, 0x33, 0xCE, 0x38, 0x63, 0xE3, 0xB9, 0xE8, + 0x44, 0xE2, 0xBC, 0x28, 0xB5, 0x8D, 0xF5, 0xEA, 0xF9, 0x1F, 0xE3, 0x99, 0x7E, 0x19, 0x5D, 0xBC, + 0x7D, 0x25, 0xDB, 0x12, 0xFA, 0x3E, 0xC5, 0x7F, 0x44, 0x9C, 0x94, 0xE9, 0x0E, 0xB3, 0xFD, 0x2C, + 0xCE, 0x7D, 0x30, 0x0B, 0x76, 0x2D, 0x6F, 0xAF, 0xD3, 0xD0, 0x7D, 0x85, 0x5B, 0xF9, 0xC6, 0x98, + 0xBF, 0xB7, 0xC6, 0x1A, 0xDD, 0x20, 0xB8, 0xD9, 0x7F, 0x37, 0xF6, 0x2C, 0xF8, 0x30, 0x95, 0xFC, + 0xF0, 0xAC, 0x19, 0xF8, 0xE4, 0xD1, 0x47, 0x1F, 0xBD, 0x11, 0x93, 0x10, 0x73, 0x82, 0xC6, 0x7D, + 0x59, 0x98, 0x9A, 0x02, 0x6F, 0xC4, 0xBE, 0x89, 0xBF, 0xD9, 0x52, 0xFE, 0x4B, 0x63, 0xFA, 0x12, + 0x7E, 0xAB, 0x58, 0x78, 0xE5, 0x5F, 0xAA, 0xE9, 0x6C, 0x5A, 0xF8, 0x26, 0xB4, 0xBC, 0xC6, 0x35, + 0xAE, 0x31, 0xE4, 0xD1, 0x06, 0xD7, 0x60, 0x7F, 0xC7, 0x67, 0x91, 0xB5, 0xCC, 0xBE, 0xA8, 0x57, + 0xEC, 0xEB, 0xFC, 0xAF, 0x56, 0xE1, 0x71, 0xFA, 0x2D, 0xD7, 0xFC, 0x86, 0x71, 0x24, 0x57, 0x72, + 0x96, 0x23, 0x28, 0x9B, 0x5F, 0xE4, 0x6B, 0x47, 0xDE, 0xF2, 0x73, 0xCA, 0x35, 0x0E, 0x3E, 0xBF, + 0x33, 0xDA, 0x95, 0x8A, 0xAF, 0x53, 0xD6, 0x13, 0x79, 0xF0, 0x38, 0x13, 0x9D, 0x98, 0xE7, 0xDA, + 0xFC, 0x8F, 0xFC, 0x2D, 0xEA, 0x63, 0xF5, 0x8A, 0xAE, 0xAA, 0x15, 0x2F, 0xB5, 0xEC, 0x39, 0x54, + 0x64, 0x61, 0xE6, 0x8E, 0xDB, 0x09, 0x6B, 0xE3, 0x19, 0xE7, 0x60, 0x66, 0x8F, 0xAB, 0xF1, 0xAC, + 0xD6, 0xC2, 0x77, 0x19, 0xE3, 0x48, 0xB7, 0x25, 0x72, 0x0A, 0x2C, 0x85, 0x97, 0x5C, 0x27, 0xE1, + 0xFE, 0xDE, 0x3E, 0x6E, 0xF1, 0x1C, 0x19, 0x3E, 0x23, 0x86, 0xC2, 0xFD, 0x79, 0x3C, 0x47, 0xAD, + 0xEE, 0xE7, 0x71, 0xD2, 0x71, 0x1E, 0xE2, 0x03, 0x48, 0xDC, 0x35, 0xF7, 0x62, 0x3D, 0xC4, 0xDF, + 0x4E, 0x29, 0xEB, 0xC0, 0x4B, 0x9A, 0xCB, 0xD8, 0x0D, 0x99, 0xBB, 0x91, 0x6E, 0x25, 0xDD, 0x51, + 0x69, 0x1C, 0xF8, 0x5C, 0x67, 0xC7, 0x71, 0x0F, 0xC5, 0x24, 0x2A, 0x07, 0x73, 0xEB, 0x39, 0x83, + 0xEB, 0xC6, 0x4B, 0xE8, 0x31, 0xE0, 0x9D, 0x25, 0xFC, 0x38, 0x85, 0x9E, 0x59, 0x8E, 0x14, 0xEF, + 0x87, 0xE7, 0x30, 0x12, 0x1D, 0xC0, 0xA9, 0xF0, 0x46, 0xF2, 0x0F, 0xC8, 0xB6, 0x31, 0xC5, 0x27, + 0x28, 0xC3, 0xF0, 0x51, 0xC7, 0xAA, 0x3E, 0xA3, 0x4B, 0xCC, 0x7C, 0xF0, 0x5B, 0xE6, 0x8B, 0x7F, + 0x9F, 0xD8, 0x4F, 0x3F, 0x67, 0xD4, 0xE7, 0xF5, 0xD8, 0x1C, 0x2F, 0xE1, 0x26, 0x0A, 0x36, 0x52, + 0x3D, 0xC3, 0x7D, 0x22, 0x33, 0x3D, 0x93, 0xC7, 0x77, 0x3F, 0xF2, 0x91, 0x8F, 0xDC, 0x88, 0xAB, + 0xD0, 0x33, 0x5A, 0xF2, 0x78, 0xFA, 0x9E, 0x9E, 0xD1, 0xF5, 0x95, 0xAF, 0x7C, 0xE5, 0x06, 0xEF, + 0xF5, 0xFE, 0xC7, 0xF6, 0x94, 0x6C, 0xCB, 0xBE, 0xCE, 0xF4, 0x19, 0x7C, 0x86, 0xB3, 0x67, 0xE5, + 0x3F, 0x57, 0x92, 0xBD, 0x7A, 0x78, 0x05, 0x3C, 0x0A, 0x9E, 0x29, 0xBC, 0xE4, 0xCF, 0xF7, 0xD8, + 0x4B, 0x72, 0xC0, 0xC8, 0xCF, 0x3C, 0xCA, 0x94, 0xBE, 0xF6, 0xD5, 0x7F, 0xFD, 0x0F, 0x6C, 0x0C, + 0x2D, 0x38, 0x4F, 0x84, 0xFB, 0x10, 0x27, 0xE7, 0xB9, 0x06, 0x5B, 0xF4, 0x3F, 0xD2, 0x21, 0x82, + 0xB5, 0xC9, 0x61, 0xEF, 0xE3, 0xE8, 0x3C, 0x19, 0xFE, 0xCB, 0x5C, 0xDD, 0xBD, 0x7B, 0x77, 0x73, + 0xFF, 0xBD, 0x0F, 0xFE, 0x5E, 0xF4, 0xE4, 0xB9, 0xF2, 0xDB, 0x77, 0xB9, 0x79, 0xCE, 0xDA, 0x1F, + 0x93, 0xFB, 0x5A, 0x6B, 0x69, 0xCF, 0xF4, 0xF9, 0x16, 0x6D, 0x97, 0xFA, 0x1F, 0xB8, 0x93, 0x7D, + 0x98, 0x7C, 0xE0, 0xE4, 0x1F, 0x89, 0x63, 0x50, 0xF3, 0xAD, 0xC8, 0xD6, 0x5F, 0x29, 0x1F, 0x3E, + 0x9F, 0x83, 0xEF, 0xC9, 0x45, 0x11, 0x7D, 0x95, 0xC7, 0xEC, 0x71, 0xA5, 0x0A, 0x2E, 0x59, 0xF2, + 0x7C, 0x77, 0x8A, 0x72, 0xEB, 0x4D, 0x1D, 0x53, 0xF0, 0x92, 0xEC, 0x71, 0x63, 0x3A, 0xA3, 0x9E, + 0xC2, 0xF7, 0xDD, 0xA7, 0x75, 0xC9, 0xBA, 0x84, 0xBF, 0x77, 0x5C, 0xF7, 0xE0, 0x0C, 0x8D, 0x2D, + 0xE3, 0xED, 0x38, 0xC9, 0xE3, 0x97, 0x78, 0x4F, 0xEC, 0x0A, 0xDF, 0x8F, 0x3E, 0x4A, 0xF1, 0x3A, + 0xE2, 0x07, 0x61, 0x78, 0xB0, 0x99, 0xE2, 0xE8, 0xB1, 0x41, 0xFB, 0xFF, 0x7A, 0xE9, 0x1C, 0xFB, + 0xBE, 0xB4, 0xFF, 0x92, 0xF0, 0x92, 0x9F, 0x67, 0x3D, 0xB5, 0x6D, 0xC2, 0x4B, 0xBA, 0x56, 0x7C, + 0x9C, 0xE7, 0x59, 0x75, 0x1E, 0x99, 0xE9, 0x25, 0x23, 0xE6, 0xA7, 0xAF, 0xCA, 0x57, 0xD9, 0x8B, + 0xE9, 0x4B, 0x25, 0xAE, 0xA9, 0xA5, 0xF0, 0x92, 0xF7, 0x2D, 0xF2, 0xC0, 0xC8, 0xEB, 0x90, 0x73, + 0x39, 0xDB, 0xFC, 0x33, 0x9F, 0xF9, 0x4C, 0xCA, 0xDB, 0xA6, 0xE0, 0xA6, 0x88, 0x77, 0xBD, 0x70, + 0x9E, 0x2D, 0x67, 0x7A, 0x20, 0x1B, 0x46, 0x79, 0xAF, 0xA5, 0x7F, 0xF1, 0xFB, 0xE4, 0x87, 0x7E, + 0xDF, 0xFB, 0xDE, 0x37, 0xDC, 0x3B, 0x62, 0x93, 0x2C, 0x86, 0xB4, 0x56, 0x7C, 0x3D, 0x81, 0x97, + 0xF0, 0x8F, 0xF1, 0x33, 0x20, 0x4A, 0x3A, 0x7D, 0xF7, 0x17, 0xC6, 0x67, 0x21, 0xC6, 0xDA, 0x64, + 0xF9, 0x01, 0x32, 0xBC, 0xE4, 0xF3, 0xD7, 0xFD, 0xEF, 0xB0, 0x6B, 0x60, 0x57, 0xD7, 0xF3, 0xB3, + 0xBC, 0x41, 0x91, 0x86, 0x35, 0xDC, 0xA4, 0xFF, 0xD3, 0x2F, 0xF4, 0x4B, 0xCA, 0xEF, 0x9D, 0xB5, + 0xB5, 0xA7, 0x28, 0x2E, 0x57, 0xFA, 0xA5, 0x4C, 0x6E, 0xE6, 0x3D, 0x3A, 0x4F, 0x72, 0xA8, 0xFB, + 0xB9, 0x62, 0xE2, 0xB1, 0x19, 0x46, 0xF3, 0x31, 0xC5, 0x16, 0x23, 0x7B, 0x16, 0xF7, 0x82, 0x47, + 0x6A, 0xFC, 0xE3, 0xEF, 0x22, 0x5F, 0x74, 0x1A, 0x73, 0xB6, 0x1F, 0x36, 0x23, 0x74, 0xB0, 0x19, + 0x9D, 0x78, 0x95, 0xBC, 0xDA, 0x9A, 0xDF, 0xBE, 0xB4, 0xF7, 0x7B, 0x3F, 0xDC, 0x1E, 0x97, 0xC5, + 0x39, 0x4E, 0x5D, 0xF7, 0x35, 0xDD, 0x71, 0xCF, 0xFD, 0xC7, 0x62, 0x60, 0x22, 0x8F, 0x64, 0x2E, + 0xE2, 0x53, 0x87, 0x9C, 0xE0, 0xF9, 0xD6, 0x23, 0xEE, 0x6D, 0x59, 0x83, 0x19, 0xCF, 0xF0, 0xFD, + 0x4A, 0x3C, 0x9D, 0x3D, 0x59, 0xB1, 0x71, 0xEE, 0x63, 0xBE, 0x83, 0x97, 0xC6, 0xCB, 0x76, 0xC7, + 0x4B, 0x14, 0xE5, 0xA9, 0x97, 0xAE, 0x43, 0x73, 0x4E, 0xB6, 0x73, 0x9F, 0xAB, 0xDA, 0xE3, 0xA8, + 0x9C, 0x2D, 0x8F, 0xAD, 0x3E, 0x3E, 0xD3, 0xD7, 0x7F, 0xC6, 0x1F, 0x28, 0xF8, 0x07, 0xE3, 0x17, + 0xA3, 0x67, 0xE1, 0xE3, 0xA5, 0xEF, 0xCC, 0xD9, 0xEB, 0xAF, 0x08, 0x78, 0x89, 0xE2, 0x74, 0x01, + 0x37, 0x6A, 0x1D, 0xB9, 0xBF, 0x82, 0xEB, 0x69, 0x33, 0xDE, 0xEE, 0xFF, 0x97, 0x7E, 0x49, 0xF7, + 0x5E, 0xC2, 0x7F, 0xC9, 0xD7, 0xD4, 0xD4, 0xB5, 0x5E, 0xE2, 0x91, 0x11, 0x2B, 0x45, 0xFF, 0xF6, + 0xBD, 0xF7, 0xDE, 0x7B, 0xC8, 0x7F, 0x43, 0x2C, 0x81, 0xF2, 0xC6, 0x67, 0xB4, 0xEB, 0xF5, 0x5B, + 0x8A, 0x63, 0x20, 0x1D, 0xA8, 0x78, 0x1D, 0xBE, 0xDE, 0xF8, 0x2E, 0xB5, 0x9C, 0xDB, 0x59, 0xEB, + 0xA7, 0xAE, 0xB1, 0x41, 0xE0, 0x2F, 0x94, 0xB5, 0xB7, 0x77, 0x8C, 0x7C, 0x5C, 0xD9, 0xF3, 0xF1, + 0x17, 0x12, 0x9E, 0xAE, 0xE1, 0x4E, 0xF9, 0xE4, 0xF0, 0x19, 0x79, 0x65, 0xE5, 0x8B, 0xD3, 0xD3, + 0x96, 0xA8, 0x63, 0xF2, 0xB6, 0x80, 0x65, 0xC9, 0x35, 0x95, 0xED, 0x59, 0x59, 0x7B, 0x4A, 0x73, + 0xC2, 0xB1, 0x80, 0xF6, 0x1A, 0x7C, 0xFB, 0xF1, 0x7D, 0x53, 0x89, 0x3E, 0x60, 0x3D, 0x85, 0xDF, + 0x29, 0x5F, 0x44, 0xA6, 0x5F, 0x52, 0x3B, 0xB1, 0xC5, 0x81, 0xD1, 0xB1, 0x89, 0xF9, 0x73, 0x75, + 0x0F, 0x7F, 0x8D, 0x74, 0x84, 0x1F, 0x72, 0xD6, 0x32, 0xF3, 0x97, 0xFB, 0xA1, 0xA7, 0x64, 0xAC, + 0x32, 0x5C, 0x9F, 0xDD, 0x4B, 0xDF, 0x93, 0x1E, 0x4C, 0xE7, 0xF2, 0x38, 0xFF, 0x55, 0xBB, 0xA5, + 0x5F, 0x6A, 0xCD, 0x6F, 0x9F, 0xD1, 0x23, 0xF2, 0x5B, 0x9D, 0xE5, 0xC1, 0xBD, 0x97, 0xF2, 0x1B, + 0xC9, 0xB0, 0xD1, 0x14, 0x5E, 0x12, 0xE7, 0x50, 0x4D, 0xDE, 0xE2, 0x7F, 0xC8, 0x3C, 0xF7, 0xBF, + 0xFF, 0xFD, 0x87, 0x9C, 0xB6, 0x60, 0x5F, 0xCF, 0x65, 0xA2, 0xD2, 0x9B, 0xB7, 0xA6, 0x14, 0x3F, + 0xE7, 0x34, 0xE4, 0x79, 0xD9, 0x19, 0x8A, 0x3B, 0x78, 0x69, 0xBC, 0x6C, 0x67, 0xBC, 0xE4, 0x7E, + 0x47, 0x14, 0xE5, 0xB3, 0xD0, 0x78, 0x2A, 0xC7, 0x68, 0x1C, 0x6F, 0x5D, 0x9F, 0x74, 0xD2, 0x49, + 0x9B, 0xCE, 0x9E, 0xAD, 0x61, 0x75, 0xFE, 0xE7, 0x39, 0x2A, 0xE1, 0x81, 0xC8, 0x70, 0xBA, 0x37, + 0x36, 0xEC, 0x29, 0xF4, 0x8D, 0x65, 0xBB, 0xE1, 0xA5, 0xD2, 0x9A, 0x72, 0xBE, 0xE9, 0x34, 0xCF, + 0x6C, 0x71, 0x25, 0xBD, 0x81, 0xF3, 0x07, 0xF6, 0xE5, 0x78, 0x86, 0xF5, 0xDC, 0x92, 0xE9, 0x97, + 0xE6, 0xE0, 0x25, 0xB7, 0x25, 0x78, 0x7F, 0x9D, 0xA7, 0xA0, 0x33, 0xC1, 0xC7, 0xF7, 0xD8, 0x63, + 0x8F, 0x1D, 0x7C, 0x88, 0x5D, 0xA7, 0x14, 0x7D, 0x6D, 0xE6, 0x60, 0x42, 0xDF, 0x77, 0x5D, 0xD6, + 0x04, 0x73, 0xE2, 0x6F, 0xA1, 0xB6, 0x4D, 0xD5, 0x31, 0xA9, 0x92, 0xAB, 0xCF, 0xE3, 0xD1, 0x4A, + 0xF2, 0x43, 0x4B, 0x71, 0xFD, 0x14, 0x39, 0x05, 0x90, 0x31, 0x14, 0x8F, 0x56, 0xC3, 0x4B, 0x1E, + 0xF3, 0xF5, 0x9A, 0xD7, 0xBC, 0x66, 0xE3, 0x5E, 0x1E, 0xAF, 0xD7, 0x43, 0xCB, 0xA8, 0x67, 0x62, + 0x9C, 0x0E, 0x39, 0xE4, 0x90, 0x22, 0x0D, 0x5A, 0x68, 0x16, 0x31, 0xB4, 0x5E, 0x99, 0x0F, 0xE8, + 0xD2, 0xF4, 0x4C, 0xCF, 0xFF, 0x38, 0x85, 0x57, 0x28, 0x1F, 0x69, 0xC4, 0x4B, 0xEE, 0x53, 0x8D, + 0x0D, 0xEC, 0x45, 0x2F, 0x7A, 0xD1, 0xE0, 0xBF, 0xA7, 0x12, 0x73, 0x09, 0xF8, 0xB3, 0x7D, 0x5E, + 0x62, 0x8B, 0x61, 0x2D, 0x32, 0x2E, 0xD2, 0xD1, 0x23, 0x0F, 0xE9, 0x1E, 0x71, 0xDE, 0xC5, 0x7B, + 0x39, 0x5F, 0xF8, 0xDC, 0xE7, 0x3E, 0x37, 0xF8, 0x7C, 0x8B, 0x4E, 0x5A, 0x2B, 0xA2, 0x17, 0x36, + 0x33, 0xD9, 0xE3, 0xA6, 0xAC, 0x05, 0xCD, 0x79, 0xD7, 0xE7, 0xEB, 0xBC, 0x5D, 0xB7, 0x47, 0x2F, + 0xC1, 0x3B, 0x5D, 0xE6, 0xEB, 0xF5, 0x87, 0x8A, 0xF3, 0x2A, 0xCA, 0x07, 0xF1, 0x5E, 0xD7, 0xBA, + 0xD6, 0xB5, 0x06, 0x7B, 0xD8, 0xE3, 0x1F, 0xFF, 0xF8, 0x21, 0x7E, 0x2E, 0x16, 0x9F, 0x3F, 0x53, + 0x79, 0x48, 0x3C, 0x4B, 0x51, 0xE3, 0xC6, 0x7E, 0xC8, 0x98, 0x44, 0xBB, 0x72, 0x46, 0x8F, 0x1A, + 0xDF, 0xF0, 0xBA, 0x83, 0x97, 0x96, 0xA9, 0x4B, 0xC4, 0xC7, 0xF9, 0xB8, 0x4B, 0xCF, 0xAF, 0xFB, + 0x7B, 0x4E, 0xF6, 0x38, 0xC6, 0xE8, 0xAC, 0xB5, 0x3F, 0xBB, 0x9F, 0x92, 0xEE, 0x53, 0xB2, 0xC3, + 0xE9, 0xFD, 0x0B, 0x5E, 0xF0, 0x82, 0xE1, 0xCC, 0x34, 0xF1, 0x2A, 0x6C, 0xCB, 0xFE, 0xDD, 0xFF, + 0x2D, 0xF6, 0xB8, 0x12, 0x76, 0xF4, 0xDC, 0x4D, 0x8A, 0x49, 0x14, 0x4F, 0xD4, 0x33, 0xB3, 0x58, + 0xF1, 0xD2, 0x2B, 0x71, 0xF9, 0xDC, 0x47, 0xF7, 0x5F, 0x22, 0x5E, 0x6C, 0xEE, 0x9A, 0xCA, 0x68, + 0x98, 0xC9, 0x84, 0xFA, 0x9F, 0x72, 0x3C, 0xE2, 0x37, 0xE2, 0xF6, 0x4A, 0x9F, 0xDF, 0x25, 0xFF, + 0x9F, 0xDE, 0xFD, 0xDE, 0xE3, 0x2F, 0xF5, 0x5B, 0xF7, 0xD7, 0x1A, 0xE3, 0xC9, 0x63, 0x3C, 0x5D, + 0x95, 0x39, 0xE3, 0x31, 0x02, 0x35, 0x7B, 0x4C, 0x4B, 0xBB, 0x35, 0xAE, 0xE8, 0x3E, 0xF0, 0x25, + 0xC6, 0xB7, 0x2B, 0x6B, 0xA7, 0x7F, 0x26, 0x7B, 0x1D, 0xB4, 0xD7, 0xDE, 0x4D, 0x29, 0xC5, 0x52, + 0xB7, 0xB4, 0x43, 0xAF, 0x54, 0xE4, 0x69, 0xEC, 0x4E, 0x2D, 0xB4, 0x69, 0xA5, 0xA3, 0xD6, 0x01, + 0xF6, 0x14, 0x6F, 0xF3, 0x5C, 0xBC, 0xA4, 0xF3, 0x01, 0x75, 0xDE, 0x8D, 0xC7, 0x02, 0xAB, 0x6D, + 0xE8, 0x17, 0x75, 0xF6, 0x5F, 0xEC, 0x73, 0x46, 0x0B, 0x9F, 0xAB, 0x9C, 0x05, 0xA9, 0x38, 0x41, + 0xCD, 0xA1, 0xB3, 0xCE, 0x3A, 0x6B, 0xF8, 0x7F, 0x0B, 0x5E, 0x8A, 0x7B, 0xB0, 0x62, 0xAB, 0xA3, + 0x1E, 0x51, 0x78, 0x69, 0xAA, 0x3D, 0x2E, 0xEB, 0x0F, 0x9F, 0x29, 0xD7, 0x22, 0x3A, 0xB6, 0x28, + 0xB3, 0xCD, 0x59, 0xF7, 0x63, 0xBF, 0xEF, 0x59, 0x5F, 0x8E, 0xB7, 0xDC, 0xE7, 0x4C, 0xEB, 0x0D, + 0x1B, 0x38, 0xF1, 0x07, 0xE4, 0x49, 0x57, 0x8E, 0x5C, 0x61, 0xA3, 0x12, 0xE6, 0x6D, 0x89, 0xC7, + 0x2E, 0xF1, 0x1B, 0xC5, 0x69, 0x50, 0xF1, 0x89, 0xD0, 0x79, 0x76, 0x63, 0x78, 0xA9, 0x95, 0xBE, + 0x3B, 0x78, 0x69, 0x99, 0xBA, 0x94, 0xFF, 0x92, 0xC7, 0xB4, 0x11, 0x43, 0xAB, 0xF9, 0xE8, 0x67, + 0xFE, 0x79, 0x45, 0x5E, 0x25, 0xDE, 0x81, 0x73, 0x9D, 0xF4, 0x3B, 0xCD, 0xB7, 0xC8, 0xCB, 0x9C, + 0x9F, 0x78, 0x8E, 0x5B, 0xF2, 0x64, 0x2B, 0x7E, 0x80, 0xE7, 0xF9, 0x39, 0xB6, 0x7E, 0x9F, 0xDE, + 0x72, 0x45, 0xC4, 0x4B, 0xE8, 0x97, 0x44, 0x73, 0xCF, 0x83, 0x1F, 0xDB, 0x90, 0xC5, 0xC9, 0xEA, + 0x1A, 0xBC, 0xB9, 0x6E, 0xFD, 0xD2, 0x12, 0x35, 0xFA, 0x2F, 0x69, 0xED, 0x11, 0x0B, 0xF4, 0xFA, + 0xD7, 0xBF, 0x7E, 0xD0, 0x9B, 0xC4, 0xB9, 0xA4, 0xE2, 0x67, 0xCE, 0x46, 0x7A, 0xB6, 0x94, 0x6C, + 0x2C, 0x7C, 0xED, 0x90, 0x2B, 0x47, 0x79, 0x04, 0xA6, 0xC4, 0x66, 0xF8, 0x78, 0xE8, 0x2C, 0x10, + 0xC6, 0x93, 0x3C, 0xD1, 0x2A, 0x7E, 0xE6, 0x82, 0xCB, 0x11, 0x2D, 0x6B, 0xD6, 0xFD, 0x8A, 0xB1, + 0x81, 0x91, 0x83, 0x09, 0x3D, 0xC0, 0xD8, 0x5E, 0x23, 0xBD, 0x04, 0xF9, 0x13, 0xA5, 0xB3, 0xCB, + 0xF4, 0x73, 0x63, 0x6D, 0x88, 0x72, 0xB9, 0xBE, 0x4F, 0xFE, 0x4B, 0x74, 0x32, 0x25, 0x8C, 0xE9, + 0xAF, 0x2D, 0xFB, 0x62, 0xE4, 0x3D, 0x8A, 0xEB, 0xA7, 0x4C, 0xCD, 0x33, 0xA2, 0x76, 0x97, 0xEC, + 0x71, 0xDE, 0xEE, 0xBB, 0xDE, 0xF5, 0xAE, 0x1B, 0xE7, 0xFE, 0xB5, 0x9C, 0xB1, 0xEB, 0x78, 0x89, + 0xBC, 0x8C, 0x8A, 0x13, 0x54, 0x85, 0x3E, 0xE4, 0x64, 0xA2, 0x94, 0xEC, 0x71, 0x11, 0xC3, 0xE8, + 0x1A, 0x9F, 0x07, 0x3F, 0x87, 0x6F, 0x0E, 0x5E, 0x1A, 0xA3, 0x0D, 0x65, 0xD7, 0xAE, 0x5D, 0xE9, + 0xBC, 0xDA, 0x2E, 0x78, 0xA9, 0xB4, 0x16, 0xA1, 0x05, 0xE7, 0xFC, 0xA0, 0xCB, 0x25, 0x3E, 0xAD, + 0x65, 0x4F, 0x8C, 0x3A, 0xA2, 0x5E, 0x5A, 0x51, 0xA2, 0x5D, 0xE5, 0xB1, 0x8F, 0x7D, 0xEC, 0x90, + 0xB3, 0x95, 0x36, 0x95, 0xE2, 0x1E, 0x76, 0xF0, 0x52, 0xB9, 0x6C, 0x67, 0xBC, 0xE4, 0xB6, 0x0E, + 0xAE, 0xF1, 0x31, 0x3C, 0xF1, 0xC4, 0x13, 0xD3, 0xB8, 0x20, 0xDF, 0x3F, 0x88, 0xDF, 0x64, 0x5E, + 0xB0, 0xB6, 0x74, 0x9F, 0x6C, 0x8F, 0x8B, 0xFB, 0x82, 0xDA, 0xF9, 0xC5, 0x2F, 0x7E, 0x71, 0x53, + 0xCE, 0x73, 0x5E, 0x23, 0x5E, 0xFA, 0xDF, 0xA4, 0x5F, 0x1A, 0xD3, 0xBB, 0x7B, 0x4C, 0x62, 0x8C, + 0xC5, 0x92, 0x4E, 0x9F, 0xBD, 0x8E, 0x18, 0x31, 0x2A, 0xD8, 0x08, 0xB9, 0x93, 0x6B, 0xFA, 0x48, + 0x7D, 0xEA, 0x53, 0x9F, 0x3A, 0x9C, 0x87, 0xBE, 0x64, 0xD1, 0x9A, 0x6A, 0xDD, 0xE3, 0xC6, 0xBE, + 0xE3, 0xBA, 0x25, 0xFA, 0xB9, 0xEF, 0xBE, 0xFB, 0x0E, 0x67, 0x3F, 0xE1, 0x83, 0x4C, 0xBE, 0xC3, + 0x48, 0xAB, 0xCC, 0xB7, 0x52, 0xAF, 0xF1, 0x7C, 0x96, 0xD6, 0x12, 0x6D, 0x49, 0xDA, 0xEB, 0xD8, + 0x73, 0xB0, 0x0F, 0xBB, 0x4E, 0x75, 0x8C, 0x47, 0xD7, 0x68, 0x20, 0xDC, 0xCB, 0x35, 0x63, 0x45, + 0x8E, 0xCE, 0x68, 0x03, 0xEB, 0xC5, 0x4B, 0xBE, 0x2F, 0x33, 0x36, 0x9C, 0xBB, 0x4B, 0x7C, 0xA9, + 0xDA, 0x58, 0xB2, 0xD9, 0x52, 0xF1, 0x61, 0x42, 0x07, 0xA9, 0xBC, 0x81, 0x51, 0x1F, 0x1C, 0x65, + 0x6F, 0x7D, 0x9E, 0xCD, 0x59, 0x61, 0x04, 0xFD, 0x8F, 0xFC, 0xFE, 0xB2, 0x3F, 0x65, 0x71, 0xDD, + 0x3D, 0x7E, 0x30, 0xFA, 0x9D, 0x7C, 0xAE, 0xA8, 0xC4, 0x34, 0xC5, 0x39, 0x90, 0x8D, 0x69, 0x4B, + 0x61, 0xDE, 0xC4, 0xF3, 0x01, 0xE3, 0x2B, 0xBE, 0x01, 0x8C, 0x17, 0x05, 0x3F, 0xCB, 0x88, 0x6B, + 0xFC, 0xDA, 0x75, 0x7E, 0x94, 0xD7, 0xBD, 0xEE, 0x75, 0x7B, 0xF4, 0xFF, 0x98, 0x63, 0x8E, 0xD9, + 0xC8, 0x29, 0x50, 0xE2, 0x8F, 0xA5, 0x7B, 0x83, 0x87, 0xE0, 0xB7, 0xBA, 0x67, 0xB4, 0xC7, 0x09, + 0x2F, 0x4D, 0xE1, 0x97, 0x8E, 0x9B, 0xD5, 0x2E, 0xCE, 0x4C, 0x26, 0xE7, 0x04, 0xBA, 0xDE, 0xDE, + 0xF5, 0x3D, 0x36, 0xA6, 0x19, 0x4E, 0xE8, 0xBD, 0x7F, 0xF4, 0x9B, 0xC6, 0xAF, 0x9A, 0x79, 0x8D, + 0x0D, 0x11, 0x59, 0xC0, 0xF7, 0x21, 0xAE, 0xE3, 0x9C, 0xF5, 0xCF, 0x22, 0x1D, 0x5A, 0x4A, 0xC9, + 0xE7, 0x0F, 0x1F, 0x60, 0x72, 0x66, 0xE9, 0x5C, 0x47, 0xF1, 0x6D, 0xCD, 0x7D, 0x3F, 0xB3, 0xBD, + 0xD7, 0x26, 0xB9, 0x83, 0x97, 0xB6, 0x07, 0x5E, 0x72, 0xFE, 0x4B, 0x25, 0xF7, 0xFF, 0x93, 0x9F, + 0xFC, 0xE4, 0x4D, 0xE3, 0xAA, 0x39, 0xEA, 0xFC, 0x9F, 0xDC, 0x34, 0xC8, 0x7C, 0xC4, 0xC5, 0x78, + 0xFC, 0x7F, 0x7C, 0x6E, 0xF4, 0x37, 0x51, 0x61, 0x6F, 0x94, 0x3E, 0x5C, 0xF7, 0x94, 0x3D, 0x6E, + 0x0A, 0x8D, 0xB3, 0xBE, 0x6F, 0x17, 0xBC, 0x94, 0xB5, 0x8D, 0x12, 0xFD, 0xBD, 0xF5, 0x9C, 0x18, + 0x5B, 0xA4, 0x78, 0x1D, 0xE2, 0x92, 0xD1, 0x43, 0x61, 0x73, 0x83, 0x27, 0xF3, 0x1B, 0xFA, 0xC8, + 0x67, 0x5C, 0x63, 0xC3, 0xC2, 0xDF, 0xC2, 0x7D, 0x98, 0xE7, 0x16, 0xC7, 0x4B, 0x51, 0x16, 0x8A, + 0xEF, 0x7B, 0x7C, 0x1D, 0xE0, 0x23, 0xE4, 0x99, 0x46, 0xEE, 0xF6, 0xF3, 0x26, 0xB2, 0xF3, 0x2E, + 0xE3, 0xFE, 0x12, 0xE5, 0xF3, 0x1E, 0x7F, 0x4D, 0xDF, 0xE7, 0x55, 0xB9, 0x3F, 0xF1, 0x62, 0xF8, + 0xE2, 0x81, 0x3D, 0x22, 0x4E, 0xEA, 0xE1, 0x6D, 0xCE, 0xC7, 0x1D, 0x23, 0xDC, 0xE9, 0x4E, 0x77, + 0x5A, 0xED, 0xBE, 0xD4, 0xC7, 0x24, 0xD3, 0x91, 0x65, 0xFB, 0x64, 0x49, 0x1E, 0xA6, 0xC8, 0x17, + 0x90, 0xFD, 0x01, 0xFE, 0x1C, 0xF7, 0xA1, 0xCC, 0x4F, 0x6C, 0xAF, 0xBD, 0xF6, 0x1A, 0xEC, 0x04, + 0x1E, 0xAB, 0x25, 0x39, 0x29, 0xDA, 0xD1, 0xBD, 0x5D, 0x11, 0x2F, 0xC5, 0x9C, 0x0C, 0xFC, 0x96, + 0x33, 0xA8, 0x23, 0x36, 0x72, 0x7A, 0x4D, 0x89, 0x47, 0x77, 0x1B, 0x22, 0xF1, 0xA3, 0xB1, 0xC4, + 0x7C, 0x02, 0xAD, 0x3C, 0x23, 0xDA, 0xE3, 0x44, 0x37, 0xE9, 0x03, 0xA1, 0x19, 0xB1, 0xBA, 0xBA, + 0x9F, 0xF2, 0x57, 0x68, 0xEE, 0xE9, 0x59, 0x9E, 0xAB, 0xC7, 0xF5, 0xE7, 0xA7, 0x9C, 0x72, 0xCA, + 0x1E, 0x3E, 0x58, 0xD0, 0x87, 0xB1, 0xF2, 0x31, 0x8C, 0xE3, 0xAE, 0x7E, 0x50, 0x3C, 0x2F, 0xCB, + 0xE9, 0xA7, 0x9F, 0x3E, 0xE4, 0x72, 0xCA, 0xF4, 0x60, 0xE0, 0x25, 0x70, 0x02, 0x31, 0x79, 0x2D, + 0xC5, 0xDB, 0xAF, 0x71, 0x8F, 0x7D, 0x22, 0xC7, 0x0B, 0x3E, 0x53, 0xDA, 0xDF, 0xFD, 0xCC, 0xB0, + 0x39, 0xBC, 0xB3, 0xF4, 0x7B, 0xD1, 0xBC, 0x05, 0x53, 0x3B, 0x0D, 0xA8, 0xE0, 0x48, 0x6C, 0xDD, + 0x8A, 0x63, 0x94, 0xFC, 0x53, 0x92, 0xB3, 0x5C, 0x56, 0xC9, 0x74, 0x4B, 0xB5, 0xB5, 0xA7, 0xFF, + 0xBB, 0x7E, 0xD3, 0xC7, 0x1D, 0xFB, 0x38, 0x39, 0x97, 0xD0, 0x2D, 0xC5, 0xFE, 0x66, 0x3C, 0x7D, + 0x07, 0x2F, 0x95, 0xBF, 0xBF, 0x5D, 0xF1, 0x92, 0xCE, 0xDD, 0xD2, 0x1C, 0x61, 0xDF, 0x80, 0x06, + 0xEE, 0x37, 0xA3, 0x31, 0x76, 0x3B, 0x31, 0xFC, 0x9F, 0x35, 0xEA, 0x76, 0x38, 0xDD, 0x8F, 0xE2, + 0x6B, 0xD2, 0xCF, 0xA4, 0xE5, 0x3D, 0x79, 0xC2, 0x88, 0x79, 0x22, 0xEE, 0xC5, 0x7D, 0x2C, 0x95, + 0x7F, 0xC9, 0xEF, 0x33, 0xA5, 0x5C, 0x11, 0xF0, 0x92, 0xF6, 0x6D, 0xCF, 0xBF, 0x24, 0x9B, 0x89, + 0x64, 0x12, 0x5F, 0x63, 0xE4, 0x0E, 0x61, 0x6E, 0xEB, 0xF7, 0x31, 0xCF, 0xD5, 0xD8, 0x3A, 0x9F, + 0x5A, 0xB2, 0x35, 0xE5, 0x7B, 0x73, 0xB4, 0xBD, 0x44, 0xBE, 0x17, 0xE3, 0xDF, 0xF8, 0x0E, 0xBE, + 0xDC, 0xE0, 0x24, 0xF8, 0x32, 0xF7, 0xAF, 0xE5, 0x44, 0x9A, 0xD2, 0x9F, 0x2C, 0x7E, 0x25, 0xEE, + 0x47, 0x11, 0x1F, 0xE0, 0x73, 0x00, 0x7E, 0x63, 0x8F, 0xC8, 0x72, 0xCB, 0xF5, 0xCC, 0x11, 0xD7, + 0xBB, 0xEB, 0x9A, 0x98, 0x78, 0x74, 0x7F, 0x11, 0x0F, 0x39, 0x56, 0x99, 0x12, 0xA7, 0x03, 0xF6, + 0x21, 0xEF, 0xA7, 0xF3, 0xE0, 0xAC, 0x1D, 0xBC, 0x32, 0x77, 0xD1, 0x03, 0x7D, 0xFC, 0xE3, 0x1F, + 0xDF, 0x44, 0x9F, 0x48, 0xFB, 0xD2, 0x7B, 0xD7, 0x41, 0x48, 0x76, 0xA7, 0x90, 0xA3, 0x1F, 0x1C, + 0x56, 0xD2, 0x1D, 0x4C, 0xD9, 0x67, 0xE3, 0x6F, 0xDC, 0x7F, 0x69, 0x6A, 0x11, 0xBD, 0xA5, 0x5F, + 0x02, 0x2F, 0x65, 0x98, 0x1F, 0x5B, 0x1A, 0x74, 0x52, 0x71, 0x99, 0x32, 0xD2, 0x22, 0xCE, 0xAF, + 0xAF, 0x7C, 0xE5, 0x2B, 0xC3, 0xDC, 0x8E, 0xF6, 0x47, 0x72, 0x48, 0xB1, 0xC6, 0x45, 0x3B, 0xDD, + 0x33, 0xE2, 0x4F, 0xC7, 0x30, 0xE2, 0x11, 0xC8, 0x46, 0xE0, 0x17, 0xDD, 0xD3, 0x73, 0x47, 0x70, + 0xDE, 0x06, 0x78, 0x21, 0x9E, 0x49, 0x31, 0x67, 0xFD, 0x20, 0x77, 0xB1, 0x46, 0x5D, 0x1F, 0x32, + 0x75, 0xDC, 0x44, 0xD3, 0x8C, 0x5F, 0x78, 0x75, 0xDF, 0xCD, 0x2C, 0x26, 0x35, 0xCA, 0x02, 0xC4, + 0x0C, 0xD2, 0x6F, 0xF2, 0x82, 0x92, 0xDB, 0x6C, 0xCE, 0xD9, 0xEC, 0x2D, 0x18, 0x29, 0x8E, 0x3D, + 0xC5, 0xF7, 0x3D, 0xF4, 0x7B, 0x27, 0x9C, 0x70, 0xC2, 0xB0, 0xC6, 0x7C, 0x7C, 0xDC, 0x6F, 0xA9, + 0x45, 0xC7, 0x56, 0xAA, 0x3B, 0x78, 0x69, 0x7B, 0xE0, 0xA5, 0x38, 0x57, 0x74, 0x5E, 0x58, 0x36, + 0xD7, 0x65, 0xA7, 0x50, 0x0E, 0x36, 0xE1, 0x2C, 0xC7, 0x43, 0xFE, 0x1A, 0xE5, 0x56, 0x7D, 0xCE, + 0xFC, 0x3E, 0xEA, 0xA8, 0xA3, 0x86, 0x78, 0x5B, 0xD7, 0x2D, 0xA3, 0x5F, 0x9A, 0x13, 0x3B, 0x14, + 0x7F, 0xB7, 0x1D, 0xF0, 0x52, 0x6D, 0x0D, 0x3A, 0x26, 0xD4, 0x79, 0xBB, 0x3C, 0x07, 0xDF, 0xB0, + 0xC8, 0x27, 0xF0, 0xBD, 0xC4, 0xDE, 0xE6, 0xBF, 0x5F, 0x1A, 0x1B, 0x65, 0xF7, 0xF5, 0x33, 0xAC, + 0xC5, 0xCF, 0x9C, 0x1E, 0xD9, 0xB9, 0x56, 0xBE, 0x57, 0xE8, 0xFB, 0x57, 0xBF, 0xFA, 0xD5, 0x87, + 0x3C, 0x32, 0x07, 0x1F, 0x7C, 0xF0, 0x80, 0x95, 0xD9, 0x63, 0x29, 0x99, 0x5E, 0xA0, 0x85, 0x87, + 0x8D, 0xF5, 0x21, 0xFA, 0xE6, 0xF8, 0xFD, 0xB4, 0x17, 0x89, 0xDF, 0xA1, 0x43, 0x27, 0xFE, 0xBB, + 0x94, 0xE7, 0x36, 0x62, 0x91, 0x9E, 0xFD, 0x42, 0x95, 0x9C, 0xE6, 0xEC, 0x7B, 0xE8, 0x63, 0x7D, + 0x8D, 0x78, 0xFF, 0x5B, 0xFA, 0xEA, 0x38, 0x85, 0x6B, 0xE2, 0xA7, 0xC0, 0x62, 0x6A, 0xB7, 0x8F, + 0x87, 0x8F, 0x19, 0x9F, 0x61, 0xFB, 0xC4, 0x7E, 0xA7, 0xDC, 0x4B, 0xD1, 0x77, 0x75, 0x4C, 0x46, + 0x89, 0xBA, 0x3E, 0x5D, 0x83, 0xBF, 0x38, 0xCB, 0xA8, 0x77, 0x6F, 0xED, 0xA1, 0x63, 0x2B, 0x5E, + 0x6A, 0x99, 0x37, 0xD2, 0x2F, 0xE1, 0xA7, 0xE6, 0x34, 0xD2, 0x5C, 0x65, 0x9E, 0x12, 0x8B, 0xA2, + 0xFB, 0xC5, 0xFC, 0xB9, 0x99, 0x0E, 0x4E, 0x05, 0x3D, 0xC7, 0xA3, 0x1F, 0xFD, 0xE8, 0x3D, 0xF0, + 0x12, 0x58, 0xFC, 0xB4, 0xD3, 0x4E, 0xDB, 0xF8, 0x5E, 0xD4, 0xEB, 0x65, 0xFD, 0xD0, 0x2B, 0x67, + 0x07, 0x29, 0xF6, 0x30, 0xDA, 0x29, 0xB1, 0x45, 0x09, 0x2F, 0xD5, 0xF4, 0x82, 0x3D, 0x65, 0x1D, + 0x78, 0xC9, 0x73, 0xA3, 0xE8, 0x7F, 0xFE, 0x59, 0x5C, 0x5B, 0x9E, 0xB3, 0x56, 0xED, 0x80, 0x2F, + 0x12, 0x1F, 0x84, 0xEE, 0x8F, 0xF1, 0x71, 0x5F, 0x90, 0x29, 0xB1, 0xB2, 0x35, 0xD9, 0x85, 0x52, + 0xD3, 0x59, 0xFA, 0xF8, 0x60, 0xB7, 0x25, 0x3F, 0x29, 0xFE, 0xBC, 0xA5, 0x73, 0xFE, 0xE6, 0xAE, + 0x8B, 0x1D, 0xBC, 0xB4, 0x3D, 0xF0, 0x52, 0x2C, 0x8E, 0x97, 0x4A, 0x63, 0xBE, 0xCF, 0x3E, 0xFB, + 0xAC, 0x9E, 0xF4, 0xA4, 0x27, 0x6D, 0xFC, 0xC6, 0xED, 0x0B, 0xD9, 0x73, 0x7D, 0x1E, 0xF2, 0x4A, + 0xEE, 0x39, 0x7C, 0x07, 0xA2, 0x0E, 0x45, 0xF9, 0x04, 0xE6, 0xF6, 0x61, 0x3B, 0xE1, 0xA5, 0xB1, + 0xFE, 0xE8, 0x33, 0xC7, 0x4B, 0xF0, 0xC3, 0xB8, 0xBE, 0x88, 0x81, 0xF2, 0x3C, 0xEA, 0x5B, 0x85, + 0x97, 0x74, 0xC6, 0x50, 0x5C, 0xF3, 0x59, 0xEC, 0xBA, 0xEF, 0xD9, 0x91, 0x76, 0xF0, 0x12, 0x78, + 0x0A, 0xB1, 0xB6, 0x51, 0x9E, 0x56, 0x51, 0xDC, 0x90, 0xE6, 0xCB, 0x94, 0x3E, 0xD6, 0xE6, 0x9F, + 0xF3, 0x42, 0xE2, 0x66, 0x28, 0xE4, 0xF9, 0xC5, 0x47, 0xD4, 0xC7, 0x78, 0x8E, 0x9E, 0x24, 0xDA, + 0x61, 0x54, 0x75, 0x36, 0xA5, 0xFB, 0xE5, 0x2E, 0xD1, 0x47, 0x68, 0xE6, 0x7E, 0x80, 0x25, 0xFC, + 0xCA, 0x67, 0xC4, 0x6C, 0xE1, 0x07, 0x84, 0x3F, 0x8E, 0xB7, 0x21, 0xB6, 0x67, 0xAC, 0x78, 0xBB, + 0x91, 0xEB, 0x89, 0xD7, 0x2E, 0x9D, 0x2D, 0x32, 0x67, 0xAD, 0xF9, 0xFB, 0x29, 0xFA, 0xA5, 0x6C, + 0x3F, 0xA4, 0xB8, 0x3D, 0x2E, 0xA3, 0x1B, 0x72, 0x1B, 0x31, 0xC2, 0x51, 0xE6, 0xAB, 0x3D, 0x47, + 0x05, 0x5B, 0x39, 0x7E, 0x98, 0x3E, 0x0F, 0xA8, 0xC8, 0x86, 0xD8, 0xCD, 0xA2, 0x9E, 0x22, 0xEA, + 0x3D, 0xE3, 0x59, 0x52, 0x94, 0x28, 0xB3, 0xB8, 0x1F, 0xBC, 0xF6, 0xAC, 0x56, 0x7B, 0x5C, 0x4B, + 0x99, 0x83, 0x97, 0xB2, 0x71, 0x2C, 0xE9, 0x97, 0x32, 0x1B, 0xAD, 0xEB, 0x63, 0x1C, 0x47, 0xF1, + 0x8A, 0x8E, 0x8D, 0x38, 0x43, 0x9D, 0x63, 0x22, 0x3A, 0x4D, 0xF5, 0xD7, 0xAE, 0xC9, 0x65, 0x31, + 0x77, 0xB7, 0xDB, 0x5E, 0xE3, 0x9A, 0x21, 0xDF, 0x16, 0xFA, 0xD5, 0xD8, 0xB7, 0x5E, 0xDE, 0x51, + 0xAB, 0x3B, 0x78, 0x69, 0x99, 0xBA, 0x24, 0x5E, 0xE2, 0x37, 0xE0, 0x25, 0xDF, 0x1F, 0xB3, 0x71, + 0xE7, 0xEC, 0x2F, 0xE5, 0x70, 0xA1, 0xD4, 0xE2, 0x47, 0xB2, 0xBD, 0x8A, 0xFC, 0x36, 0xE4, 0xC7, + 0x60, 0x7E, 0x39, 0x36, 0xE0, 0x4C, 0xA0, 0xA9, 0x6D, 0x8F, 0xCF, 0xA4, 0x5C, 0x51, 0xF0, 0x12, + 0xB4, 0x01, 0x2F, 0x89, 0x2F, 0xB8, 0x9F, 0x98, 0x6A, 0x7C, 0xEE, 0x3A, 0xB0, 0x92, 0xEE, 0xEB, + 0xF7, 0x8E, 0xF3, 0xC1, 0x69, 0x91, 0xF1, 0x00, 0xFF, 0x0C, 0xDE, 0x87, 0x0C, 0xCF, 0x99, 0x0E, + 0xC4, 0x51, 0x2A, 0xDE, 0x28, 0xB6, 0xDF, 0xFD, 0x0D, 0x96, 0xD0, 0x2D, 0xC5, 0xFB, 0xFB, 0xB5, + 0xF6, 0x28, 0x9E, 0x89, 0x2E, 0xE0, 0x51, 0x8F, 0x7A, 0xD4, 0xC6, 0xB9, 0x0F, 0xDE, 0xAF, 0x5E, + 0x7D, 0xB9, 0xF3, 0x78, 0xE7, 0x97, 0xBA, 0x0F, 0x71, 0xA0, 0xF8, 0xD0, 0xCA, 0xCF, 0x82, 0x32, + 0xC5, 0x96, 0xEA, 0x7B, 0xBE, 0x0A, 0x71, 0x85, 0xD8, 0x70, 0x33, 0x9F, 0x08, 0xE7, 0xE1, 0xD8, + 0x30, 0x88, 0xB1, 0xF6, 0x18, 0xF9, 0xEC, 0xFC, 0xDF, 0xB1, 0xBD, 0xC4, 0xF7, 0x79, 0xF4, 0x84, + 0xE4, 0xBF, 0x44, 0x27, 0xB3, 0x54, 0xAE, 0x9E, 0x6C, 0x7F, 0x59, 0x0A, 0x2F, 0x51, 0xDD, 0xDF, + 0x3B, 0xEA, 0x4D, 0x79, 0x7D, 0xF8, 0xC3, 0x1F, 0x3E, 0xC4, 0x68, 0x46, 0x5D, 0x79, 0xE9, 0x19, + 0xBE, 0xB7, 0x72, 0x2E, 0x19, 0x73, 0x3E, 0xDA, 0x97, 0x58, 0x0B, 0xE8, 0x9D, 0x9C, 0x1F, 0x3A, + 0x6D, 0xA3, 0x3D, 0xC9, 0xF7, 0x66, 0xFE, 0x77, 0xEA, 0xA9, 0xA7, 0x6E, 0x5A, 0x57, 0xBA, 0x56, + 0x7E, 0x6F, 0xF4, 0x8C, 0x4B, 0x95, 0x25, 0xF1, 0x52, 0xF6, 0x7B, 0xC7, 0x50, 0xD9, 0xF7, 0x7C, + 0x2C, 0xB4, 0xC7, 0x91, 0x3B, 0x9E, 0x3C, 0xB2, 0x9F, 0xFF, 0xFC, 0xE7, 0x37, 0xE8, 0xEE, 0x7B, + 0x4A, 0x2F, 0x6E, 0xEA, 0xE1, 0x33, 0x25, 0xDD, 0x15, 0xEB, 0x88, 0xBD, 0x0C, 0x5F, 0x73, 0xF6, + 0x33, 0xAD, 0xB7, 0xB9, 0x3C, 0x24, 0xAB, 0x3B, 0x78, 0x69, 0xFB, 0xE0, 0x25, 0x9F, 0x37, 0xAE, + 0x5F, 0xD2, 0xDE, 0xAD, 0x6B, 0xF1, 0x00, 0x7C, 0xDA, 0x88, 0xA1, 0x50, 0x69, 0xD1, 0x5B, 0xEA, + 0x7B, 0xD8, 0xF7, 0x4F, 0x3E, 0xF9, 0xE4, 0x8D, 0xF6, 0xBB, 0xED, 0x29, 0xE6, 0x5F, 0x9A, 0x5A, + 0xB6, 0x13, 0x5E, 0xAA, 0xD1, 0xC5, 0x73, 0xCD, 0xEA, 0xFC, 0xB8, 0x92, 0xDF, 0x23, 0x7E, 0x8D, + 0x73, 0xFC, 0xA6, 0x5A, 0xDB, 0x97, 0xE1, 0x25, 0x5F, 0x53, 0xD1, 0x5F, 0xC9, 0x7D, 0x0A, 0x3C, + 0x9F, 0x2D, 0x67, 0x67, 0x11, 0xBB, 0x47, 0x6C, 0xEF, 0x17, 0xBE, 0xF0, 0x85, 0x3D, 0x70, 0x4C, + 0x9C, 0x33, 0x53, 0xF4, 0xE9, 0xB5, 0xFE, 0xB8, 0x7C, 0x1E, 0x6D, 0x1F, 0xD2, 0x71, 0x92, 0xCF, + 0x02, 0x3F, 0xFA, 0xD8, 0xAF, 0x38, 0xE6, 0xBD, 0x3C, 0xCF, 0xC7, 0x50, 0x39, 0x78, 0xD8, 0x7B, + 0x38, 0xE7, 0x53, 0xBE, 0xD6, 0x6E, 0x57, 0x6B, 0xD1, 0x61, 0xC4, 0xFE, 0x29, 0xD6, 0x8E, 0x42, + 0x1E, 0x6A, 0xEC, 0x9D, 0x59, 0x3B, 0x1C, 0x7B, 0xB3, 0x07, 0xEA, 0xDC, 0xB8, 0x2C, 0x26, 0x3F, + 0xB3, 0x5F, 0xC6, 0x67, 0x47, 0x9B, 0xDD, 0xC7, 0x3E, 0xF6, 0xB1, 0x01, 0x73, 0xA2, 0x73, 0x5E, + 0x6A, 0x6F, 0x10, 0xDD, 0xFD, 0xFD, 0x54, 0xBC, 0x94, 0x15, 0xE9, 0x97, 0x1C, 0x2F, 0x09, 0x1B, + 0x30, 0x6E, 0xC4, 0xBB, 0x38, 0xB6, 0xF7, 0xF3, 0x8F, 0x33, 0x7A, 0x38, 0xDE, 0x87, 0xB7, 0x11, + 0xC7, 0xEA, 0x7B, 0xBF, 0xAE, 0xC9, 0x2B, 0x26, 0x3A, 0x47, 0x9F, 0xA8, 0xCC, 0xEF, 0xD8, 0xB1, + 0x2C, 0xB1, 0x35, 0xB2, 0xC3, 0xF9, 0x59, 0xE7, 0xCA, 0x57, 0x39, 0x35, 0x3E, 0x2E, 0x2B, 0x4B, + 0xDA, 0xE3, 0x4A, 0xDF, 0xC9, 0xFC, 0x1E, 0x7D, 0xAD, 0xF1, 0x4A, 0x7E, 0x0A, 0xF6, 0x4D, 0xB0, + 0x22, 0x71, 0xDB, 0x4E, 0x2F, 0xCA, 0xDC, 0xBC, 0x12, 0x19, 0x5E, 0x2A, 0xC5, 0xBE, 0xC5, 0x5C, + 0xB9, 0xE8, 0xFC, 0xB0, 0xAF, 0xE3, 0x5F, 0xA0, 0x7E, 0xF8, 0xB9, 0x9F, 0x19, 0x3D, 0xE6, 0xAC, + 0x8F, 0x1D, 0xBC, 0xB4, 0x7D, 0xF0, 0x92, 0xBE, 0x1F, 0xF1, 0x92, 0xDB, 0x56, 0x3C, 0x97, 0x1B, + 0x3E, 0x10, 0xCA, 0x25, 0x92, 0x3D, 0xAF, 0x84, 0xD9, 0x99, 0x7F, 0x92, 0xE9, 0xD5, 0x7E, 0xC5, + 0xA4, 0x50, 0xDD, 0xDF, 0x5B, 0xDF, 0x9F, 0x52, 0xAE, 0x68, 0x78, 0x89, 0x6B, 0xF4, 0xF8, 0xB5, + 0x35, 0xB6, 0x55, 0x78, 0x29, 0x16, 0xD6, 0x94, 0x9F, 0xB7, 0x4B, 0xAD, 0xE5, 0x70, 0x84, 0x5F, + 0xB0, 0x8E, 0xB0, 0x3D, 0x78, 0x6E, 0x64, 0xCD, 0xCF, 0xDA, 0x98, 0x2E, 0xC1, 0xEF, 0x23, 0x2E, + 0x8B, 0xF7, 0x84, 0xC7, 0x12, 0x9B, 0x49, 0x0E, 0x83, 0x8C, 0xC7, 0x65, 0x32, 0xEF, 0x14, 0xBC, + 0x94, 0xED, 0x97, 0xC4, 0x38, 0xE1, 0x8B, 0xA2, 0x76, 0xC5, 0xD8, 0xD4, 0x9E, 0xE2, 0x74, 0x44, + 0xBF, 0xC0, 0xBC, 0x8C, 0xED, 0xE5, 0xD5, 0xFD, 0x40, 0xB0, 0x13, 0x69, 0x8F, 0x01, 0x6F, 0x45, + 0x9D, 0x5E, 0xAF, 0x7C, 0x4E, 0x81, 0x96, 0xD8, 0xD1, 0x33, 0xBC, 0x36, 0x77, 0xAD, 0xF9, 0xFB, + 0x25, 0xFC, 0xBD, 0x55, 0x98, 0x8B, 0x3A, 0x3F, 0x4E, 0xF7, 0x77, 0x3D, 0x37, 0x7E, 0xBB, 0x9E, + 0x2B, 0xA9, 0x46, 0x17, 0x8F, 0x2F, 0xA3, 0xB0, 0x56, 0x7C, 0x2C, 0xDC, 0x97, 0x0C, 0xFE, 0x96, + 0xD9, 0xDB, 0xE2, 0xFD, 0x74, 0x2F, 0xE7, 0xE9, 0xE7, 0x9E, 0x7B, 0xEE, 0x80, 0x8D, 0x7C, 0x7E, + 0xF1, 0x2A, 0xBC, 0x14, 0xFD, 0xBD, 0xE7, 0x94, 0xA5, 0xF5, 0x4B, 0xB5, 0xB1, 0x8D, 0x36, 0x0C, + 0xD1, 0x0B, 0x1E, 0x42, 0x8E, 0x11, 0xF4, 0x66, 0x9E, 0x0B, 0x92, 0xE2, 0xBE, 0xF2, 0x2A, 0xAD, + 0xEB, 0xA7, 0x45, 0xA7, 0x54, 0x93, 0xDD, 0xF8, 0x9C, 0x5C, 0x38, 0xAF, 0x7A, 0xD5, 0xAB, 0x86, + 0x78, 0x25, 0xEF, 0xCF, 0xD2, 0x74, 0xF2, 0xBA, 0x83, 0x97, 0x96, 0xA9, 0xEB, 0xF0, 0x5F, 0x92, + 0xFD, 0xC5, 0xF9, 0xAF, 0xD6, 0x0E, 0xE7, 0x44, 0x28, 0x27, 0x62, 0x0D, 0x17, 0x95, 0xEC, 0x2D, + 0x67, 0x9F, 0x7D, 0xF6, 0xE0, 0xCB, 0x22, 0x19, 0xDC, 0xE7, 0x18, 0xD8, 0x66, 0x89, 0x18, 0xF8, + 0xED, 0x84, 0x97, 0xB2, 0x76, 0xA9, 0xF8, 0x9A, 0xEC, 0xC5, 0x4B, 0x4B, 0xC9, 0x92, 0x63, 0xBC, + 0xC3, 0xF1, 0x52, 0xD4, 0x97, 0x53, 0x1D, 0x6F, 0xF0, 0x4A, 0x1C, 0x00, 0x39, 0x27, 0xF1, 0xA7, + 0x88, 0xF1, 0x54, 0xA5, 0x67, 0x67, 0x31, 0xEA, 0x4B, 0xF5, 0xCB, 0x79, 0x2C, 0x32, 0x38, 0x67, + 0x5C, 0x70, 0x4E, 0x82, 0xCE, 0x3B, 0x11, 0x8F, 0x1E, 0xCB, 0x25, 0x37, 0x67, 0x3F, 0xD0, 0xBD, + 0xD1, 0xD9, 0xFB, 0x39, 0x72, 0xD1, 0x26, 0xD3, 0xD2, 0xF7, 0x8C, 0x97, 0xBF, 0xEC, 0x65, 0x2F, + 0x1B, 0x6C, 0xE4, 0x99, 0x4F, 0xAD, 0xD6, 0x2D, 0x9F, 0xE1, 0x33, 0xAC, 0xE2, 0x6B, 0x32, 0xDA, + 0x43, 0x5B, 0x8A, 0xBE, 0x8F, 0x9D, 0x95, 0xF8, 0xBC, 0x52, 0x5E, 0xDB, 0x12, 0x5D, 0x7A, 0xBF, + 0x3B, 0x17, 0x2F, 0x39, 0x9D, 0xB1, 0xA3, 0x44, 0x9F, 0x2B, 0x72, 0x47, 0x89, 0x6E, 0xE4, 0x2A, + 0xD7, 0x9E, 0xAC, 0x98, 0x16, 0xBF, 0x4F, 0x46, 0x0B, 0x7D, 0x4E, 0x6E, 0x49, 0x3F, 0xAB, 0xCF, + 0xF7, 0x52, 0xFC, 0xF2, 0xF1, 0x8D, 0x8F, 0x73, 0xBD, 0x84, 0x57, 0x3D, 0x06, 0x56, 0x67, 0x1A, + 0xBA, 0xDC, 0x2A, 0xFD, 0x12, 0x78, 0xB9, 0x05, 0x2F, 0xB5, 0x8E, 0xED, 0xBA, 0xF0, 0x52, 0xB6, + 0xAE, 0xFC, 0x1A, 0x6C, 0x0F, 0x0F, 0xC1, 0xCE, 0x40, 0xDE, 0x58, 0xE2, 0x82, 0x6A, 0x7D, 0x88, + 0xFA, 0xCE, 0x56, 0x7B, 0xF6, 0x98, 0x2D, 0x24, 0xFA, 0x27, 0x39, 0x0F, 0x43, 0xDE, 0xC1, 0xBE, + 0x72, 0xA3, 0x1B, 0xDD, 0xA8, 0x98, 0x9B, 0xB0, 0x64, 0x6F, 0x9C, 0x53, 0x77, 0xF0, 0xD2, 0xF6, + 0xC0, 0x4B, 0x71, 0xFE, 0x44, 0x1A, 0x0A, 0xD3, 0xF0, 0x4A, 0x9C, 0xED, 0x9D, 0xEF, 0x7C, 0xE7, + 0x8D, 0x9C, 0x88, 0xA5, 0x7D, 0x2E, 0xE2, 0x25, 0xCF, 0x0F, 0x46, 0xDE, 0x58, 0xD9, 0x40, 0x9C, + 0xA7, 0xF0, 0x0A, 0x8D, 0x96, 0xB0, 0xCB, 0x6C, 0x47, 0xBC, 0x94, 0xAD, 0x53, 0xEF, 0xAB, 0x9F, + 0x1F, 0xE7, 0x3A, 0x81, 0xCB, 0x1B, 0x2F, 0x91, 0x1B, 0x49, 0xF9, 0x97, 0x62, 0xDC, 0x95, 0xF3, + 0x03, 0xFC, 0x28, 0x88, 0x5B, 0x41, 0x0E, 0x2E, 0xDD, 0xD7, 0x3F, 0x2B, 0xC5, 0x63, 0xB5, 0xFA, + 0x1C, 0x97, 0x4A, 0x16, 0x77, 0x84, 0xAE, 0x80, 0x33, 0xBD, 0x9E, 0xF6, 0xB4, 0xA7, 0x0D, 0x3A, + 0x1E, 0xB5, 0x59, 0xE7, 0x86, 0xFB, 0x5C, 0x8C, 0xBC, 0xDD, 0xFF, 0xD7, 0x92, 0x1F, 0x26, 0xF3, + 0x6D, 0x75, 0x5F, 0x62, 0xFC, 0x5B, 0x94, 0x07, 0x51, 0xED, 0x2C, 0xD9, 0x64, 0x6A, 0xFD, 0x73, + 0x5A, 0x41, 0x73, 0xF2, 0x61, 0xC6, 0xF1, 0x51, 0x1F, 0x79, 0x05, 0xCF, 0x90, 0x63, 0xBC, 0x94, + 0x3F, 0x49, 0x6D, 0x89, 0xFA, 0x94, 0x28, 0x8F, 0xFB, 0xB8, 0xF1, 0x19, 0x7E, 0x40, 0xF8, 0xB2, + 0x67, 0xF4, 0xCB, 0xF6, 0xCA, 0x9E, 0xB5, 0xE6, 0xEF, 0x5B, 0xF1, 0x52, 0x8C, 0x39, 0xCC, 0xFE, + 0x0F, 0x5E, 0x82, 0x66, 0xCA, 0x57, 0x49, 0xD5, 0x19, 0x7C, 0xE4, 0xA8, 0x22, 0x3F, 0xB7, 0xFA, + 0x27, 0xCC, 0xE2, 0xB6, 0xF3, 0x12, 0xF6, 0xA7, 0xA0, 0x6B, 0x13, 0xDF, 0xF4, 0xFC, 0x2B, 0xF4, + 0x87, 0x73, 0x04, 0xB1, 0xE1, 0x48, 0x77, 0x15, 0xF1, 0x12, 0xC5, 0x63, 0x1F, 0x9D, 0xA7, 0x93, + 0xAF, 0x9A, 0x31, 0xC6, 0x7F, 0xC1, 0x7D, 0xE3, 0xFC, 0xFC, 0xB8, 0x31, 0xDC, 0x7D, 0x79, 0xE0, + 0x25, 0x5F, 0x0B, 0x25, 0x1B, 0x9C, 0xE6, 0x29, 0x36, 0x5D, 0xF8, 0x35, 0xB9, 0x3D, 0x44, 0x03, + 0xB5, 0xDB, 0xE7, 0xA8, 0x8F, 0x4B, 0x6F, 0x19, 0xF3, 0x1D, 0xF1, 0xFC, 0x4C, 0x5E, 0x90, 0xFF, + 0xE0, 0xD1, 0x9C, 0xDD, 0x8B, 0xDC, 0x13, 0xF3, 0x29, 0x95, 0x78, 0x48, 0x6D, 0x4D, 0x38, 0x7D, + 0xC6, 0xD6, 0xC7, 0x0E, 0x5E, 0xDA, 0x1E, 0x78, 0xC9, 0x73, 0x95, 0x51, 0x94, 0x7F, 0x49, 0xE3, + 0xE7, 0x79, 0xF8, 0x59, 0x9B, 0xE8, 0x48, 0x59, 0x9B, 0x7A, 0x86, 0xAF, 0x6F, 0xDD, 0xC3, 0x79, + 0xBA, 0x7C, 0x25, 0xC4, 0x67, 0xEE, 0x7B, 0xDF, 0xFB, 0x6E, 0xDA, 0x43, 0x54, 0x91, 0xC9, 0x98, + 0x8B, 0x2A, 0x73, 0x70, 0xD3, 0x76, 0xC2, 0x4B, 0x35, 0xBE, 0xED, 0x38, 0x92, 0xFD, 0x40, 0x7C, + 0x10, 0x5C, 0x1A, 0x63, 0xDB, 0x79, 0xAE, 0xC7, 0xC7, 0x2D, 0x55, 0xC6, 0xF0, 0x09, 0xFA, 0x70, + 0xE9, 0x1B, 0x33, 0xCC, 0xC0, 0x7B, 0x6C, 0x31, 0xD8, 0x58, 0x89, 0x7D, 0x2B, 0xF9, 0x05, 0xA8, + 0xC4, 0xFF, 0x67, 0x75, 0xAC, 0x64, 0x39, 0x50, 0x1D, 0x23, 0xF9, 0xDC, 0x23, 0xD7, 0x05, 0x3E, + 0x99, 0xC8, 0xF6, 0xF8, 0x44, 0x97, 0x78, 0x53, 0xED, 0xB3, 0x29, 0xFA, 0x26, 0xC7, 0x94, 0xEE, + 0x6F, 0x02, 0x7F, 0x22, 0xBE, 0x27, 0xEB, 0x6F, 0x8F, 0x7C, 0xEC, 0x7D, 0x45, 0x57, 0xC2, 0xDA, + 0xF1, 0xE7, 0x45, 0xF9, 0x56, 0xF9, 0xBB, 0xFC, 0x1E, 0x7E, 0xCF, 0xDA, 0x7A, 0xF3, 0xB6, 0x46, + 0x9C, 0xCB, 0x1A, 0xD3, 0x7A, 0x5E, 0x42, 0x9E, 0xCE, 0xF4, 0x0F, 0x54, 0x3F, 0x0F, 0x65, 0x8C, + 0x3E, 0xB5, 0xF6, 0x53, 0xC0, 0xAB, 0x7F, 0x72, 0x69, 0x3E, 0x01, 0xDF, 0xD7, 0xA8, 0xC8, 0x83, + 0xF8, 0xB6, 0x39, 0x5D, 0x54, 0xE2, 0xFC, 0xE2, 0x95, 0xB9, 0xA8, 0x7C, 0x96, 0xF8, 0xE9, 0x71, + 0x8E, 0x8A, 0xEB, 0xE4, 0xD5, 0x17, 0xEE, 0xBD, 0xDF, 0x7E, 0xFB, 0x0D, 0x78, 0x19, 0x7B, 0x8E, + 0xDB, 0xE5, 0x36, 0xF1, 0x48, 0x9E, 0xC3, 0xE7, 0x17, 0xDF, 0xFB, 0x6B, 0x36, 0xCF, 0xD1, 0x8D, + 0x32, 0x7E, 0xEC, 0x51, 0x3E, 0xB6, 0xF8, 0x09, 0xF2, 0xB9, 0x72, 0xE1, 0x2D, 0x51, 0xC0, 0x4B, + 0xE4, 0xD7, 0xAB, 0xC9, 0x0F, 0xBD, 0xE3, 0xE7, 0xB8, 0x29, 0xBB, 0x0F, 0xF1, 0x10, 0xF8, 0xD9, + 0x7F, 0xF6, 0x73, 0x7F, 0xB7, 0xFA, 0xFA, 0xF9, 0xEC, 0x65, 0x17, 0xAD, 0x2E, 0xB8, 0xF0, 0xFC, + 0x8B, 0xFF, 0x5E, 0x38, 0x5C, 0x5F, 0x78, 0xD1, 0x05, 0xC3, 0x2B, 0xEF, 0xF5, 0x59, 0xFA, 0x3E, + 0x99, 0xDB, 0x51, 0x87, 0x1B, 0xFD, 0xED, 0xE3, 0xDC, 0x8F, 0xBF, 0xC7, 0x97, 0xED, 0x59, 0xCF, + 0x7A, 0xD6, 0x1E, 0xB4, 0x8F, 0x6B, 0x7D, 0x9D, 0x75, 0x07, 0x2F, 0x6D, 0x0F, 0xBC, 0x14, 0xE7, + 0x97, 0xDB, 0xE3, 0x98, 0x1B, 0xCA, 0xB9, 0xC4, 0x7B, 0xE4, 0x23, 0xE2, 0xB8, 0x24, 0x1F, 0x53, + 0xA2, 0x7C, 0x1C, 0xF7, 0x5F, 0xE9, 0x4C, 0x79, 0x65, 0xEF, 0xF5, 0x3C, 0x2D, 0x8E, 0x09, 0x3C, + 0x5E, 0x3E, 0xCA, 0xDD, 0xBD, 0x65, 0x3B, 0xE1, 0xA5, 0xAC, 0x5D, 0xA2, 0x95, 0xC7, 0x29, 0x81, + 0x97, 0x44, 0x13, 0xCF, 0x99, 0x28, 0xDA, 0xC7, 0xFD, 0x4E, 0xF7, 0xD0, 0xFB, 0x4C, 0x97, 0xD3, + 0x82, 0x37, 0xC7, 0x70, 0x8D, 0xF0, 0xB3, 0xB7, 0xC5, 0xE7, 0x04, 0xB9, 0x6C, 0xF1, 0x8F, 0xD5, + 0x59, 0x0F, 0xBD, 0x78, 0x29, 0xFB, 0xBC, 0xD6, 0x56, 0x7F, 0x75, 0x1A, 0x50, 0x7C, 0xBF, 0x60, + 0x0F, 0xC3, 0xF6, 0x05, 0x8E, 0x23, 0x2E, 0x8C, 0x36, 0x3B, 0x6E, 0xA9, 0x8D, 0xF1, 0x52, 0x73, + 0x25, 0x9B, 0xE7, 0xC4, 0x48, 0x41, 0x2B, 0xF5, 0xC1, 0xCF, 0xBB, 0x6D, 0xC5, 0x4B, 0xF1, 0x1A, + 0xBB, 0x05, 0x67, 0x13, 0x69, 0xCD, 0xAA, 0x0D, 0xAE, 0xEB, 0x62, 0xAF, 0x7E, 0xE1, 0x0B, 0x5F, + 0xB8, 0xF1, 0x3B, 0x5F, 0x5F, 0x11, 0x0F, 0xB5, 0x62, 0x56, 0xF0, 0x31, 0xF7, 0xF4, 0xE7, 0x2D, + 0x41, 0xB7, 0x6C, 0x4F, 0xC2, 0x5E, 0x3D, 0xF5, 0x5C, 0xE0, 0xD8, 0x3F, 0xDA, 0x2E, 0x7F, 0x6F, + 0x7F, 0x2E, 0xB8, 0xFF, 0xA0, 0x83, 0x0E, 0x1A, 0x62, 0xE3, 0x4A, 0x74, 0xCA, 0xE8, 0x23, 0x0C, + 0x49, 0x0C, 0x0C, 0xB8, 0x5C, 0xF7, 0x74, 0xDC, 0xCA, 0x2B, 0xD8, 0x86, 0xBC, 0x41, 0xDA, 0xF7, + 0xE2, 0x59, 0xC7, 0x43, 0xDB, 0xB8, 0xD7, 0x45, 0x17, 0x6D, 0x60, 0x26, 0xF1, 0x54, 0xFC, 0x9D, + 0xC9, 0x5B, 0xC6, 0x38, 0x3A, 0x6D, 0xD8, 0xB3, 0x9E, 0xF2, 0x94, 0xA7, 0x4C, 0xF6, 0x5F, 0xCA, + 0xD6, 0x1C, 0xBA, 0x58, 0x7C, 0x26, 0xE2, 0x9A, 0x99, 0x3A, 0xBE, 0x99, 0xFD, 0xCD, 0xE5, 0x2E, + 0x72, 0x2D, 0xC0, 0xDB, 0x86, 0x58, 0x84, 0x8B, 0x31, 0x92, 0xE3, 0x24, 0x55, 0xF0, 0x92, 0x3E, + 0xD7, 0xFF, 0x74, 0xBD, 0xE9, 0xB3, 0x0A, 0xCF, 0xF1, 0xF7, 0xF1, 0xFF, 0x7E, 0xAD, 0x31, 0x61, + 0x2F, 0x7C, 0xC9, 0x4B, 0x5E, 0x32, 0xC4, 0xAD, 0xE0, 0x7B, 0x5E, 0x92, 0x09, 0xE6, 0xD8, 0xEE, + 0x5B, 0xEB, 0x0E, 0x5E, 0x5A, 0xA6, 0xAE, 0xDB, 0x7F, 0x49, 0xE7, 0x46, 0x32, 0x1F, 0xF0, 0x91, + 0xD8, 0xB5, 0x6B, 0xD7, 0x26, 0x79, 0x28, 0x93, 0x53, 0x23, 0x7F, 0xA2, 0x90, 0xE7, 0x06, 0x9B, + 0x34, 0x39, 0x60, 0xE2, 0x7A, 0xA1, 0x46, 0xFD, 0xC9, 0xD4, 0xF6, 0xFB, 0x6F, 0xB7, 0x33, 0x5E, + 0x92, 0x6E, 0x4E, 0x9F, 0xC5, 0xF8, 0xB8, 0xB8, 0xFE, 0xD0, 0xED, 0x3D, 0xFB, 0xD9, 0xCF, 0x1E, + 0xBE, 0x5B, 0xB2, 0x65, 0xAD, 0xA3, 0xF0, 0x9C, 0xE3, 0x8F, 0x3F, 0x3E, 0xE5, 0x7D, 0xD0, 0xE2, + 0xE8, 0xA3, 0x8F, 0xDE, 0x94, 0x2F, 0x3A, 0x9B, 0x13, 0xCE, 0xAF, 0xA2, 0xCF, 0x4E, 0xFC, 0x5E, + 0xE9, 0xBD, 0x7F, 0x56, 0x93, 0x07, 0x89, 0x6F, 0x27, 0xFF, 0xE4, 0x19, 0x67, 0x9C, 0x31, 0x8C, + 0xBD, 0xFB, 0xA5, 0x38, 0x6F, 0xEB, 0xD1, 0x33, 0xCD, 0xD9, 0x23, 0x84, 0x97, 0xF4, 0x39, 0xFE, + 0x5D, 0xD8, 0xB0, 0xA6, 0xE2, 0x25, 0x2F, 0xDA, 0xFB, 0xC1, 0x2D, 0xD8, 0x1A, 0x63, 0xBE, 0x1A, + 0xCF, 0xC1, 0xC8, 0xDA, 0x45, 0xB7, 0xA1, 0xDF, 0x8D, 0x8D, 0x53, 0xF6, 0x79, 0xC4, 0xA9, 0xF0, + 0x02, 0x62, 0xF3, 0x7A, 0xCE, 0x86, 0x9B, 0x4A, 0x47, 0xD9, 0x68, 0x7A, 0x8A, 0xCF, 0x95, 0x68, + 0x73, 0x94, 0xBF, 0x77, 0xD4, 0xC1, 0x81, 0x67, 0xE5, 0x37, 0xE3, 0xBF, 0xF1, 0xFB, 0xF9, 0xFD, + 0x55, 0x18, 0x03, 0xFC, 0xF6, 0xC8, 0x4B, 0xA9, 0xFB, 0x45, 0x7F, 0x32, 0x64, 0x0B, 0x72, 0x3F, + 0x7C, 0xF4, 0xA3, 0x1F, 0x1D, 0x7E, 0x93, 0xE5, 0x61, 0x01, 0x23, 0x09, 0x2F, 0x5D, 0x68, 0xF4, + 0x47, 0x46, 0xC5, 0x86, 0xA8, 0x36, 0xAB, 0xDD, 0xD2, 0xF9, 0x2F, 0x85, 0x97, 0xE8, 0x1F, 0xEB, + 0x07, 0x7B, 0x5C, 0x8B, 0x4F, 0xDA, 0x94, 0xF1, 0x84, 0x1E, 0xB2, 0x67, 0xC1, 0x43, 0x90, 0x69, + 0x88, 0xB3, 0xBC, 0xB4, 0x45, 0xAB, 0xF3, 0x2F, 0xF8, 0xFA, 0x26, 0x4C, 0x04, 0x4E, 0x8A, 0xF8, + 0xA8, 0x07, 0x2F, 0x79, 0x71, 0x5F, 0xBD, 0xC8, 0x47, 0x35, 0xDE, 0xBB, 0x77, 0xEF, 0x1E, 0xD6, + 0x28, 0x7C, 0x0F, 0x1D, 0x41, 0xC9, 0xDF, 0xCA, 0xFB, 0xD3, 0xC2, 0x37, 0x4A, 0xDF, 0x69, 0xE1, + 0x37, 0x3B, 0x78, 0x69, 0x99, 0xBA, 0xEE, 0x7C, 0x95, 0xC2, 0x4B, 0xD8, 0xCD, 0xC9, 0x1F, 0x23, + 0xDD, 0x52, 0x7C, 0x9E, 0x9E, 0x99, 0xE9, 0x3D, 0x29, 0xF0, 0x20, 0x72, 0x5C, 0x2A, 0x76, 0x44, + 0xFC, 0x44, 0xD7, 0x4B, 0xDA, 0x9B, 0xB6, 0x13, 0x5E, 0xAA, 0xC9, 0x35, 0xBE, 0x67, 0xB9, 0xBF, + 0x77, 0xB6, 0x96, 0xD0, 0x57, 0x63, 0x73, 0xC1, 0x2E, 0x41, 0x2E, 0x3D, 0xF0, 0x15, 0xD7, 0xE8, + 0xA5, 0xA8, 0xE8, 0xFD, 0x78, 0xCF, 0xAB, 0x3E, 0xA3, 0xF2, 0xBD, 0x5A, 0xF5, 0xEF, 0xFA, 0xBD, + 0x54, 0xC1, 0x1D, 0xC8, 0xDC, 0x6A, 0x8B, 0xF8, 0x1C, 0x38, 0xE4, 0x91, 0x8F, 0x7C, 0xE4, 0x46, + 0xEE, 0x38, 0xE6, 0x43, 0xCC, 0xF1, 0xA6, 0x3E, 0xC7, 0x79, 0x51, 0xC3, 0x41, 0x25, 0xDA, 0x65, + 0xBF, 0x8D, 0x36, 0x60, 0xF6, 0x2C, 0x68, 0x80, 0x4D, 0x04, 0xDB, 0x5B, 0x9C, 0x67, 0x19, 0x56, + 0xF2, 0x9C, 0x45, 0x63, 0x18, 0xAA, 0x47, 0xBE, 0x2E, 0xF9, 0x45, 0xA1, 0x5F, 0xF5, 0xDC, 0x65, + 0x73, 0x62, 0x7C, 0x44, 0x03, 0xE5, 0xE7, 0x11, 0xCE, 0xD6, 0x7E, 0xE4, 0xFD, 0x21, 0xB7, 0x19, + 0x76, 0x49, 0xFD, 0xBE, 0x55, 0x8F, 0x94, 0xE9, 0x67, 0xF4, 0x3B, 0xF6, 0x55, 0xFC, 0x9B, 0xFD, + 0x0C, 0xE5, 0xA5, 0xAB, 0xC6, 0x07, 0x2C, 0x32, 0x85, 0xEF, 0x66, 0xD8, 0x90, 0xF7, 0x9C, 0x39, + 0x8C, 0xDF, 0xBF, 0xAF, 0x31, 0x74, 0x08, 0xC8, 0x24, 0x31, 0xFF, 0x79, 0x16, 0xB3, 0x20, 0x3D, + 0x84, 0xE8, 0x82, 0x9F, 0xDF, 0xF3, 0x9F, 0xFF, 0xFC, 0x8D, 0xB3, 0x8F, 0xB3, 0x3D, 0x16, 0xDF, + 0x06, 0xEC, 0x5C, 0xE8, 0x6F, 0xBC, 0x6C, 0xF2, 0x49, 0x5B, 0x5D, 0x66, 0x8F, 0xBB, 0xC0, 0xC6, + 0x19, 0xD9, 0x8A, 0xBC, 0x88, 0x6A, 0xB3, 0xC6, 0xFA, 0xFA, 0xD7, 0xBF, 0xFE, 0xC0, 0x37, 0xB1, + 0xC7, 0x4D, 0xE5, 0xF9, 0xF1, 0x77, 0x8C, 0x2B, 0xED, 0xF4, 0x3C, 0x4F, 0x4B, 0xF2, 0x50, 0x1F, + 0x5B, 0x7C, 0xEA, 0xC8, 0x79, 0x4F, 0x41, 0xDF, 0x8E, 0x1E, 0x09, 0xBC, 0x24, 0xBD, 0x12, 0xD7, + 0xC2, 0x4B, 0xC2, 0x48, 0xAE, 0x77, 0x8A, 0xF6, 0xB8, 0x96, 0xBE, 0x66, 0xE3, 0xA8, 0x02, 0x56, + 0x62, 0xFF, 0xBB, 0xF1, 0x8D, 0x6F, 0xBC, 0xC9, 0x8F, 0x34, 0xE6, 0x53, 0x8B, 0xFC, 0x23, 0xF2, + 0x90, 0x52, 0xDF, 0xA7, 0xCA, 0x67, 0x3B, 0x78, 0x69, 0xFB, 0xE0, 0x25, 0xE7, 0x87, 0x31, 0x7E, + 0x5C, 0xF3, 0x04, 0x5D, 0x32, 0x71, 0xB6, 0x9A, 0x5B, 0xCC, 0xED, 0x31, 0x1A, 0x39, 0x1F, 0x80, + 0x3F, 0x11, 0xF7, 0x00, 0xFE, 0x72, 0xD9, 0x3B, 0xB3, 0xC7, 0xCD, 0x2D, 0xDB, 0x15, 0x2F, 0xD5, + 0xFE, 0x2F, 0xFD, 0x52, 0x56, 0xB3, 0x7C, 0xD9, 0xFA, 0x3C, 0x93, 0x6D, 0x7A, 0xFC, 0x6D, 0x5A, + 0xF4, 0x2D, 0xEE, 0xF3, 0xAF, 0xCF, 0x39, 0x5F, 0x8B, 0xF3, 0x25, 0xC7, 0xE2, 0xA3, 0x5B, 0x68, + 0x51, 0xC2, 0x4B, 0xB5, 0xFB, 0xB8, 0x0F, 0x13, 0x7B, 0x05, 0x31, 0x62, 0x0F, 0x7E, 0xF0, 0x83, + 0x57, 0x37, 0xBF, 0xF9, 0xCD, 0x07, 0x6C, 0x2F, 0x7E, 0x5C, 0xE2, 0xD5, 0x19, 0xBF, 0x2B, 0xC9, + 0x89, 0xFE, 0xBD, 0xD6, 0xB9, 0x52, 0xC2, 0x4B, 0xEC, 0xA7, 0xE4, 0xEF, 0x54, 0x3F, 0x7C, 0x2F, + 0x6E, 0x59, 0xB3, 0xAE, 0xEB, 0x70, 0x9A, 0xA3, 0xBB, 0xD5, 0x33, 0x9C, 0xCF, 0x6B, 0x0D, 0x83, + 0x6B, 0x64, 0x67, 0x6A, 0x19, 0x8B, 0x1A, 0xED, 0xD5, 0x06, 0x30, 0x3E, 0x6B, 0x9A, 0x67, 0x2C, + 0xB5, 0xB7, 0x66, 0x7E, 0xC1, 0xBC, 0x82, 0x45, 0xC0, 0xC3, 0x3D, 0xA5, 0xA4, 0x33, 0xA3, 0x70, + 0x2F, 0x72, 0x32, 0xFB, 0x73, 0x98, 0x3B, 0xE0, 0x6D, 0x72, 0xC4, 0xC5, 0xB1, 0x89, 0x34, 0x8B, + 0xBA, 0x74, 0xFC, 0x8B, 0xB0, 0x8B, 0xC1, 0xC7, 0x22, 0xB6, 0xF6, 0xF9, 0x84, 0xBE, 0x02, 0xFF, + 0x28, 0xD7, 0x29, 0x7A, 0x5E, 0x09, 0xE1, 0xA4, 0xF3, 0x2F, 0xF5, 0x65, 0xE2, 0x7F, 0xF2, 0x11, + 0x45, 0x47, 0x8F, 0x7F, 0x95, 0xD3, 0x0B, 0xBC, 0xA4, 0xF3, 0x76, 0x97, 0xC2, 0x4B, 0x9C, 0xEB, + 0x08, 0xAE, 0x97, 0x7E, 0xD2, 0xF9, 0x75, 0x0F, 0x3F, 0x29, 0x8D, 0xAF, 0xF8, 0xC8, 0xA1, 0x87, + 0x1E, 0x3A, 0xEC, 0x0B, 0xBE, 0x77, 0x95, 0xF4, 0x77, 0xF1, 0x7F, 0x4B, 0x14, 0xE7, 0x21, 0xF8, + 0x6C, 0x61, 0x57, 0xC1, 0xA7, 0x1E, 0xDC, 0x1C, 0xF7, 0x3F, 0xB5, 0x3D, 0xE3, 0x97, 0xDE, 0xDF, + 0x2C, 0x67, 0x6C, 0xA4, 0xCD, 0xD8, 0x67, 0x59, 0xDD, 0xC1, 0x4B, 0xCB, 0xD4, 0xAD, 0xC2, 0x4B, + 0xAC, 0x53, 0xF9, 0x5C, 0x4A, 0xA6, 0xAD, 0xCD, 0x5F, 0xE7, 0xE7, 0x5C, 0xA3, 0x4B, 0xC6, 0x4E, + 0xCD, 0x1E, 0x4F, 0xF5, 0xD8, 0x0B, 0xE1, 0x90, 0xFF, 0x8D, 0x78, 0xA9, 0xD4, 0xB6, 0x58, 0xD0, + 0xEB, 0x64, 0xCF, 0xF3, 0x57, 0xF1, 0x9A, 0x12, 0x7E, 0x1A, 0xE3, 0x5F, 0x63, 0xD8, 0xA8, 0xF4, + 0x7B, 0xBD, 0x2A, 0x4F, 0x31, 0x7E, 0x1F, 0x6F, 0x7D, 0xEB, 0x5B, 0xF7, 0xD8, 0x4F, 0xA6, 0xE8, + 0x4A, 0xFC, 0xFB, 0x63, 0x7B, 0x35, 0x45, 0x36, 0x0C, 0x2A, 0x7B, 0x04, 0x63, 0x8C, 0x3D, 0x02, + 0x7B, 0x93, 0xFC, 0x2D, 0xBC, 0xBD, 0x59, 0x5F, 0x4A, 0xF4, 0x69, 0xD5, 0xAB, 0xB7, 0xD0, 0xAB, + 0x84, 0x97, 0xE2, 0x59, 0xAE, 0xAE, 0x1F, 0xEB, 0x2D, 0xA2, 0x3B, 0xFB, 0x29, 0xF6, 0x2A, 0xEC, + 0x3D, 0x1A, 0x23, 0xAD, 0x5D, 0xB5, 0xE7, 0x31, 0x8F, 0x79, 0x4C, 0x1A, 0x9F, 0x9D, 0x8D, 0x43, + 0xCB, 0x33, 0xF9, 0x1E, 0xBE, 0x1D, 0x60, 0x0C, 0xE7, 0x13, 0x4B, 0xAC, 0xB1, 0x28, 0x4F, 0x71, + 0x0D, 0x16, 0x41, 0x87, 0xB3, 0x44, 0xFB, 0xF5, 0x1D, 0x62, 0xD9, 0xFC, 0x19, 0xCC, 0x21, 0xE2, + 0xD0, 0xFC, 0xEC, 0x8B, 0x78, 0xCF, 0x92, 0x7E, 0x14, 0xDF, 0x1B, 0xCE, 0xD5, 0x41, 0x0F, 0x1C, + 0x31, 0x9F, 0x63, 0x04, 0xE2, 0x48, 0xE1, 0xD7, 0x2A, 0x6E, 0x8F, 0x95, 0xBF, 0xF7, 0xD7, 0x39, + 0x03, 0x1D, 0xFE, 0x7A, 0xE9, 0xBD, 0xDD, 0x5F, 0xF4, 0xB0, 0xC3, 0x0E, 0xDB, 0x74, 0x9E, 0x2B, + 0xF7, 0x63, 0xCF, 0x9B, 0x93, 0x7F, 0x29, 0xEA, 0x7F, 0xD1, 0x2F, 0xA1, 0xA3, 0xF5, 0xB5, 0xB4, + 0xE4, 0x9E, 0xC5, 0xFC, 0x24, 0x1E, 0x9F, 0x58, 0x41, 0xA7, 0x43, 0xD4, 0x01, 0x66, 0xBE, 0xF6, + 0x73, 0x4A, 0xD4, 0x91, 0x72, 0x26, 0x12, 0xBE, 0x04, 0xE8, 0x7B, 0x8F, 0x38, 0xE2, 0x88, 0xA1, + 0x4D, 0x3E, 0x5E, 0x92, 0x11, 0xB3, 0xB8, 0xD3, 0x52, 0x1D, 0x93, 0xBB, 0xA6, 0xD2, 0x6C, 0x07, + 0x2F, 0x2D, 0x53, 0xD7, 0x6D, 0x8F, 0xD3, 0x5C, 0xC1, 0xAE, 0xCF, 0xDC, 0xE2, 0xBE, 0x1E, 0xCB, + 0x59, 0x93, 0x53, 0x5D, 0x17, 0x75, 0xFA, 0xE9, 0xA7, 0x6F, 0xDC, 0xCF, 0xE3, 0x46, 0x54, 0x97, + 0xCC, 0xC7, 0xB8, 0xDD, 0xF1, 0x52, 0xC6, 0x6F, 0x75, 0x1E, 0x8A, 0xEF, 0x13, 0xA5, 0xBD, 0x3B, + 0xF3, 0xC7, 0xA9, 0xAD, 0xD3, 0xB1, 0x3E, 0xC5, 0x67, 0xD5, 0x9E, 0x4D, 0xEE, 0x62, 0xCE, 0x5F, + 0xC7, 0x4F, 0xC8, 0x71, 0x52, 0x8F, 0x6E, 0x68, 0xCC, 0x26, 0x97, 0xCD, 0xA9, 0x28, 0xEF, 0xB3, + 0x46, 0x91, 0xAB, 0xD1, 0xD7, 0x94, 0xE2, 0x9E, 0x5D, 0x37, 0x36, 0x46, 0x93, 0xB9, 0x38, 0x29, + 0xF2, 0xC4, 0x0C, 0x2F, 0xE9, 0x19, 0xF7, 0xBE, 0xF7, 0xBD, 0x37, 0xE5, 0xF6, 0x9E, 0x32, 0x87, + 0xBC, 0x40, 0x7F, 0x72, 0x7C, 0x70, 0xBE, 0x96, 0xE7, 0x48, 0xF0, 0xDC, 0xDE, 0x9C, 0xD5, 0x0C, + 0x7F, 0xAC, 0xD1, 0xBE, 0x65, 0xCC, 0x5C, 0x06, 0x62, 0x1D, 0xE0, 0xF3, 0x93, 0xD1, 0x7E, 0xA9, + 0xF5, 0xA6, 0xBE, 0x20, 0xFB, 0x7B, 0xFE, 0xD3, 0xB1, 0xB6, 0x96, 0x8A, 0xDB, 0x8D, 0xB1, 0x51, + 0x7A, 0xDB, 0xC9, 0x61, 0x4A, 0xEC, 0x9A, 0x68, 0x5A, 0x9A, 0x87, 0x19, 0xFD, 0xC1, 0x18, 0xB7, + 0xBF, 0xFD, 0xED, 0x37, 0x61, 0x19, 0x1F, 0x73, 0x8D, 0x05, 0xAF, 0xE4, 0xA0, 0x53, 0x89, 0xF9, + 0x19, 0x3C, 0x36, 0x4E, 0x2B, 0xCA, 0xDB, 0x0C, 0xCD, 0x39, 0x7B, 0x5B, 0xF7, 0x65, 0xCF, 0xD2, + 0x79, 0xBB, 0xAD, 0x25, 0xD3, 0xDB, 0xF8, 0xBA, 0x23, 0x07, 0x3D, 0xD8, 0xD1, 0x63, 0xA3, 0xE7, + 0xE2, 0x61, 0xE7, 0x53, 0xD8, 0x2A, 0x88, 0x11, 0x01, 0xFF, 0x6A, 0x4E, 0xD5, 0xCE, 0x34, 0x2E, + 0x61, 0x57, 0xFF, 0xDE, 0x18, 0xA6, 0x8D, 0x9F, 0x83, 0x41, 0xD1, 0xA3, 0x71, 0xEE, 0x3B, 0xF9, + 0x30, 0xA2, 0xBD, 0xAD, 0xB6, 0xB6, 0xE7, 0xF2, 0x90, 0x9A, 0x2E, 0xBF, 0xF4, 0x9B, 0x1D, 0xBC, + 0xB4, 0x4C, 0x5D, 0xB7, 0xBF, 0x37, 0x15, 0x1E, 0xCC, 0xB9, 0x16, 0x2A, 0x6E, 0x83, 0xC9, 0xE2, + 0x6C, 0xFC, 0x9A, 0xFA, 0xA9, 0x4F, 0x7D, 0x6A, 0x88, 0xDF, 0xF1, 0x7C, 0x34, 0xBC, 0xFA, 0x1A, + 0xFC, 0xBF, 0x82, 0x97, 0xBC, 0x7D, 0xFE, 0x5E, 0x78, 0x29, 0xDA, 0x8C, 0xB2, 0xF5, 0xB5, 0x2E, + 0x5F, 0x91, 0x52, 0xF5, 0xE7, 0x41, 0x4F, 0xF4, 0x3A, 0x9E, 0xA7, 0x24, 0xF2, 0xB8, 0x1A, 0xEF, + 0x72, 0xFF, 0xDB, 0x18, 0xD7, 0x1B, 0x6D, 0x1C, 0xF1, 0x3E, 0xCC, 0x37, 0xF4, 0x28, 0xC7, 0x1E, + 0x7B, 0xEC, 0x20, 0xFF, 0xEA, 0xDC, 0x37, 0xD1, 0xC5, 0xF3, 0x66, 0x46, 0xDE, 0xE3, 0x7E, 0xD0, + 0x73, 0xF4, 0xE2, 0x2D, 0x73, 0x24, 0xD2, 0x2C, 0x3E, 0x9B, 0x7D, 0x15, 0xDB, 0x0A, 0x25, 0xCB, + 0x8D, 0x50, 0x2B, 0x4E, 0x77, 0xBF, 0xC6, 0xAE, 0x81, 0x7D, 0xC9, 0xF7, 0x38, 0x3D, 0x17, 0x7A, + 0x9C, 0x79, 0xE6, 0x99, 0x1B, 0x3A, 0xE1, 0xCC, 0x9F, 0xC7, 0xF7, 0xA6, 0x1A, 0xE6, 0xF0, 0xEF, + 0x12, 0xFF, 0xED, 0x6B, 0x79, 0xA9, 0x79, 0x99, 0x8D, 0xC3, 0xD3, 0x9F, 0xFE, 0xF4, 0xA6, 0xFD, + 0xA2, 0x34, 0xFF, 0x54, 0x75, 0xCE, 0x32, 0x73, 0x49, 0x78, 0x49, 0x3C, 0x09, 0xFB, 0x90, 0xFC, + 0x0C, 0xB2, 0xF3, 0xDC, 0xE2, 0xBD, 0xFC, 0x7F, 0xEF, 0x7C, 0xE7, 0x3B, 0xD3, 0x33, 0xF4, 0xD4, + 0x17, 0xC6, 0x45, 0xFF, 0x3B, 0xE5, 0x94, 0x53, 0x86, 0xB1, 0xF3, 0x67, 0xE8, 0x9E, 0xC2, 0x49, + 0x1B, 0x7E, 0xDF, 0x01, 0x2B, 0x9C, 0x78, 0xE2, 0x89, 0xC3, 0x73, 0x34, 0xD7, 0x95, 0x7F, 0x89, + 0xD8, 0xE3, 0xD6, 0x78, 0xD8, 0x38, 0xFE, 0x7E, 0xA6, 0x0B, 0x95, 0x35, 0x76, 0xED, 0x6B, 0x5F, + 0x7B, 0xD3, 0x9A, 0xA2, 0x1F, 0x73, 0xF4, 0xDA, 0xAE, 0x63, 0x23, 0xBF, 0x29, 0x3E, 0xEF, 0x3C, + 0xCB, 0x65, 0xEF, 0x88, 0x51, 0x5D, 0x46, 0x2A, 0x8D, 0x41, 0xE4, 0x19, 0x71, 0xCC, 0x23, 0x7D, + 0xC9, 0xF9, 0xC0, 0xB9, 0xDF, 0xE8, 0xE9, 0xD8, 0x3B, 0xC9, 0xF9, 0x14, 0xD7, 0x67, 0x5C, 0x3F, + 0x63, 0xFC, 0xC1, 0xFB, 0xD8, 0x4A, 0x9B, 0xCC, 0x66, 0x57, 0xFB, 0xFD, 0x0E, 0x5E, 0x5A, 0xA6, + 0xAE, 0x3B, 0x9F, 0x00, 0x15, 0x79, 0xC6, 0xF3, 0x12, 0x3B, 0x9F, 0xF6, 0x39, 0x5E, 0xE2, 0x25, + 0xFC, 0x56, 0x79, 0xDC, 0x34, 0x5F, 0x9C, 0xAF, 0xF3, 0x1A, 0xF1, 0x52, 0xD4, 0xC7, 0xF6, 0x94, + 0xED, 0x88, 0x97, 0x6A, 0x7A, 0x38, 0x6A, 0xC9, 0x1E, 0x57, 0x5B, 0xA3, 0xA5, 0xF5, 0x15, 0xF9, + 0xD3, 0x58, 0x9F, 0xC6, 0xD6, 0xBF, 0x8F, 0x11, 0xFB, 0x96, 0xC6, 0xC7, 0x73, 0xF8, 0xD5, 0xFA, + 0x98, 0xD1, 0x21, 0xB3, 0x3F, 0x65, 0x71, 0x62, 0x5C, 0x83, 0x2D, 0x90, 0x79, 0xD9, 0xF3, 0x1F, + 0xF0, 0x80, 0x07, 0x0C, 0x3E, 0x22, 0x59, 0xFB, 0x7B, 0xF8, 0x55, 0xE9, 0x7A, 0x2C, 0xBF, 0xDC, + 0x14, 0x5E, 0xE8, 0x9F, 0xF1, 0x4A, 0xCC, 0x39, 0xF8, 0xC6, 0xE9, 0x37, 0xA6, 0x17, 0xC9, 0x8A, + 0xAF, 0x3D, 0x74, 0xBF, 0x0F, 0x7C, 0xE0, 0x03, 0x07, 0x9B, 0x9C, 0x9E, 0xEB, 0x67, 0x3F, 0xB2, + 0x06, 0xE7, 0xDA, 0x34, 0x5C, 0xBF, 0x04, 0xEE, 0x20, 0x3F, 0xA9, 0x63, 0xB2, 0x75, 0xF0, 0x37, + 0xD5, 0xA5, 0xF6, 0x0B, 0xCF, 0xD7, 0x8D, 0xEF, 0x95, 0xC6, 0x05, 0x5A, 0x11, 0xEB, 0xA9, 0x12, + 0x73, 0xC8, 0x39, 0x0D, 0xB2, 0xEF, 0xBC, 0xFD, 0xED, 0x6F, 0x1F, 0x68, 0xCF, 0xBD, 0x3C, 0xDF, + 0x46, 0x1C, 0x0B, 0x2A, 0xB9, 0x7C, 0x62, 0x9C, 0xC4, 0x06, 0x7D, 0x2F, 0xD5, 0x31, 0x61, 0x93, + 0xBB, 0x30, 0x3C, 0x87, 0xF1, 0x23, 0xA7, 0x00, 0xBE, 0xD8, 0x9A, 0x57, 0xE8, 0x46, 0x88, 0xA3, + 0x69, 0x39, 0x3F, 0xAE, 0xA4, 0x73, 0xA1, 0x38, 0x4F, 0x57, 0x6E, 0x13, 0x9E, 0xE1, 0xF9, 0xE1, + 0x7B, 0xD7, 0x80, 0xAF, 0x4B, 0xDD, 0x8F, 0x9C, 0x0D, 0xC7, 0x1C, 0x73, 0xCC, 0x26, 0xDB, 0x43, + 0x4F, 0xF1, 0xBD, 0x46, 0xAF, 0x2E, 0xB7, 0x65, 0x73, 0x9C, 0x75, 0xC6, 0xDC, 0x21, 0x4F, 0x19, + 0xBA, 0x71, 0xE8, 0xE7, 0x7A, 0xC0, 0x68, 0x8B, 0x6F, 0xC1, 0x46, 0x35, 0x1E, 0x52, 0xBB, 0xCE, + 0xFC, 0x25, 0xB7, 0x72, 0xFE, 0x7B, 0xD9, 0xC1, 0x4B, 0xD3, 0xDA, 0xE8, 0xB2, 0x3E, 0xB9, 0xB9, + 0xA0, 0x81, 0xD6, 0x09, 0x71, 0x50, 0x07, 0x1E, 0x78, 0xE0, 0xA0, 0xEF, 0x77, 0xB9, 0x36, 0xD3, + 0x9F, 0xFA, 0xB3, 0xA5, 0x7B, 0xE2, 0x95, 0xF3, 0xCB, 0x65, 0x1B, 0x8E, 0x39, 0x49, 0x34, 0xF7, + 0xB6, 0x6B, 0xFE, 0xA5, 0x38, 0xE7, 0x1D, 0x2F, 0x4D, 0x6D, 0x5F, 0x56, 0x6A, 0xFE, 0xDE, 0xB5, + 0x36, 0xC5, 0x75, 0x57, 0x92, 0x8F, 0x4A, 0x75, 0x2C, 0xFF, 0x9A, 0xAF, 0x73, 0x62, 0xE1, 0xE5, + 0x7B, 0x91, 0xC9, 0x6F, 0x53, 0x0A, 0xBF, 0x8B, 0xB9, 0x7A, 0xDD, 0xA7, 0x83, 0xBC, 0x33, 0x8C, + 0x23, 0xE7, 0x5A, 0x32, 0x17, 0xE3, 0xD9, 0xE5, 0xAA, 0x3D, 0xFB, 0x75, 0xEC, 0xDF, 0x98, 0xDE, + 0xAE, 0x17, 0x37, 0x65, 0xF4, 0x74, 0x3A, 0x93, 0x53, 0x83, 0x3D, 0x89, 0xB8, 0xA0, 0x8C, 0xEF, + 0x8F, 0xD1, 0x2B, 0xAE, 0x0F, 0x5E, 0xD9, 0x2F, 0x91, 0x73, 0xE0, 0x61, 0x7A, 0xA6, 0xF6, 0x04, + 0xF2, 0x11, 0x13, 0x53, 0x39, 0xB7, 0x68, 0x5D, 0xEB, 0x79, 0xF0, 0x05, 0xF5, 0xB1, 0x47, 0xF7, + 0x30, 0xA5, 0x2E, 0xB5, 0x5F, 0xB8, 0x2F, 0x10, 0x79, 0x75, 0x74, 0x7F, 0xFC, 0x80, 0xE0, 0x3F, + 0xA2, 0xAF, 0xFB, 0xC9, 0x39, 0x9E, 0xF1, 0x79, 0xEF, 0xF3, 0x14, 0xDF, 0x4E, 0xAD, 0x45, 0x97, + 0x05, 0x1D, 0x77, 0xE8, 0x1A, 0xBC, 0xA0, 0x7C, 0x65, 0x94, 0x4D, 0xF9, 0x0A, 0x56, 0x97, 0xC4, + 0xC7, 0xC9, 0xDF, 0x3B, 0xFE, 0x9F, 0xF5, 0x47, 0xCE, 0x5F, 0xCD, 0x55, 0xF0, 0x12, 0xED, 0xDE, + 0x75, 0x69, 0x9E, 0x97, 0xD6, 0x12, 0x71, 0x87, 0xFB, 0x9C, 0x3B, 0x5E, 0x8A, 0x72, 0x6D, 0x0B, + 0x3F, 0x89, 0xEF, 0x35, 0xF7, 0x59, 0xA3, 0xE4, 0x29, 0xF0, 0xF8, 0x50, 0xE1, 0xD7, 0x1E, 0xFE, + 0x31, 0xB6, 0x56, 0xF8, 0xBF, 0xE3, 0x30, 0xB0, 0x3D, 0xE7, 0x20, 0x91, 0x87, 0xCD, 0x73, 0xAE, + 0xF7, 0xC6, 0x70, 0xF4, 0xAE, 0x7D, 0xCF, 0xE7, 0x31, 0x97, 0xA7, 0xEC, 0xE0, 0xA5, 0x65, 0xEA, + 0x5C, 0xBC, 0x14, 0x71, 0x89, 0xD3, 0x50, 0xBA, 0x25, 0xD6, 0x37, 0xB1, 0x50, 0xB5, 0x7B, 0x47, + 0xFD, 0xA8, 0xCF, 0x67, 0xF4, 0xF6, 0x51, 0x5E, 0xF1, 0x79, 0x13, 0xF1, 0x52, 0x4F, 0xFB, 0xB3, + 0xB2, 0x1D, 0xF5, 0x4B, 0x63, 0xA5, 0x15, 0x2F, 0x8D, 0xC9, 0x40, 0xBD, 0x76, 0xA5, 0xD2, 0x3D, + 0xFC, 0x5A, 0x6B, 0x9E, 0x58, 0xEB, 0x78, 0x96, 0x83, 0x4A, 0x8F, 0xEE, 0xC2, 0x73, 0xC2, 0x3B, + 0x56, 0xF2, 0xFD, 0x07, 0x2C, 0x41, 0x0C, 0x39, 0x31, 0x6F, 0xB7, 0xB8, 0xC5, 0x2D, 0x86, 0x33, + 0x74, 0x62, 0x0E, 0x4F, 0xBF, 0xF6, 0x9C, 0x2E, 0x73, 0x78, 0x9C, 0xB0, 0xCD, 0x92, 0xFC, 0x34, + 0xCA, 0x06, 0xF8, 0x6F, 0x10, 0xEF, 0x45, 0xDC, 0x7A, 0x29, 0x17, 0x4C, 0xAD, 0x64, 0xBE, 0xB0, + 0x9F, 0xFF, 0xFC, 0xE7, 0x87, 0x9C, 0x02, 0xD8, 0x6A, 0xF4, 0x5C, 0x9D, 0xED, 0x07, 0x3E, 0x23, + 0xDF, 0xD0, 0x9C, 0x12, 0xD7, 0x36, 0xE7, 0xEC, 0x2A, 0xB6, 0x5D, 0xCF, 0x5A, 0xC2, 0x9E, 0x59, + 0xAA, 0x4B, 0xED, 0x17, 0x5F, 0xFD, 0xEA, 0x57, 0x37, 0xE6, 0x2E, 0xFA, 0x31, 0x8D, 0x0F, 0xF1, + 0x60, 0xC4, 0x58, 0x3A, 0x46, 0xCA, 0x74, 0x19, 0xBE, 0xB7, 0x6B, 0x0C, 0x58, 0x13, 0x27, 0x9D, + 0x74, 0xD2, 0xC6, 0x3C, 0xD4, 0x3C, 0xF5, 0xF9, 0xE3, 0x78, 0x19, 0xB9, 0x03, 0xFB, 0x5D, 0xA4, + 0xED, 0x70, 0xCF, 0xD5, 0x65, 0xF9, 0x04, 0x2E, 0xB4, 0xFF, 0xAB, 0xC0, 0x87, 0xE1, 0xC7, 0xBA, + 0x2F, 0x39, 0xCA, 0x89, 0x8D, 0x54, 0x4C, 0x7E, 0x8B, 0x8E, 0x29, 0xDA, 0xAE, 0x28, 0x8E, 0x09, + 0xC5, 0x8B, 0xB4, 0xF6, 0xC7, 0x74, 0x2E, 0x59, 0xF5, 0xFE, 0xBA, 0x0E, 0x92, 0xB3, 0xD7, 0x94, + 0xAF, 0x4D, 0x73, 0x3E, 0xB6, 0xA5, 0xA5, 0x38, 0x66, 0x12, 0xBE, 0xA5, 0xB8, 0x8D, 0x93, 0xF8, + 0x06, 0xC6, 0x85, 0x71, 0xC6, 0xEF, 0xD2, 0xF7, 0x9E, 0x8C, 0x57, 0xD4, 0xE6, 0x70, 0x6B, 0xFF, + 0x9D, 0x66, 0xDB, 0x71, 0xFE, 0x7B, 0xD9, 0xC1, 0x4B, 0xD3, 0xDB, 0xA8, 0xDF, 0xE0, 0x9B, 0x42, + 0x2C, 0x8A, 0xC6, 0x1E, 0x4C, 0x0E, 0xEE, 0x90, 0xBF, 0xC5, 0xD8, 0xEF, 0xE3, 0x7A, 0x84, 0x97, + 0x28, 0x6E, 0xD7, 0x75, 0x4B, 0x63, 0xF9, 0x2A, 0xE7, 0x94, 0xFF, 0x6B, 0x78, 0x29, 0xD3, 0x29, + 0x97, 0xBE, 0xDF, 0xA2, 0x73, 0xCE, 0x78, 0x1F, 0xBA, 0x0A, 0xCE, 0xE4, 0xA6, 0xB8, 0x2C, 0xDA, + 0x63, 0x8B, 0x53, 0xC9, 0x62, 0x86, 0x85, 0x9B, 0x78, 0x25, 0x46, 0x09, 0x1F, 0x0F, 0x7C, 0x94, + 0x74, 0xAE, 0x57, 0xA4, 0x81, 0xCF, 0xA3, 0xA5, 0x30, 0x8D, 0xBF, 0xC6, 0xCF, 0xA9, 0x53, 0x6C, + 0x4E, 0x91, 0xDE, 0xB4, 0x15, 0xBB, 0x26, 0xF1, 0x6A, 0xE8, 0x04, 0x32, 0xFF, 0x8B, 0xD6, 0xE2, + 0xDF, 0x47, 0x0F, 0xF7, 0xEA, 0x57, 0xBF, 0x7A, 0x75, 0xC0, 0x01, 0x07, 0x6C, 0x7A, 0x3E, 0xF1, + 0x78, 0xAC, 0x01, 0xF0, 0x4D, 0xAF, 0x8D, 0x3E, 0xCA, 0x40, 0x7A, 0x45, 0x5E, 0x47, 0x9F, 0xA2, + 0xD8, 0x38, 0xCD, 0x91, 0x75, 0xFA, 0xD5, 0x2D, 0xB5, 0x5F, 0x28, 0x47, 0x2C, 0xFB, 0x34, 0xB1, + 0xE3, 0x6A, 0x3B, 0xB9, 0xE5, 0x5C, 0x77, 0x5A, 0xD2, 0x6F, 0x67, 0xFE, 0xC8, 0x9F, 0xF9, 0xCC, + 0x67, 0x06, 0xFF, 0x4C, 0xC7, 0x49, 0x3E, 0xF6, 0xFA, 0x4C, 0xD7, 0xE8, 0x58, 0x38, 0xD3, 0x57, + 0xF7, 0x73, 0x1D, 0x96, 0xFC, 0x96, 0x4A, 0x78, 0x09, 0x5C, 0x44, 0x5E, 0x17, 0xDD, 0x9B, 0x7B, + 0xE1, 0xB7, 0x5C, 0x3A, 0xF7, 0x2C, 0x96, 0x0C, 0x03, 0x0E, 0xCF, 0x35, 0xAC, 0x5E, 0xCA, 0x05, + 0xD7, 0x63, 0xEF, 0xF6, 0xB5, 0xE2, 0x38, 0x05, 0xFC, 0x82, 0x8E, 0x2F, 0xFA, 0xB9, 0x53, 0xA2, + 0xCF, 0x58, 0x56, 0x4A, 0x31, 0x73, 0x7E, 0xCD, 0xFC, 0x24, 0x67, 0x03, 0x7C, 0xFA, 0x56, 0xB7, + 0xBA, 0xD5, 0xC6, 0xDA, 0xA5, 0x5D, 0x8E, 0x93, 0x24, 0x63, 0xF5, 0xF8, 0x29, 0xD5, 0x3E, 0xCB, + 0xF4, 0xD4, 0xD9, 0x5E, 0x37, 0xC6, 0x83, 0xD6, 0x39, 0xFF, 0xBD, 0xEC, 0xE0, 0xA5, 0xE9, 0x6D, + 0xA4, 0x30, 0x5F, 0xF1, 0x13, 0x21, 0x66, 0x40, 0xF7, 0xBF, 0xC7, 0x3D, 0xEE, 0xB1, 0x11, 0x57, + 0xE3, 0xF9, 0xD9, 0x32, 0x39, 0x2B, 0x3E, 0x13, 0x9D, 0x28, 0xB9, 0xD9, 0x90, 0x43, 0x7D, 0x5E, + 0x66, 0xEB, 0x6E, 0x49, 0x1C, 0xF2, 0x7F, 0x09, 0x2F, 0x39, 0x2D, 0xC9, 0x3B, 0x44, 0xBC, 0xD2, + 0x0D, 0x6E, 0x70, 0x83, 0x41, 0x87, 0xC1, 0xEB, 0xDC, 0x8A, 0x3F, 0x29, 0x31, 0xD2, 0xAC, 0x0D, + 0xE9, 0x28, 0x4A, 0xFE, 0x1C, 0x2D, 0x73, 0x4E, 0x76, 0x5A, 0xD7, 0x2B, 0x69, 0xEE, 0xF2, 0x7B, + 0xCE, 0xFF, 0x26, 0x2E, 0x5B, 0x71, 0x57, 0x54, 0xC9, 0x7D, 0x1E, 0x5B, 0x99, 0xF9, 0x19, 0xB5, + 0xCA, 0x7F, 0x19, 0x5F, 0xCC, 0xF6, 0xB8, 0x16, 0x1E, 0x3A, 0xA5, 0xE2, 0xC3, 0x01, 0x3F, 0x50, + 0x3E, 0xA4, 0x29, 0x76, 0x94, 0xF8, 0x3B, 0x9D, 0x89, 0xC6, 0xFE, 0xE0, 0xED, 0x45, 0x2F, 0x87, + 0x6F, 0xAB, 0x62, 0x5B, 0x5B, 0x9F, 0xE1, 0xDF, 0x8D, 0x7E, 0xF9, 0xC8, 0x54, 0xAC, 0x01, 0x9D, + 0xA7, 0xB5, 0x15, 0xF1, 0x07, 0x4B, 0xED, 0x17, 0x8E, 0x13, 0x64, 0x8F, 0x83, 0x56, 0xC4, 0x10, + 0x28, 0xDF, 0x42, 0xA6, 0x23, 0x8F, 0xB4, 0x73, 0x1A, 0xC1, 0x33, 0xD1, 0x83, 0xBA, 0xAD, 0xB8, + 0xE4, 0x3B, 0xCC, 0x5C, 0x46, 0xD7, 0x81, 0x7E, 0x51, 0xC5, 0xE3, 0x4B, 0x4B, 0xF9, 0xBD, 0x5D, + 0x0F, 0x89, 0x3D, 0x4B, 0xFB, 0x3E, 0x71, 0x6C, 0xEF, 0x78, 0xC7, 0x3B, 0x2E, 0xC9, 0xF5, 0x38, + 0xC1, 0x3F, 0x2D, 0xC3, 0x2A, 0x3A, 0x13, 0x30, 0xD6, 0x96, 0x71, 0xCE, 0xD6, 0x8E, 0x72, 0xC7, + 0xD2, 0x66, 0xF8, 0x9C, 0xFA, 0x21, 0x5B, 0x5C, 0x4F, 0xBB, 0xE3, 0x77, 0x7D, 0x5E, 0xEA, 0x7F, + 0xE4, 0x3A, 0x21, 0x56, 0x94, 0x33, 0x49, 0x4B, 0xFC, 0x53, 0xE3, 0x34, 0x85, 0x87, 0xD4, 0xFA, + 0x1E, 0xFD, 0xB6, 0xE6, 0xFA, 0x43, 0x2E, 0x3D, 0xFF, 0xBD, 0xEC, 0xE0, 0xA5, 0xFE, 0x36, 0xBA, + 0x1C, 0xC5, 0xBA, 0x25, 0x07, 0xB0, 0xF2, 0x92, 0x30, 0xD6, 0x87, 0x1F, 0x7E, 0xF8, 0x26, 0xBF, + 0xA5, 0x8C, 0x6F, 0x44, 0xFB, 0xBE, 0x0A, 0xE3, 0xC1, 0x79, 0x49, 0x9E, 0xFF, 0xCB, 0xD7, 0x9D, + 0xCF, 0xA5, 0xE8, 0xEF, 0x3D, 0x45, 0xDE, 0x8E, 0x7D, 0xFF, 0xDF, 0xEA, 0xBF, 0xE4, 0xD5, 0x73, + 0xA4, 0xC0, 0x87, 0x0F, 0x39, 0xE4, 0x90, 0xC1, 0x8F, 0x85, 0x58, 0x7B, 0xF4, 0x75, 0xB4, 0x75, + 0x4E, 0x45, 0x6E, 0x26, 0x9E, 0x8B, 0x9C, 0x4B, 0x3A, 0x87, 0x34, 0xF6, 0x7D, 0xCE, 0x38, 0x79, + 0x8C, 0x25, 0x71, 0x2B, 0x77, 0xB9, 0xCB, 0x5D, 0x86, 0x3D, 0x5E, 0xFC, 0xAC, 0x96, 0x43, 0x29, + 0xEA, 0xD3, 0x7A, 0xF1, 0x52, 0x36, 0x27, 0x55, 0xE3, 0xB3, 0x97, 0xC2, 0x4B, 0xDC, 0x07, 0xCC, + 0x87, 0x1E, 0x88, 0x33, 0x17, 0x28, 0x31, 0xCE, 0xB0, 0x87, 0x7E, 0x14, 0xD9, 0x31, 0xF1, 0x29, + 0xC2, 0xAE, 0xE4, 0x6D, 0x65, 0x5D, 0x61, 0xBF, 0x41, 0x07, 0x32, 0x27, 0x7E, 0xC2, 0xC7, 0x98, + 0xD8, 0x26, 0x62, 0xC9, 0xF0, 0x8B, 0xAA, 0xD1, 0x70, 0xC9, 0xBA, 0xA4, 0x7E, 0x49, 0x45, 0xFA, + 0x25, 0xE8, 0x85, 0xCE, 0x46, 0xBE, 0x4D, 0x99, 0xBE, 0x2F, 0xE2, 0x47, 0x97, 0x19, 0x19, 0x47, + 0x9D, 0x77, 0xAC, 0xB9, 0x53, 0xF3, 0x5B, 0x41, 0x06, 0x79, 0xC6, 0x33, 0x9E, 0xB1, 0x71, 0x4F, + 0xF1, 0xEE, 0x21, 0xAE, 0xFE, 0xA2, 0xCB, 0x72, 0x55, 0x3A, 0x5E, 0x72, 0x6C, 0x4C, 0xFC, 0x1A, + 0x32, 0x0C, 0xF7, 0xBA, 0xF5, 0xAD, 0x6F, 0x3D, 0x3C, 0x3F, 0x3B, 0x6F, 0x21, 0x96, 0x9A, 0xBE, + 0xCC, 0x79, 0xBB, 0xF4, 0x4B, 0xD2, 0xBF, 0x4C, 0xB5, 0xEF, 0xC7, 0xB5, 0xC6, 0xFE, 0x8A, 0xCF, + 0xB5, 0xB0, 0xA8, 0x9E, 0x39, 0x65, 0x3F, 0x8D, 0x7A, 0x69, 0x0A, 0x3E, 0xF4, 0xEC, 0x37, 0xC4, + 0x53, 0x08, 0x2B, 0xF9, 0x3A, 0x8E, 0xE7, 0x47, 0x46, 0x9B, 0x61, 0x8B, 0xDE, 0x3D, 0xD3, 0xDD, + 0x97, 0x78, 0x44, 0xE4, 0x55, 0x73, 0xD6, 0xC7, 0x0E, 0x5E, 0x5A, 0xA6, 0x2E, 0xE5, 0xEF, 0xAD, + 0xEF, 0xE3, 0xEB, 0x87, 0x1F, 0x27, 0xF3, 0x8C, 0x58, 0x4B, 0xCE, 0xA5, 0x52, 0xC9, 0xE2, 0x5F, + 0xF5, 0x7B, 0x7D, 0xE6, 0x3C, 0xF9, 0x43, 0x1F, 0xFA, 0xD0, 0xC0, 0x57, 0x91, 0xA7, 0x7D, 0x7E, + 0x45, 0xFB, 0x91, 0xF8, 0xFA, 0x0E, 0x5E, 0xEA, 0x6F, 0x9F, 0x74, 0xDD, 0xF0, 0x02, 0xB0, 0x06, + 0x31, 0x64, 0xC8, 0xC9, 0xE8, 0x00, 0xB0, 0xF7, 0xEC, 0xDE, 0xBD, 0xBB, 0x5A, 0xFD, 0x3B, 0x5C, + 0xC7, 0x8A, 0x9F, 0xFF, 0xE3, 0x1E, 0xF7, 0xB8, 0x61, 0x6F, 0xE1, 0x5A, 0xFD, 0x9E, 0xBA, 0xF7, + 0x2A, 0x56, 0xC0, 0xF7, 0x1B, 0x7C, 0x4A, 0x88, 0xDF, 0xC2, 0xB6, 0x90, 0xF1, 0x14, 0x9D, 0x41, + 0xAC, 0xB1, 0xC0, 0x36, 0xC8, 0xF7, 0xC8, 0x6D, 0x8C, 0x6F, 0x13, 0x3A, 0x15, 0xF0, 0x1C, 0xBE, + 0x1C, 0xAC, 0x87, 0x5A, 0xD5, 0xF7, 0x78, 0xE5, 0x3D, 0xF6, 0x66, 0xAE, 0xD9, 0x77, 0x78, 0x8F, + 0xFF, 0x8F, 0xE6, 0x6B, 0x6C, 0xC3, 0x14, 0xF9, 0xDA, 0xAB, 0x7C, 0x81, 0xF9, 0x0E, 0x98, 0x50, + 0x3E, 0xD8, 0x99, 0x3E, 0xA3, 0xB5, 0x88, 0x7E, 0x14, 0xCE, 0x18, 0x66, 0xBE, 0x7B, 0x1B, 0x88, + 0xB3, 0x20, 0xDE, 0x02, 0xFF, 0xA6, 0xDE, 0x1C, 0x59, 0x2A, 0xB1, 0x6D, 0xCC, 0x03, 0x62, 0x8C, + 0x5C, 0x7E, 0xEF, 0xB1, 0x3B, 0x5C, 0x9E, 0xFB, 0x85, 0x9F, 0x4B, 0xE0, 0xFE, 0x4B, 0xF2, 0x41, + 0xF6, 0xB8, 0xCF, 0x48, 0x13, 0xBD, 0xBA, 0xDF, 0x0D, 0xF5, 0xAC, 0xB3, 0xCE, 0x1A, 0xCE, 0xA7, + 0x75, 0x5A, 0x64, 0x73, 0x45, 0xE3, 0x02, 0xCE, 0x04, 0xC3, 0x0A, 0x07, 0xE9, 0x79, 0xC2, 0x4B, + 0x8A, 0x8D, 0xF3, 0x7C, 0x02, 0x9E, 0xCF, 0x11, 0x1D, 0xAC, 0xEC, 0xAE, 0xC4, 0xE6, 0xA3, 0xF7, + 0xA5, 0x5F, 0x53, 0x72, 0xEC, 0x8B, 0xF7, 0x7B, 0xDC, 0x20, 0xBC, 0x48, 0x3C, 0x5A, 0x6B, 0xAD, + 0x37, 0x3E, 0x2E, 0xCE, 0x07, 0xF8, 0x53, 0x94, 0xB9, 0xB2, 0x76, 0xB4, 0xB4, 0x3F, 0xB3, 0xE5, + 0x81, 0x95, 0xE0, 0x7D, 0xA2, 0x4B, 0x29, 0x1E, 0x24, 0xF6, 0x83, 0x73, 0x4F, 0xB0, 0xFB, 0x93, + 0x5B, 0x02, 0x3D, 0x01, 0xAF, 0x54, 0xF6, 0xEB, 0x58, 0xF5, 0x79, 0xFC, 0x0E, 0x71, 0x96, 0x54, + 0xBD, 0xDF, 0x77, 0xDF, 0x7D, 0x37, 0xC5, 0x43, 0xB6, 0xC6, 0x2A, 0x6F, 0xC5, 0xFC, 0xF7, 0xB2, + 0x83, 0x97, 0xFA, 0xDB, 0xA8, 0x35, 0xAB, 0xF9, 0x87, 0xEC, 0xC2, 0xBE, 0xCB, 0x18, 0x23, 0xAB, + 0x2A, 0x8F, 0x40, 0xC6, 0x43, 0xA3, 0x0D, 0x9C, 0xE2, 0x6B, 0x16, 0xBD, 0x28, 0xF9, 0x04, 0xB5, + 0xDF, 0xC5, 0xBD, 0xC3, 0x79, 0xC8, 0xFF, 0x85, 0xF3, 0x76, 0x6B, 0x65, 0x0C, 0x2F, 0x95, 0x6C, + 0xE7, 0x31, 0x37, 0x12, 0x34, 0x77, 0x3A, 0x8C, 0xD5, 0xB1, 0x42, 0xFE, 0x3E, 0x72, 0x1D, 0x92, + 0xAF, 0x14, 0x4C, 0x15, 0x73, 0x53, 0xF6, 0xFA, 0x2F, 0x89, 0xD7, 0xB1, 0xB7, 0xAB, 0x20, 0x1F, + 0xE3, 0x0B, 0xE3, 0x7A, 0xF2, 0xCC, 0x17, 0x40, 0x7C, 0x57, 0xFF, 0x23, 0x7E, 0x1E, 0xBA, 0xB1, + 0x5F, 0xE0, 0x3F, 0x8B, 0x5D, 0x82, 0xB5, 0x30, 0x56, 0x91, 0x71, 0x75, 0x4D, 0x1C, 0x38, 0xCF, + 0x67, 0x0F, 0xE2, 0x15, 0xF9, 0x80, 0x35, 0xE5, 0x32, 0x69, 0xB4, 0xAF, 0xD4, 0x6A, 0x29, 0x2E, + 0x59, 0xB2, 0xBA, 0xF3, 0x51, 0xD9, 0x26, 0xA0, 0x5D, 0x8C, 0x11, 0x2C, 0x95, 0x68, 0x0B, 0x85, + 0x9E, 0xC2, 0x4B, 0xBC, 0x27, 0x17, 0xA6, 0xEB, 0x6F, 0x39, 0x7F, 0x83, 0x7E, 0xB6, 0xDE, 0x5F, + 0x63, 0xE4, 0xE3, 0x2A, 0xFE, 0xA0, 0xE7, 0x41, 0x6B, 0x9D, 0x9B, 0xAD, 0xF1, 0xBA, 0xA2, 0xE4, + 0x13, 0xF0, 0xB8, 0x5E, 0x62, 0x2E, 0xB5, 0x8E, 0xC0, 0xAE, 0xC2, 0x0D, 0x99, 0xAE, 0x26, 0xEA, + 0x00, 0x1D, 0x5F, 0x90, 0x5F, 0x1E, 0xFB, 0x71, 0xB4, 0xC1, 0x89, 0x2E, 0xDA, 0x2F, 0xC1, 0x1E, + 0xA2, 0x13, 0x6B, 0x55, 0xF4, 0xF5, 0xFB, 0x7A, 0xAE, 0xCA, 0xF3, 0x2F, 0x5D, 0x2B, 0x54, 0x9E, + 0x27, 0xDC, 0xF4, 0x91, 0x8F, 0x7C, 0x64, 0xE3, 0x1C, 0x1A, 0xF0, 0xBE, 0x74, 0x36, 0x7E, 0xBF, + 0x52, 0x89, 0xBA, 0x33, 0xBD, 0xF7, 0xF9, 0xE1, 0xB9, 0x73, 0xB1, 0xA5, 0xF5, 0x62, 0xE1, 0x4C, + 0x57, 0x0B, 0xB6, 0x46, 0x1E, 0x7A, 0xD7, 0xBB, 0xDE, 0x95, 0xD2, 0xB3, 0x15, 0xCB, 0xBB, 0xEF, + 0xA4, 0xE6, 0xA6, 0xF2, 0xDB, 0x73, 0xD6, 0x71, 0xC6, 0x37, 0x34, 0x0E, 0x9E, 0x03, 0x4B, 0xB6, + 0x7D, 0x9F, 0x57, 0x1E, 0x27, 0x3E, 0x46, 0xC3, 0xD2, 0xFA, 0xA0, 0x2D, 0xDC, 0x13, 0xF9, 0x5F, + 0x74, 0x1B, 0xD3, 0x7F, 0xB7, 0xF0, 0x95, 0x1D, 0xBC, 0xB4, 0x3D, 0xF0, 0x12, 0xFB, 0x96, 0xC7, + 0xCE, 0xB2, 0xDF, 0x32, 0xAF, 0xB9, 0x37, 0xE7, 0x46, 0x7F, 0xF2, 0x93, 0x9F, 0xDC, 0xB4, 0xBE, + 0xE2, 0xAB, 0xCF, 0x15, 0x8A, 0xCB, 0x4A, 0xF8, 0x34, 0xBA, 0x4E, 0x80, 0x57, 0xE5, 0x1F, 0x16, + 0x1F, 0x11, 0x8F, 0xD9, 0xF1, 0xF7, 0x1E, 0xC7, 0x4B, 0x99, 0x2E, 0xD8, 0xD7, 0x22, 0xBE, 0x66, + 0xE7, 0x9C, 0x73, 0x4E, 0x17, 0x1E, 0x8A, 0xBE, 0x29, 0xFE, 0x9E, 0xC2, 0x9A, 0x22, 0x17, 0x2F, + 0x36, 0x3E, 0x6C, 0x3A, 0xA2, 0x6F, 0x66, 0x97, 0xED, 0x59, 0x17, 0x9A, 0x27, 0xE4, 0x21, 0xC2, + 0xF7, 0x39, 0x3B, 0x7F, 0x2C, 0xC3, 0x1D, 0xF0, 0x6F, 0xF1, 0xEE, 0xE3, 0x8E, 0x3B, 0x6E, 0xD0, + 0xA5, 0x31, 0xF7, 0xB1, 0xA5, 0xE0, 0xE7, 0xC9, 0x6B, 0xAD, 0x82, 0x2D, 0x98, 0xF3, 0xBC, 0xEA, + 0x33, 0x7E, 0xC7, 0x67, 0x5C, 0xA3, 0x5F, 0xBD, 0xFB, 0xDD, 0xEF, 0x5E, 0x6C, 0x47, 0xCB, 0x1C, + 0x89, 0xEF, 0x1D, 0x43, 0x09, 0x2F, 0xD1, 0x5F, 0xCE, 0x91, 0xE3, 0xAC, 0x32, 0x4A, 0x6B, 0x1E, + 0x9A, 0x68, 0x23, 0x82, 0x8E, 0x9E, 0xC3, 0x07, 0xFB, 0x29, 0xB6, 0x1A, 0xED, 0x09, 0xE8, 0x3D, + 0xDE, 0xF3, 0x9E, 0xF7, 0x74, 0xE9, 0xAE, 0x32, 0xFB, 0xBA, 0xEB, 0x37, 0xD8, 0x9F, 0xE5, 0x87, + 0xEF, 0xF9, 0xC4, 0x5B, 0xD7, 0x50, 0xCF, 0x7E, 0xAB, 0xEF, 0x13, 0x83, 0x32, 0x67, 0xBF, 0x50, + 0x5F, 0xDC, 0xF6, 0x25, 0x7B, 0x1C, 0x76, 0x6C, 0xF0, 0x72, 0xEB, 0x7A, 0xD1, 0xEF, 0x45, 0x93, + 0x27, 0x3E, 0xF1, 0x89, 0x83, 0x4E, 0x52, 0x7C, 0xAD, 0x84, 0x97, 0xA1, 0x95, 0xE6, 0x39, 0xE7, + 0x4B, 0x21, 0x8B, 0x5C, 0x68, 0x98, 0x28, 0xEA, 0xEF, 0xB3, 0x3E, 0xF0, 0x7D, 0xE4, 0x16, 0xCE, + 0xD4, 0x01, 0x83, 0xA0, 0x4F, 0x81, 0xFF, 0xC7, 0xF3, 0x44, 0xC6, 0x68, 0xC1, 0xD1, 0xB4, 0x17, + 0x5D, 0x78, 0x49, 0xBD, 0xF0, 0x82, 0x8B, 0xF7, 0xF9, 0xAF, 0x9D, 0x3F, 0xBC, 0xF2, 0x3F, 0xEC, + 0x71, 0x11, 0x77, 0xF4, 0xCC, 0x7F, 0xD7, 0xE5, 0xE8, 0x9A, 0x7E, 0x63, 0xD7, 0xE7, 0x9C, 0xB6, + 0x31, 0xDA, 0x8E, 0xB5, 0xDD, 0xF7, 0x1E, 0xAE, 0xC1, 0x8F, 0x9C, 0xFD, 0xED, 0xBA, 0xB0, 0x12, + 0xAF, 0x54, 0xEC, 0x0A, 0x9F, 0xD3, 0x36, 0xE4, 0x23, 0xC9, 0x6E, 0xD1, 0x5F, 0x2D, 0xAE, 0xB5, + 0xD2, 0xFB, 0xA8, 0x6F, 0x7F, 0xE6, 0x33, 0x9F, 0x39, 0xC4, 0x95, 0xEB, 0xF9, 0x8E, 0x99, 0xA7, + 0xEE, 0x3D, 0x3B, 0x78, 0x69, 0x7B, 0xE0, 0xA5, 0x38, 0x07, 0x38, 0xE7, 0x0D, 0x1D, 0x2F, 0xF7, + 0xC6, 0xA6, 0xCF, 0x3A, 0x94, 0x7F, 0xC4, 0x98, 0xCE, 0x34, 0xEE, 0xB3, 0xE4, 0x65, 0xF3, 0x75, + 0x93, 0xD9, 0x88, 0x25, 0x77, 0x83, 0xC7, 0xD9, 0x93, 0x75, 0x9F, 0x39, 0xB9, 0xF5, 0x96, 0xC4, + 0x4B, 0x31, 0x86, 0x1D, 0x9F, 0xEA, 0x87, 0x3D, 0xEC, 0x61, 0xD5, 0x67, 0x47, 0x9A, 0x66, 0x45, + 0x72, 0x91, 0x78, 0x24, 0xF1, 0x46, 0xA2, 0x87, 0xFC, 0x23, 0xF5, 0xDE, 0xE9, 0x26, 0x5A, 0x66, + 0xF1, 0x1E, 0xE8, 0x95, 0x91, 0x93, 0x7B, 0x68, 0x37, 0x86, 0x7B, 0x18, 0x47, 0xE4, 0x67, 0xFC, + 0xA1, 0xC8, 0x21, 0x9C, 0x7D, 0xA7, 0xA7, 0xC4, 0x7C, 0xD6, 0xD8, 0x32, 0xD0, 0x81, 0xC4, 0xBE, + 0x64, 0xBC, 0x8E, 0xF7, 0x6E, 0x03, 0x42, 0xEF, 0xC5, 0xB9, 0x2C, 0x53, 0xDA, 0x54, 0x1A, 0x23, + 0xE8, 0x87, 0xAE, 0x7D, 0xE9, 0xF3, 0xD0, 0xB2, 0xBD, 0x06, 0x6C, 0x83, 0x3C, 0x22, 0x5A, 0x4C, + 0x29, 0x92, 0x6F, 0xF5, 0xFB, 0xE3, 0x8F, 0x3F, 0x7E, 0xB0, 0x07, 0x68, 0xEE, 0xA0, 0x23, 0xD6, + 0xB8, 0xB5, 0xC4, 0x1F, 0x95, 0xDA, 0xA2, 0xCF, 0xD8, 0x5B, 0xB0, 0x7B, 0xA8, 0x0F, 0x63, 0x71, + 0x1C, 0x53, 0x6A, 0xDC, 0xA3, 0xA9, 0xCC, 0xC1, 0xA5, 0xFD, 0x97, 0xD0, 0xA3, 0xF3, 0x1C, 0x74, + 0x72, 0xE7, 0x9D, 0x77, 0x5E, 0x97, 0x8E, 0xD4, 0x0B, 0x67, 0x19, 0x4B, 0x0F, 0x13, 0xC7, 0xDE, + 0xFB, 0xE4, 0xD8, 0x12, 0x99, 0x94, 0x73, 0x0F, 0x84, 0x79, 0x7B, 0xE6, 0x2E, 0xB6, 0x27, 0xF2, + 0x7C, 0x63, 0xD3, 0x65, 0xAC, 0x33, 0xFE, 0x3F, 0x5A, 0x2E, 0xC5, 0x4B, 0x7A, 0x3D, 0xFF, 0xEB, + 0x17, 0x5C, 0x82, 0x9D, 0x2E, 0xEE, 0x9B, 0xCB, 0x6E, 0x2D, 0xE7, 0x84, 0x64, 0x63, 0xE7, 0xFD, + 0x97, 0x5D, 0x0F, 0xBC, 0x04, 0x76, 0xDF, 0x68, 0x42, 0x23, 0xAF, 0xCC, 0x8A, 0x8F, 0xC1, 0x19, + 0x67, 0x9C, 0x31, 0xD8, 0xD8, 0x5B, 0x72, 0x1F, 0xC4, 0xF3, 0x37, 0xFD, 0x5C, 0x42, 0xC7, 0x3F, + 0x63, 0xFC, 0x24, 0xE3, 0x9B, 0x6A, 0x17, 0xBC, 0xD2, 0xE3, 0x55, 0x96, 0x58, 0x1F, 0x3B, 0x78, + 0x69, 0xFB, 0xE0, 0x25, 0xC7, 0xEB, 0xD8, 0xDF, 0xE0, 0xB1, 0xE8, 0x51, 0xC8, 0x7F, 0x33, 0x66, + 0xBF, 0x89, 0x36, 0x3A, 0xF1, 0x64, 0xD6, 0x05, 0xB9, 0x98, 0x35, 0x4F, 0xC6, 0xFC, 0xE9, 0x98, + 0x5F, 0x51, 0xBF, 0x34, 0xE5, 0x0C, 0x52, 0x6F, 0xD3, 0x92, 0xFA, 0x25, 0xC9, 0x24, 0x54, 0xE4, + 0xD2, 0x29, 0x6D, 0x8B, 0xBC, 0xC1, 0xEF, 0x81, 0x5E, 0x43, 0xF2, 0x91, 0x9E, 0x55, 0xF2, 0x81, + 0x70, 0xEC, 0xE9, 0x32, 0x2D, 0x7C, 0x1F, 0xFD, 0x60, 0xCC, 0xBB, 0x3D, 0xA7, 0xE0, 0xF7, 0xC2, + 0x9A, 0x80, 0x07, 0x90, 0xCB, 0x54, 0x6D, 0x9F, 0xCA, 0xE7, 0x28, 0x6E, 0x13, 0x61, 0xBD, 0x72, + 0x0E, 0x73, 0x0D, 0x9F, 0x64, 0x73, 0x06, 0x9E, 0xC7, 0x6F, 0x75, 0x06, 0x55, 0x6F, 0xC9, 0x64, + 0x43, 0xAE, 0x89, 0x77, 0x40, 0x4F, 0xE7, 0xBC, 0x6E, 0xE9, 0xDC, 0x76, 0xE2, 0xD7, 0x9E, 0xFF, + 0x73, 0x6E, 0x51, 0x7F, 0xC8, 0xC1, 0xA4, 0x18, 0x6A, 0xDA, 0x8B, 0x4F, 0x86, 0xE8, 0xED, 0xB9, + 0x1A, 0x5B, 0xEE, 0x95, 0x7D, 0xA6, 0xF9, 0xA0, 0x71, 0x71, 0xBA, 0xF4, 0xF8, 0x05, 0xD7, 0xC6, + 0x3A, 0xCB, 0x49, 0xDA, 0x7A, 0x7E, 0x5C, 0x4B, 0x91, 0x5C, 0xA7, 0x3C, 0xCF, 0xE0, 0x56, 0xCF, + 0x2F, 0xD7, 0xF2, 0x7B, 0x15, 0x68, 0x0B, 0x6F, 0x2F, 0xAD, 0x55, 0xC7, 0x0C, 0x1E, 0x9B, 0x01, + 0xDF, 0xD6, 0x5A, 0xCD, 0xF4, 0xF7, 0x2A, 0x19, 0xDF, 0x45, 0x27, 0x89, 0x0E, 0x08, 0xBF, 0x71, + 0xFC, 0x1D, 0xB0, 0x43, 0xF7, 0x9C, 0xE1, 0xB8, 0xF9, 0x01, 0x97, 0xD4, 0x0B, 0xCE, 0xBF, 0xF0, + 0x92, 0xEB, 0xD5, 0x6A, 0x93, 0x7E, 0x29, 0xFA, 0x48, 0x8F, 0xD5, 0x8C, 0x0E, 0xE2, 0x69, 0x60, + 0x44, 0xE1, 0xA5, 0xD8, 0xE7, 0x29, 0x6B, 0x58, 0xFD, 0x85, 0x0F, 0xB0, 0x5F, 0x39, 0xCD, 0x6B, + 0xED, 0x45, 0xE6, 0xD5, 0xDC, 0xE2, 0xB7, 0x9A, 0x57, 0x63, 0x7B, 0xDD, 0x26, 0xB2, 0x15, 0xF0, + 0x12, 0xAF, 0xAC, 0x0F, 0x78, 0x5A, 0x8F, 0x5E, 0x7A, 0xAC, 0xEE, 0xE0, 0xA5, 0x65, 0xEA, 0x12, + 0xFE, 0xDE, 0x6E, 0x0B, 0xC0, 0x76, 0x4D, 0xFE, 0x58, 0x70, 0x06, 0x67, 0x48, 0xB6, 0x94, 0x98, + 0x73, 0x0C, 0x1E, 0xA0, 0xB3, 0xCB, 0x5B, 0xE6, 0x0C, 0xEB, 0x89, 0xF9, 0xCE, 0x9E, 0x4C, 0x99, + 0xBB, 0xCF, 0x2F, 0x89, 0x97, 0xD4, 0x6E, 0xF7, 0x3B, 0x61, 0x3F, 0xF5, 0xE7, 0xE8, 0xBA, 0xB4, + 0x86, 0xFC, 0xFF, 0x19, 0xCE, 0x80, 0x7E, 0xF8, 0xE0, 0x90, 0xAB, 0xD7, 0xF7, 0xA1, 0x16, 0x7B, + 0xB7, 0xE7, 0xDF, 0x45, 0xCE, 0x95, 0x4F, 0xF6, 0x1C, 0xDA, 0x79, 0x3B, 0xC1, 0x23, 0xEC, 0x55, + 0x60, 0x59, 0x9D, 0xE9, 0x99, 0xF1, 0xBA, 0xDE, 0xF9, 0x26, 0xBC, 0x48, 0x5C, 0x11, 0x3A, 0xA3, + 0x96, 0x38, 0x1C, 0xB7, 0x67, 0x51, 0x91, 0x0D, 0x91, 0xB5, 0x4B, 0x7B, 0x4D, 0xA9, 0x7F, 0x14, + 0xCF, 0x27, 0xA4, 0x3D, 0x8B, 0xEB, 0x0C, 0x2F, 0x2D, 0xC1, 0xEF, 0xBC, 0x0A, 0xEF, 0x72, 0xBE, + 0x2B, 0x7A, 0xC5, 0xD6, 0xB6, 0xC7, 0x31, 0xCA, 0x3E, 0x23, 0x77, 0x21, 0x38, 0x40, 0x6D, 0x26, + 0xCE, 0x5D, 0xFD, 0x75, 0x9F, 0xB1, 0xDE, 0x67, 0x69, 0x4D, 0x12, 0x1B, 0x87, 0x9D, 0x3E, 0xFA, + 0x66, 0x2C, 0x55, 0x1D, 0xFF, 0xFB, 0xDE, 0x0B, 0x5F, 0x26, 0xBF, 0xE7, 0xDC, 0xE2, 0x7C, 0x92, + 0x98, 0x73, 0xE6, 0x13, 0x7C, 0x47, 0x39, 0x53, 0x5A, 0xE8, 0x41, 0x11, 0x06, 0x25, 0xAE, 0x02, + 0xF9, 0xD2, 0xC7, 0xD6, 0x75, 0xE7, 0x99, 0xBE, 0x85, 0xCF, 0xB0, 0x01, 0x92, 0x8B, 0x88, 0xF3, + 0xCC, 0x54, 0x32, 0x1F, 0xB3, 0x38, 0xD6, 0x8A, 0x2B, 0xFB, 0xC0, 0x07, 0x3E, 0x30, 0xC4, 0x26, + 0x90, 0x37, 0x44, 0x71, 0x96, 0x2D, 0xFA, 0xC3, 0x3D, 0xB0, 0xD9, 0xA5, 0x78, 0x09, 0x5B, 0x9C, + 0xF0, 0x92, 0xEB, 0x97, 0x7A, 0x73, 0xC0, 0x66, 0xBA, 0x14, 0x61, 0x45, 0xE8, 0x24, 0xBC, 0x94, + 0xE5, 0x5C, 0xED, 0xD5, 0xEF, 0xA9, 0x2F, 0xE4, 0xCB, 0xF0, 0x33, 0xB7, 0xC7, 0x64, 0x73, 0xE7, + 0x21, 0xF8, 0x1A, 0x30, 0xF6, 0x53, 0x6C, 0x1A, 0xCE, 0x4B, 0xDC, 0xFE, 0xC2, 0x5C, 0x25, 0x56, + 0xAA, 0xE4, 0x73, 0x3A, 0x05, 0x47, 0xED, 0xE0, 0xA5, 0x65, 0xEA, 0x12, 0x78, 0xC9, 0x65, 0x13, + 0xF8, 0xED, 0x91, 0x47, 0x1E, 0x39, 0xD8, 0xE4, 0xE1, 0x8D, 0xBA, 0xD7, 0xD8, 0x9E, 0xE8, 0xF1, + 0xA1, 0x14, 0xF2, 0x99, 0xE0, 0xE3, 0xD0, 0x32, 0x2F, 0xF8, 0x3F, 0x31, 0x23, 0xEC, 0x7F, 0x7E, + 0xBF, 0xA9, 0x36, 0x9F, 0x75, 0xD8, 0xE3, 0x9C, 0x0F, 0x60, 0xAF, 0x51, 0x1B, 0x9D, 0x3E, 0xAD, + 0xED, 0x8A, 0x05, 0xFA, 0xE3, 0x43, 0xEB, 0x3E, 0xCF, 0xD9, 0xFA, 0x8A, 0x7C, 0x97, 0xEA, 0xBA, + 0x28, 0xE2, 0xD8, 0x76, 0xEF, 0xDE, 0xDD, 0xD5, 0xA6, 0xD8, 0xBE, 0x58, 0x59, 0x53, 0xAC, 0x09, + 0x30, 0xD3, 0xAE, 0x5D, 0xBB, 0xBA, 0xFA, 0x95, 0x15, 0xE5, 0x5D, 0xD1, 0xEF, 0xFC, 0xCC, 0xD3, + 0xCC, 0x87, 0x29, 0xD2, 0x82, 0xEF, 0x88, 0x87, 0x63, 0xA3, 0x01, 0x2F, 0xCD, 0x99, 0x2B, 0x6A, + 0x93, 0x0A, 0xF6, 0x38, 0x8F, 0x31, 0x5B, 0x07, 0x5E, 0x52, 0x5F, 0xB0, 0x43, 0x9E, 0x76, 0xDA, + 0x69, 0x1B, 0xCF, 0x9E, 0xAA, 0x4F, 0x75, 0xFF, 0x33, 0xE6, 0x11, 0x39, 0x25, 0xD4, 0x66, 0x7C, + 0xC3, 0x74, 0xEF, 0x56, 0x7B, 0x5C, 0xBC, 0xB7, 0xEF, 0x05, 0xE0, 0x7A, 0x30, 0x6E, 0xE6, 0x3F, + 0xB7, 0x34, 0x7D, 0xFC, 0x95, 0xF9, 0xB7, 0x64, 0xBE, 0x4A, 0x0A, 0xF6, 0xA1, 0xBD, 0xF6, 0xDA, + 0x6B, 0x38, 0x4B, 0x5C, 0xE7, 0xF0, 0xB6, 0xD0, 0x83, 0x22, 0x3F, 0x05, 0xFC, 0x71, 0xF0, 0x5F, + 0x70, 0x7D, 0x8C, 0xF3, 0x8A, 0x88, 0x29, 0x75, 0x8D, 0x3E, 0x1D, 0xBD, 0x16, 0x36, 0x39, 0x95, + 0x38, 0xFE, 0x99, 0xBC, 0xA5, 0xEF, 0xE0, 0xFB, 0x44, 0x6C, 0x28, 0x72, 0xA6, 0xFB, 0x7B, 0xB7, + 0x94, 0x4C, 0xBE, 0xC0, 0x1E, 0x37, 0xD8, 0xE6, 0x2E, 0xDA, 0x7C, 0x96, 0xE5, 0x9C, 0x1C, 0xAD, + 0xFE, 0x19, 0x74, 0xC1, 0x67, 0x4B, 0x32, 0xB8, 0xDB, 0x22, 0x1C, 0x8F, 0xB7, 0xB6, 0xDF, 0x71, + 0xBC, 0xEC, 0x18, 0x63, 0x58, 0xC9, 0x75, 0x7C, 0x1A, 0x1B, 0xCE, 0x2C, 0x80, 0x96, 0xBD, 0x6D, + 0x70, 0xFA, 0xF9, 0x1A, 0xA1, 0xC2, 0x2F, 0xDD, 0x1E, 0x17, 0xB1, 0xFF, 0x94, 0xBA, 0x83, 0x97, + 0x96, 0xA9, 0x73, 0xF1, 0x92, 0xE7, 0x91, 0x67, 0xCC, 0x39, 0xCF, 0x11, 0xAC, 0x74, 0xF6, 0xD9, + 0x67, 0x6F, 0x9C, 0x09, 0x59, 0xC2, 0x4B, 0xF1, 0x33, 0xE9, 0x0D, 0xE0, 0x3D, 0xD8, 0x86, 0x32, + 0xFE, 0x17, 0xE7, 0x90, 0xE6, 0x35, 0x76, 0x78, 0x72, 0x67, 0x78, 0x99, 0xE3, 0xD3, 0x41, 0x59, + 0xD2, 0x1E, 0xE7, 0xF3, 0x1D, 0xFD, 0x83, 0x64, 0xF5, 0xA9, 0xBA, 0x64, 0xFD, 0x56, 0xF4, 0x27, + 0xA7, 0xF5, 0x41, 0x07, 0x1D, 0x34, 0xF0, 0x6F, 0xE7, 0x31, 0x63, 0xFC, 0xC8, 0xF9, 0x33, 0xBE, + 0x2B, 0x3A, 0x17, 0x61, 0x2A, 0xFD, 0xE2, 0x58, 0xB3, 0x16, 0x9E, 0xF0, 0x84, 0x27, 0x0C, 0xF1, + 0x71, 0xCE, 0xDB, 0xE7, 0x14, 0xA7, 0x17, 0x67, 0xE5, 0x64, 0x34, 0xAE, 0xF5, 0xDB, 0x75, 0xE9, + 0xD8, 0x08, 0x3D, 0xC6, 0x26, 0xC3, 0x7C, 0x99, 0x9E, 0xDD, 0x5F, 0xDD, 0xBF, 0x99, 0x38, 0x1B, + 0x62, 0x8F, 0x22, 0x5E, 0x9A, 0xCA, 0xF3, 0xA2, 0x3C, 0xE9, 0xFB, 0x0F, 0x7B, 0x9D, 0x7C, 0xF6, + 0x28, 0xDD, 0x3E, 0x28, 0xAB, 0xCB, 0xF6, 0x1A, 0xF5, 0x07, 0x7F, 0x28, 0xF6, 0x61, 0xEE, 0x8F, + 0x0F, 0xB2, 0xF2, 0x81, 0x48, 0x9E, 0xE9, 0x19, 0x1B, 0xBD, 0x77, 0x9B, 0x11, 0x71, 0xF7, 0xE8, + 0x65, 0xD4, 0x87, 0x75, 0xC5, 0xC5, 0x45, 0x1B, 0x1F, 0xB8, 0x4F, 0xBE, 0x5E, 0x53, 0x68, 0xE4, + 0xFD, 0x12, 0x66, 0x22, 0x87, 0x04, 0x36, 0x2D, 0xE5, 0xC7, 0xEE, 0x95, 0x79, 0xB0, 0x8B, 0xA1, + 0x8F, 0xC7, 0xE7, 0x5A, 0xED, 0x8D, 0x39, 0x10, 0x23, 0xDE, 0xD6, 0xF7, 0xF0, 0x3D, 0x42, 0xF7, + 0x87, 0xAF, 0x72, 0xD4, 0xE1, 0x95, 0xC6, 0xC1, 0xE7, 0x37, 0x73, 0x16, 0x5F, 0x7E, 0xDA, 0x8F, + 0x3D, 0xAE, 0x27, 0xFE, 0x31, 0xD2, 0x85, 0x2A, 0x7F, 0x6F, 0x8A, 0xEC, 0x71, 0x25, 0x9F, 0xC2, + 0x1E, 0x5E, 0x29, 0x1A, 0x20, 0xE7, 0x40, 0x6F, 0xF9, 0x7B, 0xF3, 0x4C, 0xC5, 0xFC, 0x4D, 0xC1, + 0x2A, 0x1E, 0xD3, 0x4D, 0x6E, 0x06, 0x6C, 0x6C, 0xD9, 0x3E, 0x53, 0xE3, 0x1F, 0x54, 0xCE, 0x2C, + 0x98, 0x92, 0xFF, 0x2C, 0x1B, 0x1F, 0x15, 0xF4, 0x95, 0xAC, 0x6D, 0x9F, 0xC3, 0x3B, 0x78, 0xA9, + 0xBD, 0x6C, 0x67, 0xBC, 0x14, 0xE7, 0x08, 0xBE, 0x73, 0xE4, 0x9E, 0x25, 0xF7, 0xDD, 0x58, 0x9F, + 0x1C, 0x5F, 0x7B, 0x61, 0xEF, 0x67, 0x6D, 0x44, 0xDE, 0x11, 0xE5, 0x2C, 0xF7, 0x25, 0xE4, 0xCC, + 0x14, 0x7C, 0xA7, 0x7C, 0xFF, 0x9A, 0x5A, 0xD6, 0x85, 0x97, 0xD4, 0x7E, 0xFC, 0x44, 0xD1, 0xC3, + 0xAB, 0xEF, 0xB5, 0xB5, 0xD3, 0xD2, 0x4E, 0x5E, 0xB9, 0x1F, 0x3E, 0x9C, 0xE4, 0xD4, 0xCE, 0x68, + 0x35, 0xF6, 0x9E, 0xF6, 0xF9, 0x19, 0x0B, 0x4B, 0xF8, 0x2E, 0x51, 0xD0, 0xFB, 0x63, 0xE7, 0xC3, + 0x0F, 0x86, 0x6B, 0xB5, 0x77, 0x89, 0xFB, 0xB3, 0x0F, 0x23, 0xDF, 0x71, 0x76, 0x20, 0xFD, 0x70, + 0xFD, 0x52, 0xA9, 0xCF, 0x9C, 0xEF, 0xA1, 0x7D, 0x89, 0xB9, 0xEA, 0x3E, 0x39, 0xAD, 0xF1, 0x35, + 0xF1, 0x7D, 0xD4, 0x2F, 0xF9, 0xB9, 0xF5, 0x73, 0xF9, 0x5C, 0x86, 0x97, 0xD4, 0x2F, 0x74, 0x83, + 0xE4, 0x27, 0x13, 0x66, 0x9E, 0xB2, 0xE7, 0xA9, 0x0F, 0xEA, 0x17, 0xF6, 0x1D, 0xFC, 0xE0, 0xB9, + 0x3F, 0x79, 0x62, 0xF1, 0xCD, 0x56, 0x69, 0xB9, 0x7F, 0x8C, 0x4B, 0x77, 0x4C, 0x4F, 0x79, 0xEE, + 0x73, 0x9F, 0x3B, 0xF8, 0xCC, 0xC4, 0x35, 0xBC, 0x54, 0x2D, 0xE9, 0xF5, 0xD0, 0x99, 0xF9, 0x99, + 0x6B, 0x35, 0x5A, 0x64, 0xB4, 0xD1, 0xE7, 0x4E, 0x03, 0xF4, 0x7B, 0xFB, 0xED, 0xB7, 0xDF, 0x70, + 0x96, 0x0C, 0x45, 0x79, 0x19, 0xC6, 0xEE, 0x2F, 0x1A, 0x61, 0xAB, 0x66, 0xCD, 0x42, 0x8F, 0x6C, + 0xBE, 0xC4, 0x39, 0xEC, 0xDF, 0xD1, 0x39, 0x35, 0xC4, 0x87, 0x52, 0xA4, 0xFF, 0x8B, 0xF1, 0xFE, + 0xF1, 0xD9, 0xFE, 0x3D, 0xE6, 0x0E, 0xF9, 0xBD, 0xC1, 0x7B, 0x3D, 0x58, 0x3B, 0x93, 0x19, 0x1C, + 0x13, 0x2B, 0xFF, 0x92, 0x70, 0xCE, 0x14, 0x5E, 0xE9, 0xFD, 0x57, 0x7C, 0x0A, 0xFE, 0x06, 0x7E, + 0x8E, 0xA1, 0x9F, 0xE1, 0xD2, 0xB3, 0x5F, 0x29, 0x26, 0x54, 0xEF, 0x89, 0x2B, 0xE2, 0xBC, 0xE4, + 0xD2, 0xDA, 0x8B, 0x73, 0xCB, 0xCF, 0x92, 0x57, 0xBE, 0x1C, 0xD7, 0xA1, 0x66, 0x7A, 0xBD, 0x12, + 0x0D, 0xB3, 0xF7, 0x60, 0x08, 0xE2, 0x97, 0x7C, 0x7F, 0xDB, 0xC1, 0x4B, 0xED, 0x65, 0x3B, 0xE3, + 0x25, 0x8A, 0xEF, 0x17, 0xF8, 0x53, 0xE0, 0xE7, 0xAD, 0xB9, 0x5C, 0xB2, 0x75, 0x94, 0xE4, 0x50, + 0xCE, 0x8B, 0xE3, 0x1C, 0x2B, 0xCF, 0xCF, 0x92, 0xCD, 0xDF, 0x28, 0x7B, 0xB1, 0x1F, 0x93, 0x0B, + 0xC7, 0xCB, 0x76, 0xF0, 0xF7, 0x76, 0xFE, 0xAD, 0x57, 0xCE, 0x77, 0x21, 0xEF, 0x5A, 0x4B, 0xCC, + 0xE0, 0x25, 0x27, 0x1B, 0xE4, 0xFF, 0x1F, 0xE4, 0xBA, 0x8B, 0xE9, 0xAC, 0x1C, 0x8E, 0xC4, 0xE8, + 0x78, 0xDE, 0x3B, 0xC5, 0xDC, 0x8C, 0xD9, 0x34, 0xD1, 0x23, 0x78, 0xEC, 0x89, 0xF8, 0xC9, 0x1C, + 0x1B, 0x95, 0x0A, 0xFC, 0x0D, 0x5D, 0x21, 0xF3, 0x4C, 0x31, 0xD7, 0xCE, 0xB3, 0x33, 0xBA, 0xD7, + 0x4A, 0xC4, 0xC3, 0x8C, 0x11, 0xFA, 0xBA, 0x28, 0xC7, 0x66, 0xF6, 0x1E, 0xD7, 0xA9, 0x91, 0x87, + 0x51, 0xB9, 0xEF, 0xF4, 0xDC, 0x96, 0xF9, 0x92, 0xB5, 0xD9, 0x7F, 0xC7, 0xDC, 0xC7, 0x6E, 0xA0, + 0x67, 0x46, 0xDF, 0xFA, 0x29, 0xF3, 0x27, 0xEA, 0xA7, 0x7C, 0x2C, 0xC9, 0x0D, 0x8B, 0x3E, 0xB6, + 0x07, 0x63, 0x97, 0x74, 0xBD, 0xEA, 0x1F, 0xF2, 0x8E, 0xEC, 0x7D, 0xF8, 0x63, 0x09, 0x23, 0xB4, + 0x3C, 0x23, 0xC6, 0x0A, 0x44, 0xBC, 0x44, 0x1C, 0x3B, 0x7B, 0xBD, 0xF7, 0x27, 0x8B, 0xE1, 0x9E, + 0xB3, 0xD6, 0x54, 0x7D, 0xBF, 0x21, 0xC7, 0x83, 0xF2, 0x55, 0xD5, 0x4A, 0x5C, 0x8F, 0x91, 0x56, + 0xD2, 0xBF, 0x32, 0xE6, 0x60, 0x0D, 0xAA, 0xBE, 0xD3, 0x92, 0xD3, 0xC1, 0xEF, 0x85, 0xBE, 0xEB, + 0xF1, 0x8F, 0x7F, 0xFC, 0xA0, 0xE3, 0x89, 0x3C, 0xAD, 0xA4, 0x5B, 0x72, 0x9D, 0x0D, 0xF9, 0x82, + 0x1C, 0x03, 0x7A, 0x1C, 0x72, 0xA9, 0xF8, 0x79, 0xC1, 0xF8, 0x14, 0x62, 0x1B, 0x25, 0xA6, 0xB9, + 0xF5, 0x3C, 0x94, 0x98, 0x3F, 0xC4, 0x3F, 0xA7, 0x20, 0x7F, 0x60, 0x5B, 0x50, 0x9B, 0x1D, 0x2F, + 0xB5, 0xCE, 0x7F, 0x5F, 0xA7, 0xFE, 0x8A, 0xDF, 0x10, 0xBA, 0x2B, 0xCD, 0xC7, 0xB1, 0xFC, 0x09, + 0xB5, 0xF6, 0xFB, 0xFC, 0x84, 0x47, 0x11, 0x83, 0x13, 0x79, 0x48, 0x9C, 0x97, 0xBE, 0x16, 0xF1, + 0x99, 0x84, 0xEF, 0xE0, 0xEF, 0xE9, 0x6B, 0x2A, 0xD2, 0xA7, 0x86, 0x97, 0x1C, 0x6F, 0xBA, 0x9D, + 0x16, 0xFB, 0x0C, 0xFA, 0xC3, 0xA8, 0x5F, 0xCA, 0xD6, 0x47, 0x94, 0xA7, 0x4A, 0x34, 0xDD, 0xC1, + 0x4B, 0xDB, 0x03, 0x2F, 0x79, 0xBE, 0x24, 0xC6, 0x9C, 0x3D, 0x1B, 0xFD, 0x90, 0xCA, 0xD8, 0x39, + 0x8E, 0x7E, 0xA6, 0x3C, 0x85, 0x1C, 0x3D, 0xE4, 0xC2, 0x40, 0x67, 0x90, 0xD9, 0xEE, 0xB3, 0xF7, + 0xF2, 0x09, 0x62, 0x2D, 0xA9, 0xDD, 0x53, 0x6C, 0x13, 0x2A, 0xEB, 0xC0, 0x4B, 0xEE, 0x57, 0xBD, + 0xFF, 0xFE, 0xFB, 0xAF, 0xDE, 0xF0, 0x86, 0x37, 0x6C, 0xEC, 0x73, 0x35, 0x4C, 0xE9, 0x78, 0x29, + 0x5B, 0x7B, 0x6E, 0xF7, 0xA6, 0x60, 0x3F, 0x41, 0xE6, 0x1D, 0xD3, 0x2B, 0xFB, 0x1E, 0x0E, 0xDF, + 0x25, 0x2E, 0x1F, 0xFB, 0x69, 0xE9, 0x6C, 0x9A, 0x52, 0x29, 0xD9, 0xB0, 0x54, 0xB8, 0x2F, 0xBA, + 0x42, 0xD6, 0x06, 0x78, 0xD6, 0xED, 0x01, 0x91, 0x67, 0xD4, 0xF6, 0xA9, 0x4C, 0x1F, 0xC9, 0xDC, + 0x61, 0xCD, 0x62, 0x93, 0x8A, 0x7C, 0x2E, 0xB3, 0xDF, 0xEA, 0x1A, 0xD9, 0x0D, 0x9B, 0x93, 0xCE, + 0x39, 0xF7, 0x7B, 0x96, 0x4A, 0xB4, 0x79, 0x78, 0xBB, 0xA5, 0xA3, 0xA2, 0x4F, 0xF8, 0x13, 0x41, + 0x4F, 0xCF, 0x57, 0xD9, 0x3B, 0x5F, 0x6A, 0x63, 0xE7, 0xF1, 0xCC, 0x7C, 0x8F, 0xFD, 0xDA, 0x75, + 0x0C, 0x4E, 0xDB, 0xB8, 0x2F, 0x64, 0xE3, 0xA6, 0x82, 0x7D, 0x58, 0xEF, 0xB5, 0xDF, 0x91, 0x4F, + 0xF9, 0x6D, 0x6F, 0x7B, 0x5B, 0x7D, 0x02, 0x24, 0xC5, 0xEF, 0x1D, 0xAF, 0xD9, 0x9F, 0x95, 0x6B, + 0xDD, 0xCF, 0xCF, 0x76, 0x7C, 0xB3, 0x74, 0xE5, 0xFE, 0xAC, 0x63, 0xE5, 0x43, 0x9F, 0x5A, 0x84, + 0x89, 0x34, 0x17, 0xB8, 0x27, 0x7B, 0x66, 0xAF, 0x3E, 0x58, 0x05, 0x3E, 0xC9, 0x59, 0x87, 0xE4, + 0xBB, 0x1A, 0xF3, 0x31, 0x76, 0x5D, 0x8B, 0x62, 0x1B, 0x90, 0x73, 0xD4, 0x27, 0xF7, 0xEB, 0xAB, + 0x15, 0x97, 0x83, 0x4E, 0x3E, 0xF9, 0xE4, 0x01, 0xAF, 0xE1, 0xBF, 0xA4, 0x33, 0x6C, 0xB3, 0x35, + 0xD7, 0xB2, 0x4E, 0xF5, 0x19, 0xF7, 0xC1, 0xAE, 0x2F, 0xAC, 0xC1, 0x58, 0xC7, 0x9C, 0x2A, 0xB5, + 0xEA, 0x74, 0xC8, 0xFA, 0x8F, 0x2C, 0xED, 0xEB, 0x5F, 0xA5, 0x24, 0xEB, 0xD4, 0x70, 0x8B, 0xF3, + 0x5E, 0xF4, 0xA8, 0xE8, 0x8B, 0x3C, 0xBE, 0x38, 0xB6, 0x59, 0xB9, 0x67, 0xB9, 0x66, 0x8D, 0x83, + 0xBF, 0xBF, 0xF4, 0xA5, 0x2F, 0xA5, 0x6D, 0x68, 0xE1, 0x5F, 0xFE, 0x1B, 0x6F, 0x23, 0xFA, 0x78, + 0x3D, 0xCF, 0x31, 0x66, 0x4D, 0xF7, 0xB8, 0x55, 0x78, 0xC9, 0xFB, 0x41, 0x5C, 0xA0, 0xF0, 0xD2, + 0xD8, 0xF3, 0xB3, 0x76, 0x3A, 0x5E, 0xAA, 0xEE, 0x81, 0x85, 0xF5, 0x55, 0xC3, 0xA2, 0x8E, 0x97, + 0x7A, 0xE4, 0xB0, 0x4C, 0x9F, 0xE8, 0xEF, 0xE1, 0x89, 0x8E, 0x97, 0x7C, 0x5D, 0xB4, 0x16, 0xB7, + 0xDF, 0x82, 0x01, 0x90, 0x61, 0x46, 0xF5, 0x26, 0x17, 0x6D, 0xB6, 0xA7, 0xCB, 0xE7, 0x8D, 0xFC, + 0xAD, 0xE8, 0x96, 0xB4, 0x97, 0xD7, 0xE4, 0x4E, 0xFF, 0x1F, 0xF2, 0x23, 0xF8, 0x26, 0x3E, 0xA3, + 0xA5, 0x94, 0xD6, 0x93, 0xE3, 0xA5, 0xD6, 0xF9, 0x90, 0xED, 0x6F, 0xBE, 0xCF, 0x71, 0x0F, 0xB0, + 0x20, 0xE7, 0x3F, 0xB9, 0xEF, 0x8C, 0x9F, 0x85, 0xB4, 0xD9, 0x1E, 0x76, 0xD1, 0x50, 0xC1, 0x4D, + 0x17, 0x5E, 0x74, 0xC1, 0x1E, 0xF8, 0x29, 0x16, 0x7C, 0x22, 0x5E, 0xF8, 0xC2, 0x17, 0x0E, 0x7E, + 0x4C, 0xBE, 0x27, 0x95, 0xD6, 0x1D, 0x7E, 0x85, 0xCC, 0x59, 0xD9, 0x14, 0x3C, 0x1F, 0x5F, 0x0D, + 0x43, 0xD4, 0xF8, 0x8F, 0xFB, 0x66, 0xC9, 0x16, 0x8F, 0x4E, 0x01, 0x5E, 0xA7, 0xE2, 0xB2, 0x78, + 0xDC, 0xD7, 0x6B, 0x72, 0x59, 0x76, 0xA6, 0x0E, 0x76, 0x3E, 0xFC, 0x98, 0x74, 0x6E, 0x9C, 0xC6, + 0x2B, 0x9B, 0x3F, 0xF0, 0xC4, 0x23, 0x8E, 0x38, 0x62, 0xF0, 0xFB, 0x80, 0xE6, 0xDE, 0xDF, 0xB1, + 0x12, 0xE5, 0x69, 0x1F, 0x3B, 0x15, 0xEC, 0x4D, 0xD8, 0xB1, 0xA2, 0x5E, 0x71, 0xEA, 0xFC, 0xC9, + 0xD6, 0xB2, 0xE7, 0x19, 0x26, 0x3F, 0x33, 0x98, 0x86, 0x7D, 0x2A, 0xAE, 0xDD, 0xB8, 0xCF, 0xA9, + 0xDD, 0x7A, 0xF5, 0xFE, 0x68, 0x3C, 0xF8, 0x1C, 0x7F, 0xDD, 0x6B, 0x5F, 0xFB, 0xDA, 0x83, 0x7F, + 0x0C, 0xF2, 0x4B, 0x0F, 0x4F, 0xC8, 0x9E, 0xA7, 0x76, 0xE0, 0x17, 0x1B, 0x63, 0x07, 0xBD, 0x5F, + 0x73, 0xE9, 0x53, 0xA2, 0x17, 0xAF, 0x3C, 0x17, 0x5D, 0x59, 0x4B, 0xFB, 0x6B, 0x3C, 0xDA, 0x71, + 0xE5, 0x43, 0x1F, 0xFA, 0xD0, 0xA1, 0xF6, 0xC8, 0x68, 0xA2, 0x3F, 0xF3, 0x0D, 0xDD, 0x04, 0x67, + 0xF6, 0xCA, 0x46, 0x5C, 0xC2, 0x0A, 0x3E, 0x7F, 0x64, 0x53, 0xD6, 0xDA, 0x46, 0x9F, 0xE9, 0x31, + 0x9A, 0xB1, 0x1F, 0xB1, 0xB8, 0x4E, 0x1B, 0x5F, 0x32, 0xE4, 0x2B, 0xE2, 0xE3, 0xD0, 0x9B, 0xB5, + 0xCA, 0x48, 0x35, 0x7A, 0x91, 0xCF, 0x0C, 0xBD, 0x95, 0xDA, 0x1C, 0xF7, 0xFC, 0x9E, 0xFD, 0x34, + 0xFB, 0x1F, 0x7C, 0x93, 0x67, 0x44, 0x7E, 0xD1, 0x2A, 0xE7, 0x39, 0xFD, 0x7D, 0x0D, 0xE0, 0x5B, + 0xF9, 0xCB, 0xBF, 0xFC, 0xCB, 0xC3, 0x1E, 0xAE, 0xE7, 0x49, 0xC6, 0x8D, 0xF9, 0xE7, 0xF1, 0xBF, + 0x3B, 0xE5, 0x94, 0x53, 0x36, 0xFC, 0xBC, 0x3D, 0xBE, 0xDB, 0xE9, 0xD2, 0x53, 0xD4, 0x1E, 0xE6, + 0x90, 0x9F, 0x25, 0x58, 0x9B, 0x0F, 0x2D, 0x9F, 0xA9, 0x2E, 0xA9, 0x5F, 0xCA, 0xF0, 0x52, 0xEF, + 0x9A, 0xA4, 0xB6, 0xE8, 0x97, 0xC6, 0xC6, 0x33, 0xCE, 0x79, 0xBD, 0x62, 0x6F, 0x6A, 0x99, 0x53, + 0x3D, 0x34, 0x5C, 0x02, 0x2F, 0xB9, 0xCC, 0x4D, 0x89, 0xFA, 0xA2, 0x1A, 0x66, 0xD4, 0xFF, 0xFC, + 0x37, 0xF0, 0x34, 0xF7, 0xBD, 0x1B, 0x93, 0xBB, 0x7A, 0xF9, 0x61, 0x4F, 0x59, 0x4A, 0xBF, 0x14, + 0xDB, 0x0E, 0x96, 0xC1, 0x46, 0x25, 0xBD, 0x80, 0xEF, 0xB7, 0x71, 0x4F, 0x16, 0x5E, 0x12, 0x66, + 0xCA, 0xF0, 0x52, 0xC4, 0x1B, 0xF8, 0x8E, 0x21, 0x2F, 0x71, 0xDE, 0x07, 0x72, 0x90, 0x9F, 0x6B, + 0x0A, 0x3D, 0x91, 0x4B, 0xD9, 0x67, 0xE1, 0xF5, 0xF0, 0x5B, 0xC5, 0x31, 0x52, 0x34, 0x0E, 0x2D, + 0xF9, 0x58, 0xE2, 0xD8, 0x6F, 0x6E, 0xF7, 0x25, 0x05, 0x1C, 0x23, 0x79, 0x0D, 0x2C, 0xF1, 0xE5, + 0x2F, 0x7F, 0x79, 0xE3, 0x3B, 0x6A, 0x7F, 0x2B, 0x56, 0x89, 0x7C, 0x51, 0x85, 0xB9, 0x8B, 0x6D, + 0xED, 0x11, 0x8F, 0x78, 0xC4, 0x30, 0x9F, 0x39, 0x17, 0x0E, 0x5C, 0x84, 0x3D, 0x12, 0xBD, 0xF9, + 0x35, 0xAE, 0x71, 0x8D, 0x61, 0x6D, 0xA2, 0x8B, 0x21, 0x57, 0x28, 0x3E, 0xD9, 0xFE, 0xDB, 0xAC, + 0x0D, 0xA5, 0xF9, 0x9F, 0xF9, 0xD4, 0x72, 0x0F, 0x8D, 0x21, 0x7E, 0xC5, 0x11, 0xB7, 0x89, 0xEE, + 0x73, 0x7C, 0x10, 0x7C, 0x0E, 0xB9, 0xFC, 0x8B, 0xAF, 0x30, 0x3A, 0x3C, 0x8F, 0x2B, 0x2F, 0xD1, + 0x2F, 0xBE, 0x3A, 0x36, 0x77, 0xFC, 0x4A, 0x5E, 0x1F, 0x74, 0x94, 0xF8, 0x31, 0xB1, 0x27, 0xF4, + 0xF8, 0x45, 0xF9, 0xFC, 0xF1, 0xF9, 0xC1, 0xEB, 0x27, 0x3E, 0xF1, 0x89, 0xE1, 0x2C, 0xD3, 0x8C, + 0x36, 0x73, 0xD6, 0xD8, 0x18, 0xEF, 0x93, 0x7E, 0x69, 0x2E, 0x7F, 0xF0, 0xF9, 0x47, 0x7F, 0xC0, + 0x05, 0xC8, 0x03, 0x99, 0xCC, 0x33, 0x56, 0xF8, 0x0D, 0x7E, 0x43, 0xE4, 0x05, 0xC8, 0xF8, 0x74, + 0xCD, 0xCE, 0xE2, 0x39, 0x57, 0x89, 0xCD, 0xD3, 0xF8, 0x64, 0xB6, 0xE2, 0xD8, 0x1E, 0xE7, 0x13, + 0xE8, 0x7B, 0x5F, 0xFC, 0xE2, 0x17, 0x0F, 0xED, 0x90, 0x9E, 0xA4, 0x66, 0xFF, 0xCF, 0xE8, 0x11, + 0xE5, 0x5E, 0x64, 0x40, 0xE2, 0x4E, 0xD5, 0x07, 0xCF, 0xF3, 0xB1, 0x44, 0xBC, 0x03, 0xB1, 0x6C, + 0x9E, 0x6F, 0x3E, 0xEA, 0xA9, 0x7B, 0x8B, 0xAF, 0x01, 0xF8, 0x20, 0x98, 0x09, 0x1B, 0x37, 0xFC, + 0x91, 0xB1, 0x81, 0x97, 0xE0, 0x13, 0x8A, 0xFD, 0x9E, 0xBC, 0x64, 0xC4, 0xD4, 0xBC, 0xFC, 0xE5, + 0x2F, 0xDF, 0xC8, 0xE1, 0xEA, 0xF7, 0xE9, 0x2D, 0xDE, 0x07, 0xF9, 0xAE, 0x23, 0x9F, 0x90, 0x37, + 0x58, 0xF4, 0xF2, 0x1C, 0x9A, 0xAD, 0xFB, 0x7A, 0x56, 0xB7, 0x0B, 0x5E, 0xF2, 0x0A, 0x4F, 0x66, + 0x0D, 0xB1, 0x5F, 0xB5, 0xE2, 0xA5, 0x56, 0x99, 0xCD, 0xF1, 0xD2, 0x14, 0x7A, 0x95, 0x6A, 0xB4, + 0xC7, 0xF5, 0x8E, 0x7B, 0xCD, 0x47, 0x49, 0xFF, 0x8F, 0xFD, 0x8D, 0x3A, 0x7A, 0xE9, 0x23, 0xD8, + 0x4B, 0xF1, 0x9D, 0xD0, 0x5C, 0x71, 0xBE, 0x10, 0xF7, 0x8C, 0x8C, 0x1F, 0xCA, 0xF7, 0x6E, 0xA9, + 0x02, 0x7F, 0xD5, 0x39, 0x4B, 0x4B, 0xF2, 0x70, 0xE4, 0x16, 0xF2, 0x9E, 0xC8, 0xF7, 0x40, 0x7A, + 0x0E, 0xD1, 0x64, 0xF3, 0xFE, 0x74, 0x51, 0xB5, 0x3A, 0xFF, 0x73, 0x7E, 0xC9, 0xFE, 0xC7, 0xFD, + 0x89, 0x19, 0x64, 0x0F, 0x27, 0xB7, 0x21, 0x18, 0x8D, 0x57, 0xEC, 0x9D, 0x9C, 0xA1, 0x4A, 0xAC, + 0x89, 0xFF, 0x26, 0x8E, 0x4B, 0x6B, 0x89, 0x7A, 0x71, 0xCD, 0x09, 0xEC, 0x7B, 0x8E, 0x37, 0xD1, + 0x33, 0x7F, 0xF0, 0x83, 0x1F, 0xBC, 0xAC, 0x67, 0xA1, 0xCD, 0x35, 0xDC, 0x14, 0xF1, 0xB5, 0xDA, + 0xEA, 0xBF, 0x41, 0xB7, 0x86, 0x6D, 0x01, 0x1B, 0x03, 0x3C, 0x8F, 0xBD, 0x99, 0x9C, 0x2D, 0x60, + 0x69, 0xF8, 0x20, 0x71, 0x40, 0xF8, 0xC7, 0x79, 0xBB, 0x33, 0xD9, 0xD0, 0x9F, 0x19, 0x4B, 0xA4, + 0x17, 0xD5, 0xF7, 0x2B, 0xF4, 0x05, 0x59, 0x5C, 0xCB, 0xD4, 0x5C, 0x43, 0x71, 0xCE, 0x73, 0x3F, + 0xCF, 0xFF, 0x02, 0x2F, 0x87, 0x67, 0x29, 0xB7, 0x55, 0x4B, 0xBB, 0xFD, 0x7B, 0x2E, 0xD7, 0xEA, + 0x77, 0xE0, 0x25, 0x6C, 0xA8, 0xE4, 0xF7, 0x11, 0xBE, 0x2D, 0xDD, 0xB7, 0xF4, 0x1C, 0x1F, 0x23, + 0x0A, 0xF3, 0x91, 0xB1, 0x61, 0xCF, 0x89, 0x7B, 0xC0, 0xBA, 0xF1, 0x12, 0xF7, 0x67, 0x1D, 0xCF, + 0xB1, 0xC7, 0x45, 0xBE, 0x0D, 0xDD, 0xC8, 0xED, 0x49, 0x9E, 0xB8, 0x5E, 0x7E, 0x2E, 0x1A, 0x61, + 0xCF, 0x91, 0xDE, 0xC2, 0xC7, 0xB4, 0x34, 0xF6, 0xAA, 0x6E, 0x8F, 0xC5, 0x16, 0xAD, 0xBC, 0x52, + 0x31, 0xDF, 0x43, 0x86, 0x67, 0x9C, 0x5F, 0x80, 0x0F, 0xF0, 0x61, 0x40, 0xBF, 0x04, 0x2E, 0x1E, + 0x3E, 0xDF, 0x90, 0xC9, 0xDA, 0xE8, 0x11, 0xFD, 0x75, 0xE2, 0x1E, 0xEA, 0x63, 0x3D, 0xD5, 0x36, + 0xED, 0x95, 0x1C, 0x08, 0x60, 0x44, 0x15, 0xE7, 0x95, 0xA5, 0x39, 0x1E, 0x71, 0x63, 0xFC, 0x8D, + 0xE3, 0x5D, 0xC6, 0x15, 0xCC, 0x02, 0xEF, 0xC7, 0x0F, 0x1C, 0xFA, 0x22, 0x37, 0x70, 0x56, 0x05, + 0xEB, 0x02, 0x3D, 0x7C, 0x9C, 0xE3, 0x7A, 0x4E, 0x4B, 0xC9, 0xBE, 0xAF, 0xB6, 0xB1, 0x0F, 0xE2, + 0xFF, 0xEB, 0x67, 0xFE, 0x46, 0x1B, 0x75, 0x0D, 0x47, 0xD7, 0xEA, 0x3A, 0xEC, 0x71, 0x4B, 0xF8, + 0x2F, 0x4D, 0xC1, 0x4B, 0x25, 0x1D, 0xB0, 0x8F, 0x3F, 0x7C, 0x78, 0x69, 0x3E, 0x42, 0x5D, 0x2A, + 0xBF, 0xF7, 0x66, 0x1B, 0x52, 0x59, 0xAF, 0x5D, 0x92, 0x77, 0x28, 0xEF, 0x7F, 0xFF, 0xFB, 0x07, + 0x5B, 0x89, 0xFB, 0xF7, 0x95, 0xF8, 0x87, 0xEF, 0x45, 0xEB, 0xC4, 0x4B, 0x9E, 0xDF, 0x67, 0x4A, + 0x8D, 0x7B, 0x81, 0xEF, 0x9F, 0xAF, 0x7C, 0xE5, 0x2B, 0x37, 0xC9, 0xAB, 0x11, 0x2F, 0x44, 0xFD, + 0x52, 0xAC, 0xF0, 0xB5, 0x4C, 0x97, 0xE7, 0x32, 0xBD, 0x3E, 0x97, 0xCE, 0xDE, 0x73, 0x2B, 0xFA, + 0x6F, 0xE6, 0xC8, 0x68, 0x2A, 0xAE, 0x93, 0xC2, 0x2E, 0xCB, 0x7E, 0x00, 0x7F, 0x53, 0xDF, 0xD1, + 0x75, 0x11, 0x93, 0xC6, 0x73, 0x68, 0x47, 0xA6, 0x57, 0xCB, 0x7C, 0x49, 0x23, 0x4D, 0xB2, 0x3C, + 0x40, 0xBA, 0x17, 0xCF, 0xC5, 0x8F, 0xF6, 0x7D, 0xEF, 0x7B, 0xDF, 0xE0, 0x5F, 0xFE, 0xEE, 0x77, + 0xBF, 0x7B, 0xC0, 0x68, 0xF0, 0x40, 0xB7, 0x59, 0x65, 0xD8, 0xAC, 0xC4, 0x6F, 0x4B, 0x7D, 0xD5, + 0x6F, 0x84, 0x77, 0xD1, 0x17, 0xEA, 0x2C, 0xA0, 0x68, 0x5B, 0x59, 0x2A, 0x0F, 0x4D, 0xE4, 0x97, + 0xE8, 0x0A, 0xE1, 0x0D, 0xF4, 0xB1, 0x86, 0x75, 0xB3, 0xB5, 0xE9, 0x9F, 0xBB, 0x5E, 0x08, 0x9C, + 0x4D, 0x0E, 0x3F, 0xF4, 0x70, 0x3D, 0xF6, 0xCA, 0xDA, 0xF3, 0xC8, 0xEB, 0x8D, 0x0D, 0x83, 0xF3, + 0xDC, 0xA3, 0xFD, 0x6D, 0x49, 0xDC, 0x14, 0xFD, 0x73, 0xF5, 0x0A, 0x5E, 0x72, 0xBD, 0x62, 0xA9, + 0x8C, 0xAD, 0x03, 0xE7, 0x73, 0x60, 0x0D, 0xF9, 0x00, 0x8C, 0xF1, 0xFB, 0x38, 0xBF, 0x29, 0xF8, + 0xBA, 0x95, 0xC6, 0xB9, 0xF4, 0x39, 0xFD, 0x73, 0x1B, 0xFB, 0xE1, 0x87, 0x1F, 0xBE, 0x91, 0x63, + 0xB6, 0xC4, 0x6B, 0xFD, 0xF9, 0xCE, 0xAB, 0xF1, 0x9B, 0x40, 0xE7, 0x07, 0x8E, 0xBD, 0x2C, 0xDF, + 0x66, 0xAC, 0x79, 0x3F, 0x4A, 0x9F, 0x81, 0xDD, 0x64, 0x8F, 0x8B, 0x63, 0xBA, 0x84, 0x7E, 0x09, + 0x5F, 0x2F, 0xF4, 0xC8, 0x9A, 0x8F, 0x91, 0x87, 0xD4, 0xF6, 0x53, 0x1F, 0xC3, 0x38, 0xFF, 0xE3, + 0x9E, 0x84, 0x9C, 0xC0, 0x3E, 0xBE, 0x6B, 0xD7, 0xAE, 0x41, 0x16, 0x41, 0x6F, 0xA6, 0x1C, 0x5B, + 0x63, 0xEB, 0x6B, 0xAC, 0xC4, 0xFC, 0xCC, 0xBA, 0xE6, 0x59, 0xE0, 0x0F, 0x3F, 0x3B, 0x2E, 0xE6, + 0xEF, 0xDC, 0x0A, 0xBC, 0x54, 0x1A, 0xE7, 0x78, 0xBD, 0x24, 0x5E, 0xF2, 0x67, 0x65, 0xED, 0x29, + 0xB5, 0xD3, 0x69, 0xEA, 0x18, 0x66, 0x2A, 0x5E, 0xCA, 0xD6, 0x9B, 0x62, 0x76, 0x78, 0xBF, 0x44, + 0x7C, 0x5C, 0x89, 0xC6, 0x2D, 0x45, 0xF3, 0x9D, 0xFE, 0xE2, 0x03, 0x4D, 0x6E, 0xE1, 0xC8, 0x43, + 0x4B, 0xF3, 0xC3, 0xDF, 0x67, 0xF6, 0xB8, 0x9E, 0x3E, 0x64, 0xEB, 0x0C, 0xFC, 0x35, 0x17, 0x2F, + 0xC5, 0xF3, 0x93, 0xBC, 0xCD, 0x47, 0x1F, 0x7D, 0xF4, 0xEA, 0x63, 0x1F, 0xFB, 0xD8, 0xA6, 0x78, + 0x8F, 0xB8, 0x7F, 0x65, 0x18, 0x49, 0xAF, 0xF8, 0x33, 0xE9, 0xBB, 0x19, 0xFE, 0xA1, 0x8C, 0xF9, + 0x91, 0x79, 0xFF, 0xE3, 0x9A, 0x6F, 0xE1, 0x01, 0xFE, 0x1C, 0xFF, 0x3E, 0xE7, 0xD8, 0x22, 0x9B, + 0xE1, 0xBB, 0xA4, 0x7E, 0xA3, 0x2F, 0xC4, 0x3E, 0xA7, 0xB8, 0xEB, 0x2C, 0xCE, 0x65, 0x0C, 0x2F, + 0xF9, 0x73, 0xA3, 0xCD, 0x30, 0xDA, 0x82, 0xE2, 0x7A, 0xCA, 0xFA, 0xE9, 0x39, 0xEF, 0xC6, 0xFA, + 0xE8, 0x25, 0xEA, 0x99, 0xF0, 0xA9, 0xC0, 0xB6, 0x81, 0xDE, 0x3E, 0xDB, 0x1B, 0x5A, 0xF9, 0xDB, + 0xD8, 0x77, 0xFC, 0xFF, 0x92, 0x3F, 0xC9, 0x53, 0xAA, 0x58, 0x3F, 0xEF, 0x6B, 0xA9, 0x0F, 0x19, + 0x5E, 0xF2, 0xF9, 0x83, 0xDC, 0x42, 0xDE, 0xE2, 0x0F, 0x7D, 0xE8, 0x43, 0x1B, 0x34, 0xEA, 0xC5, + 0x4B, 0x71, 0xFF, 0x01, 0xC3, 0x12, 0x1B, 0xA7, 0x73, 0x27, 0xE2, 0xDA, 0x6E, 0xE9, 0x7B, 0xEB, + 0x7A, 0xCB, 0xFC, 0x80, 0x5A, 0xFD, 0xBD, 0xC7, 0xE6, 0x9D, 0xCF, 0x73, 0x30, 0xB9, 0xB0, 0x4A, + 0x69, 0xAD, 0x64, 0x78, 0x49, 0x98, 0xFF, 0x45, 0x2F, 0x7A, 0x51, 0x8A, 0xEF, 0xC6, 0xC6, 0xDF, + 0xF5, 0x4B, 0xC4, 0x75, 0xA1, 0xF7, 0xC8, 0xFC, 0x72, 0x5A, 0x30, 0x0E, 0x76, 0x5C, 0x64, 0x0A, + 0xE6, 0xEF, 0x25, 0x63, 0x9C, 0xE3, 0x25, 0xFF, 0x6D, 0xAD, 0x28, 0x3F, 0x6D, 0xDC, 0xEF, 0x97, + 0xAC, 0xEC, 0x11, 0xF0, 0x4D, 0xC9, 0x7E, 0x51, 0x47, 0xDC, 0xD2, 0x4E, 0x97, 0x77, 0x32, 0x2C, + 0x10, 0xFD, 0x05, 0x22, 0xDE, 0xD4, 0xF5, 0x94, 0x73, 0x64, 0xFC, 0xF7, 0x8A, 0x1F, 0xA0, 0x30, + 0x97, 0x88, 0xAD, 0xC5, 0x3F, 0x2D, 0xFA, 0x9D, 0x6E, 0x65, 0x3E, 0x81, 0x1A, 0x5E, 0xF2, 0x32, + 0x17, 0x2F, 0x91, 0x1F, 0x02, 0x7B, 0xB6, 0xEB, 0x97, 0x7A, 0xF5, 0x34, 0x4E, 0x53, 0xC7, 0xCE, + 0xDB, 0x1D, 0x2F, 0x4D, 0x29, 0x9A, 0x6F, 0xEA, 0x27, 0xBE, 0x87, 0xCA, 0x83, 0xA1, 0x18, 0x9A, + 0x31, 0x7F, 0x6F, 0x5D, 0x47, 0xBC, 0x34, 0x45, 0x5F, 0x12, 0x79, 0x89, 0x72, 0xE9, 0xF8, 0x7E, + 0x37, 0x95, 0xA7, 0xBB, 0x7C, 0xA0, 0x38, 0x0B, 0xE2, 0xE4, 0xB0, 0x8B, 0xA9, 0xB8, 0xCF, 0xED, + 0x46, 0x0C, 0xF7, 0x86, 0x3F, 0xC1, 0x65, 0xFE, 0x4B, 0xAA, 0xC2, 0x4B, 0x14, 0xC7, 0x0A, 0xEA, + 0x4B, 0xC4, 0x02, 0x2E, 0x5B, 0x46, 0x7C, 0x15, 0xF1, 0x4E, 0x2F, 0xDD, 0x1C, 0xA3, 0x50, 0xF1, + 0xDB, 0x27, 0xB7, 0x81, 0xCE, 0x2A, 0x51, 0xFF, 0xD1, 0xBF, 0xE0, 0x9F, 0x1C, 0x75, 0x5F, 0xFE, + 0x1A, 0xD7, 0x6A, 0x66, 0x4F, 0x50, 0x89, 0x7A, 0x8C, 0x92, 0x1E, 0xC5, 0x69, 0x93, 0xC9, 0x94, + 0x2D, 0xB9, 0x1D, 0xB2, 0xFB, 0xEA, 0x95, 0x58, 0x3B, 0xFC, 0xA3, 0xF1, 0x15, 0x8B, 0x73, 0x76, + 0x09, 0x3C, 0x90, 0xCD, 0x3F, 0xF9, 0x86, 0x10, 0x8F, 0x8E, 0x8E, 0x40, 0xED, 0xC9, 0xCE, 0x5F, + 0xCD, 0xFC, 0xAE, 0x22, 0x4D, 0xBC, 0x2F, 0xA7, 0x9F, 0x7E, 0xFA, 0x1E, 0xF9, 0x45, 0x5B, 0xE6, + 0x87, 0xCF, 0x23, 0xC7, 0x58, 0x60, 0x30, 0x62, 0x56, 0x3C, 0x67, 0x7F, 0x96, 0x1F, 0x61, 0x6E, + 0x2D, 0xC9, 0x57, 0x73, 0xF4, 0xCF, 0x99, 0x8E, 0x86, 0x42, 0xFE, 0x24, 0x3F, 0x13, 0x31, 0xD2, + 0x36, 0xFB, 0xAD, 0x68, 0xC4, 0x6F, 0x7D, 0xAF, 0xE9, 0xE1, 0x2D, 0xFE, 0x3D, 0xF2, 0x80, 0x90, + 0x33, 0x51, 0xF7, 0x1D, 0x9B, 0xC7, 0xB1, 0x1D, 0xD8, 0xB0, 0xD1, 0x9F, 0x28, 0x46, 0xA7, 0xAC, + 0xCF, 0x6E, 0xE3, 0xA9, 0xB1, 0x5F, 0xBD, 0x78, 0x70, 0x6C, 0xFE, 0x73, 0x8D, 0x5E, 0x82, 0x67, + 0xEC, 0xDE, 0xBD, 0x7B, 0x53, 0xBF, 0x5B, 0xC6, 0xB0, 0xE4, 0xEB, 0xE5, 0x34, 0x89, 0xFF, 0xCF, + 0xE8, 0xE9, 0x7C, 0x49, 0xEF, 0x4B, 0xF9, 0xEF, 0x23, 0xCD, 0x23, 0xDE, 0xA2, 0xF0, 0xDB, 0xD7, + 0xBD, 0xEE, 0x75, 0x83, 0xAF, 0xA5, 0xEF, 0x7F, 0x4B, 0xAD, 0x8B, 0x75, 0xE8, 0x97, 0xB0, 0xBD, + 0x2A, 0x36, 0x79, 0xCA, 0xDE, 0x58, 0xC2, 0x4B, 0xB5, 0x39, 0x16, 0x65, 0x81, 0x8C, 0xCE, 0xBC, + 0x4E, 0xF5, 0xF7, 0xCE, 0xE6, 0x9D, 0xCF, 0xE1, 0x25, 0xEC, 0x71, 0xA5, 0x3D, 0xAA, 0xF5, 0x1E, + 0xFA, 0xBD, 0x9F, 0x93, 0x50, 0xCB, 0x37, 0xA1, 0x57, 0xD7, 0xDD, 0x44, 0x7E, 0x38, 0x15, 0xEF, + 0x79, 0xFB, 0xB9, 0x9F, 0xE2, 0x79, 0xB2, 0x36, 0xB5, 0xCA, 0x83, 0x25, 0x5B, 0x0C, 0xFF, 0xE3, + 0xAC, 0x3D, 0xF9, 0x5A, 0xC6, 0x31, 0x18, 0xE4, 0xFA, 0x0B, 0xCF, 0xDF, 0xA4, 0x53, 0x8A, 0xF5, + 0xFC, 0x0B, 0xBE, 0x7E, 0xC9, 0xFF, 0x92, 0x3D, 0x70, 0x8C, 0x16, 0x71, 0xCD, 0xFB, 0xE7, 0x99, + 0x5F, 0x75, 0x56, 0x32, 0xFD, 0x0E, 0xB1, 0x36, 0xF2, 0x43, 0xF3, 0xFE, 0x43, 0x3F, 0x7C, 0xDD, + 0xC9, 0x1D, 0xA8, 0xF3, 0x49, 0x63, 0xBE, 0x9E, 0xE8, 0x0F, 0x11, 0xD7, 0x86, 0xE7, 0xE5, 0xCD, + 0xDA, 0xA1, 0x3E, 0xF9, 0x77, 0xBC, 0x8F, 0x25, 0x9D, 0x96, 0xF7, 0x7D, 0x6C, 0xBD, 0x66, 0xB8, + 0x0B, 0xBF, 0x03, 0xE5, 0xC0, 0x88, 0xE3, 0x3D, 0x57, 0x46, 0x8C, 0xF8, 0xC2, 0x63, 0xB5, 0x79, + 0x4F, 0x7C, 0x04, 0x31, 0x6D, 0xEA, 0x7B, 0xCC, 0x5B, 0xE8, 0xE3, 0x19, 0xE9, 0x17, 0x31, 0xB5, + 0xEC, 0x34, 0xE0, 0x80, 0x2C, 0xE6, 0x6E, 0xAC, 0x38, 0x3F, 0x70, 0x9F, 0x28, 0xF4, 0x5F, 0xE0, + 0xE7, 0xEC, 0x6C, 0x37, 0xBD, 0x5F, 0xA7, 0x1F, 0xD3, 0x52, 0xFA, 0x25, 0xD7, 0x35, 0xD0, 0xBF, + 0xB8, 0x66, 0xE3, 0x7A, 0xCA, 0xF6, 0x1E, 0x0A, 0x3E, 0xD6, 0xC4, 0x63, 0xD0, 0xBE, 0x1E, 0xDF, + 0xB6, 0x98, 0x07, 0x9C, 0x5C, 0x97, 0xCF, 0x79, 0xCE, 0x73, 0x36, 0xEE, 0x5D, 0x8A, 0xD5, 0xF2, + 0x76, 0x44, 0x7F, 0x43, 0xC6, 0xFB, 0xB2, 0xCF, 0xF6, 0xE4, 0x33, 0x8E, 0x97, 0x6A, 0xD8, 0x81, + 0xCA, 0xBC, 0x29, 0xE9, 0x1C, 0x5A, 0xC6, 0xD7, 0x63, 0x5A, 0xBD, 0xEA, 0x73, 0xC9, 0xFB, 0xC8, + 0x9A, 0xEC, 0x5B, 0x25, 0xB9, 0xAB, 0x84, 0x19, 0x4B, 0x98, 0x29, 0x62, 0x98, 0x6C, 0xCC, 0x1C, + 0x13, 0xE5, 0xBE, 0x13, 0xE3, 0xBA, 0x19, 0x97, 0xFB, 0x9C, 0xC7, 0xA2, 0x7F, 0xC5, 0xAF, 0x54, + 0x74, 0x70, 0x5F, 0x94, 0xA8, 0xE3, 0xC8, 0x78, 0xC3, 0x18, 0x26, 0x58, 0x0A, 0x2F, 0x39, 0xFF, + 0x90, 0xAF, 0x9A, 0x78, 0x7C, 0xAF, 0x7F, 0xDA, 0x14, 0xBC, 0x54, 0x1A, 0x9B, 0xD8, 0x7E, 0xE5, + 0x13, 0x98, 0xC2, 0x5B, 0x22, 0x7F, 0xF2, 0x8A, 0xFF, 0x25, 0xF9, 0xBA, 0xE6, 0xE4, 0x2B, 0xF2, + 0xB9, 0x93, 0xE9, 0x2E, 0x4B, 0x38, 0x90, 0xA2, 0xE7, 0xB2, 0xCE, 0x94, 0xE7, 0x4F, 0xFA, 0x97, + 0x31, 0x9B, 0x46, 0xF4, 0x4F, 0x10, 0x3F, 0xEC, 0xC1, 0x4A, 0x51, 0xA7, 0xE1, 0xD7, 0xE8, 0xAB, + 0xC8, 0x53, 0x10, 0xD7, 0x71, 0xCF, 0xFA, 0x8F, 0x3C, 0x4E, 0xF7, 0x10, 0x8F, 0x64, 0xCE, 0xE0, + 0x57, 0x2B, 0x9F, 0x4D, 0xD1, 0x6C, 0xC3, 0x6F, 0xE4, 0x62, 0xBC, 0x74, 0x89, 0x1E, 0x29, 0xC6, + 0xC7, 0x5D, 0x56, 0xBF, 0x7E, 0x7E, 0x8E, 0x75, 0x9D, 0x7F, 0xC4, 0xBE, 0xF9, 0x77, 0xE2, 0xF7, + 0x7C, 0x4C, 0xC7, 0xE6, 0xAF, 0x74, 0x19, 0xF2, 0x95, 0xA4, 0x80, 0x1D, 0x88, 0x53, 0x2B, 0xE5, + 0x2C, 0xBE, 0xCE, 0x75, 0xAE, 0xB3, 0x7A, 0xD9, 0xCB, 0x5E, 0xB6, 0x91, 0xC3, 0x20, 0xB6, 0x31, + 0x8E, 0x4D, 0x4B, 0x3B, 0x96, 0x2A, 0xB5, 0xBD, 0xC6, 0xF7, 0x49, 0xFF, 0x3F, 0xF9, 0x0C, 0x1E, + 0xF4, 0xA0, 0x07, 0x0D, 0x7D, 0x53, 0xBE, 0x99, 0x8C, 0xE7, 0xB7, 0xCC, 0x15, 0xFF, 0x6D, 0xF6, + 0x7F, 0x8F, 0x37, 0x72, 0xDF, 0x28, 0x7C, 0x83, 0x5C, 0xB7, 0x4F, 0x89, 0x3A, 0xC7, 0x9A, 0x7E, + 0xA8, 0x85, 0xBE, 0x6D, 0xF4, 0xBF, 0x6C, 0x9E, 0x32, 0x2F, 0x35, 0x5F, 0xE1, 0x31, 0xE8, 0x8E, + 0xE5, 0xAF, 0x9E, 0xF9, 0xF5, 0x2D, 0x25, 0x4F, 0xC7, 0x7C, 0x3F, 0xBC, 0x27, 0xFF, 0xBF, 0xF4, + 0xCF, 0x63, 0xF2, 0x5D, 0x4D, 0xBE, 0xE8, 0x2D, 0x99, 0xCE, 0x47, 0xBE, 0x07, 0xB4, 0xA9, 0xB7, + 0xEF, 0x11, 0x7B, 0xA3, 0xAF, 0x23, 0xBF, 0x61, 0xD6, 0x9F, 0xF8, 0x59, 0x36, 0x97, 0xFD, 0x3B, + 0x3D, 0xF6, 0xF7, 0xEC, 0xB7, 0x54, 0xFC, 0xD4, 0xDC, 0x7F, 0xA9, 0x77, 0x1F, 0xCD, 0x7C, 0x2E, + 0x7C, 0xFD, 0x48, 0x1E, 0xE1, 0x3D, 0xE7, 0x36, 0xA3, 0x03, 0x8D, 0xBE, 0x4C, 0xD9, 0xB9, 0x72, + 0xB5, 0xB1, 0x5D, 0x92, 0xB7, 0x44, 0x1A, 0x96, 0xB0, 0xAA, 0xEF, 0x99, 0xF8, 0x79, 0x83, 0x79, + 0x6F, 0x76, 0xB3, 0x9B, 0x35, 0xCB, 0xE0, 0xD9, 0x5E, 0x18, 0xE5, 0x2A, 0x97, 0xDB, 0x38, 0x5B, + 0x15, 0x7C, 0xD3, 0x5B, 0x4A, 0xF3, 0x86, 0x57, 0xEE, 0xA7, 0x58, 0x48, 0x6A, 0x4B, 0x2E, 0x77, + 0xD7, 0x3B, 0xC0, 0x0F, 0xD0, 0x4F, 0xC9, 0x7F, 0x29, 0xC3, 0x68, 0x63, 0x9F, 0xF9, 0xE7, 0x3E, + 0x06, 0x8A, 0x33, 0x52, 0xDC, 0x58, 0x2B, 0x0F, 0x8E, 0x78, 0x3D, 0xF2, 0x13, 0xE2, 0x60, 0x1C, + 0x2F, 0xC5, 0x3D, 0x6A, 0x6E, 0xA9, 0xF1, 0x23, 0xCD, 0x2D, 0xE6, 0x0B, 0x36, 0x78, 0xF2, 0x09, + 0x7B, 0x9B, 0xE3, 0xFA, 0x71, 0x5A, 0x3B, 0xE6, 0x50, 0xFC, 0x4B, 0xF4, 0x5F, 0x6A, 0xB5, 0x2F, + 0x65, 0x7B, 0x0C, 0x9F, 0x71, 0x3F, 0xD7, 0xEB, 0x31, 0x1F, 0x7A, 0x6D, 0x08, 0xB5, 0x1C, 0x52, + 0x7C, 0x46, 0x6C, 0x38, 0x71, 0xEE, 0xE8, 0xB2, 0x3C, 0x8F, 0x72, 0xF4, 0xCB, 0xA6, 0xE4, 0xFE, + 0x4D, 0xEB, 0x2D, 0x25, 0xF9, 0xD8, 0xF5, 0x41, 0x3E, 0x8F, 0xF1, 0x1F, 0x45, 0x4F, 0x48, 0x2C, + 0xBF, 0xAF, 0xE3, 0x48, 0x93, 0xA8, 0x0F, 0x2C, 0x8D, 0x95, 0x7C, 0xD4, 0x6B, 0xDF, 0x59, 0x67, + 0x89, 0xFD, 0x17, 0xDD, 0x15, 0x67, 0xC7, 0xFF, 0xC8, 0x7D, 0x19, 0x73, 0xE8, 0x2C, 0xB1, 0xEF, + 0xFB, 0x9C, 0x77, 0xD9, 0x5A, 0x9F, 0x3B, 0x7F, 0xC2, 0x67, 0x04, 0x5B, 0x48, 0x6C, 0xBB, 0xBF, + 0xF6, 0xF6, 0xBB, 0xE5, 0xB3, 0x58, 0x36, 0xE7, 0x08, 0xBB, 0x68, 0x03, 0xEB, 0x83, 0xA1, 0xBD, + 0xDD, 0xD9, 0xBE, 0x38, 0x87, 0x46, 0x4E, 0x27, 0xC7, 0x93, 0xAA, 0x9E, 0xDF, 0xBB, 0x24, 0x3B, + 0x6F, 0x05, 0x1E, 0x1F, 0x68, 0x74, 0xF1, 0x3C, 0x26, 0xF7, 0xD1, 0xED, 0x6E, 0x77, 0xBB, 0x6E, + 0x1A, 0xA8, 0x3F, 0x1A, 0x7B, 0xB0, 0x08, 0x71, 0xA7, 0x94, 0xCC, 0x0E, 0x1B, 0xFB, 0x59, 0xD3, + 0xBD, 0xB4, 0x94, 0xB1, 0xDF, 0x21, 0xF7, 0x31, 0x17, 0xC5, 0x9F, 0xE3, 0x99, 0x56, 0x53, 0xC7, + 0x36, 0xFB, 0x2D, 0x7A, 0x55, 0xCE, 0xA5, 0xC4, 0x37, 0x3B, 0xCB, 0xF5, 0x9D, 0xE9, 0x9C, 0xB7, + 0x4A, 0xEE, 0xCA, 0xFC, 0x9A, 0xA2, 0xDC, 0xA2, 0x36, 0x63, 0xAB, 0x66, 0x2E, 0x8C, 0xD9, 0x54, + 0xA6, 0xD0, 0x4E, 0x3C, 0x09, 0x5C, 0x12, 0xF9, 0x43, 0x56, 0xC6, 0xE8, 0xE3, 0xFF, 0x93, 0xFF, + 0xD2, 0xD4, 0x3C, 0xB3, 0xD2, 0x2F, 0x29, 0x37, 0x43, 0x69, 0xAF, 0x69, 0x69, 0x4B, 0x7C, 0xCF, + 0xBE, 0xAD, 0xFE, 0xB3, 0xC7, 0x4E, 0x8D, 0xB7, 0xE1, 0xD5, 0x7F, 0x4B, 0x9E, 0x09, 0xF0, 0x52, + 0x4D, 0x47, 0x39, 0xA7, 0x94, 0xF8, 0x91, 0x7F, 0x86, 0xFD, 0x1C, 0xBA, 0xF9, 0x19, 0x3E, 0xBE, + 0x47, 0xC4, 0xB5, 0xA3, 0x6B, 0xEF, 0x07, 0xFC, 0x10, 0x7C, 0x53, 0xD2, 0x69, 0x8D, 0xB5, 0x2F, + 0xC3, 0x21, 0x31, 0x9F, 0x80, 0xCF, 0xDB, 0x56, 0xFA, 0xC7, 0x36, 0x8B, 0xAF, 0x8B, 0x97, 0x68, + 0x8D, 0x90, 0x0B, 0x49, 0xE7, 0x91, 0x44, 0x1A, 0x45, 0xDF, 0xA2, 0xCB, 0x03, 0x37, 0xF8, 0xFA, + 0x8F, 0xF4, 0xD5, 0xE7, 0xE8, 0x94, 0x1F, 0xF7, 0xB8, 0xC7, 0xAD, 0xF6, 0xDE, 0x7B, 0xEF, 0x0D, + 0x1A, 0x95, 0x78, 0x1D, 0x76, 0xB9, 0xFB, 0xDC, 0xE7, 0x3E, 0x43, 0x9F, 0x9D, 0xFE, 0xB5, 0x7E, + 0x6E, 0x55, 0xBF, 0x7D, 0x5F, 0x71, 0x3E, 0x1B, 0x0B, 0x31, 0xD8, 0xC4, 0x36, 0xDF, 0xF4, 0xA6, + 0x37, 0x5D, 0xAB, 0x2D, 0x29, 0x93, 0x1D, 0xB5, 0x57, 0xEA, 0x9A, 0xBC, 0x52, 0x9E, 0xE7, 0x3B, + 0xF6, 0xC7, 0xAF, 0xC7, 0xF8, 0x61, 0x49, 0x9E, 0x6C, 0xD5, 0x2F, 0x51, 0x65, 0x27, 0x86, 0x7E, + 0xC4, 0x15, 0xC9, 0x3E, 0xAB, 0x76, 0x2F, 0x89, 0x97, 0x62, 0x8D, 0x3C, 0x83, 0x57, 0xC7, 0xE7, + 0x53, 0x74, 0x98, 0x25, 0x1D, 0x4D, 0x4D, 0x5F, 0x11, 0x9F, 0xE3, 0x7A, 0x10, 0xE8, 0xE1, 0xE7, + 0xE8, 0xB5, 0xCA, 0xBF, 0x11, 0x2F, 0x71, 0xCD, 0x3A, 0x52, 0x89, 0xE7, 0x29, 0x44, 0xDF, 0xBF, + 0x58, 0xC7, 0xFA, 0x32, 0x46, 0x87, 0xF8, 0xBF, 0xA8, 0x73, 0xE8, 0xF5, 0x5F, 0xA8, 0xED, 0x5B, + 0x3E, 0x77, 0x34, 0xC6, 0xC4, 0x92, 0x11, 0x37, 0x43, 0xFC, 0xAB, 0xFB, 0x02, 0x95, 0xFC, 0xF5, + 0x7A, 0xFB, 0xDB, 0x5B, 0xE2, 0x7C, 0x72, 0xFD, 0xA2, 0xDA, 0xE6, 0xFF, 0x23, 0x97, 0xC3, 0xDD, + 0xEE, 0x76, 0xB7, 0x41, 0x4F, 0x18, 0xF7, 0x8B, 0x6C, 0x6E, 0xB4, 0xE8, 0xAC, 0xC5, 0x77, 0x7D, + 0x8F, 0x02, 0x2F, 0xB5, 0xD8, 0xE3, 0xC6, 0xE8, 0xE3, 0xB8, 0x94, 0xB1, 0x46, 0x6F, 0xD5, 0xBB, + 0x36, 0xD5, 0x6E, 0xF6, 0x7B, 0xF6, 0x7D, 0xE5, 0xF7, 0xA6, 0x78, 0x3E, 0x9A, 0x9A, 0x6D, 0x9B, + 0xD7, 0x68, 0xCB, 0x92, 0xFD, 0x9F, 0x8A, 0x3D, 0xCE, 0xF1, 0xE2, 0x94, 0x73, 0x9F, 0x33, 0xBC, + 0x84, 0xDD, 0x44, 0xE7, 0x53, 0x47, 0x5F, 0xB4, 0x25, 0x4A, 0xE4, 0x19, 0x99, 0x6F, 0x03, 0x71, + 0x26, 0x9C, 0x41, 0xAB, 0x3C, 0x95, 0x4E, 0xD7, 0x1A, 0x5E, 0x72, 0x5D, 0x4F, 0x8C, 0x17, 0xEE, + 0x59, 0xFF, 0x5E, 0x7C, 0x9D, 0x81, 0x97, 0xF0, 0x5F, 0xCA, 0xE6, 0x66, 0x2F, 0x5E, 0x8A, 0x7B, + 0x5E, 0xC4, 0x82, 0xFB, 0xEC, 0xB3, 0xCF, 0x70, 0x36, 0x02, 0x7E, 0x1E, 0xAE, 0x5F, 0x52, 0x1B, + 0x19, 0x9F, 0x29, 0xE7, 0x25, 0x2D, 0x51, 0x4A, 0xFB, 0x8B, 0xEF, 0x01, 0xC8, 0x08, 0xE4, 0xDE, + 0x85, 0x7F, 0x31, 0x37, 0xC1, 0xF4, 0xD9, 0x7A, 0x76, 0x99, 0x13, 0xDF, 0x68, 0x64, 0x63, 0x7C, + 0xC3, 0x75, 0x2E, 0x17, 0xC5, 0xF5, 0x49, 0x6E, 0xEF, 0xDB, 0xAA, 0x3E, 0xB7, 0xC8, 0x57, 0xF0, + 0x0A, 0x72, 0x23, 0xE0, 0xFF, 0xA7, 0xBD, 0x2B, 0x9B, 0x13, 0x53, 0x6C, 0x72, 0xBD, 0xB8, 0x80, + 0xE7, 0x82, 0x07, 0x14, 0xDB, 0x7E, 0x79, 0xE0, 0x69, 0xA3, 0xD0, 0x50, 0xB1, 0x23, 0xAF, 0x2E, + 0xF5, 0x7B, 0x21, 0x56, 0x92, 0x1C, 0x60, 0xA2, 0x4F, 0x66, 0x53, 0xEC, 0xE1, 0x61, 0x63, 0xB4, + 0xCC, 0x6C, 0xF9, 0xC4, 0xB9, 0xC6, 0xFC, 0xFF, 0x5B, 0x59, 0x58, 0x27, 0x9E, 0x13, 0x14, 0xB9, + 0x82, 0x5C, 0x10, 0xF4, 0x63, 0x0A, 0x2F, 0x77, 0x59, 0x04, 0xDE, 0x49, 0x9C, 0x5B, 0xB6, 0x4E, + 0x32, 0xB9, 0x46, 0x9F, 0xB7, 0x60, 0xBF, 0xDE, 0xC2, 0x9E, 0x8C, 0x3D, 0x2E, 0xB3, 0x09, 0xAD, + 0xA3, 0x72, 0x7F, 0xE8, 0x08, 0x1E, 0x20, 0x9F, 0x94, 0x72, 0xF9, 0x79, 0x3F, 0x33, 0x9B, 0xDC, + 0x1C, 0x1D, 0x5B, 0xAD, 0x8C, 0x61, 0x6E, 0x15, 0xE5, 0x8A, 0x23, 0xFF, 0xA6, 0xE7, 0x11, 0x1F, + 0x5B, 0x0F, 0xD9, 0x7E, 0x52, 0xFA, 0x8E, 0xCF, 0x2B, 0xE8, 0x83, 0xAD, 0x74, 0x6E, 0xDF, 0xBC, + 0xE8, 0x2C, 0xAA, 0x0C, 0x57, 0x8C, 0xF5, 0x81, 0x57, 0xF0, 0x52, 0xCC, 0xBF, 0x54, 0xC3, 0xF0, + 0x3E, 0x96, 0xB1, 0x3D, 0x7C, 0xEE, 0x63, 0x0F, 0x5E, 0x9A, 0x9A, 0xF3, 0x2E, 0xB6, 0xD3, 0xE9, + 0x78, 0xCB, 0x5B, 0xDE, 0x72, 0x18, 0xB7, 0x38, 0xCF, 0xD6, 0x61, 0xEF, 0xF1, 0xFE, 0xF2, 0x3C, + 0x5D, 0x93, 0x67, 0x96, 0x7D, 0x56, 0x63, 0xEC, 0x58, 0xA8, 0x16, 0x5F, 0x11, 0xF1, 0x92, 0xF4, + 0x4B, 0x4E, 0xC3, 0x96, 0x36, 0xF9, 0xAB, 0xFF, 0x86, 0xFC, 0x2A, 0x8E, 0x97, 0xFC, 0xF9, 0xAD, + 0xFA, 0x84, 0x31, 0xDE, 0xEE, 0xB8, 0x82, 0xDC, 0x22, 0xE4, 0x9F, 0xC2, 0x17, 0x74, 0x2C, 0x86, + 0x7B, 0x2B, 0xF7, 0x44, 0xB7, 0x13, 0x46, 0xFA, 0xB2, 0x07, 0xE0, 0xBF, 0xF3, 0xF4, 0xA7, 0x3F, + 0x7D, 0xF0, 0x85, 0xF3, 0x71, 0xCA, 0xE4, 0x24, 0xA7, 0x9F, 0x64, 0x20, 0x72, 0x4B, 0x9E, 0x73, + 0xCE, 0x39, 0x9B, 0xEE, 0x5B, 0xD2, 0x65, 0x6D, 0x75, 0x29, 0xE9, 0x0F, 0xC8, 0x9D, 0x43, 0x6E, + 0xA9, 0x75, 0xE9, 0x95, 0x4A, 0x3C, 0xD2, 0xE9, 0xE7, 0x71, 0xE5, 0x9E, 0xC7, 0xAF, 0x24, 0xFB, + 0x97, 0xFA, 0x57, 0xD2, 0x01, 0x4F, 0xA2, 0x57, 0xC8, 0x77, 0xC8, 0xF8, 0x61, 0x6F, 0x40, 0xFF, + 0xA5, 0x31, 0xD7, 0x1A, 0x5F, 0x0A, 0x43, 0x66, 0x32, 0xB8, 0xEF, 0xA7, 0xBC, 0x0A, 0x2F, 0xF5, + 0xF8, 0xF6, 0x8F, 0xD1, 0xAB, 0x07, 0x6F, 0xC8, 0x27, 0x51, 0xB2, 0x00, 0xBE, 0xDE, 0x99, 0xCE, + 0xB0, 0xB5, 0xBF, 0x1E, 0x73, 0xCA, 0xBA, 0x43, 0xE6, 0xF0, 0xB3, 0x74, 0x4B, 0x6D, 0xC8, 0xFA, + 0x30, 0xA5, 0x94, 0x7E, 0x8B, 0xCD, 0x87, 0x3D, 0x54, 0x6D, 0x73, 0x3D, 0x58, 0x4B, 0x3F, 0x5B, + 0xE6, 0x84, 0xCB, 0x9A, 0xC2, 0xC6, 0xF0, 0x4E, 0x72, 0x86, 0x71, 0xCE, 0x51, 0xC6, 0x3B, 0xB2, + 0xF5, 0xB0, 0x6E, 0xBE, 0x12, 0x75, 0x7A, 0x7A, 0x1E, 0xF3, 0x00, 0x5F, 0x75, 0xE5, 0xCE, 0x69, + 0xED, 0x77, 0xCF, 0x1E, 0x2F, 0xDA, 0x6B, 0xCD, 0xA1, 0xF3, 0x5B, 0x42, 0xBF, 0x24, 0xBD, 0x0E, + 0x7B, 0x02, 0x32, 0x23, 0xB6, 0xD7, 0x5E, 0x1F, 0x15, 0x7D, 0x8F, 0x38, 0x47, 0xF4, 0x4B, 0x9F, + 0xFD, 0xEC, 0x67, 0x37, 0xEE, 0xD9, 0x22, 0xAB, 0x66, 0xDF, 0xD1, 0xEF, 0x35, 0xF6, 0xF2, 0xF7, + 0x9E, 0x83, 0xD7, 0x33, 0xBC, 0x84, 0x7C, 0x2C, 0xFD, 0x52, 0xA4, 0xC9, 0x12, 0x25, 0xF6, 0x51, + 0xAF, 0xA2, 0x0D, 0xFC, 0xE3, 0x15, 0xAF, 0x78, 0xC5, 0xA6, 0x3C, 0xB7, 0x19, 0x5E, 0xCA, 0xE6, + 0x93, 0xD6, 0x0D, 0xFD, 0x81, 0x1F, 0xA2, 0x6F, 0xEF, 0xE5, 0x05, 0xAE, 0x07, 0x8C, 0xBF, 0x81, + 0xBF, 0xFA, 0x79, 0x57, 0x4E, 0xC3, 0x39, 0xF3, 0xBB, 0xF4, 0x5B, 0xD1, 0xE0, 0xE0, 0x83, 0x0F, + 0x1E, 0x6C, 0xA4, 0x6A, 0x9F, 0xF7, 0x27, 0xEA, 0x9A, 0xD7, 0x5D, 0x32, 0x9D, 0x96, 0xCF, 0x0D, + 0x72, 0x86, 0xA0, 0x23, 0xE2, 0xBC, 0x31, 0x1F, 0x97, 0xB8, 0x7E, 0xDC, 0x8E, 0x20, 0x9C, 0xA4, + 0xFF, 0xA3, 0x57, 0xC4, 0x87, 0x0B, 0x3E, 0x4B, 0x5E, 0x15, 0x7F, 0x96, 0xB7, 0x61, 0x2B, 0x7C, + 0xB6, 0x4A, 0xFA, 0x5E, 0x0A, 0x74, 0x47, 0xFF, 0x47, 0xFE, 0x70, 0x72, 0x6F, 0xEA, 0x5C, 0x92, + 0xA8, 0xFB, 0x5E, 0x67, 0xF5, 0x3D, 0xC7, 0x9F, 0x49, 0xBE, 0x78, 0xCE, 0x9B, 0xC9, 0x70, 0x7F, + 0x6B, 0x9F, 0xE3, 0xF5, 0x44, 0x0A, 0x0E, 0xD5, 0x65, 0x78, 0xE2, 0x30, 0x3C, 0x8F, 0xD9, 0x5C, + 0x9F, 0x96, 0xD2, 0x7A, 0xAA, 0xF1, 0x08, 0xF8, 0x27, 0x72, 0x61, 0x49, 0x3E, 0x5D, 0x47, 0x89, + 0x74, 0x75, 0x7B, 0x5C, 0x3C, 0x0F, 0xB4, 0x87, 0x9F, 0x38, 0xE6, 0xE4, 0x3D, 0x73, 0xF1, 0xB5, + 0xAF, 0x7D, 0xED, 0xA6, 0x33, 0x1A, 0xC6, 0xF8, 0xDF, 0x52, 0x3A, 0xA5, 0x78, 0x0F, 0x62, 0x38, + 0xFC, 0xFC, 0xEB, 0xDE, 0x35, 0xD2, 0x62, 0x6B, 0x2A, 0x5D, 0x73, 0x16, 0x26, 0xF9, 0x4A, 0x90, + 0xDD, 0x9C, 0x8F, 0x6C, 0xA5, 0xCC, 0x55, 0xC2, 0x18, 0x2A, 0xE8, 0xC0, 0xC8, 0x9B, 0x83, 0x1F, + 0x0C, 0x18, 0x2F, 0xDB, 0x93, 0xE7, 0xEC, 0x27, 0x8E, 0x25, 0xFD, 0x9E, 0x7E, 0x46, 0xE8, 0x12, + 0x7D, 0xA2, 0xA0, 0xD3, 0x04, 0xEF, 0xF4, 0xAC, 0x61, 0xFF, 0xAE, 0xF0, 0x92, 0x70, 0x5C, 0xCF, + 0x7C, 0xCC, 0xF4, 0x4E, 0xFE, 0x19, 0x67, 0x59, 0x38, 0x0F, 0x98, 0x22, 0x97, 0xA8, 0x3A, 0x1D, + 0x91, 0x4D, 0xD0, 0x67, 0xD4, 0x70, 0xC3, 0x9C, 0x52, 0x92, 0x73, 0xF5, 0x8C, 0x98, 0xF3, 0xCA, + 0xE3, 0x28, 0xC7, 0x74, 0x8F, 0xFE, 0x1E, 0x5C, 0xD3, 0x92, 0xBF, 0xB7, 0xD6, 0x4E, 0x6F, 0x2B, + 0x74, 0x80, 0xCF, 0x63, 0xE7, 0xF0, 0xFD, 0xDF, 0x69, 0xDE, 0x2A, 0x2F, 0x95, 0xE6, 0xB6, 0xEE, + 0x11, 0xF9, 0x08, 0x39, 0x38, 0xC8, 0xAB, 0x82, 0xAE, 0xD2, 0xF3, 0x36, 0x4F, 0xD9, 0x0B, 0x97, + 0x2A, 0x31, 0x06, 0x72, 0xD7, 0xAE, 0x5D, 0x43, 0x4C, 0x07, 0x7E, 0x8A, 0xC2, 0x4A, 0x11, 0xE7, + 0xD6, 0xFA, 0xAD, 0x6B, 0xF8, 0xA9, 0xC6, 0x9C, 0x3C, 0x42, 0xD8, 0x6D, 0xC0, 0xBD, 0xF0, 0x15, + 0x9D, 0xD1, 0xB0, 0x55, 0xBE, 0xED, 0x94, 0x8C, 0xB7, 0xA2, 0x3B, 0xC7, 0x37, 0x88, 0xB3, 0xF6, + 0xF0, 0x33, 0x83, 0xCF, 0xB5, 0x8C, 0x75, 0xAD, 0xFF, 0x53, 0xF7, 0x8B, 0xD2, 0xE7, 0x9C, 0x59, + 0x47, 0x3C, 0xB2, 0x72, 0x10, 0xF3, 0x4A, 0x3E, 0x00, 0x2A, 0x7A, 0x07, 0x5E, 0xD1, 0xE9, 0xEA, + 0x33, 0x5D, 0xF3, 0x3F, 0xFF, 0xBF, 0xCE, 0xCB, 0xD6, 0xF7, 0xF4, 0x39, 0x15, 0x5D, 0xA2, 0xBE, + 0x5F, 0xAA, 0xFA, 0x0D, 0x34, 0x03, 0x17, 0xF0, 0x3B, 0xCE, 0x7F, 0xE6, 0x0C, 0xED, 0xCC, 0x46, + 0x93, 0xCD, 0x89, 0xD6, 0xBD, 0xA1, 0x56, 0xA3, 0x1D, 0x9F, 0xB3, 0x71, 0x90, 0xCB, 0x68, 0x23, + 0xED, 0x52, 0x5F, 0x22, 0x8D, 0x62, 0xDF, 0x4B, 0xFD, 0x73, 0xBA, 0x38, 0x7D, 0x44, 0x77, 0xDE, + 0xC7, 0xDF, 0xF0, 0x3F, 0x2A, 0x3A, 0x10, 0xD6, 0xB7, 0xDB, 0xE6, 0x7B, 0x71, 0xA3, 0xAF, 0x33, + 0xCE, 0x39, 0x7B, 0xF6, 0xB3, 0x9F, 0x3D, 0xF8, 0x81, 0x68, 0x0C, 0xA1, 0xBF, 0xC6, 0x52, 0x6D, + 0xA2, 0x7D, 0xA5, 0x7E, 0xF5, 0x54, 0x9F, 0x3F, 0xEA, 0x93, 0x9E, 0x45, 0x1B, 0x9E, 0xF4, 0xA4, + 0x27, 0x6D, 0xB4, 0x4F, 0x71, 0x1F, 0xBD, 0x75, 0x8C, 0xDF, 0xBB, 0x6E, 0xD5, 0x75, 0xAD, 0xF0, + 0x12, 0x72, 0xC8, 0x1F, 0x73, 0xCC, 0x31, 0x43, 0x0C, 0x22, 0xBA, 0x4D, 0x72, 0x71, 0x52, 0x96, + 0xB4, 0x3B, 0xD6, 0x8A, 0xDB, 0x51, 0x78, 0xC5, 0x07, 0x9E, 0xB3, 0x06, 0xCE, 0x3E, 0xFB, 0xEC, + 0x41, 0xD6, 0xCA, 0x72, 0xDA, 0xB6, 0xE0, 0xA5, 0x12, 0x4D, 0x4A, 0x3C, 0xC3, 0xD7, 0x19, 0x63, + 0xB2, 0x7B, 0xF7, 0xEE, 0xE6, 0xB1, 0x75, 0xFE, 0xE0, 0x3C, 0x01, 0xBF, 0x09, 0x7D, 0x87, 0xFB, + 0x71, 0xCE, 0x94, 0x9E, 0xDD, 0x2B, 0x33, 0x62, 0x8F, 0x3B, 0xEE, 0xB8, 0xE3, 0x86, 0x7C, 0x6F, + 0x5A, 0x3B, 0x71, 0x4D, 0x66, 0xF3, 0xAD, 0xD4, 0x76, 0xFE, 0xC7, 0x7D, 0xC8, 0xCF, 0xA3, 0x38, + 0x2D, 0x97, 0xCD, 0xA7, 0xCA, 0x66, 0x3E, 0x36, 0xE4, 0x06, 0x06, 0x17, 0xF0, 0x0C, 0x9E, 0xA5, + 0x3A, 0x77, 0x4D, 0x65, 0x3C, 0x86, 0xFB, 0xB2, 0x8E, 0x89, 0x67, 0x80, 0x67, 0xF1, 0xBF, 0x37, + 0xBD, 0xE9, 0x4D, 0x1B, 0x36, 0x2F, 0x61, 0x87, 0xA8, 0x57, 0xCF, 0xE6, 0x43, 0xD4, 0xBF, 0xE3, + 0xEF, 0x4D, 0x0C, 0x4E, 0x1C, 0xF3, 0xB1, 0xB6, 0x89, 0xB7, 0x70, 0x2D, 0x1E, 0x43, 0x3B, 0x99, + 0x17, 0xC4, 0xD3, 0x60, 0x2B, 0x72, 0x7F, 0xA3, 0xCC, 0x97, 0x74, 0x8C, 0xAF, 0x8D, 0xE1, 0xBE, + 0x38, 0xBF, 0x15, 0x83, 0x4B, 0x2E, 0x64, 0xEC, 0x18, 0xAC, 0x33, 0x70, 0x13, 0x7A, 0x4B, 0xE9, + 0x5A, 0x6A, 0xB1, 0x30, 0x4B, 0x16, 0xB7, 0x0B, 0x72, 0x1E, 0xDC, 0x87, 0x3F, 0xFC, 0xE1, 0x01, + 0x97, 0x72, 0xA6, 0x12, 0x7C, 0xBA, 0xA4, 0x6F, 0xD3, 0x78, 0x7A, 0x9F, 0x23, 0x36, 0x74, 0x5A, + 0xA2, 0x77, 0xD2, 0xBC, 0xC4, 0x5F, 0x1C, 0x7B, 0x05, 0xF4, 0xBF, 0xEC, 0x9C, 0x86, 0xAD, 0xC1, + 0x4D, 0x11, 0x2F, 0x31, 0x0F, 0xD0, 0x4B, 0x60, 0x27, 0xC5, 0xC7, 0x2C, 0x8E, 0xAB, 0xCB, 0x72, + 0xDE, 0xCF, 0xB1, 0xBE, 0x4F, 0xD9, 0x3F, 0x7C, 0x8F, 0x74, 0xEC, 0x21, 0xBA, 0x93, 0xDF, 0x08, + 0xBD, 0x24, 0x73, 0x05, 0x3F, 0x52, 0xD5, 0x73, 0xCF, 0x3D, 0x77, 0xD0, 0xFF, 0x73, 0x4D, 0x5F, + 0xF8, 0x8E, 0x2A, 0xEF, 0xA9, 0xFA, 0x3F, 0xDF, 0xD5, 0x77, 0xF8, 0x4C, 0x9F, 0xA3, 0x83, 0xA6, + 0xEA, 0xB3, 0x5A, 0xD5, 0xF3, 0xF0, 0x4B, 0xE4, 0x1A, 0x1F, 0x0D, 0xC5, 0x00, 0xF8, 0x3C, 0x8F, + 0x7D, 0x9A, 0x73, 0x66, 0x4C, 0x5C, 0x9B, 0x71, 0x9D, 0x12, 0x8B, 0x03, 0x9E, 0xA4, 0x5D, 0xD8, + 0xAE, 0x38, 0xF3, 0xC5, 0xFB, 0x28, 0x1A, 0xF8, 0x67, 0x7A, 0x1F, 0x69, 0x16, 0x69, 0xE3, 0xF4, + 0x81, 0x97, 0xE2, 0x5F, 0x90, 0xFD, 0x8F, 0xCF, 0xB0, 0x3B, 0x73, 0xA6, 0x23, 0x7B, 0x7A, 0x6C, + 0x7F, 0x0F, 0x3F, 0x77, 0x1A, 0x92, 0x9F, 0x83, 0x73, 0x51, 0x88, 0xB9, 0x43, 0xFF, 0x49, 0xDF, + 0xF4, 0x6C, 0xDA, 0x4A, 0x7B, 0xE8, 0x03, 0x6D, 0xD0, 0x78, 0xFB, 0x18, 0xFB, 0x5C, 0x69, 0x19, + 0x5B, 0x7E, 0xA7, 0xEF, 0x8A, 0x1E, 0xEA, 0xE7, 0xAB, 0x5F, 0xFD, 0xEA, 0x8D, 0xBC, 0x52, 0x5A, + 0xD7, 0x71, 0x9E, 0xF6, 0x8C, 0x6B, 0xA4, 0x91, 0xCF, 0x11, 0xF1, 0x8B, 0x0C, 0x87, 0x73, 0x8D, + 0x5C, 0xC3, 0x79, 0x99, 0x9C, 0x3B, 0xC5, 0xDE, 0x3E, 0x76, 0x5E, 0xE4, 0x12, 0xC5, 0xEF, 0xCF, + 0xF3, 0xF0, 0x43, 0xC7, 0x4E, 0xCE, 0xFE, 0xA4, 0x5C, 0x94, 0x4E, 0x0B, 0x8F, 0x71, 0xCD, 0x74, + 0x05, 0xA5, 0xF7, 0x2D, 0x7C, 0xC2, 0x7D, 0x45, 0xB1, 0x55, 0x82, 0x1F, 0xC7, 0xC6, 0x57, 0x73, + 0xC5, 0xE7, 0xBE, 0xE6, 0x4A, 0xE4, 0x1F, 0xE4, 0x7C, 0x63, 0xDE, 0x45, 0xFE, 0xDD, 0x3A, 0x7F, + 0xD9, 0xDF, 0x0E, 0x3D, 0xF4, 0xD0, 0x61, 0x7F, 0x03, 0x4F, 0x6A, 0xBE, 0x6A, 0x4E, 0x66, 0xFC, + 0x87, 0x5C, 0xC7, 0x71, 0xAD, 0xEA, 0x77, 0xFC, 0x8F, 0xF8, 0x21, 0xAE, 0xF1, 0xCB, 0xD6, 0x1C, + 0x71, 0xDE, 0xDC, 0x42, 0xBF, 0x78, 0xED, 0xB9, 0xB3, 0x89, 0xD1, 0x38, 0xF1, 0xC4, 0x13, 0x87, + 0x75, 0x1C, 0xD7, 0x0C, 0xEB, 0xAE, 0x85, 0x3F, 0xD6, 0xAA, 0xD3, 0x9B, 0xFE, 0xB2, 0xDE, 0xD8, + 0x6F, 0x39, 0xEB, 0x95, 0xFB, 0x13, 0x0F, 0x2A, 0xDF, 0x25, 0xA7, 0x65, 0xA6, 0x57, 0xCF, 0xD6, + 0x90, 0xDE, 0x43, 0x1F, 0xF4, 0x9C, 0xB4, 0x1F, 0x7D, 0x19, 0x55, 0x7C, 0x7B, 0x6C, 0x7E, 0x40, + 0x67, 0xD1, 0x9C, 0x36, 0x72, 0x3E, 0x00, 0xEF, 0xF1, 0x5F, 0xD6, 0x79, 0x60, 0xBE, 0x66, 0x7B, + 0xE6, 0x6F, 0x36, 0x97, 0xB3, 0x33, 0x1B, 0x5C, 0x0E, 0x13, 0x26, 0x56, 0x2E, 0x1F, 0xD6, 0x19, + 0x78, 0x99, 0x71, 0x52, 0x0C, 0x14, 0x65, 0x2B, 0xF0, 0x12, 0xEB, 0x9F, 0x75, 0x8F, 0xEE, 0x95, + 0x75, 0x0F, 0x2F, 0xF4, 0x33, 0xD5, 0x9D, 0xCF, 0xBB, 0x9F, 0xAD, 0xEC, 0xAA, 0xA5, 0x75, 0x5F, + 0xA3, 0x1F, 0xF7, 0x40, 0x67, 0x05, 0x96, 0xA7, 0xDF, 0xC8, 0x8A, 0xE4, 0x9B, 0x66, 0xBE, 0x78, + 0xEC, 0x69, 0x2D, 0x8F, 0x8E, 0x5F, 0x8F, 0xF9, 0x42, 0xB9, 0xDE, 0x0E, 0x2C, 0x7F, 0xDE, 0x79, + 0xE7, 0x0D, 0x39, 0x93, 0x91, 0x05, 0xC9, 0xAB, 0x8F, 0x8F, 0x1F, 0xBA, 0xFE, 0xDE, 0xBD, 0x7C, + 0x5D, 0x35, 0xA3, 0x1D, 0x73, 0x85, 0x9C, 0x06, 0xE4, 0x07, 0xB9, 0xCD, 0x6D, 0x6E, 0x33, 0xAC, + 0x07, 0x6C, 0xED, 0xAA, 0xD8, 0x3B, 0xFD, 0x7D, 0xA9, 0xF2, 0x3D, 0xE6, 0x3C, 0xBF, 0xF7, 0xCA, + 0xFF, 0xD0, 0x45, 0x8F, 0xFD, 0x9E, 0xDF, 0x62, 0x6B, 0xE0, 0x1A, 0x9D, 0x0E, 0xD7, 0xD7, 0xBD, + 0xEE, 0x75, 0x37, 0xED, 0x6D, 0x71, 0x0E, 0xC4, 0xB5, 0x30, 0xA7, 0x96, 0xF0, 0x38, 0xB4, 0x81, + 0xCF, 0xC4, 0x7E, 0x79, 0xFF, 0x5A, 0x6A, 0xE9, 0xF7, 0xB5, 0x7B, 0xF9, 0x67, 0x5C, 0xA3, 0x5F, + 0xC0, 0x47, 0xD9, 0xDB, 0xD9, 0x6B, 0x2B, 0xF0, 0x75, 0x87, 0x8E, 0xF6, 0xFA, 0xD7, 0xBF, 0xFE, + 0x60, 0x97, 0x83, 0xFE, 0xD4, 0x38, 0x8E, 0x3E, 0x3E, 0xAA, 0x73, 0xE8, 0x50, 0xAA, 0xCC, 0x11, + 0xF2, 0xB6, 0xAA, 0x6D, 0x35, 0xFF, 0xD3, 0x75, 0xD4, 0xB8, 0x77, 0xA0, 0x77, 0x25, 0xB7, 0xE5, + 0x5D, 0xEF, 0x7A, 0xD7, 0x21, 0x9E, 0x06, 0xFB, 0x0F, 0x98, 0x8E, 0xFD, 0x87, 0x9C, 0xB9, 0xCA, + 0x15, 0x2C, 0x5E, 0xE7, 0xBC, 0xA0, 0x74, 0x86, 0x52, 0x86, 0xB9, 0x90, 0xFF, 0xE1, 0x4D, 0xEC, + 0x1D, 0xDC, 0x9F, 0xBD, 0x83, 0xE7, 0xE1, 0xA3, 0x74, 0x93, 0x9B, 0xDC, 0x64, 0x53, 0x2C, 0xD3, + 0xBA, 0x79, 0x43, 0xA4, 0x3B, 0x6B, 0x8F, 0xB9, 0xCF, 0x5A, 0xD4, 0xBC, 0x88, 0xF3, 0x99, 0x6B, + 0xF8, 0x5C, 0xCB, 0xFA, 0xE6, 0x1E, 0x54, 0xF8, 0x33, 0x63, 0x5D, 0xB2, 0x29, 0x94, 0xE6, 0xAD, + 0xAE, 0xD9, 0xF3, 0xB0, 0x29, 0x70, 0x9F, 0xD2, 0x7C, 0x2C, 0xCD, 0x51, 0xF1, 0xA2, 0xD8, 0x7E, + 0xF4, 0xB6, 0xF4, 0x53, 0x36, 0x0F, 0xC7, 0x8C, 0x3D, 0xFA, 0x8D, 0x12, 0xAF, 0x65, 0xDD, 0xEE, + 0xBB, 0xEF, 0xBE, 0x1B, 0xED, 0xE5, 0x59, 0xBC, 0xB6, 0xF2, 0xD7, 0x16, 0xFA, 0x66, 0xEB, 0x56, + 0x7D, 0x66, 0x9D, 0x2B, 0x77, 0x8D, 0xFA, 0x37, 0xC5, 0xFF, 0x11, 0x59, 0x82, 0x7D, 0x5C, 0x34, + 0xE4, 0xDE, 0x2D, 0xEB, 0x5F, 0xED, 0x12, 0xFD, 0x35, 0x17, 0xC8, 0x05, 0xB5, 0xDF, 0x7E, 0xFB, + 0x0D, 0x71, 0xEF, 0x35, 0xDC, 0xBF, 0xC4, 0xFC, 0xAE, 0x61, 0x0A, 0xF1, 0x52, 0x68, 0x04, 0x9F, + 0x65, 0x3E, 0x90, 0x1F, 0x1B, 0xFD, 0x0E, 0xF8, 0x1E, 0x19, 0x9E, 0x75, 0x9A, 0x9D, 0x5D, 0xEB, + 0xD8, 0x21, 0xEA, 0xA1, 0xF5, 0x3E, 0xE6, 0x2A, 0xA0, 0x60, 0x6B, 0x83, 0x9F, 0x60, 0x7F, 0x22, + 0xEE, 0xF9, 0xA8, 0xA3, 0x8E, 0x1A, 0x72, 0xEB, 0x31, 0xAF, 0x89, 0x69, 0xDB, 0x0A, 0xDE, 0x17, + 0x79, 0x1E, 0x63, 0x02, 0xFF, 0xA1, 0xDF, 0xC4, 0xA5, 0x21, 0xC7, 0x23, 0x4B, 0x83, 0x6B, 0xDF, + 0xFB, 0xDE, 0xF7, 0x0E, 0xF2, 0x23, 0xFA, 0x37, 0xF2, 0xD7, 0x11, 0x6F, 0xC1, 0x2B, 0x39, 0x50, + 0xD1, 0x31, 0xA2, 0xA3, 0x42, 0xE7, 0x8B, 0xAD, 0x80, 0xCA, 0x77, 0x91, 0xFB, 0xC0, 0x9E, 0xF8, + 0x5F, 0x41, 0x43, 0xE4, 0x05, 0xF8, 0xDC, 0xF3, 0x9E, 0xF7, 0xBC, 0xE1, 0x9C, 0x33, 0xEC, 0x8C, + 0xC8, 0xED, 0xA5, 0x75, 0x74, 0x79, 0xD7, 0x6C, 0x1E, 0xD6, 0xF8, 0x56, 0x6B, 0xDB, 0xE7, 0xF6, + 0xD1, 0x75, 0xDF, 0x19, 0x0E, 0x28, 0xD9, 0x13, 0xD6, 0x3D, 0x87, 0x4A, 0x74, 0xB9, 0xBC, 0xC6, + 0x6E, 0xEA, 0x7C, 0xAA, 0xE9, 0xE0, 0xB6, 0xCA, 0x87, 0x6E, 0xAC, 0x6F, 0x8E, 0x8F, 0xA6, 0xDA, + 0x1B, 0xE7, 0xD6, 0x8C, 0x16, 0x7C, 0x86, 0x9E, 0xF1, 0x8E, 0x77, 0xBC, 0xE3, 0x60, 0x57, 0x27, + 0x16, 0xFE, 0x84, 0x13, 0x4E, 0x58, 0x9D, 0x75, 0xD6, 0x59, 0x03, 0x2F, 0x25, 0x07, 0x20, 0x32, + 0x34, 0x3A, 0x0A, 0x70, 0x0F, 0xFC, 0x45, 0xD7, 0x54, 0x78, 0x22, 0x9F, 0xC1, 0x6F, 0xD0, 0x87, + 0xC0, 0x83, 0xB0, 0x8F, 0x70, 0x8E, 0xC9, 0xA9, 0xA7, 0x9E, 0x3A, 0x60, 0x31, 0x7C, 0x39, 0xB9, + 0x3F, 0xBE, 0x39, 0x92, 0x11, 0xE6, 0xF8, 0x26, 0x4D, 0xA1, 0xBF, 0xAE, 0xB3, 0xBD, 0x7F, 0xC9, + 0x67, 0x4D, 0xB1, 0xB7, 0x48, 0x17, 0x30, 0x87, 0x47, 0x8D, 0x55, 0xDF, 0xAF, 0xB7, 0x82, 0xCE, + 0x5B, 0x59, 0x5D, 0xB6, 0x8C, 0x34, 0xEC, 0xC5, 0xAB, 0xD9, 0x3D, 0xA6, 0xD0, 0xA1, 0xE4, 0x53, + 0xE8, 0xED, 0xDD, 0x0A, 0xDA, 0xC4, 0xB9, 0xEF, 0xD7, 0xF8, 0xF7, 0xA2, 0xE3, 0x3D, 0xF2, 0xC8, + 0x23, 0x07, 0xFF, 0xAF, 0x97, 0xBC, 0xE4, 0x25, 0x03, 0xBE, 0x61, 0xDF, 0x47, 0x47, 0xC6, 0xBA, + 0xD6, 0x1A, 0xF7, 0xF5, 0xEE, 0x95, 0xCF, 0xC0, 0x0A, 0xE8, 0x6D, 0x88, 0x2D, 0x64, 0xDD, 0xBF, + 0xFC, 0xE5, 0x2F, 0x1F, 0x7C, 0x03, 0x39, 0x17, 0x17, 0x3B, 0x29, 0x58, 0xDA, 0xF1, 0xAC, 0xE8, + 0xB3, 0x2E, 0xDE, 0x5C, 0xDA, 0x4F, 0xE3, 0xBE, 0x0A, 0x6E, 0x3B, 0xE0, 0x80, 0x03, 0x06, 0x2C, + 0x0E, 0x7E, 0xC4, 0xC7, 0x14, 0xFD, 0x22, 0x3E, 0x5F, 0x54, 0x72, 0x1E, 0x43, 0x13, 0x74, 0x86, + 0xBC, 0x12, 0xBF, 0xCD, 0xE7, 0xF4, 0x8D, 0x0A, 0x6F, 0xC3, 0xC6, 0x46, 0x5C, 0xA5, 0x63, 0xA3, + 0x6C, 0x2D, 0x6F, 0x37, 0xAC, 0x14, 0x69, 0x53, 0xA2, 0x61, 0xC4, 0xDD, 0x73, 0x9E, 0x31, 0xA7, + 0xFF, 0x6D, 0xFA, 0x93, 0x2B, 0x5F, 0x5A, 0x97, 0xA5, 0xCB, 0x12, 0x3C, 0x61, 0x1D, 0xF3, 0xB7, + 0xE5, 0xB7, 0xCB, 0xD0, 0x75, 0xFA, 0xFD, 0xE7, 0xD0, 0x20, 0xFA, 0xA8, 0x6D, 0xF5, 0xFA, 0xC9, + 0x6C, 0xD7, 0x99, 0xEE, 0x45, 0x15, 0xFD, 0x2C, 0xB2, 0x31, 0xFA, 0x82, 0x3B, 0xDC, 0xE1, 0x0E, + 0x43, 0x85, 0x2F, 0x20, 0x9F, 0xEA, 0x95, 0x0A, 0x16, 0x42, 0x57, 0x45, 0x3C, 0x2A, 0x32, 0x7A, + 0xE4, 0xCB, 0xFE, 0x8C, 0xD8, 0x96, 0xAD, 0xA0, 0x41, 0xEB, 0x3C, 0xCB, 0xBE, 0xD7, 0xAA, 0x7F, + 0x59, 0x02, 0x87, 0x8D, 0xE9, 0x71, 0x5A, 0xFA, 0x59, 0xEA, 0x77, 0xD6, 0xB6, 0x29, 0x3A, 0xDC, + 0xAC, 0x46, 0xEC, 0x5B, 0xDA, 0xA3, 0xE7, 0x8E, 0x5F, 0x2F, 0xAF, 0x98, 0x33, 0xB7, 0x4A, 0xB2, + 0x6D, 0xEB, 0x1C, 0x2B, 0xC9, 0x7F, 0x5B, 0xCD, 0x7B, 0xB3, 0x79, 0x10, 0xF5, 0xCD, 0xFE, 0x9E, + 0x6B, 0xF6, 0x7D, 0xF2, 0xEA, 0x63, 0x0B, 0x21, 0x2F, 0x0B, 0x6B, 0x9D, 0x6B, 0xAF, 0xFE, 0x19, + 0xFE, 0x59, 0xAC, 0x7D, 0x7E, 0x07, 0x2E, 0xF7, 0xB3, 0xDE, 0xE2, 0xFC, 0xD8, 0xAA, 0xBE, 0xD7, + 0xE8, 0xEC, 0xB9, 0xA1, 0x69, 0x2B, 0xB6, 0x08, 0xF4, 0x4F, 0xC8, 0x8D, 0x37, 0xBC, 0xE1, 0x0D, + 0x07, 0x1C, 0x79, 0x83, 0x1B, 0xDC, 0x60, 0xB0, 0x8D, 0x83, 0xF5, 0xD0, 0x1B, 0xE2, 0x2B, 0x82, + 0x3E, 0x9A, 0xFF, 0xF3, 0x3F, 0xFC, 0x0C, 0xB9, 0x46, 0x67, 0x4B, 0xAE, 0x7C, 0xE1, 0xC1, 0xAD, + 0xD4, 0x7D, 0x4C, 0xAD, 0x25, 0x3E, 0x53, 0xE2, 0x7F, 0x5B, 0x69, 0x0B, 0xF1, 0xF6, 0xF5, 0xEB, + 0x50, 0xD6, 0x83, 0x97, 0x7C, 0x3E, 0x6D, 0x07, 0xFD, 0x92, 0xE7, 0x01, 0x10, 0xBD, 0xA6, 0xFA, + 0x7B, 0x47, 0x59, 0x71, 0x4C, 0x8F, 0xB1, 0x15, 0x73, 0x20, 0xF2, 0xA7, 0xAD, 0x5E, 0x43, 0x63, + 0xB4, 0x8C, 0xB4, 0x8F, 0xB9, 0x53, 0x69, 0x3F, 0xB9, 0x23, 0xE1, 0x09, 0xF0, 0x06, 0x2A, 0x76, + 0x23, 0xEC, 0x69, 0x7C, 0xC6, 0x35, 0xFF, 0x97, 0xDF, 0x51, 0xB4, 0x37, 0xAA, 0xFA, 0x7D, 0xB7, + 0x7A, 0xDE, 0x65, 0xBE, 0x80, 0x4B, 0xCF, 0xFF, 0xA9, 0x32, 0x65, 0xE9, 0x9C, 0xB3, 0x25, 0xDA, + 0x24, 0xBA, 0xBB, 0xFD, 0x6D, 0xAE, 0xBC, 0x58, 0x7B, 0xD6, 0x3A, 0xE6, 0xF5, 0xD8, 0x7D, 0xB3, + 0x71, 0xEC, 0xB5, 0xC9, 0xF9, 0x99, 0x42, 0x53, 0xDB, 0x58, 0x7A, 0xDE, 0x56, 0xAF, 0xFD, 0x6C, + 0xFF, 0xCB, 0xE6, 0xBF, 0xB7, 0x39, 0xE3, 0x9D, 0xAC, 0x73, 0xE4, 0x25, 0xD6, 0x38, 0x6B, 0x5D, + 0x6B, 0x9F, 0xEB, 0x58, 0x15, 0xF3, 0x3B, 0x36, 0x2E, 0xB1, 0xEF, 0xEB, 0xE0, 0x03, 0x3E, 0x8E, + 0xE2, 0x67, 0x91, 0xA7, 0x95, 0xE4, 0xB8, 0x38, 0x56, 0xFE, 0xBB, 0x88, 0x03, 0xB3, 0xF1, 0x94, + 0x9F, 0x7D, 0x49, 0x1E, 0xDC, 0x0E, 0xFB, 0x6D, 0x0B, 0x5F, 0x8A, 0xFC, 0xBB, 0xA5, 0xED, 0xB5, + 0xB9, 0x5D, 0xC3, 0x67, 0x59, 0x2D, 0xFD, 0x36, 0x6F, 0xC3, 0x95, 0x43, 0x5D, 0x76, 0x1D, 0xB5, + 0x7C, 0xA7, 0xA7, 0xB6, 0x3E, 0xB7, 0xF5, 0xBB, 0x53, 0xFA, 0x35, 0xE5, 0x7B, 0xAD, 0x7D, 0x99, + 0x42, 0x93, 0xDA, 0xD8, 0x97, 0x7C, 0xF0, 0xB7, 0xA2, 0x66, 0xBE, 0x53, 0x35, 0x3E, 0xDF, 0xE2, + 0xE7, 0x12, 0x31, 0x69, 0xCB, 0xBA, 0xDA, 0x4A, 0x3B, 0xE9, 0x94, 0x7D, 0x30, 0xCA, 0x55, 0xBD, + 0x63, 0x3C, 0xE7, 0x79, 0x3E, 0x4F, 0x5A, 0xE8, 0x54, 0xD2, 0x63, 0x4C, 0xE3, 0x3D, 0xD3, 0xE6, + 0x54, 0x6C, 0x43, 0x09, 0x33, 0xAF, 0x83, 0xBF, 0xD4, 0xDA, 0x31, 0xA7, 0xF6, 0xB4, 0x4F, 0xE3, + 0x35, 0x65, 0xDC, 0x97, 0x9E, 0xEF, 0x35, 0x1A, 0xFA, 0xBC, 0xD2, 0xE7, 0x7E, 0x36, 0xB1, 0xFE, + 0xDF, 0x6B, 0x53, 0xD6, 0xF7, 0x33, 0x7E, 0x51, 0xC2, 0x6A, 0xBD, 0xFD, 0xFA, 0xFF, 0x24, 0xDD, + 0xAA, 0x60, 0x06, 0x69, 0x03, 0x00 +}; diff --git a/board/samsung/xyref4415/lowlevel_init.S b/board/samsung/xyref4415/lowlevel_init.S new file mode 100644 index 000000000..b0e6347ed --- /dev/null +++ b/board/samsung/xyref4415/lowlevel_init.S @@ -0,0 +1,275 @@ +/* + * Lowlevel setup for XYREF4415 board based on EXYNOS4 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* Multi Core Timer */ +#define G_TCON_OFFSET 0x0240 +#define GLOBAL_FRC_ENABLE 0x100 + +#define PSHOLD_CONTROL_OFFSET 0x330C + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + + .globl lowlevel_init +lowlevel_init: + /* use iRAM stack in bl2 */ + ldr sp, =CONFIG_IRAM_STACK + stmdb r13!, {ip,lr} + + bl relocate_code + + /* check warm reset status */ + bl check_warm_reset + + /* check reset status */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + + /* AFTR wakeup reset */ + ldr r2, =S5P_CHECK_DIDLE + cmp r1, r2 + beq exit_wakeup + + /* LPA wakeup reset */ + ldr r2, =S5P_CHECK_LPA + cmp r1, r2 + beq exit_wakeup + + /* Sleep wakeup reset */ + ldr r2, =S5P_CHECK_SLEEP + cmp r1, r2 + beq wakeup_reset + + /* set GPX2[7] to high to hold PMIC power */ + ldr r1, =0x11000C48 + ldr r0, =0x0 + str r0, [r1] + ldr r1, =0x11000C40 + ldr r0, =0x10000000 + str r0, [r1] + ldr r1, =0x11000C44 + ldr r0, =0xff + str r0, [r1] + + /* PS-Hold high */ + ldr r0, =(EXYNOS4_POWER_BASE + PSHOLD_CONTROL_OFFSET) + ldr r1, [r0] + orr r1, r1, #0x100 + str r1, [r0] + +#if defined(CONFIG_PM) + bl pmic_enable_peric_dev +#endif + + bl read_om + + /* + * If U-boot is already running in RAM, no need to relocate U-Boot. + * Memory controller must be configured before relocating U-Boot + * in ram. + */ + ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ + bic r1, pc, r0 /* pc <- current addr of code */ + /* r1 <- unmasked bits of pc */ + ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ + bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ + cmp r1, r2 /* compare r1, r2 */ + beq 1f /* r0 == r1 then skip sdram init */ + +#if defined(CONFIG_PM) + bl pmic_init +#endif + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +#if defined(CONFIG_TZPC) + bl tzpc_init +#endif + +1: + ldmia r13!, {ip,pc} + +wakeup_reset: + bl start_mct_frc + + bl read_om + + /* If eMMC booting */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +exit_wakeup: + b warmboot + +read_om: + /* Read booting information */ + ldr r0, =(EXYNOS4_POWER_BASE + OM_STATUS_OFFSET) + ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC BOOT */ + cmp r2, #0x6 + moveq r3, #BOOT_EMMC + + /* eMMC 4.4 BOOT */ + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x28 + moveq r3, #BOOT_EMMC_4_4 + + ldr r0, =(EXYNOS4_POWER_BASE + INFORM3_OFFSET) + str r3, [r0] + + mov pc, lr + +check_warm_reset: + /* check reset status */ + ldr r0, =(EXYNOS4_POWER_BASE + RST_STAT_OFFSET) + ldr r1, [r0] + and r1, r1, #WRESET + cmp r1, #WRESET @ check warm reset + /* clear reset_status */ + ldreq r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + moveq r1, #0x0 + streq r1, [r0] + + mov pc, lr + +start_mct_frc: + ldr r0, =(EXYNOS4_MCT_BASE + G_TCON_OFFSET) + ldr r1, [r0] + orr r1, r1, #GLOBAL_FRC_ENABLE + str r1, [r0] + + mov pc, lr + +/* + * Relocate code + */ +relocate_code: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + .word 0xF57FF04F @dsb sy + .word 0xF57FF06F @isb sy + + mov pc, lr + +/******************************************************************************/ +/* + * CPU1, 2, 3 waits here until CPU0 wake it up. + * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory. + */ +nscode_base: + b 1f + nop @ for backward compatibility + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 + .word 0x0 @ REG4: RESERVED +_hotplug_addr: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6 +_c2_addr: + .word 0x0 @ REG7: REG_C2_ADDR +_cpu_state: + .word 0x1 @ CPU0_STATE : RESET + .word 0x2 @ CPU1_STATE : SECONDARY RESET + .word 0x2 @ CPU2_STATE : SECONDARY RESET + .word 0x2 @ CPU3_STATE : SECONDARY RESET + .word 0x0 @ RESERVED + .word 0x0 @ RESERVED + .word 0x0 @ RESERVED + .word 0x0 @ RESERVED + +#define RESET (1 << 0) +#define SECONDARY_RESET (1 << 1) +#define HOTPLUG (1 << 2) +#define C2_STATE (1 << 3) + +1: + adr r0, _cpu_state + + mrc p15, 0, r7, c0, c0, 5 @ read MPIDR + and r7, r7, #0xf @ r7 = cpu id + + /* read the current cpu state */ + ldr r10, [r0, r7, lsl #2] + +ns_svc_entry: + tst r10, #C2_STATE + adrne r0, _c2_addr + bne wait_for_addr + + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS4_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + cmp r1, #0x0 + movne r1, #0x0 + strne r1, [r0] + ldrne r1, =(EXYNOS4_POWER_BASE + INFORM0_OFFSET) + ldrne pc, [r1] + + tst r10, #RESET + ldrne pc, =CONFIG_SYS_TEXT_BASE + + adr r0, _hotplug_addr +wait_for_addr: + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + wfe + b wait_for_addr + .ltorg +nscode_end: + diff --git a/board/samsung/xyref4415/mmc_boot.c b/board/samsung/xyref4415/mmc_boot.c new file mode 100644 index 000000000..0696df20d --- /dev/null +++ b/board/samsung/xyref4415/mmc_boot.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/mmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/clk.h> +#include <asm/arch/smc.h> +#include "setup.h" + +/* 1st_dev: eMMC, 2nd_dev: SD/MMC */ +#define SDMMC_SECOND_DEV 0x29 +#define SECOND_BOOT_MODE 0xFEED0002 +#define UBOOT 0x1 +#define TZSW 0x2 +#define SIGNATURE_CHECK_FAIL -1 + +/* find boot device for secondary booting */ +static int find_second_boot_dev(void) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + unsigned int om_status = readl(&pmu->om_stat) & 0x3f; + + writel(0x1, CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (om_status == SDMMC_SECOND_DEV) + return BOOT_SEC_DEV; + else + return -1; +} + +static unsigned int device(unsigned int boot_dev) +{ + switch(boot_dev) { + case BOOT_MMCSD: + case BOOT_SEC_DEV: + boot_dev = SDMMC_CH2; + break; + case BOOT_EMMC_4_4: + boot_dev = EMMC; + break; + default: + while(1); + } + return boot_dev; +} + +static int ld_image_from_2nd_dev(int image) +{ + int ret = SIGNATURE_CHECK_FAIL; + unsigned int boot_dev = 0; + + boot_dev = find_second_boot_dev(); + + /* sdmmc enumerate */ + if (device(boot_dev) == SDMMC_CH2) + sdmmc_enumerate(); + + switch (image) { + case UBOOT: + /* load uboot from 2nd dev */ + ret = load_uboot_image(device(boot_dev)); + break; + case TZSW: + /* load uboot from 2nd dev */ + ret = coldboot(device(boot_dev)); + break; + } + + if (ret == SIGNATURE_CHECK_FAIL) + while(1); + + return boot_dev; +} + +void jump_to_uboot(void) +{ + unsigned int om_status = readl(EXYNOS4_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + int ret = 0; + + /* TODO : find second boot function */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + /* Load u-boot image to ram */ + ret = load_uboot_image(device(boot_dev)); + if (ret == SIGNATURE_CHECK_FAIL) + boot_dev = ld_image_from_2nd_dev(UBOOT); + + /* Load tzsw image & U-Boot boot */ + ret = coldboot(device(boot_dev)); + if (ret == SIGNATURE_CHECK_FAIL) + ld_image_from_2nd_dev(TZSW); + +} + +void board_init_f(unsigned long bootflag) +{ + /* Jump to U-Boot image */ + jump_to_uboot(); + + /* Never returns Here */ +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /* Function attribute is no-return */ + /* This Function never executes */ + while (1); +} + +void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} diff --git a/board/samsung/xyref4415/pmic.c b/board/samsung/xyref4415/pmic.c new file mode 100644 index 000000000..f9d10c5fa --- /dev/null +++ b/board/samsung/xyref4415/pmic.c @@ -0,0 +1,331 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include "pmic.h" + +void Delay(void) +{ + unsigned long i; + for (i = 0; i < DELAY; i++); +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + /* Function <- Input */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPD1DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + ack = (ack>>0)&0x1; + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + /* Function <- Output */ + IIC0_ESDA_OUTP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + /* Function <- Input (SDA) */ + IIC0_ESDA_INP; + + IIC0_SCLL_SDAL(); +} + +void IIC0_ESetport(void) +{ + /* Pull Up/Down Disable SCL, SDA */ + GPD1PUD &= ~(0xf<<0); + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + /* Function <- Output (SCL) */ + IIC0_ESCL_OUTP; + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + Delay(); +} + +void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. data. */ + for (i = 8; i > 0; i--) { + if ((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EEnd(); +} + +void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* read */ + IIC0_EHigh(); + /* ACK */ + IIC0_EAck_write(); + + /* read reg. data. */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for (i = 8; i > 0; i--) { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPD1DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + reg = (reg >> 0) & 0x1; + + data |= reg << (i-1); + } + + /* ACK */ + IIC0_EAck_read(); + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + +void PMIC_Delay(int t) +{ + volatile u32 i; + for(;t > 0; t--) + for(i=0; i<1000; i++) ; +} + +void pmic_init(void) +{ + unsigned char reg, tmp; + + IIC0_ESetport(); + + /* 0x54[7:6] = 01 eMMC Buck6 Mode '01' */ + IIC0_ERead(S5M8767_RD_ADDR, 0x54, ®); + tmp = reg; + reg &= ~0xC0; + reg |= 0x40 & 0xC0; + IIC0_EWrite(S5M8767_WR_ADDR, 0x54, reg); + if((tmp & 0xC0) == 0) { + PMIC_Delay(0x300); + } + + /* 0x5A[7:6] = 01 eMMC Buck9 Mode '01' */ + IIC0_ERead(S5M8767_RD_ADDR, 0x5A, ®); + reg &= ~0xC0; + reg |= 0x40 & 0xC0; + IIC0_EWrite(S5M8767_WR_ADDR, 0x5A, reg); + + /* 0x62[7:6] = 00 eMMC LDO4 Mode '00' */ + IIC0_ERead(S5M8767_RD_ADDR, 0x62, ®); + reg &= ~0xC0; + reg |= 0x00 & 0xC0; + IIC0_EWrite(S5M8767_WR_ADDR, 0x62, reg); + + /* 0x34[5] = 0 ARM Buck2 remote sense off */ + IIC0_ERead(S5M8767_RD_ADDR, 0x34, ®); + reg &= ~0x20; + reg |= 0x00 & 0x20; + IIC0_EWrite(S5M8767_WR_ADDR, 0x34, reg); + + /* 0x46[5] = 0 G3D Buck4 remote sense off */ + IIC0_ERead(S5M8767_RD_ADDR, 0x46, ®); + reg &= ~0x20; + reg |= 0x00 & 0x20; + IIC0_EWrite(S5M8767_WR_ADDR, 0x46, reg); + + /* 0x0A[3:0] = 1111 Low jitter & 32kHz CLK on */ + IIC0_ERead(S5M8767_RD_ADDR, 0x0A, ®); + reg &= ~0x0F; + reg |= 0x0F & 0x0F; + IIC0_EWrite(S5M8767_WR_ADDR, 0x0A, reg); +} + +void pmic_enable_peric_dev(void) +{ + IIC0_ESetport(); + + /* enable LDO9 and set 1.8V for UART */ + IIC0_EWrite(S5M8767_WR_ADDR, 0x67, 0xD4); +} + diff --git a/board/samsung/xyref4415/pmic.h b/board/samsung/xyref4415/pmic.h new file mode 100644 index 000000000..5ed7bd5fe --- /dev/null +++ b/board/samsung/xyref4415/pmic.h @@ -0,0 +1,142 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __PMIC_H__ +#define __PMIC_H__ + +#define GPD1CON *(volatile unsigned long *)(0x114000C0) +#define GPD1DAT *(volatile unsigned long *)(0x114000C4) +#define GPD1PUD *(volatile unsigned long *)(0x114000C8) + +#define IIC0_ESCL_Hi GPD1DAT |= (0x1<<1) +#define IIC0_ESCL_Lo GPD1DAT &= ~(0x1<<1) +#define IIC0_ESDA_Hi GPD1DAT |= (0x1<<0) +#define IIC0_ESDA_Lo GPD1DAT &= ~(0x1<<0) + +#define IIC0_ESCL_INP GPD1CON &= ~(0xf<<4) +#define IIC0_ESCL_OUTP GPD1CON = (GPD1CON & ~(0xf<<4))|(0x1<<4) + +#define IIC0_ESDA_INP GPD1CON &= ~(0xf<<0) +#define IIC0_ESDA_OUTP GPD1CON = (GPD1CON & ~(0xf<<0))|(0x1<<0) + +#define DELAY 100 + +/* S5M8767 slave address */ +#define S5M8767_WR_ADDR 0xCC +#define S5M8767_RD_ADDR 0xCD + +#define VDD_BASE_VOLT 60000 +#define VDD_VOLT_STEP 625 +#define MIN_VOLT 600 +#define MAX_RD_VAL 0xA0 +#define RD_BUCK_VOLT(x) (((x > MAX_RD_VAL) ? 0 : \ + ((x * VDD_VOLT_STEP) + VDD_BASE_VOLT) / 100)) +#define WR_BUCK_VOLT(x) ((x < MIN_VOLT) ? 0 : \ + ((((x) * 100) - VDD_BASE_VOLT) / VDD_VOLT_STEP)) +/* RTC CTRL */ +#define RTC_CTRL2 (0x1 << 4) +#define RTC_CTRL1 (0x1 << 3) +#define BT_32KHZ_EN (0x1 << 2) +#define CP_32KHZ_EN (0x1 << 1) +#define AP_32KHZ_EN (0x1 << 0) + +/* S5M8767 Revision ID */ +#define REV_00 0x00 +#define REV_01 0x01 + +/* S5M8767 Register Address */ +#define PMIC_ID 0x00 +#define RTC_CTRL 0x0B +#define BUCK1_CTRL1 0x2D +#define BUCK1_CTRL2 0x2E +#define BUCK2_CTRL1 0x2F +#define BUCK2_CTRL2 0x30 +#define BUCK3_CTRL1 0x31 +#define BUCK3_CTRL2 0x32 +#define BUCK4_CTRL1 0x33 +#define BUCK4_CTRL2 0x34 +#define BUCK5_CTRL1 0x35 +#define BUCK5_CTRL2 0x36 +#define CM_DUAL_TEST1 0x89 +#define CM_SINGLE_TEST4 0x95 +#define VMBUCK_ALL 0x9A + +/* S5M8767 Register Address */ +#define REV01_RTC_CTRL 0x0B +#define REV01_BUCK1_CTRL1 0x28 +#define REV01_BUCK1_CTRL2 0x29 +#define REV01_BUCK2_CTRL1 0x2A +#define REV01_BUCK2_CTRL2 0x2B +#define REV01_BUCK3_CTRL1 0x2C +#define REV01_BUCK3_CTRL2 0x2D +#define REV01_BUCK4_CTRL1 0x2E +#define REV01_BUCK4_CTRL2 0x2F +#define REV01_BUCK5_CTRL1 0x30 +#define REV01_BUCK5_CTRL2 0x31 +#define REV01_LDO33_CTRL 0x4B +#define REV01_LDO34_CTRL 0x4C +#define REV01_SELMIF 0x59 +#define REV01_LDO29 0x47 +#define REV01_LDO37 0x4F + +/* LDO CTRL bit */ +#define OFF (0x0) +#define ON (0x1) +#define OUTPUT_OFF (~(3 << 6)) +#define OUTPUT_PWREN_ON (1 << 6) +#define OUTPUT_LOWPWR_MODE (2 << 6) +#define OUTPUT_NORMAL_MODE (3 << 6) + +/* SELMIF bit */ +#define SELMIF_BUCK1 (1 << 0) +#define SELMIF_LDO2 (1 << 1) +#define SELMIF_LDO5 (1 << 2) +#define SELMIF_LDO6 (1 << 3) + +/* CM_DUAL_TEST1 bit */ +#define CM_DT1_PROTECT_EN (1 << 7) +#define CM_DT1_DVS_PFM_EN (1 << 6) +#define CM_DT1_TEMP_SELB (1 << 5) +#define CM_DT1_H2L (1 << 4) +#define CM_DT1_ZERO_VOSTEP (1 << 3) +#define CM_DT1_DVS_FPWM (1 << 2) +#define CM_DT1_PCLK_DLY_EN (1 << 1) +#define CM_DT1_PWMVTHL_DNB (1 << 0) + +/* CM_SINGLE_TEST4 bit */ +#define CM_ST4_RS_PMUP_EN (1 << 7) +#define CM_ST4_OVP_EN (1 << 6) +#define CM_ST4_DVS_FPWM (1 << 5) +#define CM_ST4_CAP_ADD_FB (1 << 4) +#define CM_ST4_PROTECT_EN (1 << 3) +#define CM_ST4_PON_USE (1 << 2) +#define CM_ST4_PFMVTH_DNB_PNOFF (1 << 1) +#define CM_ST4_PFM_MIN_EN (1 << 0) + +/* VMBUCK_ALL bit */ +#define VMBUCK_ALL_EN_DSCHG_DVS_DN (1 << 7) +#define VMBUCK_ALL_PFM_VTH_DNB_PNOFF (1 << 6) +#define VMBUCK_ALL_PWMVTHH_UPB (1 << 5) +#define VMBUCK_ALL_PWMVTHL_DNB (1 << 4) +#define VMBUCK_ALL_PFMCALSEL (1 << 3) +#define VMBUCK_ALL_MINOFF_EN (1 << 2) +#define VMBUCK_ALL_ADDC (1 << 1) +#define VMBUCK_ALL_EN_PWM_DVS_DN (1 << 0) + +extern void pmic_init(void); +extern void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData); +extern void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData); + +#endif /*__PMIC_H__*/ + diff --git a/board/samsung/xyref4415/setup.h b/board/samsung/xyref4415/setup.h new file mode 100644 index 000000000..758a2f749 --- /dev/null +++ b/board/samsung/xyref4415/setup.h @@ -0,0 +1,57 @@ +/* + * Machine Specific Values for XYREF4415 board based on EXYNOS4 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 _XYREF4415_SETUP_H +#define _XYREF4415_SETUP_H + +#include <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* TZPC : Register Offsets */ +#define TZPC0_BASE 0x10110000 +#define TZPC1_BASE 0x10120000 +#define TZPC2_BASE 0x10130000 +#define TZPC3_BASE 0x10140000 +#define TZPC4_BASE 0x10150000 +#define TZPC5_BASE 0x10160000 +#define TZPC6_BASE 0x10170000 + +/* + * TZPC Register Value : + * R0SIZE: 0x0 : Size of secured ram + */ +#define R0SIZE 0x0 + +/* + * TZPC Decode Protection Register Value : + * DECPROTXSET: 0xFF : Set Decode region to non-secure + */ +#define DECPROTXSET 0xFF + +void sdelay(unsigned long); +void mem_ctrl_init(void); +void system_clock_init(void); +extern unsigned int second_boot_info; +#endif diff --git a/board/samsung/xyref4415/smc.c b/board/samsung/xyref4415/smc.c new file mode 100644 index 000000000..ae0a3cb65 --- /dev/null +++ b/board/samsung/xyref4415/smc.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <asm/arch/smc.h> + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1) + + ); + + return reg1; +} + + +unsigned int load_uboot_image(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } + + info_image->image_base_addr = CONFIG_PHY_UBOOT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_UBOOT_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, 0); +#else + if (boot_device == SDMMC_CH2) { + + u32 (*copy_uboot)(u32, u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + SDMMC_DEV_OFFSET); + + copy_uboot(MOVI_UBOOT_POS, + MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } else if (boot_device == EMMC) { + + u32 (*copy_uboot)(u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + EMMC_DEV_OFFSET ); + + copy_uboot(MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } + +#endif +} + +unsigned int coldboot(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } + + info_image->image_base_addr = CONFIG_PHY_TZSW_BASE; + info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_TZSW_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_COLDBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*uboot)(void); + + /* Jump to U-Boot image */ + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); +#endif + /* Never returns Here */ +} + +void warmboot(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*wakeup_kernel)(void); + + /* Jump to kernel for wakeup */ + wakeup_kernel = (void *)readl(EXYNOS4_POWER_BASE + INFORM0_OFFSET); + (*wakeup_kernel)(); + /* Never returns Here */ +#endif +} + +unsigned int find_second_boot(void) +{ +#if defined(CONFIG_SMC_CMD) + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT); +#else + return readl(IROM_FNPTR_BASE + SECCOND_BOOT_INFORM_OFFSET); +#endif +} + +void emmc_endbootop(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +#else + +#endif +} + +void sdmmc_enumerate(void) +{ + exynos_smc(SMC_CMD_SDMMC_ENUMERATE, 0, 0, 0); +} diff --git a/board/samsung/xyref4415/tzpc_init.c b/board/samsung/xyref4415/tzpc_init.c new file mode 100644 index 000000000..db0e87c84 --- /dev/null +++ b/board/samsung/xyref4415/tzpc_init.c @@ -0,0 +1,45 @@ +/* + * Lowlevel setup for XYREF4415 board based on EXYNOS4415 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <asm/arch/tzpc.h> +#include"setup.h" + +/* Setting TZPC[TrustZone Protection Controller] */ +void tzpc_init(void) +{ + struct exynos_tzpc *tzpc; + unsigned int addr; + + for (addr = TZPC0_BASE; addr <= TZPC6_BASE; addr += TZPC_BASE_OFFSET) { + tzpc = (struct exynos_tzpc *)addr; + + if (addr == TZPC0_BASE) + writel(R0SIZE, &tzpc->r0size); + + writel(DECPROTXSET, &tzpc->decprot0set); + writel(DECPROTXSET, &tzpc->decprot1set); + writel(DECPROTXSET, &tzpc->decprot2set); + writel(DECPROTXSET, &tzpc->decprot3set); + } +} diff --git a/board/samsung/xyref4415/xyref4415.c b/board/samsung/xyref4415/xyref4415.c new file mode 100644 index 000000000..9e538e21f --- /dev/null +++ b/board/samsung/xyref4415/xyref4415.c @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <netdev.h> +#include <version.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/sromc.h> +#include <asm/arch/sysreg.h> +#include "pmic.h" + +#define DEBOUNCE_DELAY 10000 + +DECLARE_GLOBAL_DATA_PTR; +unsigned int pmic; + +#ifdef CONFIG_SMC911X +static int smc9115_pre_init(void) +{ + u32 smc_bw_conf, smc_bc_conf; + int err; + + /* Ethernet needs data bus width of 16 bits */ + smc_bw_conf = SROMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK) + | SROMC_BYTE_ENABLE(CONFIG_ENV_SROM_BANK); + + smc_bc_conf = SROMC_BC_TACS(0x01) | SROMC_BC_TCOS(0x01) + | SROMC_BC_TACC(0x06) | SROMC_BC_TCOH(0x01) + | SROMC_BC_TAH(0x0C) | SROMC_BC_TACP(0x09) + | SROMC_BC_PMC(0x01); + + /* Select and configure the SROMC bank */ + err = exynos_pinmux_config(PERIPH_ID_SROMC, + CONFIG_ENV_SROM_BANK | PINMUX_FLAG_16BIT); + if (err) { + debug("SROMC not configured\n"); + return err; + } + + s5p_config_sromc(CONFIG_ENV_SROM_BANK, smc_bw_conf, smc_bc_conf); + return 0; +} +#endif + +static void display_bl1_version(void) +{ + /* display BL1 version */ +#if defined(CONFIG_TRUSTZONE_ENABLE) +#endif +} + +#if defined(CONFIG_PM) +static void display_pmic_info(void) +{ + unsigned char pmic_id = 0; + unsigned char read_0x54 = 0; + unsigned char read_0x5A = 0; + unsigned char read_0x62 = 0; + unsigned char read_0x34 = 0; + unsigned char read_0x46 = 0; + unsigned char read_0x0A = 0; + + IIC0_ERead(S5M8767_RD_ADDR, PMIC_ID, &pmic_id); + IIC0_ERead(S5M8767_RD_ADDR, 0x54, &read_0x54); + IIC0_ERead(S5M8767_RD_ADDR, 0x5A, &read_0x5A); + IIC0_ERead(S5M8767_RD_ADDR, 0x62, &read_0x62); + IIC0_ERead(S5M8767_RD_ADDR, 0x34, &read_0x34); + IIC0_ERead(S5M8767_RD_ADDR, 0x46, &read_0x46); + IIC0_ERead(S5M8767_RD_ADDR, 0x0A, &read_0x0A); + + printf("\nPMIC: S5M8767(REV%x)\n", pmic_id); + printf("0x54: %X\t", read_0x54); + printf("0x5A: %X\t", read_0x5A); + printf("0x62: %X\t", read_0x62); + printf("0x34: %X\t", read_0x34); + printf("0x46: %X\t", read_0x46); + printf("0x0A: %X\n", read_0x0A); +} + +static void keyled_ctrl(int ctrl) +{ +#if defined(CONFIG_KEYLED_ENABLE) + unsigned char pmic_id = 0; + unsigned char ldo33_ctrl = 0; + + IIC0_ERead(S5M8767_RD_ADDR, PMIC_ID, &pmic_id); + if (pmic_id == REV_01) { + /* Key LED on */ + IIC0_ERead(S5M8767_RD_ADDR, REV01_LDO33_CTRL, &ldo33_ctrl); + if (ctrl) { + ldo33_ctrl |= OUTPUT_PWREN_ON; + } else { + ldo33_ctrl &= OUTPUT_OFF; + } + IIC0_EWrite(S5M8767_WR_ADDR, REV01_LDO33_CTRL, ldo33_ctrl); + } +#endif +} + +static void motor_ctrl(int ctrl) +{ +#if defined(CONFIG_MOTOR_CTRL) + unsigned char pmic_id = 0; + unsigned char ldo34_ctrl = 0; + + IIC0_ERead(S5M8767_RD_ADDR, PMIC_ID, &pmic_id); + if (pmic_id == REV_01) { + /* Motor on/off control */ + IIC0_ERead(S5M8767_RD_ADDR, REV01_LDO34_CTRL, &ldo34_ctrl); + if (ctrl) { + ldo34_ctrl |= OUTPUT_PWREN_ON; + } else { + ldo34_ctrl &= OUTPUT_OFF; + } + IIC0_EWrite(S5M8767_WR_ADDR, REV01_LDO34_CTRL, ldo34_ctrl); + } +#endif +} + +#endif + +static void display_boot_device_info(void) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + int OmPin; + + OmPin = readl(&pmu->inform3); + + printf("\nChecking Boot Mode ..."); + + if (OmPin == BOOT_MMCSD) { + printf(" SDMMC\n"); + } else if (OmPin == BOOT_EMMC) { + printf(" EMMC\n"); + } else if (OmPin == BOOT_EMMC_4_4) { + printf(" EMMC\n"); + } else { + printf(" Please check OM_pin\n"); + } +} + +int board_init(void) +{ + keyled_ctrl(ON); + + display_bl1_version(); + +#if defined(CONFIG_PM) + display_pmic_info(); +#endif + display_boot_device_info(); + + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); + + return 0; +} + +int dram_init(void) +{ +#if defined(CONFIG_SDRAM_SIZE_1536MB) + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE) + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE) + + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_5_SIZE) + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_6_SIZE); +#else + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE) + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE); +#endif + return 0; +} + +void dram_init_banksize(void) +{ +#if defined(CONFIG_SDRAM_SIZE_1536MB) + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, + PHYS_SDRAM_4_SIZE); + gd->bd->bi_dram[4].start = PHYS_SDRAM_5; + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5, + PHYS_SDRAM_5_SIZE); + gd->bd->bi_dram[5].start = PHYS_SDRAM_6; + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6, + PHYS_SDRAM_6_SIZE); +#else + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, + PHYS_SDRAM_4_SIZE); + +#endif +} + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_SMC911X + if (smc9115_pre_init()) + return -1; + return smc911x_initialize(0, CONFIG_SMC911X_BASE); +#endif + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ +#if defined(CONFIG_MACH_UNIVERSALSS222) + printf("\nBoard: UNIVERSAL222AP\n"); +#elif defined(CONFIG_MACH_UNIVERSAL_GARDA) + printf("\nBoard: UNIVERSAL_GARDA\n"); +#elif defined(CONFIG_MACH_UNIVERSAL_LT02) + printf("\nBoard: LT02\n"); +#else + printf("\nBoard: SMDK4270\n"); +#endif + + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + int err, OmPin; + + OmPin = readl(&pmu->inform3); + + err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); + if (err) { + debug("SDMMC2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); + if (err) { + debug("MSHC0 not configured\n"); + return err; + } + + switch (OmPin) { + case BOOT_EMMC_4_4: +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 2); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 2); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif + break; + default: +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 2); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 2); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif + break; + } + + return err; +} +#endif + +static int board_uart_init(void) +{ + int err; + + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE); + if (err) { + debug("UART0 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE); + if (err) { + debug("UART1 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE); + if (err) { + debug("UART2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); + if (err) { + debug("UART3 not configured\n"); + return err; + } + + return 0; +} + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f(void) +{ + return board_uart_init(); +} +#endif + +int board_late_init(void) +{ + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *) samsung_get_base_gpio_part2(); + unsigned int gpio_debounce_cnt = 0; + unsigned int rst_stat = 0; + int err; + u32 second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + + rst_stat = readl(&pmu->rst_stat); + printf("rst_stat : 0x%x\n", rst_stat); + + err = exynos_pinmux_config(PERIPH_ID_INPUT_X0_0, PINMUX_FLAG_NONE); + if (err) { + debug("GPX0_0 INPUT not configured\n"); + return err; + } + +#if defined(CONFIG_MACH_UNIVERSALSS222) || defined(CONFIG_MACH_UNIVERSAL_GARDA) \ + || defined(CONFIG_MACH_UNIVERSAL_LT02) + +/* support auto fastboot mode */ +#if defined(CONFIG_MACH_UNIVERSAL_GARDA) + while (s5p_gpio_get_value(&gpio2->x1, 0x4) == 0x0) { + /* power on motor */ + motor_ctrl(ON); + + /* wait for 2s */ + if (gpio_debounce_cnt < 200) { + udelay(DEBOUNCE_DELAY); + gpio_debounce_cnt++; + } else { + /* clear lcd screen */ + run_command("cls", 0); +#if defined(CONFIG_LCD_PRINT) + /* print U-Boot version */ + lcd_printf("%s (%s - %s)\n", + U_BOOT_VERSION, U_BOOT_DATE, U_BOOT_TIME); +#endif + /* power off motor */ + motor_ctrl(OFF); + + /* run fastboot */ + run_command("fastboot", 0); + break; + } + } + + /* power off motor */ + motor_ctrl(OFF); +#endif +#else +#if 0 + while (s5p_gpio_get_value(&gpio2->x0, 0x0) == 0x0) { + /* wait for 2s */ + if (gpio_debounce_cnt < 5) { + udelay(DEBOUNCE_DELAY); + gpio_debounce_cnt++; + } else { + second_boot_info = 1; + break; + } + } +#endif +#endif +#ifdef CONFIG_RAMDUMP_MODE + /* check reset status for ramdump */ + if ((rst_stat & (WRESET | SYS_WDTRESET | ISP_ARM_WDTRESET)) + || (readl(CONFIG_RAMDUMP_SCRATCH) == CONFIG_RAMDUMP_MODE)) { + /* run fastboot */ + run_command("fastboot", 0); + } +#endif + if (second_boot_info == 1) { + printf("###Recovery Boot Mode###\n"); + setenv("bootcmd", CONFIG_RECOVERYCOMMAND); + /* clear secondary boot inform */ + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + } + + keyled_ctrl(OFF); + return 0; +} + +unsigned int get_board_rev(void) +{ + struct exynos4_clock *clk = (struct exynos4_clock *)EXYNOS4_CLOCK_BASE; + struct exynos4_power *pmu = (struct exynos4_power *)EXYNOS4_POWER_BASE; + unsigned int rev = 0; + int adc_val = 0; + unsigned int timeout, con; + + return (rev | pmic); +} diff --git a/board/samsung/xyref5260/Makefile b/board/samsung/xyref5260/Makefile new file mode 100644 index 000000000..ae107bab8 --- /dev/null +++ b/board/samsung/xyref5260/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2012 Samsung Electronics +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +SOBJS := lowlevel_init.o + +COBJS := clock_init.o +COBJS += dmc_init.o +COBJS += pmic.o +COBJS += smc.o + +ifdef CONFIG_LCD +COBJS += display.o +endif + +ifdef CONFIG_TZPC +COBJS += tzpc_init.o +endif + +ifndef CONFIG_SPL_BUILD +COBJS += xyref5260.o +endif + +ifdef CONFIG_SPL_BUILD +COBJS += mmc_boot.o +endif + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +ALL := $(obj).depend $(LIB) + +all: $(ALL) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/xyref5260/clock_init.c b/board/samsung/xyref5260/clock_init.c new file mode 100644 index 000000000..53486160f --- /dev/null +++ b/board/samsung/xyref5260/clock_init.c @@ -0,0 +1,254 @@ +/* + * Clock setup for XYREF5260 board based on EXYNOS5260 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include "setup.h" + +void check_mux_stat(unsigned int *addr, unsigned int mux_stat) +{ + unsigned int mux_status; + + do { + mux_status = readl(addr); + } while(mux_status != mux_stat); +} + +void check_pll_unlock(unsigned int *addr) +{ + unsigned int pll_unlock; + + do { + pll_unlock = (readl(addr) >> 21) & 0x1; + } while(!pll_unlock); + +} + +void system_clock_init() +{ + struct exynos5260_clock_egl *clk_egl = + (struct exynos5260_clock_egl *) samsung_get_base_clock_egl(); + struct exynos5260_clock_kfc *clk_kfc = + (struct exynos5260_clock_kfc *) samsung_get_base_clock_kfc(); + struct exynos5260_clock_mif *clk_mif = + (struct exynos5260_clock_mif *) samsung_get_base_clock_mif(); + struct exynos5260_clock_top *clk_top = + (struct exynos5260_clock_top *) samsung_get_base_clock_top(); + struct exynos5260_clock_fsys *clk_fsys = + (struct exynos5260_clock_fsys *) samsung_get_base_clock_fsys(); + unsigned int ubits = 0; + + /* modify wrong reset value of ARM_EMA_CTRL */ + ubits = readl(&clk_kfc->arm_ema_ctrl); + ubits &= ~((0x3 << 17) | (0x1 << 16) | (0x1 << 14)); + writel(ubits, &clk_kfc->arm_ema_ctrl); + + /* CMU_EGL clock init. */ + /* Step1. turn off pll fout */ + writel(0x0, &clk_egl->clk_mux_sel_egl); + check_mux_stat(&clk_egl->clk_mux_stat_egl, 0x00001111); + /* Step2. set pll locktime */ + writel(0x960, &clk_egl->egl_pll_lock); + writel(0x960, &clk_egl->egl_dpll_lock); + + /* Step3. set pll enable & pms */ + ubits = (175 << 9) | (3 << 3) | (1 << 0); + writel(ubits, &clk_egl->egl_pll_con0); + writel(0x0082fe40, &clk_egl->egl_pll_con1); + /* enable pll control */ + ubits |= (1 << 23); + writel(ubits, &clk_egl->egl_pll_con0); + check_pll_unlock(&clk_egl->egl_pll_con0); + + ubits = (75 << 9) | (1 << 3) | (1 << 0); + writel(ubits, &clk_egl->egl_dpll_con0); + /* enable pll control */ + ubits |= (1 << 23); + writel(ubits, &clk_egl->egl_dpll_con0); + check_pll_unlock(&clk_egl->egl_dpll_con0); + + /* Step4. set divider */ + /* + * CLK_DIV_EGL + * bit[24]:EGL_PLL, bit[20]:PCLK_DBG, bit[16]:ATCLK, + * bit[12]:PCLK_EGL, bit[8]:ACLK_EGL, bit[4]:EGL2, bit[0]:EGL1 + */ + ubits = (3 << 24) | (0 << 20) | (3 << 16) | + (0 << 12) | (1 << 8) | (0 << 4) | (0 << 0); + writel(ubits, &clk_egl->clk_div_egl); + + /* CMU_KFC clock init. */ + /* Step1. turn off pll fout */ + writel(0x0, &clk_kfc->clk_mux_sel_kfc0); + check_mux_stat(&clk_kfc->clk_mux_stat_kfc0, 0x00000001); + writel(0x0, &clk_kfc->clk_mux_sel_kfc2); + check_mux_stat(&clk_kfc->clk_mux_stat_kfc2, 0x00000001); + + /* Step2. set pll locktime */ + writel(0x960, &clk_kfc->kfc_pll_lock); + + /* Step3. set pll enable & pms */ + ubits = (400 << 9) | (4 << 3) | (2 << 0); + writel(ubits, &clk_kfc->kfc_pll_con0); + /* enable pll control */ + ubits |= (1 << 23); + writel(ubits, &clk_kfc->kfc_pll_con0); + check_pll_unlock(&clk_kfc->kfc_pll_con0); + + /* Step4. set divider */ + /* + * CLK_DIV_KFC + * bit[24]:KFC_PLL, bit[20]:PCLK_KFC, bit[16]:ACLK_KFC, + * bit[12]:PCLK_DBG, bit[8]:ATCLK, bit[4]:KFC2, bit[0]:KFC1 + */ + ubits = (1 << 24) | (3 << 20) | (1 << 16) | + (3 << 12) | (3 << 8) | (0 << 4) | (0 << 0); + writel(ubits, &clk_kfc->clk_div_kfc); + + /* CMU_MIF clock init. */ + /* Step1. turn off pll fout */ + writel(0x0, &clk_mif->clk_mux_sel_mif); + check_mux_stat(&clk_mif->clk_mux_stat_mif, 0x01111111); + + /* Step2. set pll locktime */ + writel(0x320, &clk_mif->mem_pll_lock); + writel(0x960, &clk_mif->bus_pll_lock); + writel(0x960, &clk_mif->media_pll_lock); + + /* Step3. set pll enable & pms */ + ubits = (400 << 9) | (4 << 3) | (3<< 0); + writel(ubits, &clk_mif->mem_pll_con0); + /* enable pll control */ + ubits |= (1 << 23); + writel(ubits, &clk_mif->mem_pll_con0); + check_pll_unlock(&clk_mif->mem_pll_con0); + + ubits = (200 << 9) | (3 << 3) | (1 << 0); + writel(ubits, &clk_mif->bus_pll_con0); + /* enable pll control */ + ubits |= (1 << 23); + writel(ubits, &clk_mif->bus_pll_con0); + check_pll_unlock(&clk_mif->bus_pll_con0); + + ubits = (667 << 9) | (12 << 3) | (1 << 0); + writel(ubits, &clk_mif->media_pll_con0); + /* enable pll control */ + ubits |= (1 << 23); + writel(ubits, &clk_mif->media_pll_con0); + check_pll_unlock(&clk_mif->media_pll_con0); + /* Step4. set divider */ + /* + * CLK_DIV_MIF + * bit[28]:ACLK_BUS_100_RATIO, bit[24]:ACLK_BUS_200_RATIO, + * bit[20]:ACLK_MIF_466_RATIO, bit[16]:CLK2X_PHY_RATIO, + * bit[12]:CLKM_PHY_RATIO, bit[8]:BUS_PLL_RATIO, bit[4]:MEM_PLL_RATIO, + * bit[0]:MEDIA_PLL_RATIO + */ + ubits = (7 << 28) | (3 << 24) | (1 << 20) | (0 << 16) | + (0 << 12) | (0 << 8) | (0 << 4) | (0 << 0); + writel(ubits, &clk_mif->clk_div_mif); + + /* CMU_TOP clock init. */ + /* Step1. turn off pll fout */ + writel(0x0, &clk_top->clk_mux_sel_top_pll0); + check_mux_stat(&clk_top->clk_mux_stat_top_pll0, 0x01011111); + + writel(0x0, &clk_top->clk_mux_sel_top_fsys); + check_mux_stat(&clk_top->clk_mux_stat_top_fsys, 0x01111111); + + writel(0x0, &clk_top->clk_mux_sel_top_peri1); + check_mux_stat(&clk_top->clk_mux_stat_top_peri1, 0x00111111); + + /* Step2. set pll locktime */ + writel(600, &clk_top->disp_pll_lock); + + /* Step3. set pll enable & pms */ + ubits = ((266 << 9) | (3 << 3) | (2 << 0)); + writel(ubits, &clk_top->disp_pll_con0); + /* enable pll control */ + ubits |= (1 << 23); + writel(ubits, &clk_top->disp_pll_con0); + check_pll_unlock(&clk_top->disp_pll_con0); + + /* Step4. set divider */ + /* + * CLK_DIV_TOP_HPM + * bit[0]:SCLK_HPM_TARGETCLK_RATIO + */ + ubits = (3 << 0); + writel(ubits, &clk_top->clk_div_top_hpm); + + /* CLK_DIV_TOP_FSYS0, 1 */ + writel(0x34003, &clk_top->clk_div_top_fsys0); + writel(0x34000, &clk_top->clk_div_top_fsys1); + + /* CLK_DIV_TOP_PERI0, 1 */ + writel(0x70070, &clk_top->clk_div_top_peri0); + writel(0x07770070, &clk_top->clk_div_top_peri1); + writel(0x02b00000, &clk_top->clk_div_top_peri2); + + /* + * CLK_DIV_TOP_BUS + * bit[28]:ACLK_BUS4_100_RATIO, bit[24]:ACLK_BUS4_400_RATIO, + * bit[20]:ACLK_BUS3_100_RATIO, bit[16]:ACLK_BUS3_400_RATIO, + * bit[12]:ACLK_BUS2_100_RATIO, bit[8]:ACLK_BUS2_400_RATIO, + * bit[4]:ACLK_BUS1_100_RATIO, bit[0]:ACLK_BUS1_400_RATIO + */ + ubits = (7 << 28) | (1 << 24) | (7 << 20) | (1 << 16) | + (7 << 12) | (1 << 8) | (7 << 4) | (1 << 0); + writel(ubits, &clk_top->clk_div_top_bus); + + /* Step5. set mux */ + /* set TOP BUS */ + writel(0x0, &clk_top->clk_mux_sel_top_bus); + check_mux_stat(&clk_top->clk_mux_stat_top_bus, 0x11111111); + + /* Turn on pll fout */ + /* CMU_EGL */ + writel(0x11, &clk_egl->clk_mux_sel_egl); + check_mux_stat(&clk_egl->clk_mux_stat_egl, 0x00001122); + + /* CMU_KFC */ + writel(0x1, &clk_kfc->clk_mux_sel_kfc0); + check_mux_stat(&clk_kfc->clk_mux_stat_kfc0, 0x00000002); + + /* CMU_MIF */ + writel(0x01111111, &clk_mif->clk_mux_sel_mif); + check_mux_stat(&clk_mif->clk_mux_stat_mif, 0x02222222); + + /* CMU_TOP */ + writel(0x00001111, &clk_top->clk_mux_sel_top_pll0); + check_mux_stat(&clk_top->clk_mux_stat_top_pll0, 0x01012222); + + writel(0x01111110, &clk_top->clk_mux_sel_top_fsys); + check_mux_stat(&clk_top->clk_mux_stat_top_fsys, 0x02222221); + + writel(0x00111111, &clk_top->clk_mux_sel_top_peri1); + check_mux_stat(&clk_top->clk_mux_stat_top_peri1, 0x00222222); +} diff --git a/board/samsung/xyref5260/dmc_init.c b/board/samsung/xyref5260/dmc_init.c new file mode 100644 index 000000000..91f7c40d8 --- /dev/null +++ b/board/samsung/xyref5260/dmc_init.c @@ -0,0 +1,846 @@ +/* + * Memory setup for XYREF5260 board based on EXYNOS5260 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/io.h> +#include <asm/arch/dmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/smc.h> +#include "setup.h" + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) (*(volatile u32 *)(addr)) + +volatile unsigned int *dram_pad_con; +volatile unsigned int *dram_pad_stat; +static u32 g_uBaseAddr; +static const u32 IROM_ARM_CLK = 400; + +static unsigned int g_nMEMCLK; +static unsigned int g_cal = 0; +static unsigned int g_zq_mode_dds = 6; + +unsigned int crl_dfdqs = 0; + +enum DMC_SFR +{ + CONCONTROL = 0x0000, + MEMCONTROL = 0x0004, + MEMCONFIG0 = 0x0008, + MEMCONFIG1 = 0x000c, + DIRECTCMD = 0x0010, + PRECHCONFIG = 0x0014, + PHYCONTROL0 = 0x0018, + PHYCONTROL1 = 0x001c, + PHYCONTROL2 = 0x0020, + PHYCONTROL3 = 0x0024, + PWRDNCONFIG = 0x0028, + TIMINGPZQ = 0x002c, + TIMINGAREF = 0x0030, + TIMINGROW = 0x0034, + TIMINGDATA = 0x0038, + TIMINGPOWER = 0x003c, + PHYSTATUS = 0x0040, + PHYZQCONTROL = 0x0044, + CHIP0STATUS = 0x0048, + CHIP1STATUS = 0x004c, + AREFSTATUS = 0x0050, + MRSTATUS = 0x0054, + IVCONTROL = 0x00f0, +}; + +void DMC_Delay(u32 x) +{ + while(--x) + __asm ("NOP"); +} + +void DMC_SetClockForDREX(void) +{ + volatile u32 uBits; + + // MCLK_CDREX = 800 + // MCLK_DPHY = 800 + // ACLK_CDREX = 400 + // PCLK_CDREX = 133 + + // MCLK_CDREX2(1/1), ACLK_EFCON(1/2), MCLK_DPHY(1/1), MCLK_CDREX(1/1), ACLK_C2C_200(1/2), C2C_CLK_400(1/2), PCLK_CDREX(1/6), ACLK_CDREX(1/2) + uBits = (0 << 28) | (1 << 24) | (0 << 20) | (0 << 16) | (1 << 12) | (1 << 8) | (5 << 4) | (1 << 0); + Outp32(0x10030500, uBits); // rCLK_DIV_CDREX + + // MCLK_EFPHY(1), C2C_CLK_400(1), MCLK_DPHY(1), MCLK_CDREX(1), BPLL(0) + uBits = (1 << 16) | (1 << 12) | (1 << 8) | (1 << 4) | (0 << 0); + Outp32(0x10030200, uBits); // rCLK_SRC_CDREX + + // Setting BPLL [P,M,S] + // + uBits = (1 << 21) | (3 << 12) | (8 << 8); + Outp32(0x10030114, uBits); // rBPLL_CON1 + + // ENABLE(1), MDIV(100), PDIV(3), SDIV(0) + uBits = (1u << 31) | (100 << 16) | (3 << 8) | (0 << 0); + Outp32(0x10030110, uBits); // rBPLL_CON0 BPLL=800MHz(3:100:0) + + while ((Inp32(0x10030110) & (1 << 29)) == 0); + + // MCLK_EFPHY(1), C2C_CLK_400(1), MCLK_DPHY(1), MCLK_CDREX(1), BPLL(1) + uBits = (1 << 16) | (1 << 12) | (1 << 8) | (1 << 4) | (1 << 0); + Outp32(0x10030200, uBits); // rCLK_SRC_CDREX +} + +#define CA_SWAP 1 +#define NUM_CHIP 1 +#define ZQ_MODE_DDS 7 +#define PERFORM_LEVELING 0 +#define PHY0_BASE 0x10C00000 +#define PHY1_BASE 0x10C10000 +#define DREX1_0 0x10C20000 +#define DREX1_1 0x10C30000 +#define TZASC_0 0x10c40000 +#define TZASC_1 0x10c50000 + +#define CMU_COREPART 0x10010000 +#define CMU_TOPPART 0x10020000 +#define CMU_MEMPART 0x10030000 + +#define WAKEUP_STAT_OFFSET 0x0600 +#define WAKEUP_MASK 0x80000000 +#define WAKEUP_RESET 0 +#define nRESET 1 + +void CA_swap_lpddr3(u32 DREX_address,u32 PHY_address) +{ + u32 data; + + // ca_swap_mode[0]=1 + //- DREX part + data = Inp32( DREX_address+0x0000 ); + data=data&(~0x00000001); + data=data|(0x00000001); + Outp32( DREX_address+0x0000, data ); + + //- PHY part + // Added by cju, 2013.06.26, found that the code below is needed + data = Inp32( PHY_address+0x0064 ); + data=data&(~0x00000001); + data=data|(0x00000001); + Outp32( PHY_address+0x0064, data ); +} + +void Low_frequency_init_lpddr3(u32 PHY_address, u32 DREX_address, u32 nMEMCLK) +{ + u32 wakeup_stat; + u32 data; + u32 data_RST_STAT; + u32 rd_fetch=3; + u32 update_mode=1; //- CONCONTROL.update_mode[3]=0x1 : MC initiated update/acknowledge mode + u32 i=0; + u32 sw_n_warm_reset; + + // Reset Status Check..! + wakeup_stat = readl(EXYNOS5260_POWER_BASE + WAKEUP_STAT_OFFSET); + wakeup_stat &= WAKEUP_MASK; + + sw_n_warm_reset=(Inp32(0x10D50404)>>28)&0x3; //- RESETSTATE(0x105C_0404) : [29]=SWRST, [28]=WRESET + if (wakeup_stat) { + data_RST_STAT = WAKEUP_RESET; + } else { + data_RST_STAT = nRESET; + } + + // 1. To provide stable power for controller and memory device, the controller must assert and hold CKE to a logic low level + // 2. DRAM mode setting + Outp32( PHY_address+0x0000, 0x17031A00 ); // PHY_CON0 ctrl_ddr_mode[12:11]=3(LPDDR3), ctrl_atgate (automatic gate control-controller drive gate signals)[6]=1 + + //- Setting rd_fetch and updated mode + //¡Ú MC updated mode should be applied with PHY v5. + data=Inp32( DREX_address+0x0000)&~((0x7<<12)|(0x1<<3)); + data|=((rd_fetch<<12)|(update_mode<<3)); + Outp32( DREX_address+0x0000, data); //- CONCONTROL : rd_fetch[14:12], update_mode[3] + + if(1) + { + // 3. Force lock values (DLL cannot be locked under 400MHz) + Outp32( PHY_address+0x0030, 0x10107F50|(0xF<<1) ); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0xF + Outp32( PHY_address+0x0028, 0x0000007F ); // ctrl_offsetd[7:0]=0x7F + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x7F7F7F7F ); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value, ¡Ú Best Tuning Value + Outp32( PHY_address+0x0018, 0x7F7F7F7F ); // PHY_CON6 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x0C183060 ); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x60C18306 ); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000030 ); // PHY_CON33 DeSkew Code for CA + + // Setting PHY_CON12 later + // 6. Set ctrl_dll_on to 0 + // Outp32( PHY_address+0x0030, 0x10107F50); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + // DMC_Delay(100); // Wait for 10 PCLK cycles + + // 7. Issue dfi_ctrlupd_req for more than 10 cycles + Outp32( DREX_address+0x0018, 0x00000008); // PHYCONTROL0 assert fp_resync[3]=1(Force DLL Resyncronization) + // "dfi_ctrlupd_req" should be issued more than 10 cycles after ctrl_dll_on is disabled. + DMC_Delay(100); // Wait for 10 PCLK cycles + Outp32( DREX_address+0x0018, 0x00000000); // PHYCONTROL0 deassert fp_resync[3]=1(Force DLL Resyncronization) + + // 8. Set MemControl. At this moment, all power down modes should be off. + Outp32( DREX_address+0x0004, 0x00312700); // MEMCONTROL bl[22:20]=Memory Burst Length 0x3 = 8, mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit, mem_type [11:8]=Type of Memory 0x7 = LPDDR3 + } + #if 1 // Closed by cju,2013.01.16 + else + { + // 8. Set MemControl. At this moment, all power down modes should be off. + Outp32( DREX_address+0x0004, 0x00312700); // MEMCONTROL bl[22:20]=Memory Burst Length 0x3 = 8, mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit, mem_type [11:8]=Type of Memory 0x7 = LPDDR3 + } + #endif + + // 9. Set DRAM burst length and READ latency + // 10. Set DRAM write latency + if(nMEMCLK==921){ + Outp32( PHY_address+0x00AC, 0x0000080E); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + Outp32( PHY_address+0x006C, 0x0009000F); // PHY_CON26 T_wrdata_en[20:16]=WL for LPDDR2/LPDDR3 + } + else if(nMEMCLK==825){ + Outp32( PHY_address+0x00AC, 0x0000080E); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + Outp32( PHY_address+0x006C, 0x0009000F); // PHY_CON26 T_wrdata_en[20:16]=WL for LPDDR2/LPDDR3 + } + else if(nMEMCLK==800){ + Outp32( PHY_address+0x00AC, 0x0000080C); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + Outp32( PHY_address+0x006C, 0x0007000F); // PHY_CON26 T_wrdata_en[20:16]=WL for LPDDR2/LPDDR3 + } + else if(nMEMCLK==667){ + Outp32( PHY_address+0x00AC, 0x0000080A); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + Outp32( PHY_address+0x006C, 0x0007000F); // PHY_CON26 T_wrdata_en[20:16]=WL for LPDDR2/LPDDR3 + } + else{ + Outp32( PHY_address+0x00AC, 0x0000080A); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + Outp32( PHY_address+0x006C, 0x0007000F); // PHY_CON26 T_wrdata_en[20:16]=WL for LPDDR2/LPDDR3 + } + +#if 1 + // Pulldn and Pullup enable + // ctrl_pulld_dq[11:8]=Active HIGH signal to down DQ signals. For normal operation this field should be zero. + // ctrl_pulld_dqs[3:0]=Active HIGH signal to pull-up or down PDQS/NDQS signals. + Outp32( PHY_address+0x0038, 0x0000000F); // PHY_CON14 ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf + + // ¡Ú ZQ Calibration + // zq_mode_dds :: Driver strength selection. . It recommends one of the following settings instead of 3'h0. +// PHY_CON16 : zq_clk_en[27]=ZQ I/O Clock enable, zq_manual_mode[3:2]=Manual calibration mode selection 2'b01: long calibration, zq_manual_str[1]=Manual calibration start +// PHY_CON39 : Driver Strength +//------------------------------------------------------------------------------------------------------- + if (ZQ_MODE_DDS == 7) + { + Outp32( PHY_address+0x0040, 0x0F040306); + Outp32( PHY_address+0x00A0, 0x0FFF0FFF); + } + else if (ZQ_MODE_DDS == 6) + { + Outp32( PHY_address+0x0040, 0x0E040306); + Outp32( PHY_address+0x00A0, 0x0DB60DB6); + } + else if (ZQ_MODE_DDS == 5) + { + Outp32( PHY_address+0x0040, 0x0D040306); + Outp32( PHY_address+0x00A0, 0x0B6D0B6D); + } + else if (ZQ_MODE_DDS == 4) + { + Outp32( PHY_address+0x0040, 0x0C040306); + Outp32( PHY_address+0x00A0, 0x09240924); + } + else + { + Outp32( PHY_address+0x0040, 0x0F040306); + Outp32( PHY_address+0x00A0 , 0x0FFF0FFF); + } + + // Checking the completion of ZQ calibration + do{ + if(i==2000000){ //- Just Delay + i=0; + break; + } + else i++; + }while( ( Inp32( PHY_address+0x0048 ) & 0x00000001 ) != 0x00000001 ); // PHY_CON17 zq_done[0]=ZQ Calibration is finished. + + // ZQ calibration exit + data = Inp32( PHY_address+0x0040 ); + data = data&(~0x000FFFFF); + data = data|0x00040304; + Outp32( PHY_address+0x0040, data); // PHY_CON16 zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0 +//------------------------------------------------------------------------------------------------------- +#endif + + // Disable DLL to initialize DFI ---> just "ctrl_dll_on=0" + Outp32( PHY_address+0x0030, 0x10107F50|(0xF<<1)); // PHY_CON12 + +// ★ DFI Initialization. +//------------------------------------------------------------------------------------------------------- + // Asserting the dfi_init_start + data=Inp32( DREX_address+0x0000)&~(0x1<<28); + data|=(0x1<<28); + Outp32( DREX_address+0x0000, data); //- CONCONTROL : dfi_init_start=1 + + // 6. Wait until dfi_init_complete become 1. + i=0; + do{ //- Checking lock status. + if(i==2000){ + i=0; + break; + } + else i++; + }while( ( Inp32( DREX_address+0x0040 ) & 0x00000008 ) != 0x00000008 ); // PhyStatus dfi_init_complete[3]=1 + //Deasserting the dfi_init_start + Outp32( DREX_address+0x0000, Inp32( DREX_address+0x0000)&~(0x1<<28)); //- CONCONTROL : dfi_init_start=0 + +#if 1 + // 7. ¡Ú fp_resync : Issue dfi_ctrlupd_req for more than 10 cycles + // At this time, fp_resync is not necessarilly needed + Outp32( DREX_address+0x0018, 0x00000008); // PHYCONTROL0 assert fp_resync[3]=1(Force DLL Resyncronization) + // "dfi_ctrlupd_req" should be issued more than 10 cycles after ctrl_dll_on is disabled. + DMC_Delay(100); // Wait for 10 PCLK cycles + Outp32( DREX_address+0x0018, 0x00000000); // PHYCONTROL0 deassert fp_resync[3]=1(Force DLL Resyncronization) +#endif +//------------------------------------------------------------------------------------------------------- + + //if((status != S5P_CHECK_SLEEP) && (data_RST_STAT == 0)) + //if(eBootStat == nRESET) //((eBootStat != IRAMOFF_MIFOFF_TOPOFF) && (data_RST_STAT == 0)) + if((data_RST_STAT == nRESET)&&(!sw_n_warm_reset)) // That means that sleep & wakeup is not , or This is for all reset state + { + // Direct Command P0 CH0..! + // 9. CKE low for tINIT1 and CKE high for tINIT3 + Outp32( DREX_address+0x0010, 0x07000000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + DMC_Delay(53333); // MIN 200us + + // 10. RESET command to LPDDR3 + // Add :: 2012.11.01 :: Not send reset command when occured by wake-up + Outp32( DREX_address+0x0010, 0x00071C00); // 0x0 = MRS/EMRS (mode register setting), MR63_Reset (MA<7:0> = 3FH): MRW only + + // tINIT4(MIN 1us), tINIT5(MAX 10us) + // 2013.04.15 :: Check DAI complete..! + i=0; + do{ + Outp32( DREX_address+0x0010, 0x09000000); // 0x9 = MRR (mode register reading), MR0_Device Information + if(i==20000){ //- DAI status is complete within 10us. + i=0; + break; + } + else i++; + }while ((Inp32(DREX_address+0x0054) & (1 << 0)) != 0); // OP0=DAI (Device Auto-Initialization Status) + + // 12. DRAM ZQ calibration + Outp32( DREX_address+0x0010, 0x00010BFC); // 0x0 = MRS/EMRS (mode register setting), MR10_Calibration, FFH: Calibration command after initialization + // 13. Wait for minimum 1us (tZQINIT). + DMC_Delay(267); // MIN 1us + + if(nMEMCLK==921){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00000870); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0000060C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else if(nMEMCLK==825){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00000870); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0000060C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else if(nMEMCLK==800){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00000868); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0000050C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else if(nMEMCLK==667){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00000860); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0000040C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else{ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00000860); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0000040C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + + // Add 20120501..! + // 14. I/O Configuration :: Drive Strength + Outp32( DREX_address+0x0010, 0x00000C04); // MR(3) OP(1) + DMC_Delay(267); // MIN 1us + } + else + { + Outp32( DREX_address+0x0010, 0x08000000 ); //- CH0, CS0. Self Refresh Exit Command for only sleep & wakeup + } + + + + // Initialization of second DRAM + if(NUM_CHIP == 1) //- NUM_CHIP=0 --> 1 chip, NUM_CHIP=1 --> 2 chips + { + // if((eBootStat != IRAMOFF_MIFOFF_TOPOFF) && (data_RST_STAT == 0)) + //if(eBootStat == nRESET) + if((data_RST_STAT == nRESET)&&(!sw_n_warm_reset)) // That means that sleep & wakeup is not , or This is for all reset state + { + #if 0 + SetBits(0x14000064, 4, 0x1, 0x1); + #endif + + // 9. CKE low for tINIT1 and CKE high for tINIT3 + Outp32( DREX_address+0x0010, 0x07100000); // 0x7 = NOP (exit from active/precharge power down or deep power down, + DMC_Delay(53333); // MIN 200us + + // 10. RESET command to LPDDR3 + // Add :: 2012.11.01 :: Not send reset command when occured by wake-up + Outp32( DREX_address+0x0010, 0x00171C00); // 0x0 = MRS/EMRS (mode register setting), MR63_Reset (MA<7:0> = 3FH): MRW only + + // tINIT4(MIN 1us), tINIT5(MAX 10us) + // 2013.04.15 :: Check DAI complete..! + i=0; + do{ + Outp32( DREX_address+0x0010, 0x09100000); // 0x9 = MRR (mode register reading), MR0_Device Information + if(i==20000){ //- DAI status is complete within 10us. + i=0; + break; + } + else i++; + }while ((Inp32(DREX_address+0x0054) & (1 << 0)) != 0); // OP0=DAI (Device Auto-Initialization Status) + + // 12. DRAM ZQ calibration + Outp32( DREX_address+0x0010, 0x00110BFC); // 0x0 = MRS/EMRS (mode register setting), MR10_Calibration, FFH: Calibration command after initialization + // 13. Wait for minimum 1us (tZQINIT). + DMC_Delay(267); // MIN 1us + + if(nMEMCLK==921){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00100870); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0010060C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else if(nMEMCLK==825){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00100870); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0010060C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else if(nMEMCLK==800){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00100868); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0010050C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else if(nMEMCLK==667){ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00100860); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0010040C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + else{ + // 13. DRAM parameter settings + Outp32( DREX_address+0x0010, 0x00100860); // 0x0 = MRS/EMRS (mode register setting), MR2_Device Feature, 1B : Enable nWR programming > 9,Write Leveling(0) + Outp32( DREX_address+0x0010, 0x0010040C); // 0x0 = MRS/EMRS (mode register setting), MR1_Device Feature, 011B: BL8, 010B: nWR=12 + } + + + // Add 20120501..! + // 14. I/O Configuration :: Drive Strength + Outp32( DREX_address+0x0010, 0x00100C04); // MR(3) OP(1) + DMC_Delay(267); // MIN 1us + } + else + { + Outp32( DREX_address+0x0010, 0x08100000 ); //- CH0, CS0. Self Refresh Exit Command for only sleep & wakeup + } + } + + if(1)//((eBootStat != IRAMOFF_MIFOFF_TOPOFF) && (data_RST_STAT == 0)) + { + // Reset SDLL codes + // 2012.10.11 + // Outp32( PHY_address+0x0028, 0x00000000); // PHY_CON10 ctrl_offsetd[7:0]=0x8 + Outp32( PHY_address+0x0028, 0x00000008); // PHY_CON10 ctrl_offsetd[7:0]=0x8 + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x08080808); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value, ¡Ú Best Tuning Value + Outp32( PHY_address+0x0018, 0x08080808); // PHY_CON5 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x00000000); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x00000000); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000000); // PHY_CON33 DeSkew Code for CA + } + + return; +} + +void High_frequency_init_lpddr3(u32 PHY_address, u32 DREX_address, u32 TZASC_address, u32 nMEMCLK) +{ +#if defined(CONFIG_SMC_CMD) + reg_arr_t reg_arr; +#endif + u32 data,ch; + u32 i=0; + u32 tmp; +// BOOT_STAT eBootStat; + +// eBootStat = GetRstStat(); + if (DREX_address == DREX1_0) + ch =0; + else + ch =1; + + // 1. Set DRAM burst length and READ latency + //Outp32( PHY_address+0x00AC, 0x0000080C); // PHY_CON42 ctrl_bstlen(Burst Length(BL))[12:8]=8, ctrl_rdlat(Read Latency(RL))[4:0]=12 + + // 2. Set DRAM write latency + //Outp32( PHY_address+0x006C, 0x0007000F); // PHY_CON26 T_wrdata_en[20:16]=WL for DDR3 + + // DLL LOCK Setting..! + // Set the DLL lock parameters + // Reserved [31] ctrl_start_point [30:24]=0x10 Reserved [23] ctrl_inc [22:16]=0x10 ctrl_force [14:8] ctrl_start [6]=0x1 ctrl_dll_on [5]=0x1 ctrl_ref [4:1]=0x8 Reserved [0] + // Next Step : Same Operation "CONCONTROL dfi_init_start[28]=1" + // 2012.10.11 + // Outp32( PHY_address+0x0030, 0x10100070); // PHY_CON12 + Outp32( PHY_address+0x0030, 0x10100010|(0xF<<1)); // PHY_CON12, "ctrl_dll_on[6] = 0", "ctrl_start[6] = 0" + Outp32( PHY_address+0x0030, 0x10100030|(0xF<<1)); // PHY_CON12, "ctrl_dll_on[6] = 1", "ctrl_start[6] = 0" + Outp32( PHY_address+0x0030, 0x10100070|(0xF<<1)); // PHY_CON12, "ctrl_dll_on[6] = 1", "ctrl_start[6] = 1" + do{ + if(i==2000){ //- Just Delay + i=0; + break; + } + else i++; + }while((Inp32(PHY_address+0x0034) & 0x5) != 0x5); // ctrl_locked[0]=1 + + // 7. ¡Ú¡Ú¡Ú fp_resync : Forcing DLL resynchronization - dfi_ctrlupd_req + // ¡Ú¡Ú¡Ú At this time, fp_resync is necessarilly needed + Outp32( DREX_address+0x0018, 0x00000008); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=1 + DMC_Delay(20); // Wait for 10 PCLK cycles, PCLK(200MHz=10clock=50ns), DMC_Delay(40us) + Outp32( DREX_address+0x0018, 0x00000000); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=0 + +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = TZASC_address+0x0F00; + reg_arr.set0.val = 0x001007E0; + reg_arr.set1.addr = TZASC_address+0x0F04; + reg_arr.set1.val = 0x003007E0; + reg_arr.set2.addr = TZASC_address+0x0F10; + reg_arr.set2.val = 0x00462323; + reg_arr.set3.addr = TZASC_address+0x0F14; + reg_arr.set3.val = 0x00462323; + set_secure_reg((u32)®_arr, 4); +#else + // 2. Set the MemConfig0 register. If there are two external memory chips, also set the MemConfig1 register. + // LPDDR2_P0_CS0 : 32'h2000_000 ~ 32'h27FF_FFFF (4Gbit) + // Outp32( DREX_address+0x010C, 0x002007E0); // MemBaseConfig0 chip_base[26:16]=0x10, chip_mask[10:0]=0x7E0 + // Outp32( DREX_address+0x0110, 0x004007E0); // MemBaseConfig1 chip_base[26:16]=0x30, chip_mask[10:0]=0x7E0 + Outp32( TZASC_address+0x0F00, 0x001007E0); // MemBaseConfig0 chip_base[26:16]=0x10, chip_mask[10:0]=0x7E0 + Outp32( TZASC_address+0x0F04, 0x003007E0); // MemBaseConfig1 chip_base[26:16]=0x30, chip_mask[10:0]=0x7E0 + + // 3. Set the MemConfig0 + // chip_map [15:12] Address Mapping Method (AXI to Memory). 0x1 = Interleaved ({row, bank, column, width}) + // chip_col [11:8] Number of Column Address Bits. 0x3 = 10 bits + // chip_row [7:4] Number of Row Address Bits. 0x2 = 14 bits + // chip_bank [3:0] Number of Banks. 0x3 = 8 banks + // Outp32( DREX_address+0x0008, 0x00001323); // MemConfig0 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] + // Outp32( DREX_address+0x000C, 0x00001323); // MemConfig1 chip_map [15:12],chip_col [11:8],chip_row [7:4],chip_bank [3:0] + Outp32( TZASC_address+0x0F10, 0x00462323); // MemConfig0 : bank_lsb[26:16], rank_inter_en[19], bit_sel_en[18], bit_sel[17:16], chip_map[15:12], chip_col[11:8], chip_row[7:4], chip_bank[3:0] + Outp32( TZASC_address+0x0F14, 0x00462323); // MemConfig1 : bank_lsb[26:16], rank_inter_en[19], bit_sel_en[18], bit_sel[17:16], chip_map[15:12], chip_col[11:8], chip_row[7:4], chip_bank[3:0] +#endif + // 4. Set the PrechConfig and PwrdnConfig registers. + // 2013.04.18 :: DREX1_0_3 adding..! + // Outp32( DREX_address+0x0014, 0xFF000000); // PrechConfig tp_cnt[31:24]=Timeout Precharge Cycles. 0xn = n cclk cycles. Refer to chapter 1.6.2 .Timeout precharge + Outp32( DREX_address+0x0014, 0xF0000000); // PrechConfig tp_en[31:28]=Timeout Precharge per Port + + Outp32( DREX_address+0x001C, 0xFFFFFFFF); + Outp32( DREX_address+0x0028, 0xFFFF00FF); // PwrdnConfig dsref_cyc[31:16]=Number of Cycles for dynamic self refresh entry. 0xn = n aclk cycles. Refer to chapter 1.5.3 . Dynamic self refresh + + // 5. Set the TimingAref, TimingRow, TimingData and TimingPower registers. + // according to memory AC parameters. At this moment, TimingData.w1 and TimingData.r1 + // registers must be programmed according to initial clock frequency. + // 2012.12.20 :: 3.875 us * 8192 row = 250us + + Outp32( DREX_address+0x0030, 0x0000002E); // TimingAref autorefresh counter @24MHz + //Outp32( DREX_address+0x0030, g_AveragePeriodic_interval); // TimingAref autorefresh counter @24MHz + + + // TimingAref autorefresh counter @24MHz + // 2012.10.11 + // Outp32( DREX_address+0x0034, 0x34498611); // TimingRow + // 2012.11.08 :: tRC : 0x18(24) ---> 0x1A(26), tRAS : 0x12(18) ---> 0x11(17) + #if 0 + if (nMEMCLK==933) { + Outp32( DREX_address+0x0034, 0x3D5A9794); // TimingRow + Outp32( DREX_address+0x0038, 0x4742086E); // TimingData + Outp32( DREX_address+0x003C, 0x60420447); // TimingPower + } + else if(nMEMCLK==800) + { + Outp32( DREX_address+0x0034, 0x34498691); // TimingRow + Outp32( DREX_address+0x0038, 0x3630065C); // TimingData + Outp32( DREX_address+0x003C, 0x50380336); // TimingPower + } + else + { + Outp32( DREX_address+0x0034, 0x3D5A9794); // TimingRow + Outp32( DREX_address+0x0038, 0x4642065C); // TimingData + Outp32( DREX_address+0x003C, 0x60420447); // TimingPower + } + #else + if (nMEMCLK==921) //- If max freq is 921MHz + { + Outp32( DREX_address+0x0034, 0x3C6BA7D5); // TimingRow + Outp32( DREX_address+0x0038, 0x4740086E); // TimingData + Outp32( DREX_address+0x003C, 0x60410447); // TimingPower + } + else if(nMEMCLK==825) //- If max freq is 825MHz + { + Outp32( DREX_address+0x0034, 0x365A9713); // TimingRow + Outp32( DREX_address+0x0038, 0x4740085E); // TimingData + Outp32( DREX_address+0x003C, 0x543A0446); // TimingPower + } + else if(nMEMCLK==800) //- If max freq is 825MHz + { + Outp32( DREX_address+0x0034, 0x345A96D3); // TimingRow + Outp32( DREX_address+0x0038, 0x3630065C); // TimingData + Outp32( DREX_address+0x003C, 0x50380336); // TimingPower + } + else if(nMEMCLK==667) //- If max freq is 667MHz + { + Outp32( DREX_address+0x0034, 0x2C4885D0); // TimingRow + Outp32( DREX_address+0x0038, 0x3630064A); // TimingData + Outp32( DREX_address+0x003C, 0x442F0335); // TimingPower + } + else + { + Outp32( DREX_address+0x0034, 0x2C4885D0); // TimingRow + Outp32( DREX_address+0x0038, 0x3630064A); // TimingData + Outp32( DREX_address+0x003C, 0x442F0335); // TimingPower + } + #endif + + // If QoS scheme is required, set the QosControl10~15 and QosConfig0~15 registers. + //- + + // 8. calibration & levelings + if( PERFORM_LEVELING == 1) + { + #if 0 + Prepare_levelings_lpddr3( PHY_address, DREX_address); + CA_calibration_lpddr3( PHY_address, DREX_address); + Write_leveling_lpddr3( PHY_address, DREX_address); + Read_leveling_lpddr3( PHY_address, DREX_address); + Write_dq_leveling_lpddr3( PHY_address, DREX_address); + #endif + } + + //----------------------------------------------- + //- end_levelings_lpddr3_l + //----------------------------------------------- + + // ctrl_atgate = 0 + // T_WrWrCmd [30:24] It controls the interval between Write and Write during DQ Calibration. This value should be always kept by 5'h17. It will be used for debug purpose. + // T_WrRdCmd [19:17] It controls the interval between Write and Read by cycle unit during Write Calibration. It will be used for debug purpose. 3'b111 : tWTR = 6 cycles (=3'b001) + // ctrl_ddr_mode[12:11] 2'b11: LPDDR3 + // ctrl_dfdqs[9] 1¡¯b1: differential DQS + Outp32( PHY_address+0x0000, 0x17021A00); // PHY_CON0 byte_rdlvl_en[13]=1, ctrl_ddr_mode[12:11]=01, ctrl_atgate[6]=1, Bit Leveling + + if( PERFORM_LEVELING == 1) + { + // dfi_ctrlupd_req to make sure ALL SDLL is updated + // forcing DLL resynchronization - dfi_ctrlupd_req + Outp32( DREX_address+0x0018, 0x00000008); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=1 + DMC_Delay(20); // Wait for 10 PCLK cycles, PCLK(200MHz=10clock=50ns), DMC_Delay(40us) + Outp32( DREX_address+0x0018, 0x00000000); // PhyControl0 ctrl_shgate[29]=1, fp_resync[3]=0 + } + + // 27. If power down modes are required, set the MemControl register. + // bl[22:20]=Memory Burst Length 0x3 = 8 + // mem_width[15:12]=Width of Memory Data Bus 0x2 = 32-bit + // mem_type[11:8]=Type of Memory 0x7 = LPDDR3 + // dsref_en[5]=Dynamic Self Refresh. 0x1 = Enable. + // dpwrdn_en[1]=Dynamic Power Down. 0x1 = Enable + // clk_stop_en[0]=Dynamic Clock Control. 0x1 = Stops during idle periods. + + Outp32( DREX_address+0x0004, 0x00312722); // MemControl bl[22:20]=8, mem_type[11:8]=7, two chip selection + + if(nMEMCLK==100) + { + // 3. Force lock values (DLL cannot be locked under 400MHz) + Outp32( PHY_address+0x0030, 0x10107F50|(0xF<<1) ); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0xF + Outp32( PHY_address+0x0028, 0x0000007F ); // ctrl_offsetd[7:0]=0x7F + + // 4. Set ctrl_offsetr, crtrl_offsetw to 0x7F + Outp32( PHY_address+0x0010, 0x7F7F7F7F ); // PHY_CON4 ctrl_offsetr, MEM1 Port 0, Read Leveling Manual Value, ¡Ú Best Tuning Value + Outp32( PHY_address+0x0018, 0x7F7F7F7F ); // PHY_CON6 ctrl_offsetw, MEM1 Port 0, Write Training Manual Value + + // 5. set CA deskew code to 7h'60 + Outp32( PHY_address+0x0080, 0x0C183060 ); // PHY_CON31 DeSkew Code for CA + Outp32( PHY_address+0x0084, 0x60C18306 ); // PHY_CON32 DeSkew Code for CA + Outp32( PHY_address+0x0088, 0x00000030 ); // PHY_CON33 DeSkew Code for CA + + //Outp32( PHY_address+0x0030, 0x10107F10|(0xF<<1) ); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:g16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + + // Setting PHY_CON12 later + // 6. Set ctrl_dll_on to 0 + // Outp32( PHY_address+0x0030, 0x10107F50); // PHY_CON12 ctrl_start_point [30:24]=0x10, ctrl_inc[22:16]=0x10, ctrl_force[14:8]=0x7F, ctrl_start[6]=1, ctrl_dll_on[5]=0, ctrl_ref [4:1]=0x8 + // DMC_Delay(100); // Wait for 10 PCLK cycles + + #if 1 + // 7. ¡Úfp_resync : Issue dfi_ctrlupd_req for more than 10 cycles + Outp32( DREX_address+0x0018, 0x00000008); // PHYCONTROL0 assert fp_resync[3]=1(Force DLL Resyncronization) + // "dfi_ctrlupd_req" should be issued more than 10 cycles after ctrl_dll_on is disabled. + DMC_Delay(100); // Wait for 10 PCLK cycles + Outp32( DREX_address+0x0018, 0x00000000); // PHYCONTROL0 deassert fp_resync[3]=1(Force DLL Resyncronization) + #endif + + } + + return; +} + +static void mem_ctrl_init_lpddr3(u32 nMEMCLK) +{ + u32 data; + u32 io_pd_con=2; + u32 aref_en=1; +// BOOT_STAT eBootStat; + u32 nLoop; + u32 nCnt; + u32 uMif_Divider; + +// eBootStat = GetRstStat(); + + /****************************************/ + /***** CA SWAP *****/ + /****************************************/ + if (CA_SWAP == 1) + { + CA_swap_lpddr3(DREX1_0, PHY0_BASE); + CA_swap_lpddr3(DREX1_1, PHY1_BASE); + } + +#if 0 + Outp32( 0x10C20000+0x0000, 0x1FFF1101 ); //- DREX0 assert dfi_init_start + DMC_Delay(0x100); //- wait 1ms + Outp32( 0x10C20000+0x0000, 0xFFF1101 ); //- DREX0 deassert dfi_init_start + Outp32( 0x10C30000+0x0000, 0x1FFF1101 ); //- DREX1 assert dfi_init_start + DMC_Delay(0x100); //- wait 1ms + Outp32( 0x10C30000+0x0000, 0xFFF1101 ); //- DREX1 deassert dfi_init_start +#endif + // Remove because handshaking between DREX and PHY when operate in low frequency(24MHz) + // DLL LOCK Setting..! + // DLL_lock_lpddr3(PHY0_BASE, DREX1_0); + // DLL_lock_lpddr3(PHY1_BASE, DREX1_1); + + // Remove because handshaking between DREX and PHY when operate in low frequency(24MHz) + // CMU Setting..! + // Clock = 50MHz + // Outp32( CMU_MEMPART+0x0114, 0x0020F300); // BPLL_CON1 + // Outp32( CMU_MEMPART+0x0110, 0x80C80305); // BPLL_CON0 + // DMC_Delay(100); + + /****************************************/ + /***** CLOCK Pause Enable *****/ + /****************************************/ + // Pause Enable..! + data = Inp32( 0x10CE1004); + data = data | (0x1<<0); + Outp32(0x10CE1004, data); + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + + + uMif_Divider=Inp32(0x10CE0600)&0xFFF; + uMif_Divider=(uMif_Divider|(0x7<<28)|(0x3<<24)|(0x1<<20)|(0xf<<16)|(0x0<<12)); + //&CLKM_PHY_RATIO &CLK2X_PHY_RATIO &ACLK_MIF_466_RATIO &ACLK_BUS_200_RATIO &ACLK_BUS_100_RATIO + Outp32(0x10CE0600,uMif_Divider); + + //CMU_InitForMif(50); //Max Frequency Setting + + + /****************************************/ + /***** LOW FREQUENCY *****/ + /****************************************/ + // PHY0+DREX1_0 + Low_frequency_init_lpddr3(PHY0_BASE, DREX1_0, nMEMCLK); + // PHY1+DREX1_1 + Low_frequency_init_lpddr3(PHY1_BASE, DREX1_1, nMEMCLK); + + /****************************************/ + /***** CLOCK SETTTING *****/ + /****************************************/ + uMif_Divider=Inp32(0x10CE0600)&0xFFF; + uMif_Divider=(uMif_Divider|(0x7<<28)|(0x3<<24)|(0x1<<20)|(0x0<<16)|(0x0<<12)); //Max CLK Setting + //&CLKM_PHY_RATIO &CLK2X_PHY_RATIO &ACLK_MIF_466_RATIO &ACLK_BUS_200_RATIO &ACLK_BUS_100_RATIO + Outp32(0x10CE0600,uMif_Divider); + + /****************************************/ + /***** HIGH FREQUENCY *****/ + /****************************************/ + // PHY0+DREX1_0 + High_frequency_init_lpddr3(PHY0_BASE, DREX1_0, TZASC_0, nMEMCLK); + // PHY1+DREX1_1 + High_frequency_init_lpddr3(PHY1_BASE, DREX1_1, TZASC_1, nMEMCLK); + + + #if 1 // Move..! 2012.11.30 + // 26. Set the ConControl to turn on an auto refresh counter. + // aref_en[5]=Auto Refresh Counter. 0x1 = Enable + // 2012.11.08 :: rd_fetch 3 -> 2 + // 2013.04.12 :: Automatic control for ctrl_pd in none read state + data=Inp32( DREX1_0+0x0000)&~((0x3<<6)|(0x1<<5)); + data|=((io_pd_con<<6)|(aref_en<<5)); + Outp32(DREX1_0+0x0000, data); //- CH0 : CONCONTROL : io_pd_con[7:6]=2, aref_en[5]=1 + + data=Inp32( DREX1_1+0x0000)&~((0x3<<6)|(0x1<<5)); + data|=((io_pd_con<<6)|(aref_en<<5)); + Outp32(DREX1_1+0x0000, data); + #endif + + + //- CH0 : CONCONTROL : io_pd_con[7:6]=2, aref_en[5]=1 + #if 0 + Outp32( DREX1_0+0x0000, 0x0FFF31A1); // CONCONTROL aref_en[5]=1 + Outp32( DREX1_1+0x0000, 0x0FFF31A1); // CONCONTROL aref_en[5]=1 + #endif + + //- Cck Gating Control Register..! + #if 1 + Outp32( DREX1_0+0x0018, 0x00005000); //to resolve Phy Gating Problem. + Outp32( DREX1_1+0x0018, 0x00005000); + + #if 0 //- In case of EVT0 + Outp32( DREX1_0+0x0008, 0x00000010); //- CH0 : Only Support Phy CLK Gating + Outp32( DREX1_1+0x0008, 0x00000010); //- CH1 : Only Support Phy CLK Gating + #else //- In case of EVT1 + Outp32( DREX1_0+0x0008, 0x0000003F); //- CH0 : CG Control : tz_cg_en[5], phy_cg_en[4], memif_cg_en[3], scg_cg_en[2], busif_wr_cg_en[1], busif_rd_cg_en[0] + Outp32( DREX1_1+0x0008, 0x0000003F); //- CH1 : CG Control : tz_cg_en[5], phy_cg_en[4], memif_cg_en[3], scg_cg_en[2], busif_wr_cg_en[1], busif_rd_cg_en[0] + #endif + #endif + + return; +} + +void mem_ctrl_init() +{ + /* init_mif */ + mem_ctrl_init_lpddr3(667); +} diff --git a/board/samsung/xyref5260/lowlevel_init.S b/board/samsung/xyref5260/lowlevel_init.S new file mode 100644 index 000000000..51d95a760 --- /dev/null +++ b/board/samsung/xyref5260/lowlevel_init.S @@ -0,0 +1,386 @@ +/* + * Lowlevel setup for XYREF5260 board based on EXYNOS5260 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* Multi Core Timer */ +#define G_TCON_OFFSET 0x0240 +#define GLOBAL_FRC_ENABLE 0x100 + +#define PSHOLD_CONTROL_OFFSET 0x330C +#define GPA2CON_OFFSET 0x0040 +#define GPA2DAT_OFFSET 0x0044 +#define GPF1CON_OFFSET 0x01E0 +#define GPF1DAT_OFFSET 0x01E4 +#define GPX2PUD_OFFSET 0x0C48 + +/* cpu_state flag */ +#define RESET (1 << 0) +#define RESERVED (1 << 1) +#define HOTPLUG (1 << 2) +#define C2_STATE (1 << 3) +#define SWITCH (1 << 4) + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + + .globl lowlevel_init +lowlevel_init: + /* use iRAM stack in bl2 */ + ldr sp, =CONFIG_IRAM_STACK + stmdb r13!, {ip,lr} + + /* check warm reset status */ + bl check_warm_reset + + /* check reset status */ + ldr r0, =(EXYNOS5260_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + + /* AFTR wakeup reset */ + ldr r2, =S5P_CHECK_DIDLE + cmp r1, r2 + beq exit_wakeup + + /* LPA wakeup reset */ + ldr r2, =S5P_CHECK_LPA + cmp r1, r2 + beq exit_wakeup + + /* Sleep wakeup reset */ + ldr r2, =S5P_CHECK_SLEEP + cmp r1, r2 + beq wakeup_reset + + /* PS-Hold high */ + ldr r0, =(EXYNOS5260_POWER_BASE + PSHOLD_CONTROL_OFFSET) + ldr r1, =0x5300 + str r1, [r0] + + bl pmic_gpio_init + +#if defined(CONFIG_PM) + bl pmic_enable_peric_dev +#endif + + bl read_om + + /* + * If U-boot is already running in RAM, no need to relocate U-Boot. + * Memory controller must be configured before relocating U-Boot + * in ram. + */ + ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ + bic r1, pc, r0 /* pc <- current addr of code */ + /* r1 <- unmasked bits of pc */ + ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ + bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ + cmp r1, r2 /* compare r1, r2 */ + beq 1f /* r0 == r1 then skip sdram init */ + + bl set_cpu_state + + /* relocate nscode to non-secure region */ + bl relocate_code + +#if defined(CONFIG_PM) + bl pmic_init +#endif + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +#if defined(CONFIG_TZPC) + bl tzpc_init +#endif + +1: + ldmia r13!, {ip,pc} + +wakeup_reset: + bl start_mct_frc + + bl read_om + + bl set_cpu_state + + /* relocate nscode to non-secure region */ + bl relocate_code + + /* If eMMC booting */ + ldr r0, =(EXYNOS5260_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +exit_wakeup: + /* W/A for abnormal MMC interrupt */ + ldr r0, =0x1214009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + ldr r0, =0x1215009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + ldr r0, =0x1216009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + b warmboot + +pmic_gpio_init: + /* Disable EINT GPIO Pull-up/down */ + ldr r0, =(EXYNOS5260_GPIO_PART1_BASE + GPX2PUD_OFFSET) + mov r1, #0x0 + str r1, [r0] + +#if defined(CONFIG_MACH_UNIVERSAL5260) + /* Set PMIC WRSTBI(GPF1_6) to Output */ + ldr r0, =(EXYNOS5260_GPIO_PART1_BASE + GPF1CON_OFFSET) + ldr r1, [r0] + bic r2, r1, #(0xF << 24) + and r1, r1, r2 + orr r1, r1, #(0x1 << 24) + orr r1, r1, r2 + str r1, [r0] + + /* Set PMIC WRSTBI(GPF1_6) to High */ + ldr r0, =(EXYNOS5260_GPIO_PART1_BASE + GPF1DAT_OFFSET) + ldr r1, [r0] + orr r1, r1, #0x40 + str r1, [r0] +#else + /* Set PMIC WRSTBI(GPA2_0) to Output */ + ldr r0, =(EXYNOS5260_GPIO_PART1_BASE + GPA2CON_OFFSET) + ldr r1, [r0] + bic r2, r1, #0xF + and r1, r1, r2 + orr r1, r1, #0x1 + str r1, [r0] + + /* Set PMIC WRSTBI(GPA2_0) to High */ + ldr r0, =(EXYNOS5260_GPIO_PART1_BASE + GPA2DAT_OFFSET) + ldr r1, [r0] + orr r1, r1, #0x1 + str r1, [r0] +#endif + mov pc, lr + +read_om: + /* Read booting information */ + ldr r0, =(EXYNOS5260_POWER_BASE + OM_STATUS_OFFSET) + ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC BOOT */ + cmp r2, #0x6 + moveq r3, #BOOT_EMMC + + /* eMMC 4.4 BOOT */ + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x10 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x28 + moveq r3, #BOOT_EMMC_4_4 + + ldr r0, =(EXYNOS5260_POWER_BASE + INFORM3_OFFSET) + str r3, [r0] + + mov pc, lr + +set_cpu_state: + /* read boot cluster */ + adr r0, _cpu_state + mrc p15, 0, r1, c0, c0, 5 @ read MPIDR + ubfx r1, r1, #8, #4 @ r1 = cluster id + + /* set reset flag at _cpu_state of boot cpu */ + ldr r2, =RESET + str r2, [r0, r1, lsl #4] + + mov pc, lr + +check_warm_reset: + /* check reset status */ + ldr r0, =(EXYNOS5260_POWER_BASE + RST_STAT_OFFSET) + ldr r1, [r0] + and r1, r1, #WRESET + cmp r1, #WRESET @ check warm reset + /* clear reset_status */ + ldreq r0, =(EXYNOS5260_POWER_BASE + INFORM1_OFFSET) + moveq r1, #0x0 + streq r1, [r0] + + mov pc, lr + +start_mct_frc: + ldr r0, =(EXYNOS5260_MCT_BASE + G_TCON_OFFSET) + ldr r1, [r0] + orr r1, r1, #GLOBAL_FRC_ENABLE + str r1, [r0] + + mov pc, lr + + +/* + * Relocate code + */ +relocate_code: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + .word 0xF57FF04F @dsb sy + .word 0xF57FF06F @isb sy + + mov pc, lr + +/******************************************************************************/ +/* + * CPU1, 2, 3, 4, 5 waits here until CPU0 wake it up. + * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory. + */ +nscode_base: + b 1f + nop @ for backward compatibility + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 +_switch_addr: + .word 0x0 @ REG4: SWITCH_ADDR +_hotplug_addr: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6 +_c2_addr: + .word 0x0 @ REG7: REG_C2_ADDR +_cpu_state: + .word HOTPLUG @ CLUSTER0_CORE0_STATE + .word HOTPLUG @ CLUSTER0_CORE1_STATE + .word RESERVED @ CLUSTER0_CORE2_STATE + .word RESERVED @ CLUSTER0_CORE3_STATE + .word HOTPLUG @ CLUSTER1_CORE0_STATE + .word HOTPLUG @ CLUSTER1_CORE1_STATE + .word HOTPLUG @ CLUSTER1_CORE2_STATE + .word HOTPLUG @ CLUSTER1_CORE3_STATE + +_gic_state: + .word 0x0 @ CPU0 - GICD_IGROUPR0 + .word 0x0 @ CPU1 - GICD_IGROUPR0 + .word 0x0 @ CPU2 - GICD_IGROUPR0 + .word 0x0 @ CPU3 - GICD_IGROUPR0 + .word 0x0 @ CPU4 - GICD_IGROUPR0 + .word 0x0 @ CPU5 - GICD_IGROUPR0 + .word 0x0 @ RESERVED + .word 0x0 @ RESERVED + +#define RESET (1 << 0) +#define SECONDARY_RESET (1 << 1) +#define HOTPLUG (1 << 2) +#define C2_STATE (1 << 3) +#define SWITCH (1 << 4) + +1: + adr r0, _cpu_state + + mrc p15, 0, r7, c0, c0, 5 @ read MPIDR + ubfx r8, r7, #8, #4 @ r8 = cluster id + ubfx r7, r7, #0, #4 @ r7 = cpu id + add r7, r7, r8, lsl #2 @ cpuid + (clusterid * 4) + + /* read the current cpu state */ + ldr r10, [r0, r7, lsl #2] + + /* HYP entry */ + + /* + * Set the HYP spsr to itself, so that the entry point + * does not see the difference between a function call + * and an exception return. + */ + mrs r4, cpsr + msr spsr_cxsf, r4 + + bic r6, r4, #0x1f + orr r6, r6, #0x13 + msr spsr_cxsf, r6 /* Setup SPSR to jump to NS SVC mode */ + add r4, pc, #4 + .word 0xe12ef304 /* msr elr_hyp, r4 */ + .word 0xe160006e /* ERET */ +ns_svc_entry: + tst r10, #SWITCH + adrne r0, _switch_addr + bne wait_for_addr + tst r10, #C2_STATE + adrne r0, _c2_addr + bne wait_for_addr + + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS5260_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + cmp r1, #0x0 + movne r1, #0x0 + strne r1, [r0] + ldrne r1, =(EXYNOS5260_POWER_BASE + INFORM0_OFFSET) + ldrne pc, [r1] + + tst r10, #RESET + ldrne pc, =CONFIG_SYS_TEXT_BASE + + adr r0, _hotplug_addr +wait_for_addr: + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + wfe + b wait_for_addr + .ltorg +nscode_end: diff --git a/board/samsung/xyref5260/mmc_boot.c b/board/samsung/xyref5260/mmc_boot.c new file mode 100644 index 000000000..8cb4c523c --- /dev/null +++ b/board/samsung/xyref5260/mmc_boot.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/mmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/clk.h> +#include <asm/arch/smc.h> +#include "setup.h" + +/* 1st_dev: eMMC, 2nd_dev: SD/MMC */ +#define SDMMC_SECOND_DEV 0x10 +#define USB_SECOND_DEV 0x0 +#define SECOND_BOOT_MODE 0xFEED0002 +#define UBOOT 0x1 +#define TZSW 0x2 +#define SIGNATURE_CHECK_FAIL -1 +#define SIGNATURE_CHECK_SUCCESS (0) + +/* find boot device for secondary booting */ +static int find_second_boot_dev(void) +{ + struct exynos5260_power *pmu = (struct exynos5260_power *)EXYNOS5260_POWER_BASE; + unsigned int om_status = readl(&pmu->om_stat) & 0x12; + + + if (om_status == SDMMC_SECOND_DEV) { + writel(0x1, CONFIG_SECONDARY_BOOT_INFORM_BASE); + return BOOT_SEC_DEV; + } else if (om_status == USB_SECOND_DEV) { + writel(0x2, CONFIG_SECONDARY_BOOT_INFORM_BASE); + return BOOT_USB; + } else + return -1; +} + +static unsigned int device(unsigned int boot_dev) +{ + switch(boot_dev) { + case BOOT_MMCSD: + case BOOT_SEC_DEV: + boot_dev = SDMMC_CH2; + break; + case BOOT_EMMC_4_4: + boot_dev = EMMC; + break; + case BOOT_USB: + boot_dev = USB; + break; + default: + while(1); + } + return boot_dev; +} + +static int ld_image_from_2nd_dev(int image) +{ + int ret = SIGNATURE_CHECK_FAIL; + unsigned int boot_dev = 0; + + boot_dev = find_second_boot_dev(); + + /* sdmmc enumerate */ + if (device(boot_dev) == SDMMC_CH2) + sdmmc_enumerate(); + + switch (image) { + case UBOOT: + /* load uboot from 2nd dev */ + ret = load_uboot_image(device(boot_dev)); + break; + case TZSW: + /* load uboot from 2nd dev */ + ret = coldboot(device(boot_dev)); + break; + } + + if (ret != SIGNATURE_CHECK_SUCCESS) + while(1); + + return boot_dev; +} + +void jump_to_uboot(void) +{ + unsigned int om_status = readl(EXYNOS5260_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + int ret = 0; + + /* TODO : find second boot function */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + /* Load u-boot image to ram */ + ret = load_uboot_image(device(boot_dev)); + if (ret != SIGNATURE_CHECK_SUCCESS) + boot_dev = ld_image_from_2nd_dev(UBOOT); + + /* Load tzsw image & U-Boot boot */ + ret = coldboot(device(boot_dev)); + if (ret != SIGNATURE_CHECK_SUCCESS) + ld_image_from_2nd_dev(TZSW); + +} + +void board_init_f(unsigned long bootflag) +{ + /* Jump to U-Boot image */ + jump_to_uboot(); + + /* Never returns Here */ +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /* Function attribute is no-return */ + /* This Function never executes */ + while (1) + ; +} + +void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} diff --git a/board/samsung/xyref5260/pmic.c b/board/samsung/xyref5260/pmic.c new file mode 100644 index 000000000..2a1b99eba --- /dev/null +++ b/board/samsung/xyref5260/pmic.c @@ -0,0 +1,324 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include "pmic.h" + +void Delay(void) +{ + unsigned long i; + for (i = 0; i < DELAY; i++) + ; +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + /* Function <- Input */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPIO_DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + ack = (ack >> GPIO_DAT_SHIFT) & 0x1; + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + /* Function <- Output */ + IIC0_ESDA_OUTP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + /* Function <- Input (SDA) */ + IIC0_ESDA_INP; + + IIC0_SCLL_SDAL(); +} + +void IIC0_ESetport(void) +{ + /* Pull Up/Down Disable SCL, SDA */ + DIS_GPIO_PUD; + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + /* Function <- Output (SCL) */ + IIC0_ESCL_OUTP; + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + Delay(); +} + +void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. data. */ + for (i = 8; i > 0; i--) { + if ((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EEnd(); +} + +void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* read */ + IIC0_EHigh(); + /* ACK */ + IIC0_EAck_write(); + + /* read reg. data. */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for (i = 8; i > 0; i--) { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPIO_DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + reg = (reg >> GPIO_DAT_SHIFT) & 0x1; + + data |= reg << (i-1); + } + + /* ACK */ + IIC0_EAck_read(); + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + +void pmic_init(void) +{ + unsigned char pmic_id; + unsigned char rtc_ctrl; + unsigned char wrstbi_ctrl; + + IIC0_ESetport(); + + /* read pmic revision number */ + IIC0_ERead(S2MPA01_ADDR, PMIC_ID, &pmic_id); + + /* enable low_jitter, CP, AP at RTC_BUF */ + IIC0_ERead(S2MPA01_ADDR, RTC_BUF, &rtc_ctrl); + rtc_ctrl |= (LOW_JITTER_EN | CP_32KHZ_EN | AP_32KHZ_EN); + IIC0_EWrite(S2MPA01_ADDR, RTC_BUF, rtc_ctrl); + + /* enable WRSTBI detection */ + IIC0_ERead(S2MPA01_ADDR, WRSTBI_CTRL, &wrstbi_ctrl); + wrstbi_ctrl |= WRSTBI_EN; + IIC0_EWrite(S2MPA01_ADDR, WRSTBI_CTRL, wrstbi_ctrl); + + /* power control for touch device */ + /* BUCK9 = 3.5V */ + IIC0_EWrite(S2MPA01_ADDR, BUCK9_OUT, BUCK9_VDD_3_5V); + + /* BUCK Control */ + IIC0_EWrite(S2MPA01_ADDR, BUCK1_OUT, + WR_BUCK_VOLT(CONFIG_PM_VDD_MIF)); + IIC0_EWrite(S2MPA01_ADDR, BUCK2_OUT, + WR_BUCK_VOLT(CONFIG_PM_VDD_EGL)); + IIC0_EWrite(S2MPA01_ADDR, BUCK3_OUT, + WR_BUCK_VOLT(CONFIG_PM_VDD_INT)); + IIC0_EWrite(S2MPA01_ADDR, BUCK4_OUT, + WR_BUCK_VOLT(CONFIG_PM_VDD_G3D)); + IIC0_EWrite(S2MPA01_ADDR, BUCK6_OUT, + WR_BUCK_VOLT(CONFIG_PM_VDD_KFC)); +} + +void pmic_enable_peric_dev(void) +{ + unsigned char ldo_ctrl; + + IIC0_ESetport(); + + /* enable LDO24 : VCC_2.8V_PERI */ + IIC0_ERead(S2MPA01_ADDR, LDO24_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPA01_ADDR, LDO24_CTRL, ldo_ctrl); + + /* enable LDO25 : VCC_1.8V_PERI */ + IIC0_ERead(S2MPA01_ADDR, LDO25_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPA01_ADDR, LDO25_CTRL, ldo_ctrl); +} diff --git a/board/samsung/xyref5260/pmic.h b/board/samsung/xyref5260/pmic.h new file mode 100644 index 000000000..d789d3369 --- /dev/null +++ b/board/samsung/xyref5260/pmic.h @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __PMIC_H__ +#define __PMIC_H__ + +#define GPB3CON *(volatile unsigned long *)(0x116000C0) +#define GPB3DAT *(volatile unsigned long *)(0x116000C4) +#define GPB3PUD *(volatile unsigned long *)(0x116000C8) + +#define GPB4CON *(volatile unsigned long *)(0x116000E0) +#define GPB4DAT *(volatile unsigned long *)(0x116000E4) +#define GPB4PUD *(volatile unsigned long *)(0x116000E8) + +#if defined(CONFIG_MACH_UNIVERSAL5260_REV1) || defined(CONFIG_MACH_XYREF5260) +#define IIC0_ESCL_Hi GPB3DAT |= (0x1<<1) +#define IIC0_ESCL_Lo GPB3DAT &= ~(0x1<<1) +#define IIC0_ESDA_Hi GPB3DAT |= (0x1<<0) +#define IIC0_ESDA_Lo GPB3DAT &= ~(0x1<<0) + +#define IIC0_ESCL_INP GPB3CON &= ~(0xf<<4) +#define IIC0_ESCL_OUTP GPB3CON = (GPB3CON & ~(0xf<<4))|(0x1<<4) + +#define IIC0_ESDA_INP GPB3CON &= ~(0xf<<0) +#define IIC0_ESDA_OUTP GPB3CON = (GPB3CON & ~(0xf<<0))|(0x1<<0) + +#define GPIO_DAT GPB3DAT +#define GPIO_DAT_SHIFT (0) +#define DIS_GPIO_PUD GPB3PUD &= ~(0xf<<0) +#else +#define IIC0_ESCL_Hi GPB4DAT |= (0x1<<3) +#define IIC0_ESCL_Lo GPB4DAT &= ~(0x1<<3) +#define IIC0_ESDA_Hi GPB4DAT |= (0x1<<2) +#define IIC0_ESDA_Lo GPB4DAT &= ~(0x1<<2) + +#define IIC0_ESCL_INP GPB4CON &= ~(0xf<<12) +#define IIC0_ESCL_OUTP GPB4CON = (GPB4CON & ~(0xf<<12))|(0x1<<12) + +#define IIC0_ESDA_INP GPB4CON &= ~(0xf<<8) +#define IIC0_ESDA_OUTP GPB4CON = (GPB4CON & ~(0xf<<8))|(0x1<<8) + +#define GPIO_DAT GPB4DAT +#define GPIO_DAT_SHIFT (2) +#define DIS_GPIO_PUD GPB4PUD &= ~(0xf<<4) +#endif + +#define DELAY 100 + +/* S2MPA01 slave address */ +#define S2MPA01_ADDR 0xCC +#define S2MPA01_RTC 0x0C + +#define VDD_BASE_VOLT 60000 +#define VDD_VOLT_STEP 625 +#define MIN_VOLT 600 +#define MAX_RD_VAL 0xA0 +#define RD_BUCK_VOLT(x) (((x > MAX_RD_VAL) ? 0 : \ + ((x * VDD_VOLT_STEP) + VDD_BASE_VOLT) / 100)) +#define WR_BUCK_VOLT(x) ((x < MIN_VOLT) ? 0 : \ + ((((x) * 100) - VDD_BASE_VOLT) / VDD_VOLT_STEP)) + +/* S2MPA01 Revision ID */ +#define REV_00 0x00 + +/* S2MPA01 Register Address */ +#define PMIC_ID 0x00 +#define S2MPA01_INT1 0x01 +#define S2MPA01_INT2 0x02 +#define S2MPA01_INT3 0x03 +#define S2MPA01_STATUS1 0x07 +#define S2MPA01_STATUS2 0x08 +#define PWRONSRC 0x09 +#define OFFSRC 0x0A +#define RTC_BUF 0x0B +#define WRSTBI_CTRL 0x27 +#define BUCK1_CTRL 0x28 +#define BUCK1_OUT 0x29 +#define BUCK2_CTRL 0x2A +#define BUCK2_OUT 0x2B +#define BUCK3_CTRL 0x2C +#define BUCK3_OUT 0x2D +#define BUCK4_CTRL 0x2E +#define BUCK4_OUT 0x2F +#define BUCK5_CTRL 0x30 +#define BUCK5_SW 0x31 +#define BUCK5_OUT 0x32 +#define BUCK5_OUT2 0x33 +#define BUCK5_OUT3 0x34 +#define BUCK5_OUT4 0x35 +#define BUCK6_CTRL 0x36 +#define BUCK6_OUT 0x37 +#define BUCK7_CTRL 0x38 +#define BUCK7_OUT 0x39 +#define BUCK8_CTRL 0x3A +#define BUCK8_OUT 0x3B +#define BUCK9_CTRL 0x3C +#define BUCK9_OUT 0x3D +#define BUCK10_CTRL 0x3E +#define BUCK10_OUT 0x3F + +#define BUCK9_VDD_3_5V 0xD4 + +#define LDO24_CTRL 0x57 +#define LDO25_CTRL 0x58 + +/* S2MPA01 RTC Register Address */ +#define RTC_WTSR_SMPL 0x01 + +/* LDO CTRL bit */ +#define OFF (0x0) +#define ON (0x1) +#define OUTPUT_OFF (~(3 << 6)) +#define OUTPUT_PWREN_ON (1 << 6) +#define OUTPUT_LOWPWR_MODE (2 << 6) +#define OUTPUT_NORMAL_MODE (3 << 6) + +/* + * RTC_BUF + */ +#define LOW_JITTER_EN (0x1 << 4) +#define CP_32KHZ_EN (0x1 << 1) +#define AP_32KHZ_EN (0x1 << 0) + +/* + * WRSTBI + */ +#define WRSTBI_EN (0x1 << 5) + +extern void pmic_init(void); +extern void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData); +extern void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData); + +#endif /*__PMIC_H__*/ + diff --git a/board/samsung/xyref5260/setup.h b/board/samsung/xyref5260/setup.h new file mode 100644 index 000000000..86e7e52fd --- /dev/null +++ b/board/samsung/xyref5260/setup.h @@ -0,0 +1,57 @@ +/* + * Machine Specific Values for SMDK4270 board based on EXYNOS4 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 _SMDK4270_SETUP_H +#define _SMDK4270_SETUP_H + +#include <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* TZPC : Register Offsets */ +#define TZPC0_BASE 0x10110000 +#define TZPC1_BASE 0x10120000 +#define TZPC2_BASE 0x10130000 +#define TZPC3_BASE 0x10140000 +#define TZPC4_BASE 0x10150000 +#define TZPC5_BASE 0x10160000 +#define TZPC6_BASE 0x10170000 + +/* + * TZPC Register Value : + * R0SIZE: 0x0 : Size of secured ram + */ +#define R0SIZE 0x0 + +/* + * TZPC Decode Protection Register Value : + * DECPROTXSET: 0xFF : Set Decode region to non-secure + */ +#define DECPROTXSET 0xFF + +void sdelay(unsigned long); +void mem_ctrl_init(void); +void system_clock_init(void); +extern unsigned int second_boot_info; +#endif diff --git a/board/samsung/xyref5260/smc.c b/board/samsung/xyref5260/smc.c new file mode 100644 index 000000000..956306db2 --- /dev/null +++ b/board/samsung/xyref5260/smc.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <asm/arch/smc.h> + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1) + + ); + + return reg1; +} + + +unsigned int load_uboot_image(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == USB) { + + /* USB buffer, under 3 KB size, non-secure region */ + info_image->bootdev.usb.read_buffer = CONFIG_PHY_IRAM_NS_BASE + 0x800; + + } + + info_image->image_base_addr = CONFIG_PHY_UBOOT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_UBOOT_SIGNATURE_SIZE; +#if defined(CONFIG_UBOOT_SECURE_BOOT) + exynos_smc(SMC_CMD_SET_SIGNATURE_SIZE, + 0, CONFIG_IMAGE_INFO_BASE, 0); +#endif + + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, 0); +#else + if (boot_device == SDMMC_CH2) { + + u32 (*copy_uboot)(u32, u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + SDMMC_DEV_OFFSET); + + copy_uboot(MOVI_UBOOT_POS, + MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } else if (boot_device == EMMC) { + + u32 (*copy_uboot)(u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + EMMC_DEV_OFFSET ); + + copy_uboot(MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } + +#endif +} + +unsigned int coldboot(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) CONFIG_IMAGE_INFO_BASE; + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == USB) { + + /* default USB buffer of BL0, under 3 KB size, secure region */ + info_image->bootdev.usb.read_buffer = CONFIG_PHY_IRAM_BASE + 0xc00; + + } + + info_image->image_base_addr = CONFIG_PHY_TZSW_BASE; + info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_TZSW_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_COLDBOOT, + boot_device, CONFIG_IMAGE_INFO_BASE, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*uboot)(void); + + /* Jump to U-Boot image */ + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); +#endif + /* Never returns Here */ +} + +void warmboot(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*wakeup_kernel)(void); + + /* Jump to kernel for wakeup */ + wakeup_kernel = (void *)readl(EXYNOS5260_POWER_BASE + INFORM0_OFFSET); + (*wakeup_kernel)(); + /* Never returns Here */ +#endif +} + +unsigned int find_second_boot(void) +{ +#if defined(CONFIG_SMC_CMD) + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT); +#else + return readl(IROM_FNPTR_BASE + SECCOND_BOOT_INFORM_OFFSET); +#endif +} + +void emmc_endbootop(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +#else + +#endif +} + +void sdmmc_enumerate(void) +{ + exynos_smc(SMC_CMD_SDMMC_ENUMERATE, 0, 0, 0); +} + +void set_secure_reg(u32 reg_val, u32 num) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_SET_SECURE_REG, reg_val, num, 0); +#else + +#endif +} diff --git a/board/samsung/xyref5260/tzpc_init.c b/board/samsung/xyref5260/tzpc_init.c new file mode 100644 index 000000000..681e0b988 --- /dev/null +++ b/board/samsung/xyref5260/tzpc_init.c @@ -0,0 +1,45 @@ +/* + * Lowlevel setup for XYREF5260 board based on EXYNOS5260 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <asm/arch/tzpc.h> +#include"setup.h" + +/* Setting TZPC[TrustZone Protection Controller] */ +void tzpc_init(void) +{ + struct exynos_tzpc *tzpc; + unsigned int addr; + + for (addr = TZPC0_BASE; addr <= TZPC6_BASE; addr += TZPC_BASE_OFFSET) { + tzpc = (struct exynos_tzpc *)addr; + + if (addr == TZPC0_BASE) + writel(R0SIZE, &tzpc->r0size); + + writel(DECPROTXSET, &tzpc->decprot0set); + writel(DECPROTXSET, &tzpc->decprot1set); + writel(DECPROTXSET, &tzpc->decprot2set); + writel(DECPROTXSET, &tzpc->decprot3set); + } +} diff --git a/board/samsung/xyref5260/xyref5260.c b/board/samsung/xyref5260/xyref5260.c new file mode 100644 index 000000000..279075f6e --- /dev/null +++ b/board/samsung/xyref5260/xyref5260.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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 <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/sromc.h> +#include <asm/arch/sysreg.h> +#include "pmic.h" + +#define DEBOUNCE_DELAY 10000 + +DECLARE_GLOBAL_DATA_PTR; +unsigned int pmic; + +#ifdef CONFIG_SMC911X +static int smc9115_pre_init(void) +{ + u32 smc_bw_conf, smc_bc_conf; + int err; + + /* Ethernet needs data bus width of 16 bits */ + smc_bw_conf = SROMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK) + | SROMC_BYTE_ENABLE(CONFIG_ENV_SROM_BANK); + + smc_bc_conf = SROMC_BC_TACS(0x01) | SROMC_BC_TCOS(0x01) + | SROMC_BC_TACC(0x06) | SROMC_BC_TCOH(0x01) + | SROMC_BC_TAH(0x0C) | SROMC_BC_TACP(0x09) + | SROMC_BC_PMC(0x01); + + /* Select and configure the SROMC bank */ + err = exynos_pinmux_config(PERIPH_ID_SROMC, + CONFIG_ENV_SROM_BANK | PINMUX_FLAG_16BIT); + if (err) { + debug("SROMC not configured\n"); + return err; + } + + s5p_config_sromc(CONFIG_ENV_SROM_BANK, smc_bw_conf, smc_bc_conf); + return 0; +} +#endif + +static void display_bl1_version(void) +{ + char bl1_version[9] = {0}; + + /* display BL1 version */ +#if defined(CONFIG_TRUSTZONE_ENABLE) + printf("\nTrustZone Enabled BSP"); + strncpy(&bl1_version[0], (char *)CONFIG_BL1_VERSION_INFORM, 8); + printf("\nBL1 version: %s\n", &bl1_version[0]); +#endif +} + +static void display_chip_id(void) +{ +#if defined(CONFIG_DISPLAY_CHIPID) + s5p_chip_id[0] = readl(EXYNOS5260_PRO_ID + CHIPID0_OFFSET); + s5p_chip_id[1] = (readl(EXYNOS5260_PRO_ID + CHIPID1_OFFSET) & 0xFFFF); + + printf("\nChip ID : %04x%08x\n", s5p_chip_id[1], s5p_chip_id[0]); +#endif +} + +static void display_pmic_info(void) +{ +#if defined(CONFIG_PM) + unsigned char pmic_id = 0; + unsigned char rtc_ctrl = 0; + unsigned char wrstbi_ctrl = 0; + unsigned char read_vol_mif = 0; + unsigned char read_vol_egl = 0; + unsigned char read_vol_int = 0; + unsigned char read_vol_g3d = 0; + unsigned char read_vol_kfc = 0; + unsigned char read_buck9 = 0; + unsigned char read_int1 = 0; + unsigned char read_int2 = 0; + unsigned char read_int3 = 0; + unsigned char read_status1 = 0; + unsigned char read_status2 = 0; + unsigned char read_pwronsrc = 0; + unsigned char read_offsrc = 0; + unsigned char read_wtsr_smpl = 0; + + IIC0_ERead(S2MPA01_ADDR, PMIC_ID, &pmic_id); + IIC0_ERead(S2MPA01_ADDR, RTC_BUF, &rtc_ctrl); + IIC0_ERead(S2MPA01_ADDR, WRSTBI_CTRL, &wrstbi_ctrl); + IIC0_ERead(S2MPA01_ADDR, BUCK1_OUT, &read_vol_mif); + IIC0_ERead(S2MPA01_ADDR, BUCK2_OUT, &read_vol_egl); + IIC0_ERead(S2MPA01_ADDR, BUCK3_OUT, &read_vol_int); + IIC0_ERead(S2MPA01_ADDR, BUCK4_OUT, &read_vol_g3d); + IIC0_ERead(S2MPA01_ADDR, BUCK6_OUT, &read_vol_kfc); + IIC0_ERead(S2MPA01_ADDR, BUCK9_OUT, &read_buck9); + IIC0_ERead(S2MPA01_ADDR, BUCK9_OUT, &read_buck9); + + IIC0_ERead(S2MPA01_ADDR, S2MPA01_INT1, &read_int1); + IIC0_ERead(S2MPA01_ADDR, S2MPA01_INT2, &read_int2); + IIC0_ERead(S2MPA01_ADDR, S2MPA01_INT3, &read_int3); + IIC0_ERead(S2MPA01_ADDR, S2MPA01_STATUS1, &read_status1); + IIC0_ERead(S2MPA01_ADDR, S2MPA01_STATUS2, &read_status2); + IIC0_ERead(S2MPA01_ADDR, PWRONSRC, &read_pwronsrc); + IIC0_ERead(S2MPA01_ADDR, OFFSRC, &read_offsrc); + IIC0_EWrite(S2MPA01_ADDR, OFFSRC, 0xff); // to clear OFFSRC + IIC0_ERead(S2MPA01_RTC, RTC_WTSR_SMPL, &read_wtsr_smpl); + + printf("\nPMIC: S2MPA01(REV%x)\n", pmic_id); + printf("MIF: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_mif)); + printf("EGL: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_egl)); + printf("INT: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_int)); + printf("G3D: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_g3d)); + printf("KFC: %dmV\t\n", RD_BUCK_VOLT((unsigned int)read_vol_kfc)); + /* print rtc_buf & wrstbi register value */ + printf("RTC_BUF: 0x%x, WRSTBI: 0x%x\n", rtc_ctrl, wrstbi_ctrl); + printf("BUCK9: 0x%x\n", read_buck9); + + printf("S2MPA01_INT1: 0x%x\n", read_int1); + printf("S2MPA01_INT2: 0x%x\n", read_int2); + printf("S2MPA01_INT3: 0x%x\n", read_int3); + printf("S2MPA01_STATUS1: 0x%x\n", read_status1); + printf("S2MPA01_STATUS2: 0x%x\n", read_status2); + printf("PWRONSRC: 0x%x\n", read_pwronsrc); + printf("OFFSRC: 0x%x\n", read_offsrc); + printf("S2MPA01_RTC: 0x%x\n", read_wtsr_smpl); + + if (((read_pwronsrc & 0x80) >> 7) && ((read_int2 & 0x20) >> 5) && + ((read_int1 & 0x80) >> 7)) + printf("Warning: WTSR detected!!!!\n"); + else + printf("WTSR not detected\n"); + + if (((read_pwronsrc & 0x40) >> 6) && ((read_int3 & 0x08) >> 3) && + ((read_wtsr_smpl & 0x80) >> 7)) + printf("Warning: SMPL detected!!!!\n"); + else + printf("SMPL not detected\n"); +#endif +} + +static void display_boot_device_info(void) +{ + struct exynos5260_power *pmu = (struct exynos5260_power *)EXYNOS5260_POWER_BASE; + int OmPin; + + OmPin = readl(&pmu->inform3); + + printf("\nChecking Boot Mode ..."); + + if (OmPin == BOOT_MMCSD) { + printf(" SDMMC\n"); + } else if (OmPin == BOOT_EMMC) { + printf(" EMMC\n"); + } else if (OmPin == BOOT_EMMC_4_4) { + printf(" EMMC\n"); + } else { + printf(" Please check OM_pin\n"); + } +} + +int board_init(void) +{ + display_bl1_version(); + + display_chip_id(); + + display_pmic_info(); + + display_boot_device_info(); + + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE) + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE) + + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_5_SIZE) + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_6_SIZE) + + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE) + + get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE); + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, + PHYS_SDRAM_4_SIZE); + gd->bd->bi_dram[4].start = PHYS_SDRAM_5; + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5, + PHYS_SDRAM_5_SIZE); + gd->bd->bi_dram[5].start = PHYS_SDRAM_6; + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6, + PHYS_SDRAM_6_SIZE); + gd->bd->bi_dram[6].start = PHYS_SDRAM_7; + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7, + PHYS_SDRAM_7_SIZE); + gd->bd->bi_dram[7].start = PHYS_SDRAM_8; + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8, + PHYS_SDRAM_8_SIZE); +} + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_SMC911X + if (smc9115_pre_init()) + return -1; + return smc911x_initialize(0, CONFIG_SMC911X_BASE); +#endif + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ +#if defined(CONFIG_MACH_UNIVERSAL5260) + printf("\nBoard: UNIVERSAL5260\n"); +#else + printf("\nBoard: XYREF5260\n"); +#endif + + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + struct exynos5260_power *pmu = (struct exynos5260_power *)EXYNOS5260_POWER_BASE; + int err, OmPin; + + OmPin = readl(&pmu->inform3); + + err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); + if (err) { + debug("SDMMC2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); + if (err) { + debug("MSHC0 not configured\n"); + return err; + } + + switch (OmPin) { + case BOOT_EMMC_4_4: +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif + break; + default: +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif + break; + } + + return err; +} +#endif + +static int board_uart_init(void) +{ + int err; + + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE); + if (err) { + debug("UART0 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE); + if (err) { + debug("UART1 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE); + if (err) { + debug("UART2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); + if (err) { + debug("UART3 not configured\n"); + return err; + } + + return 0; +} + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f(void) +{ + return board_uart_init(); +} +#endif + +int board_late_init(void) +{ + struct exynos5260_power *pmu = (struct exynos5260_power *)EXYNOS5260_POWER_BASE; + unsigned int rst_stat = 0; + + rst_stat = readl(&pmu->rst_stat); + printf("rst_stat : 0x%x\n", rst_stat); + +#ifdef CONFIG_RAMDUMP_MODE + /* check reset status for ramdump */ + if ((rst_stat & (WRESET | CORTEXA7_WDTRESET | CORTEXA15_WDTRESET)) + || (readl(&pmu->sysip_dat0) == CONFIG_RAMDUMP_MODE) + || (readl(CONFIG_RAMDUMP_SCRATCH) == CONFIG_RAMDUMP_MODE)) { + /* run fastboot */ + run_command("fastboot", 0); + } +#endif +#ifdef CONFIG_RECOVERY_MODE + u32 second_boot_info = readl(CONFIG_SECONDARY_BOOT_INFORM_BASE); + + if (second_boot_info == 1) { + printf("###Recovery Mode(SDMMC)###\n"); + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + setenv("bootcmd", CONFIG_RECOVERYCOMMAND_SDMMC); + } else if (second_boot_info == 2) { + printf("###Recovery Mode(USB)###\n"); + writel(0x0, CONFIG_SECONDARY_BOOT_INFORM_BASE); + setenv("bootcmd", CONFIG_RECOVERYCOMMAND_USB); + } +#endif + + if ((readl(&pmu->sysip_dat0)) == CONFIG_FACTORY_RESET_MODE) { + writel(0x0, &pmu->sysip_dat0); + setenv("bootcmd", CONFIG_FACTORY_RESET_BOOTCOMMAND); + } + return 0; +} + +unsigned int get_board_rev(void) +{ + unsigned int rev = 0; +#if defined(CONFIG_MACH_UNIVERSAL5260) + struct exynos5260_gpio_part1 *gpio1 = + (struct exynos5260_gpio_part1 *) samsung_get_base_gpio_part1(); + + /* set gpd0,1,2,3 for input */ + s5p_gpio_direction_input(&gpio1->d0, 0x0); + s5p_gpio_direction_input(&gpio1->d0, 0x1); + s5p_gpio_direction_input(&gpio1->d0, 0x2); + s5p_gpio_direction_input(&gpio1->d0, 0x3); + + /* read board revision information */ + rev = s5p_gpio_get_value(&gpio1->d0, 0); + rev |= s5p_gpio_get_value(&gpio1->d0, 1) << 1; + rev |= s5p_gpio_get_value(&gpio1->d0, 2) << 2; + rev |= s5p_gpio_get_value(&gpio1->d0, 3) << 3; + + if (rev == 0x3) + rev = 0x0; +#endif + return rev; +} diff --git a/board/samsung/xyref5430/ASVGrpVoltageSetting.c b/board/samsung/xyref5430/ASVGrpVoltageSetting.c new file mode 100644 index 000000000..bb9b32d05 --- /dev/null +++ b/board/samsung/xyref5430/ASVGrpVoltageSetting.c @@ -0,0 +1,271 @@ + +typedef unsigned int u32; +typedef int s32; + +typedef enum +{ + SYSC_DVFS_L0_A=-1, + SYSC_DVFS_L0=0, + SYSC_DVFS_L1, + SYSC_DVFS_L2, + SYSC_DVFS_L3, + SYSC_DVFS_L4, + SYSC_DVFS_L5, + SYSC_DVFS_L6, + SYSC_DVFS_L7, + SYSC_DVFS_L8, + SYSC_DVFS_L9, + SYSC_DVFS_L10, + SYSC_DVFS_L11, + SYSC_DVFS_L12, + SYSC_DVFS_L13, + SYSC_DVFS_L14, + SYSC_DVFS_L15, + SYSC_DVFS_L16, + SYSC_DVFS_L17, + SYSC_DVFS_L18, + SYSC_DVFS_L19, + SYSC_DVFS_L20, + SYSC_DVFS_L21, + SYSC_DVFS_L22, + SYSC_DVFS_L23, + SYSC_DVFS_FIN=0x100, +} SYSC_DVFS_LVL; + +typedef enum +{ + SYSC_ASV_0=0 , + SYSC_ASV_1, + SYSC_ASV_2, + SYSC_ASV_3, + SYSC_ASV_4, + SYSC_ASV_5=5, + SYSC_ASV_6, + SYSC_ASV_7, + SYSC_ASV_8, + SYSC_ASV_9, + SYSC_ASV_10, + SYSC_ASV_11 = 11, + SYSC_ASV_12 = 12, + SYSC_ASV_13, + SYSC_ASV_14, + SYSC_ASV_15 = 15, + SYSC_ASV_MAX +} SYSC_ASV_GROUP; + +typedef enum +{ + SYSC_DVFS_EGL, + SYSC_DVFS_KFC, + SYSC_DVFS_MIF, + SYSC_DVFS_INT, + SYSC_DVFS_G3D, + + SYSC_DVFS_CAM, + SYSC_DVFS_DISP, + + SYSC_DVFS_NUM +} SYSC_DVFS_SEL; + +#define CHIPID_ASV_EGL_BASE 0x10004010 +#define CHIPID_ASV_KFC_BASE 0x10004014 +#define CHIPID_ASV_G3D_BASE 0x10004018 +#define CHIPID_ASV_MIF_BASE 0x10004018 +#define CHIPID_ASV_INT_BASE 0x1000401C +#define CHIPID_ASV_CAM_BASE 0x1000401C + +const u32 g_uChipidBase[SYSC_DVFS_NUM][4]= { + [SYSC_DVFS_EGL] = { CHIPID_ASV_EGL_BASE, 0 }, + [SYSC_DVFS_KFC] = { CHIPID_ASV_KFC_BASE, 0 }, + [SYSC_DVFS_G3D] = { CHIPID_ASV_G3D_BASE, 0 }, + [SYSC_DVFS_MIF] = { CHIPID_ASV_MIF_BASE, 16 }, + [SYSC_DVFS_INT] = { CHIPID_ASV_INT_BASE, 0 }, + [SYSC_DVFS_CAM] = { CHIPID_ASV_CAM_BASE, 16 }, +}; + +static volatile s32 g_uSwAsvGroup[SYSC_DVFS_NUM][3] = { + [SYSC_DVFS_EGL] = { -1,-1,-1 }, + [SYSC_DVFS_KFC] = { -1,-1,-1 }, + [SYSC_DVFS_G3D] = { -1,-1,-1 }, + [SYSC_DVFS_MIF] = { -1,-1,-1 }, + [SYSC_DVFS_INT] = { -1,-1,-1 }, + [SYSC_DVFS_CAM] = { -1,-1,-1 }, +}; + + +/* applied DVFS v0.91 */ +#define ASV_VOLTAGE_GROUP_NUM 4 +const u32 g_AsvGrpVoltage[SYSC_DVFS_NUM][ASV_VOLTAGE_GROUP_NUM]= { + // ASV0 ASV1~5 ASV6~10 ASV11~15 + [SYSC_DVFS_EGL] = { 10000000, 9500000, 9000000, 9000000 }, + [SYSC_DVFS_KFC] = { 9750000, 9750000, 9125000, 8500000 }, + [SYSC_DVFS_MIF] = { 10500000, 10250000, 9625000, 9000000 }, + [SYSC_DVFS_INT] = { 10750000, 10500000, 9875000, 9250000 }, + [SYSC_DVFS_G3D] = { 10000000, 9750000, 9125000, 8500000 }, +}; + +const u32 g_AsvGrpVoltage_v1[SYSC_DVFS_NUM][ASV_VOLTAGE_GROUP_NUM]= { + // ASV0 ASV1~5 ASV6~10 ASV11~15 + [SYSC_DVFS_EGL] = { 9250000, 9000000, 9000000, 9000000 }, + [SYSC_DVFS_KFC] = { 10250000, 10000000, 9125000, 8500000 }, + [SYSC_DVFS_MIF] = { 10250000, 10000000, 9375000, 8750000 }, + [SYSC_DVFS_INT] = { 9750000, 9500000, 8750000, 8125000 }, + [SYSC_DVFS_G3D] = { 8875000, 8750000, 8188000, 7875000 }, +}; + +typedef enum +{ + ASV_GROUP0 = 0x0, + ASV_GROUP1_5 = 0x1, + ASV_GROUP6_10 = 0x2, + ASV_GROUP11_15 = 0x3 +} ASV_GROUP; + +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define GetBits(uAddr, uBaseBit, uMaskValue) ((Inp32(uAddr)>>(uBaseBit))&(uMaskValue)) + +#define CHIPID_ASV_TABLE_VERSION 0x10004020 + +u32 uEglAsvGrpVolt; +u32 uKfcAsvGrpVolt; +u32 uMifAsvGrpVolt; +u32 uIntAsvGrpVolt; +u32 uG3dAsvGrpVolt; + +u32 DVFS_GetAsvTableVersion(void) +{ + return Inp32(CHIPID_ASV_TABLE_VERSION)&0x3; +} + + +u32 DVFS_GetSubGroup(SYSC_DVFS_SEL eSel, SYSC_DVFS_LVL eLvl) +{ + u32 subgrp = 0; // version 0 + + if (DVFS_GetAsvTableVersion() == 1) + { + switch(eSel) + { + case SYSC_DVFS_EGL: + subgrp = (eLvl <= SYSC_DVFS_L8) ? 0 : + (eLvl <= SYSC_DVFS_L13) ? 1 : 2; + break; + case SYSC_DVFS_KFC: + subgrp = (eLvl <= SYSC_DVFS_L8) ? 0 : + (eLvl <= SYSC_DVFS_L13) ? 1 : 2; + break; + case SYSC_DVFS_G3D: + subgrp = (eLvl <= SYSC_DVFS_L2) ? 0 : + (eLvl <= SYSC_DVFS_L4) ? 1 : 2; + break; + case SYSC_DVFS_MIF: + subgrp = (eLvl <= SYSC_DVFS_L0) ? 0 : + (eLvl <= SYSC_DVFS_L3) ? 1 : 2; + break; + case SYSC_DVFS_INT: + subgrp = (eLvl <= SYSC_DVFS_L0) ? 0 : + (eLvl <= SYSC_DVFS_L3) ? 1 : 2; + break; + case SYSC_DVFS_CAM: + subgrp = (eLvl <= SYSC_DVFS_L0) ? 0 : + (eLvl <= SYSC_DVFS_L2) ? 1 : 2; + break; + default: + while(1); + } + } + + return subgrp; +} + +const char * DVFS_GetDvfsName(SYSC_DVFS_SEL eSel) +{ + return (eSel == SYSC_DVFS_EGL) ? "EGL" : + (eSel == SYSC_DVFS_KFC) ? "KFC" : + (eSel == SYSC_DVFS_G3D) ? "G3D" : + (eSel == SYSC_DVFS_MIF) ? "MIF" : + (eSel == SYSC_DVFS_INT) ? "INT" : + (eSel == SYSC_DVFS_CAM) ? "CAM" : "DISP"; +} + +SYSC_ASV_GROUP DVFS_GetAsvGroup(SYSC_DVFS_SEL eSel, SYSC_DVFS_LVL eLvl) +{ + u32 subgrp, uAsvGroup=7; + + subgrp = DVFS_GetSubGroup(eSel, eLvl); + + if (DVFS_GetAsvTableVersion() == 0 && eSel == SYSC_DVFS_CAM) + { + eSel = SYSC_DVFS_INT; + } + + uAsvGroup = GetBits(g_uChipidBase[eSel][0], g_uChipidBase[eSel][1] + subgrp*4, 0xf); + + if (g_uSwAsvGroup[eSel][subgrp]>=0) + { + uAsvGroup = g_uSwAsvGroup[eSel][subgrp]; + } + else; + + return (SYSC_ASV_GROUP)uAsvGroup; +} + + + +u32 GetAsvGroupbyAsv(u32 uAsv) +{ + if(uAsv >= 1 && uAsv <= 5) + return ASV_GROUP1_5; + else if(uAsv >= 6 && uAsv <= 10) + return ASV_GROUP6_10; + else if(uAsv >= 11 && uAsv <= 15) + return ASV_GROUP11_15; + else + return ASV_GROUP0; +} + + +u32 GetVoltagebyAsvGroup(ASV_GROUP eAsvGroup, SYSC_DVFS_SEL eDvfsSel) +{ + if (DVFS_GetAsvTableVersion() == 1) + return g_AsvGrpVoltage_v1[eDvfsSel][eAsvGroup]; + else + return g_AsvGrpVoltage[eDvfsSel][eAsvGroup]; + +} + +void Get_ASV_Group(void) +{ + u32 uEglAsv; + u32 uKfcAsv; + u32 uMifAsv; + u32 uIntAsv; + u32 uG3dAsv; + + u32 uEglAsvGrp; + u32 uKfcAsvGrp; + u32 uMifAsvGrp; + u32 uIntAsvGrp; + u32 uG3dAsvGrp; + + // GET ASV VALUE + uEglAsv = DVFS_GetAsvGroup(SYSC_DVFS_EGL, 20); /* 500Mhz level 20 */ + uKfcAsv = DVFS_GetAsvGroup(SYSC_DVFS_KFC, 12); /* 800Mhz level 12 */ + uMifAsv = DVFS_GetAsvGroup(SYSC_DVFS_MIF, 0); /* 825Mhz level 0 */ + uIntAsv = DVFS_GetAsvGroup(SYSC_DVFS_INT, 0); /* 400Mhz level 0 */ + uG3dAsv = DVFS_GetAsvGroup(SYSC_DVFS_G3D, 5); /* 266Mhz level 5 */ + + // GET ASV VOLTAGE GROUP + uEglAsvGrp = GetAsvGroupbyAsv(uEglAsv); + uKfcAsvGrp = GetAsvGroupbyAsv(uKfcAsv); + uMifAsvGrp = GetAsvGroupbyAsv(uMifAsv); + uIntAsvGrp = GetAsvGroupbyAsv(uIntAsv); + uG3dAsvGrp = GetAsvGroupbyAsv(uG3dAsv); + + // GET VOLTAGE BY ASV VOLTAGE GROUP + uEglAsvGrpVolt = GetVoltagebyAsvGroup(uEglAsvGrp,SYSC_DVFS_EGL); + uKfcAsvGrpVolt = GetVoltagebyAsvGroup(uKfcAsvGrp,SYSC_DVFS_KFC); + uMifAsvGrpVolt = GetVoltagebyAsvGroup(uMifAsvGrp,SYSC_DVFS_MIF); + uIntAsvGrpVolt = GetVoltagebyAsvGroup(uIntAsvGrp,SYSC_DVFS_INT); + uG3dAsvGrpVolt = GetVoltagebyAsvGroup(uG3dAsvGrp,SYSC_DVFS_G3D); +} diff --git a/board/samsung/xyref5430/Makefile b/board/samsung/xyref5430/Makefile new file mode 100644 index 000000000..68a0944ae --- /dev/null +++ b/board/samsung/xyref5430/Makefile @@ -0,0 +1,71 @@ +# +# Copyright (C) 2012 Samsung Electronics +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +SOBJS := lowlevel_init.o + +COBJS := clock_init.o +COBJS += dmc_init.o +COBJS += pmic.o +COBJS += smc.o +COBJS += ASVGrpVoltageSetting.o + +ifdef CONFIG_LCD +COBJS += display.o +endif + +ifdef CONFIG_TZPC +COBJS += tzpc_init.o +endif + +ifndef CONFIG_SPL_BUILD +COBJS += xyref5430.o +ifndef CONFIG_MACH_UNIVERSAL5430 +COBJS += pmic_lm3560.o +endif +endif + +ifdef CONFIG_SPL_BUILD +COBJS += mmc_boot.o +endif + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +ALL := $(obj).depend $(LIB) + +all: $(ALL) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/xyref5430/clock_init.c b/board/samsung/xyref5430/clock_init.c new file mode 100644 index 000000000..00d77dd58 --- /dev/null +++ b/board/samsung/xyref5430/clock_init.c @@ -0,0 +1,563 @@ +/* + * Clock setup for XYREF5430 board based on EXYNOS5430 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pmu.h> +#include "setup.h" + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) ((*(volatile u32 *)(addr))) + +//#define WaitForMuxChange(reg, offset) while( ((Inp32(reg)>>(offset))&7) >=4 ); + +#if 0 +#define blOutp32(addr, data) {cprintf("Outp32(0x%08x, 0x%08x);\n", (addr), (data)); Outp32(addr, data);} +#define WaitUntilStatus(reg, offset, mask, stat) \ + { DEBUGMSG(1, ("WaitUntilStatus(0x%08x, %d, %d, %d);\n", reg, offset, mask, stat)); while( ((Inp32(reg)>>(offset))&(mask)) == (stat) ); } +#else +#define blOutp32(addr, data) Outp32(addr, data) +#define WaitUntilStatus(reg, offset, mask, stat) while( ((Inp32(reg)>>(offset))&(mask)) == (stat) ); +#endif +#define blSetBits(uAddr, uBaseBit, uMaskValue, uSetValue) \ + blOutp32(uAddr, (Inp32(uAddr) & ~((uMaskValue)<<(uBaseBit))) | (((uMaskValue)&(uSetValue))<<(uBaseBit))) + +#ifdef EVT0 +#include "cmu_evt0.c" +#else +// MUX +void InitCmuForWakeup(u32 uEglClkMhz, u32 uKfcClkMhz, u32 uMphyClk) // 1066 933 800 +{ + blOutp32(0x1003060C, 0x777777); + + + //MIF + blOutp32(0x105b0200, 0x00000000); + WaitUntilStatus(0x105b0400, 12, 7, 4); + WaitUntilStatus(0x105b0400, 4, 7, 4); + WaitUntilStatus(0x105b0400, 0, 7, 4); + WaitUntilStatus(0x105b0400, 8, 7, 4); + + Outp32(0x105b0004, 0x00000258); + Outp32(0x105b0000, 0x00000258); + Outp32(0x105b000c, 0x00000259); + Outp32(0x105b0008, 0x00000384); + +#if 0 + Outp32(0x105b0100, 0x82150601); // 1066 + Outp32(0x105b0110, 0x81370401); // 933 + Outp32(0x105b0120, 0x81900601); // 800 + Outp32(0x105b0130, 0x80de0401); // 667 +#else + Outp32(0x105b0100, 0x816a0402); // 543 + Outp32(0x105b0110, 0x81130401); // 825 + Outp32(0x105b0120, 0x81900601); // 800 + Outp32(0x105b0130, 0x80d30401); // 633 +#endif + WaitUntilStatus(0x105b0100, 29, 1, 0); + WaitUntilStatus(0x105b0110, 29, 1, 0); + WaitUntilStatus(0x105b0120, 29, 1, 0); + WaitUntilStatus(0x105b0130, 29, 1, 0); + +// blOutp32(0x105b0600, 0x00002100); +// blOutp32(0x105b0600, 0x00000000); + blOutp32(0x105b0608, 0x00077411); + blOutp32(0x105b0604, 0x00031100); + blOutp32(0x105b060c, 0x00011213); // 0x10013 + + if (uMphyClk == 1066) + blOutp32(0x105b0204, 0x00000000); + else if (uMphyClk == 933 || uMphyClk == 921) + blOutp32(0x105b0204, 0x01001000); + else if (uMphyClk == 667 || uMphyClk == 633) + blOutp32(0x105b0204, 0x01111110); + else + blOutp32(0x105b0204, 0x01001000); + + blOutp32(0x105b0208, 0x00000101); + blOutp32(0x105b0614, 0); + + WaitUntilStatus(0x105b0404, 4, 7, 4); + WaitUntilStatus(0x105b0404, 8, 7, 4); + WaitUntilStatus(0x105b0404, 0, 7, 4); + WaitUntilStatus(0x105b0404, 12, 7, 4); + WaitUntilStatus(0x105b0404, 16, 7, 4); + WaitUntilStatus(0x105b0404, 20, 7, 4); + WaitUntilStatus(0x105b0404, 24, 7, 4); + WaitUntilStatus(0x105b0408, 4, 7, 4); + WaitUntilStatus(0x105b0408, 0, 7, 4); + WaitUntilStatus(0x105b040c, 12, 7, 4); + WaitUntilStatus(0x105b040c, 16, 7, 4); + WaitUntilStatus(0x105b040c, 0, 7, 4); + WaitUntilStatus(0x105b040c, 4, 7, 4); + WaitUntilStatus(0x105b040c, 8, 7, 4); + + blOutp32(0x105b0610, 0x00011111); + + blOutp32(0x105b0214, 0x00000001); + blOutp32(0x105b0210, 0x00000001); + blOutp32(0x105b0200, 0x00001111); + WaitUntilStatus(0x105b0414, 0, 7, 4); + WaitUntilStatus(0x105b0414, 4, 7, 4); + WaitUntilStatus(0x105b0414, 8, 7, 4); + WaitUntilStatus(0x105b0410, 0, 7, 4); + WaitUntilStatus(0x105b0410, 4, 7, 4); + WaitUntilStatus(0x105b0410, 8, 7, 4); + WaitUntilStatus(0x105b0410, 16, 7, 4); + WaitUntilStatus(0x105b0410, 20, 7, 4); + WaitUntilStatus(0x105b0410, 24, 7, 4); + WaitUntilStatus(0x105b0410, 28, 7, 4); + WaitUntilStatus(0x105b0400, 12, 7, 4); + WaitUntilStatus(0x105b0400, 4, 7, 4); + WaitUntilStatus(0x105b0400, 0, 7, 4); + WaitUntilStatus(0x105b0400, 8, 7, 4); + + //BUS1 + blOutp32(0x14800600, 0x00000002); + + //BUS2 + blOutp32(0x13400600, 0x00000002); + blOutp32(0x13400200, 0x00000001); + WaitUntilStatus(0x13400200, 0, 7, 4); + + //TOP + blOutp32(0x1003023c, 0x00000011); + blOutp32(0x10030204, 0x00000000); + blOutp32(0x10030200, 0x00000000); + WaitUntilStatus(0x10030404, 12, 7, 4); + WaitUntilStatus(0x10030404, 16, 7, 4); + WaitUntilStatus(0x10030404, 0, 7, 4); + WaitUntilStatus(0x10030404, 4, 7, 4); + WaitUntilStatus(0x10030404, 8, 7, 4); + WaitUntilStatus(0x10030400, 4, 7, 4); + WaitUntilStatus(0x10030400, 8, 7, 4); + WaitUntilStatus(0x10030400, 0, 7, 4); + + blOutp32(0x10030610, 0x1); // BUS1 + + blOutp32(0x1003060c, 0x00441515); + blOutp32(0x10030644, 0x00001777); + blOutp32(0x10030608, 0x00000005); + blOutp32(0x1003062c, 0x00017017); + blOutp32(0x10030630, 0x00000017); + blOutp32(0x10030634, 0x0000001b); + blOutp32(0x10030604, 0x01000700); + blOutp32(0x10030608, 0x00000015); + blOutp32(0x10030604, 0x51000700); + blOutp32(0x10030618, 0x00000001); + + + blOutp32(0x1003020c, 0x00000000); + blOutp32(0x10030220, 0x00000001); + blOutp32(0x10030230, 0x01010001); + blOutp32(0x10030234, 0x00000001); + + WaitUntilStatus(0x1003040c, 12, 7, 4); + WaitUntilStatus(0x1003040c, 8, 7, 4); + WaitUntilStatus(0x1003040c, 16, 7, 4); + + blOutp32(0x10030604, 0x51000701); + blOutp32(0x10030604, 0x51000201); + + blOutp32(0x1003020c, 0x00000000); + WaitUntilStatus(0x1003040c, 0, 7, 4); + WaitUntilStatus(0x1003040c, 4, 7, 4); + + blOutp32(0x10030604, 0x51111201); + blOutp32(0x10030620, 0x00171717); + blOutp32(0x10030600, 0x07107011); + + blOutp32(0x10030600, 0x11107011); + blOutp32(0x10030208, 0x00000110); + WaitUntilStatus(0x10030408, 0, 7, 4); + WaitUntilStatus(0x10030408, 4, 7, 4); + WaitUntilStatus(0x10030408, 8, 7, 4); + WaitUntilStatus(0x10030408, 12, 7, 4); + + blOutp32(0x10030600, 0x11111011); + + blOutp32(0x10030000, 0x000003e9); + blOutp32(0x10030100, 0x81cc0502); + WaitUntilStatus(0x10030100, 29, 1, 0); + + blOutp32(0x10030204, 0x00001111); + blOutp32(0x10030200, 0x00000001); + WaitUntilStatus(0x10030404, 0, 7, 4); + WaitUntilStatus(0x10030404, 4, 7, 4); + WaitUntilStatus(0x10030404, 8, 7, 4); + WaitUntilStatus(0x10030400, 0, 7, 4); + + //EGL +#if 1 + blOutp32(0x11800600, 0x00000003); + blOutp32(0x11800200, 0x00000000); + blOutp32(0x11800208, 0x00000000); + blOutp32(0x11800208, 0x00000000); + blOutp32(0x11800204, 0x00000001); + WaitUntilStatus(0x11800400, 0, 7, 4); + WaitUntilStatus(0x11800408, 0, 7, 4); + WaitUntilStatus(0x11800404, 0, 7, 4); + + blOutp32(0x11800000, 0x000004b1); + if (uEglClkMhz <= 500) + blOutp32(0x11800100, 0x80000602|uEglClkMhz<<16); + else if (uKfcClkMhz <= 1000) + blOutp32(0x11800100, 0x80000601|(uEglClkMhz/2)<<16); + else + blOutp32(0x11800100, 0x80000600|(uEglClkMhz/4)<<16); + WaitUntilStatus(0x11800100, 29, 1, 0); + + blOutp32(0x11800600, 0x00777200); + blOutp32(0x11800604, 0x00000071); + + blOutp32(0x11800200, 0x00000001); + WaitUntilStatus(0x11800400, 0, 7, 4); +#endif + //KFC + blOutp32(0x11900600, 0x03333103); + + blOutp32(0x11900200, 0x00000000); + blOutp32(0x11900208, 0x00000000); + blOutp32(0x11900204, 0x00000001); + WaitUntilStatus(0x11900400, 0, 7, 4); + WaitUntilStatus(0x11900408, 0, 7, 4); + WaitUntilStatus(0x11900404, 0, 7, 4); + + blOutp32(0x11900000, 0x000004b1); + if (uKfcClkMhz <= 500) + blOutp32(0x11900100, 0x80000602|uKfcClkMhz<<16); + else if (uKfcClkMhz <= 1000) + blOutp32(0x11900100, 0x80000601|(uKfcClkMhz/2)<<16); + else + blOutp32(0x11900100, 0x80000600|(uKfcClkMhz/4)<<16); + + WaitUntilStatus(0x11900100, 29, 1, 0); + + blOutp32(0x11900600, 0x03777100); + blOutp32(0x11900604, 0x00000071); + + blOutp32(0x11900200, 0x00000001); + WaitUntilStatus(0x11900400, 0, 7, 4); + + //CPIF + blOutp32(0x10fc0200, 0x00000000); + blOutp32(0x10fc0208, 0x00000000); + WaitUntilStatus(0x10fc0400, 0, 7, 4); + WaitUntilStatus(0x10fc0408, 0, 7, 4); + blOutp32(0x10fc0600, 0x00000016); + + blOutp32(0x10fc0000, 0x00000384); + blOutp32(0x10fc0100, 0x81F40602); + WaitUntilStatus(0x10fc0100, 29, 1, 0); + blOutp32(0x10fc0200, 0x00000001); + WaitUntilStatus(0x10fc0400, 0, 7, 4); +} + +void InitMemClk(u32 uMemclk) +{ + blOutp32(0x105b0614, 0); + if (uMemclk == 800 || uMemclk == 825) { + blSetBits(0x105b1000, 12, 0xFFFFF, 0x00100); +// blOutp32(0x105b1000, 0x00110110); + blOutp32(0x105b0208, 0x00000100); + blOutp32(0x105b0608, 0x00089511); + blOutp32(0x105b060c, 0x00011214); + } + else // 50~100Mhz for DREX Initital + { + blSetBits(0x105b1000, 12, 0xFFFFF, 0xf0100); +// blOutp32(0x105b1000, 0x70110110); + blOutp32(0x105b0208, 0x00000100); + blOutp32(0x105b0608, 0x000bb717); + blOutp32(0x105b060c, 0x00011217); + blOutp32(0x105b0614, 1); + } +} + +void InitCmuForBl(int initial, u32 uEglClkMhz, u32 uKfcClkMhz, u32 uMphyClk) +{ + volatile u32 i; + +// blOutp32(0x120f031c, 0x13); // cam0 +// blOutp32(0x145F031c, 0x13); // cam1 +// blOutp32(0x146f031c, 0x13); // isp +// blOutp32(0x14fa031c, 0x13); // hevc + + blOutp32(0x10030308, 0x11111111); + blOutp32(0x1003030c, 0x11111); + for (i=0; i<1000000; i++); + + if (initial==1) + { + + blOutp32(0x14800600, 0x7); + blOutp32(0x13400600, 0x7); + blOutp32(0x12460600, 0x7); + blOutp32(0x150D0600, 0x7); + blOutp32(0x14AA0600, 0x777 ); + blOutp32(0x15280600, 0x7 ); + blOutp32(0x15380600, 0x7 ); + blOutp32(0x14F80600, 0x7 ); + blOutp32(0x10030600, 0x77777777); + blOutp32(0x10030604, 0x77777777); + blOutp32(0x10030608, 0x77); + blOutp32(0x10030618, 0x7); + blOutp32(0x1003061C, 0x77777777); + blOutp32(0x10030620, 0x77777777); + blOutp32(0x10030634, 0x77777777); + blOutp32(0x10030638, 0x00019777); + blOutp32(0x1003063C, 0x77777777); + blOutp32(0x10030644, 0x77777777); + + blOutp32(0x13b90200, 0x00000000); + blOutp32(0x13b9020c, 0x00000000); + blOutp32(0x13b90204, 0x00000000); + blOutp32(0x156e0200, 0x00000000); + // For ufs, 24th bit should be 1. + blOutp32(0x156e0204, 0x00000000); + blOutp32(0x13cf0200, 0x00000000); + blOutp32(0x150d0200, 0x00000000); + blOutp32(0x12460200, 0x00000000); + blOutp32(0x14f80200, 0x00000000); + blOutp32(0x15380200, 0x00000000); + blOutp32(0x146d0200, 0x00000000); + blOutp32(0x120d0200, 0x00000000); + blOutp32(0x145d0200, 0x00000000); + +// EnablePPROForBL(); +// EnableRCGForBL(); + } + + InitCmuForWakeup(uEglClkMhz, uKfcClkMhz, uMphyClk); + + if (initial==1) + { + //AUD + blOutp32(0x10030200, 0x00000001); + blOutp32(0x10030200, 0x00000001); + blOutp32(0x114c0200, 0x00000000); + WaitUntilStatus(0x10030400, 8, 7, 4); + WaitUntilStatus(0x10030400, 4, 7, 4); + WaitUntilStatus(0x114c0400, 8, 7, 4); + + blOutp32(0x10030004, 0x00002329); + blOutp32(0x10030114, 0x00000000); + blOutp32(0x10030110, 0x80c50303); + WaitUntilStatus(0x10030110, 29, 1, 0); + + blOutp32(0x114c0600, 0x00000520); + blOutp32(0x114c0604, 0x000715f3); + + blOutp32(0x10030200, 0x00000111); + blOutp32(0x114c0200, 0x00000011); + WaitUntilStatus(0x10030400, 8, 7, 4); + WaitUntilStatus(0x10030400, 4, 7, 4); + WaitUntilStatus(0x114c0400, 4, 7, 4); + WaitUntilStatus(0x114c0400, 0, 7, 4); + + //G3D + blOutp32(0x14aa0200, 0x00000000); + WaitUntilStatus(0x14aa0400, 0, 7, 4); + + blOutp32(0x14aa0000, 0x000004b1); + blOutp32(0x14aa0100, 0x810a0602); + WaitUntilStatus(0x14aa0100, 29, 1, 0); + blOutp32(0x14aa0600, 0x00000030); + + blOutp32(0x14aa0200, 0x00000001); + WaitUntilStatus(0x14aa0400, 0, 7, 4); + + //FSYS + blOutp32(0x156e0200, 0x00000001); + // For ufs, 24th bit should be 1. + blOutp32(0x156e0204, 0x00111000); + WaitUntilStatus(0x156e0404, 16, 7, 4); + WaitUntilStatus(0x156e0404, 12, 7, 4); + WaitUntilStatus(0x156e0404, 24, 7, 4); + WaitUntilStatus(0x156e0400, 0, 7, 4); + WaitUntilStatus(0x156e0404, 0, 7, 4); + WaitUntilStatus(0x156e0404, 20, 7, 4); + + //G2D + blOutp32(0x12460600, 0x00000001); + blOutp32(0x12460200, 0x00000011); + WaitUntilStatus(0x12460400, 0, 7, 4); + WaitUntilStatus(0x12460400, 4, 7, 4); + + //GSCL + blOutp32(0x150d0600, 0x00000003); + blOutp32(0x13cf0200, 0x00000011); + WaitUntilStatus(0x13cf0400, 0, 7, 4); + WaitUntilStatus(0x13cf0400, 4, 7, 4); + + //MSCL + blOutp32(0x150d0600, 0x00000001); + blOutp32(0x150d0200, 0x00000011); + WaitUntilStatus(0x150d0400, 4, 7, 4); + WaitUntilStatus(0x150d0400, 0, 7, 4); + + //HEVC + blOutp32(0x14f80600, 0x00000003); + blOutp32(0x14f80200, 0x00000001); + WaitUntilStatus(0x14f80400, 0, 7, 4); + + + //MFC0 + blOutp32(0x15280600, 0x00000003); + blOutp32(0x15280200, 0x00000001); + WaitUntilStatus(0x15280400, 0, 7, 4); + + //MFC1 + blOutp32(0x15380600, 0x00000003); + blOutp32(0x15380200, 0x00000001); + WaitUntilStatus(0x15380400, 0, 7, 4); + + EnableDynamicClkGate(); + } + + /* disable UFS related clocks */ + /* CLK_ENABLE_IP_FSYS0 - CLK_UFS_ENABLE, CLK_MPHY_ENABLE */ + blOutp32(0x156e0b00, (Inp32(0x156e0b00) & ~(1 << 14 | 1 << 5))); + /* CLK_ENABLE_ACLK_FSYS0 - ACLK_UFS_ENABLE */ + //blOutp32(0x156e0800, (Inp32(0x156e0800) & ~(1 << 5))); + /* CLK_ENABLE_IP_CPIF0 - CLK_UFS_MPHY_ENABLE */ + blOutp32(0x10fc0b00, (Inp32(0x10fc0b00) & ~(1 << 16))); + /* CLK_ENABLE_SCLK_TOP_FSYS - SCLK_UFSUNIPRO_ENABLE */ + blOutp32(0x10030a10, (Inp32(0x10030a10) & ~(1 << 3))); + /* CLK_ENABLE_SCLK_FSYS */ + blOutp32(0x156e0a00, (Inp32(0x156e0a00) & ~(0xf << 13 | 0x2 << 5))); + /* CLK_ENABLE_SCLK_CPIF - SCLK_UFS_MPHY_ENABLE */ + blOutp32(0x10fc0a00, (Inp32(0x10fc0a00) & ~(1 << 4))); + /* CLK_MUX_ENABLE_FSYS0 - SCLK_UFS_PLL_USER_ENABLE */ + blOutp32(0x156e0300, (Inp32(0x156e0300) & ~(1 << 4))); + /* CLK_MUX_ENABLE_FSYS1 - SCLK_UFSUNIPRO_USER_ENABLE */ + blOutp32(0x156e0304, (Inp32(0x156e0304) & ~(1 << 24))); + /* CLK_MUX_ENABLE_FSYS3 */ + blOutp32(0x156e030c, (Inp32(0x156e030c) & ~(1 << 4 | 1 << 8 | 1 << 12 | 1 << 16))); + /* CLK_MUX_ENABLE_CPIF1 - PHYCLK_UFS_MPHY_TO_LLI_USER_ENABLE */ + blOutp32(0x10fc0304, (Inp32(0x10fc0304) & ~(1 << 0))); + + /* disable LLI related clocks */ + /* CLK_ENABLE_IP_CPIF0 */ + blOutp32(0x10fc0b00, (Inp32(0x10fc0b00) & ~0xfff)); +} + +void EnableDynamicClkGate(void) +{ + // PowerPro dynamic clock gating + blOutp32(0x13b80500, 0x00000000); // DISP + blOutp32(0x124c0500, 0x00000000); // G2D + blOutp32(0x13cb0500, 0x00000000); // GSCL + blOutp32(0x150e0500, 0x00000000); // MSCL + blOutp32(0x120f0500, 0x00000000); // CAM0 + blOutp32(0x145f0500, 0x00000000); // CAM1 + blOutp32(0x146f0500, 0x00000000); // ISP + + // Bus dynamic clock gating + blOutp32(0x11910200, 0x00000001); // KFC_NOC + blOutp32(0x11810200, 0x00000001); // EGL_NOC + blOutp32(0x11810204, 0x00000001); // EGL_XIU + blOutp32(0x114f0200, 0x00000003); // AUD_NOC + blOutp32(0x114f0204, 0x00000001); // AUD_XIU + blOutp32(0x14830200, 0x00000005); // BUS1_NOC + blOutp32(0x13430200, 0x00000003); // BUS2_NOC + blOutp32(0x120f0200, 0x00000003); // CAM0_NOC + blOutp32(0x120f0204, 0x00000003); // CAM0_XIU + blOutp32(0x120f0208, 0x00000007); // CAM0_AXI_US + blOutp32(0x120f020c, 0x000007ff); // CAM0_XIU_ASYNC + blOutp32(0x145f0200, 0x00000003); // CAM1_NOC + blOutp32(0x145f0204, 0x00000003); // CAM1_XIU_TOP + blOutp32(0x145f0208, 0x00000007); // CAM1_AXI_US + blOutp32(0x145f020c, 0x00000fff); // CAM1_XIU_ASYNC + blOutp32(0x10fd0200, 0x0000000f); // CPIF_NOC + blOutp32(0x10fd0204, 0x00000003); // CPIF_XIU_TOP + blOutp32(0x10fd0208, 0x00000003); // CPIF_AXI_US + blOutp32(0x13b80200, 0x00000007); // DISP_NOC + blOutp32(0x13b80204, 0x0000000f); // DISP_XIU_TOP + blOutp32(0x13b80208, 0x0000001f); // DISP_AXI_US + blOutp32(0x156f0200, 0x00000003); // FSYS_NOC + blOutp32(0x156f0204, 0x00000003); // FSYS_XIU_TOP + blOutp32(0x156f0208, 0x00000007); // FSYS_AXI_US + blOutp32(0x124c0200, 0x00000003); // G2D_NOC + blOutp32(0x124c0204, 0x00000001); // G2D_XIU_TOP + blOutp32(0x124c0208, 0x00000001); // G2D_AXI_US + blOutp32(0x124c020c, 0x00000001); // G2D_XIU_ASYNC + blOutp32(0x13cb0200, 0x00000007); // GSCL_NOC + blOutp32(0x13cb0204, 0x00000001); // GSCL_XIU_TOP + blOutp32(0x14fa0200, 0x00000003); // HEVC_NOC + blOutp32(0x14fa0204, 0x00000001); // HEVC_XIU_TOP + blOutp32(0x11050200, 0x00000001); // IMEM_NOC + blOutp32(0x11050204, 0x00000003); // IMEM_XIU_TOP + blOutp32(0x11050208, 0x00000001); // IMEM_AXI_US + blOutp32(0x1105020c, 0x00000001); // IMEM_XIU_ASYNC + blOutp32(0x146f0200, 0x00000001); // ISP_NOC + blOutp32(0x146f0204, 0x00000003); // ISP_XIU_TOP + blOutp32(0x146f0208, 0x00000007); // ISP_AXI_US + blOutp32(0x146f020c, 0x0000007f); // ISP_ASYNC + blOutp32(0x152a0200, 0x00000003); // MFC0_NOC + blOutp32(0x152a0204, 0x00000001); // MFC0_XIU_TOP + blOutp32(0x153a0200, 0x00000003); // MFC1_NOC + blOutp32(0x153a0204, 0x00000001); // MFC1_XIU_TOP + blOutp32(0x105e0200, 0x00000012); // MIF_NOC + blOutp32(0x105e0204, 0x00000001); // MIF_XIU_TOP + blOutp32(0x105e0208, 0x00000002); // MIF_AXI_US + blOutp32(0x105e020c, 0x00001ffe); // MIF_XIU_ASYNC + blOutp32(0x150e0200, 0x00000003); // MSCL_NOC + blOutp32(0x150e0204, 0x00000001); // MSCL_XIU_TOP + blOutp32(0x14c60200, 0x00000001); // PERIC_NOC + blOutp32(0x10050200, 0x00000001); // PERIS_NOC +} +#endif + +void CLKOUT_Disable (void) +{ + /* CLKOUT disable */ + blOutp32(0x14AA0c00, 0x1f); /* G3D */ + blOutp32(0x105B0c00, 0x1f); /* MIF */ + blOutp32(0x10FC0c00, 0x1f); /* CPIF */ + blOutp32(0x13B90c00, 0x1f); /* DISP */ + blOutp32(0x10030c00, 0x1f); /* TOP */ + blOutp32(0x11800c00, 0x1f); /* EGL */ + blOutp32(0x11900c00, 0x1f); /* KFC */ +} + +void system_clock_init (void) +{ + unsigned int wakeup_stat; + + wakeup_stat = readl(EXYNOS5430_POWER_WAKEUP_STAT); + wakeup_stat &= WAKEUP_MASK; + + if (wakeup_stat) + InitCmuForBl(0, 800, 800, 800); + else { + InitCmuForBl(1, 500, 800, 800); + CLKOUT_Disable(); + } +} diff --git a/board/samsung/xyref5430/dmc_init.c b/board/samsung/xyref5430/dmc_init.c new file mode 100644 index 000000000..259c6af11 --- /dev/null +++ b/board/samsung/xyref5430/dmc_init.c @@ -0,0 +1,968 @@ +/* + * Memory setup for XYREF5430 board based on EXYNOS5430 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/io.h> +#include <asm/arch/dmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/cpu.h> +#include <asm/arch/smc.h> +#include <asm/arch/pmu.h> +#include "setup.h" + +#define Outp32(addr, data) (*(volatile u32 *)(addr) = (data)) +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define GetBits(uAddr, uBaseBit, uMaskValue) \ + ((Inp32(uAddr)>>(uBaseBit))&(uMaskValue)) +#define GetPOPType() (GetBits(0x10000004, 4, 0x3)) +#undef FALSE +#undef TRUE + +#define FALSE 0 +#define TRUE 1 +#define false 0 +#define true 1 + +#define PWMTIMER_BASE (0x14DD0000) //0x12D90000 + +#define rTCFG0 (PWMTIMER_BASE+0x00) +#define rTCFG1 (PWMTIMER_BASE+0x04) +#define rTCON (PWMTIMER_BASE+0x08) +#define rTCNTB0 (PWMTIMER_BASE+0x0C) +#define rTCMPB0 (PWMTIMER_BASE+0x10) +#define rTCNTO0 (PWMTIMER_BASE+0x14) +#define rTINT_CSTAT (PWMTIMER_BASE+0x44) + + + + + +void InitMemClk(u32 uMemclk); + +//---------------------------------------------------------------------------- +// +//- DMC Initialzation Script for LPDDR3 +// +//- Copyright 2013 by Samsung Electronics. All rights reserved. +// +//---------------------------------------------------------------------------- + +static void StartTimer0(void) +{ + u32 uTimer=0; + u32 uTemp0,uTemp1; + u32 uEnInt=0; + u32 uDivider=0; + u32 uDzlen=0; + u32 uPrescaler=66; //- Silicon : uPrescaler=66 / FPGA : uPrescaler=24 + u32 uEnDz=0; + u32 uAutoreload=1; + u32 uEnInverter=0; + u32 uTCNTB=0xffffffff; + u32 uTCMPB=(u32)(0xffffffff/2); + + { + uTemp0 = Inp32(rTCFG1); // 1 changed into 0xf; dohyun kim 090211 + uTemp0 = (uTemp0 & (~ (0xf << 4*uTimer) )) | (uDivider<<4*uTimer); + // TCFG1 init. selected MUX 0~4, select 1/1~1/16 + + Outp32(rTCFG1,uTemp0); + + uTemp0 = Inp32(rTINT_CSTAT); + uTemp0 = (uTemp0 & (~(1<<uTimer)))|(uEnInt<<(uTimer)); + // selected timer disable, selected timer enable or diable. + Outp32(rTINT_CSTAT,uTemp0); + } + + { + uTemp0 = Inp32(rTCON); + uTemp0 = uTemp0 & (0xfffffffe); + Outp32(rTCON, uTemp0); // Timer0 stop + + uTemp0 = Inp32(rTCFG0); + uTemp0 = (uTemp0 & (~(0xff00ff))) | ((uPrescaler-1)<<0) |(uDzlen<<16); + // init. except prescaler 1 value, set the Prescaler 0 value, set the dead zone length. + Outp32(rTCFG0, uTemp0); + + Outp32(rTCNTB0, uTCNTB); + Outp32(rTCMPB0, uTCMPB); + + + uTemp1 = Inp32(rTCON); + uTemp1 = (uTemp1 & (~(0x1f))) |(uEnDz<<4)|(uAutoreload<<3)|(uEnInverter<<2)|(1<<1)|(0<<0); + // set all zero in the Tiemr 0 con., Deadzone En or dis, set autoload, set invert, manual uptate, timer stop + Outp32(rTCON, uTemp1); //timer0 manual update + uTemp1 = (uTemp1 & (~(0x1f))) |(uEnDz<<4)|(uAutoreload<<3)|(uEnInverter<<2)|(0<<1)|(1<<0); + // set all zero in the Tiemr 0 con., Deadzone En or dis, set autoload, set invert, manual uptate disable, timer start + Outp32(rTCON, uTemp1); // timer0 start + } +} + +static void PWM_stop(u32 uNum) +{ + u32 uTemp; + + uTemp = Inp32(rTCON); + + if(uNum == 0) + uTemp &= ~(0x1); + else + uTemp &= ~((0x10)<<(uNum*4)); + + Outp32(rTCON,uTemp); +} + +static u32 StopTimer0(void) +{ + u32 uVal = 0; + + PWM_stop(0); + + uVal = Inp32(rTCNTO0); + uVal = 0xffffffff - uVal; + + return uVal; +} + +#if 0 +void DMC_Delay(int msec) +{ + volatile u32 i; + for(;msec > 0; msec--); + for(i=0; i<1000; i++) ; +} +#else +void DMC_Delay(u32 usec) +{ + u32 uElapsedTime, uVal; + + StartTimer0(); + + while(1){ + uElapsedTime = Inp32(rTCNTO0); + uElapsedTime = 0xffffffff - uElapsedTime; + + if(uElapsedTime > usec){ + StopTimer0(); + break; + } + } +} +#endif + + + +void Gate_CLKM_PHY(int gate_en) +{ + u32 temp; + + temp=Inp32(0x105B0800); + + if(gate_en){ + temp=temp&~(0x3<<16); + Outp32(0x105B0800,temp); + } + else{ + temp=temp&~(0x3<<16); + temp|=(0x3<<16); + Outp32(0x105B0800,temp); + } +} + +int Check_MRStatus(u32 ch, u32 cs) +{ + u32 mr0; + u32 resp; + u32 loop_cnt=1000; + int re=true; + + if(cs==0) mr0=0x09000000; + else mr0=0x09100000; + + if(ch==0){ + do{ + Outp32(0x10400010, mr0); + resp=Inp32(0x10400054)&0x1; + loop_cnt--; + + if(loop_cnt==0){ + DMC_Delay(10); //- Although DAI is not completed during polling it, end the loop when 10us delay is time over. + re=false; + break; + } + }while(resp); + } + else{ + do{ + Outp32(0x10440010, mr0); + resp=Inp32(0x10440054)&0x1; + loop_cnt--; + + if(loop_cnt==0){ + DMC_Delay(10); //- Although DAI is not completed during polling it, end the loop when 10us delay is time over. + re=false; + break; + } + }while(resp); + } + + return re; +} + +int Issuing_Basic_DirectCMD(void) +{ + int re[]={true,true,true,true}; + int result=true; + u32 ch_offset; + u32 cs_offset; + u32 ch,cs; + u32 sw_n_warm_reset; + + sw_n_warm_reset=(Inp32(0x105C0404)>>28)&0x3; //- RESETSTATE(0x105C_0404) : [29]=SWRST, [28]=WRESET + + for(ch=0;ch<2;ch++){ + if(ch==0) ch_offset=0; + else ch_offset=0x40000; + + for(cs=0;cs<2;cs++){ + if(cs==0) cs_offset=0; + else cs_offset=0x100000; + + if(sw_n_warm_reset){ + Outp32( 0x10400010 + ch_offset, (0x08000000)|(cs_offset)); //- Self Refresh Exit + Outp32( 0x10400010 + ch_offset, (0x00000870)|(cs_offset)); //- MR2 (MA[7:0]=0x02), RL/WL , RL&WL=OP[3:0]=0xC(RL/WL=14/8,for 825MHz), nWRE=OP[4]=1 (WR > 9(667MHz)) + Outp32( 0x10400010 + ch_offset, (0x0000060C)|(cs_offset)); //- MR1 (MA[7:0]=0x01), nWR , BL=OP[2:0]=0x3, nWR=OP[7:5]=4 (for 825MHz) + } + else{ + Outp32( 0x10400010 + ch_offset, (0x07000000)|(cs_offset)); //- NOP + DMC_Delay(200); //- Wait for 200us + Outp32( 0x10400010 + ch_offset, (0x00071C00)|(cs_offset)); //- MR63(MA[7:0]=0x3F), Reset + DMC_Delay(1); //- Wait for 1us + re[(ch<<1)|(cs)]=Check_MRStatus(ch,cs); //- Check if DAI is complete. + Outp32( 0x10400010 + ch_offset, (0x00010BFC)|(cs_offset)); //- MR10(MA[7:0]=0x0A), Calibration, OP[7:0]=0xFF(Calibration command after initialization) + DMC_Delay(1); //- Wait for 1us + Outp32( 0x10400010 + ch_offset, (0x00000870)|(cs_offset)); //- MR2 (MA[7:0]=0x02), RL/WL , RL&WL=OP[3:0]=0xC(RL/WL=14/8,for 825MHz), nWRE=OP[4]=1 (WR > 9(667MHz)) + Outp32( 0x10400010 + ch_offset, (0x0000060C)|(cs_offset)); //- MR1 (MA[7:0]=0x01), nWR , BL=OP[2:0]=0x3, nWR=OP[7:5]=4 (for 825MHz) + } + + } + } + + result=(re[3])|(re[2])|(re[1])|(re[0]); + + return result; +} + +void Issuing_Optinal_DirectCMD(u32 mem_ds, u32 odt) +{ + u32 ch_offset; + u32 cs_offset; + u32 ch,cs; + u32 mr3,mr11; + + //*** Setting Memory Driver Strength & ODT Termination *** + //--------------------------------------------------------------- + //- DS : 0x1 : 34.3 ohm typical pull-down/pull-up + //- DS : 0x2 : 40 ohm typical pull-down/pull-up (default) + //- DS : 0x3 : 48 ohm typical pull-down/pull-up + //- DS : 0x9 : 34.3 ohm typical pull-down/40 ohm typical pull-up + //- DS : 0xA : 40 ohm typical pull-down/48 ohm typical pull-up + //- DS : 0xB : 34.3 ohm typical pull-down/48 ohm typical pull-up + + //- ODT Term : 0x0 : Disable (disable) + //- ODT Term : 0x1 : RZQ/4(60 ohm, for 933MHz / 1066MHz) + //- ODT Term : 0x2 : RZQ/2(120 ohm) + //- ODT Term : 0x3 : RZQ/1(240 ohm) + //--------------------------------------------------------------- + //- Selection of Memory Option : DS -> 0x2, ODT Termination -> 0x0 + + //* mr3 : I/O configuration + if (mem_ds==0x1) mr3=0x00000C04; // 34.3 ohm typical pull-down/pull-up + else if (mem_ds==0x2) mr3=0x00000C08; // 40 ohm typical pull-down/pull-up (default) + else if (mem_ds==0x3) mr3=0x00000C0C; // 48 ohm typical pull-down/pull-up + else if (mem_ds==0x9) mr3=0x00000C24; // 34.3 ohm typical pull-down/40 ohm typical pull-up + else if (mem_ds==0xA) mr3=0x00000C28; // 40 ohm typical pull-down/48 ohm typical pull-up + else if (mem_ds==0xB) mr3=0x00000C2C; // 34.3 ohm typical pull-down/48 ohm typical pull-up + else mr3=0x00000C08; // 40 ohm typical pull-down/pull-up (default) + + //* on die termination + if (odt==0) mr11=0x00010C00; // ODT Disable + else if (odt==1) mr11=0x00010C04; // RZQ/4 + else if (odt==2) mr11=0x00010C08; // RZQ/2 + else if (odt==3) mr11=0x00010C0C; // RZQ/1 + else mr11=0x00010C00; // ODT Disable + + for(ch=0;ch<2;ch++){ + if(ch==0) ch_offset=0; + else ch_offset=0x40000; + + for(cs=0;cs<2;cs++){ + if(cs==0) cs_offset=0; + else cs_offset=0x100000; + + Outp32(0x10400010 + ch_offset, (mr3)|(cs_offset) ); //- CHx, CSx mr3 command + Outp32(0x10400010 + ch_offset, (mr11)|(cs_offset) ); //- CHx, CSx mr11 command + } + } +} + +int Init_Mem(u32 mem_ds, u32 odt) +{ + int re; + u32 sw_n_warm_reset; + + sw_n_warm_reset=(Inp32(0x105C0404)>>28)&0x3; //- RESETSTATE(0x105C_0404) : [29]=SWRST, [28]=WRESET + + //*** Setting Memory Driver Strength & ODT Termination *** + //--------------------------------------------------------------- + //- DS : 0x1 : 34.3 ohm typical pull-down/pull-up + //- DS : 0x2 : 40 ohm typical pull-down/pull-up (default) + //- DS : 0x3 : 48 ohm typical pull-down/pull-up + //- DS : 0x9 : 34.3 ohm typical pull-down/40 ohm typical pull-up + //- DS : 0xA : 40 ohm typical pull-down/48 ohm typical pull-up + //- DS : 0xB : 34.3 ohm typical pull-down/48 ohm typical pull-up + + //- ODT Term : 0x0 : Disable (disable) + //- ODT Term : 0x1 : RZQ/4(60 ohm, for 933MHz / 1066MHz) + //- ODT Term : 0x2 : RZQ/2(120 ohm) + //- ODT Term : 0x3 : RZQ/1(240 ohm) + //--------------------------------------------------------------- + //- Selection of Memory Option : DS -> 0x2, ODT Termination -> 0x0 + + re=Issuing_Basic_DirectCMD(); //- Issuing DirectCMD for CHx, CSx + if (!sw_n_warm_reset) + Issuing_Optinal_DirectCMD(mem_ds,odt); //- Setting Memory Driver Strength(MR3) & ODT Termination(MR11) + + return re; +} + +int DMCInit_For_LPDDR3(int initial, int nEnableForce, u32 uPopOption) +{ + u32 lock_val; + int re=true; +#if defined(CONFIG_SMC_CMD) + reg_arr_t reg_arr; +#endif + //u32 sw_n_warm_reset; + u32 loop_cnt=0; + + //Assert(uPopOption<=1); //- MCP Size : 0 --> 2GB, 1 --> : 3GB + + //sw_n_warm_reset=(Inp32(0x105C0404)>>28)&0x3; //- RESETSTATE(0x105C_0404) : [29]=SWRST, [28]=WRESET + + if(initial == true) + { + InitMemClk(50); + } + + //----------------------------------------------------------------------- + //--- PHASE 1 : Initializing DREX --- + //----------------------------------------------------------------------- + Outp32( 0x10400310, 0x00000021 ); //- DREX CH0 : PIPELINE_CONFIG reg, dq_pipeline[6:4]=2, ca_pipeline[6:4]=1 + Outp32( 0x10440310, 0x00000021 ); //- DREX CH1 : PIPELINE_CONFIG reg, dq_pipeline[6:4]=2, ca_pipeline[6:4]=1 + + Outp32( 0x10400000+0x0014, 0x0 ); //- DMC.PrechConfig0.tp_en=0x0, port_policy=0x0 + Outp32( 0x10400000+0x001C, 0xFFFFFFFF ); //- DMC.PrechConfig1 : tp_cnt3=0xFF, tp_cnt2=0xFF, tp_cnt1=0xFF, tp_cnt0=0xFF + Outp32( 0x10440000+0x0014, 0x0 ); //- DMC.PrechConfig0.tp_en=0x0, port_policy=0x0 + Outp32( 0x10440000+0x001C, 0xFFFFFFFF ); //- DMC.PrechConfig1 : tp_cnt3=0xFF, tp_cnt2=0xFF, tp_cnt1=0xFF, tp_cnt0=0xFF + + Outp32( 0x10400000+0x0004, 0x202600 ); //- set dynamic powe down to OFF mode for CH0. + Outp32( 0x10440000+0x0004, 0x202600 ); //- set dynamic powe down to OFF mode for CH1. + + Outp32( 0x10400000+0x0018, 0x3000 ); //- CH0. DMC.PHYCONTROL0.sl_dll_dyn_con=0x0 + Outp32( 0x10440000+0x0018, 0x3000 ); //- CH1. DMC.PHYCONTROL0.sl_dll_dyn_con=0x0 + + Outp32( 0x10400000+0x0000, 0xFFF1100 ); //- CH0. DMC.PHYCONTROL.io_pd_con=0x0, DMC.CONCONTROL.update_mode[3]=0, aref disabled + Outp32( 0x10440000+0x0000, 0xFFF1100 ); //- CH1. DMC.PHYCONTROL.io_pd_con=0x0, DMC.CONCONTROL.update_mode[3]=0, aref disabled + + if(initial == true) + { + #if 0 + Outp32( 0x10420020, 0x70707070 ); //- PHY0 : OFFSETR_CON0 : offsetr3=0x70,offsetr2=0x70,offsetr1=0x70,offsetr0=0x70 + Outp32( 0x10420030, 0x70707070 ); //- PHY0 : OFFSETW_CON0 : offsetw3=0x7F,offsetw2=0x7F,offsetw1=0x7F,offsetw0=0x7F + Outp32( 0x10420050, 0x00000070 ); //- PHY0 OFFSETD_CON0(0x50).upd_mode=0(PHY-Initiated Update Mode), offsetd=0x18 + Outp32( 0x10460020, 0x70707070 ); //- PHY1 : OFFSETR_CON0 : offsetr3=0x70,offsetr2=0x70,offsetr1=0x70,offsetr0=0x70 + Outp32( 0x10460030, 0x70707070 ); //- PHY1 : OFFSETW_CON0 : offsetw3=0x7F,offsetw2=0x7F,offsetw1=0x7F,offsetw0=0x7F + Outp32( 0x10460050, 0x00000070 ); //- PHY1 OFFSETD_CON0(0x50).upd_mode=0(PHY-Initiated Update Mode), offsetd=0x18 + + Outp32( 0x10400000, 0xFFF1100 ); //- DREX0 : CONCONTROL.update_mode[3]=0 + Outp32( 0x10440000, 0xFFF1100 ); //- DREX1 : CONCONTROL.update_mode[3]=0 + + //- Update DLL Information for CH0 + Outp32( 0x10420000+0x0050, 0x1000070 ); //- PHY0 ctrl_resync=1 + Outp32( 0x10420000+0x0050, 0x70 ); //- PHY0 ctrl_resync=0 + //- Update DLL Information for CH1 + Outp32( 0x10460000+0x0050, 0x1000070 ); //- PHY1 ctrl_resync=1 + Outp32( 0x10460000+0x0050, 0x70 ); //- PHY1 ctrl_resync=0 + #endif + } + + //-- PHY CH0,1 : GNR_CON0 reg, ctrl_upd_mode[31:30]=0x1, ctrl_upd_range[29:28]=0x0, ctrl_dfdqs[26]=0x1, ctrl_ddr_mode[25:24]=0x3, ctrl_fnc_fb[23:21]=0x0 + //- ctrl_wrlat[20:16]=0x7(WL+1), ctrl_bstlen[12:8]=0x8, ctrl_ckdis[6]=0x0, ctrl_cmosrcv[5]=0x0, ctrl_rdlat[4:0]=0xC + Outp32( 0x10420000, 0x4709080E ); //- PHY0 : GNR_CON0, for 825MHz on SILICON + Outp32( 0x10460000, 0x4709080E ); //- PHY1 : GNR_CON0, for 825MHz on SILICON + + Outp32( 0x10420018, 0x0000000f ); //- PHY0 : LP_CON0(0x18), Active HIGH signal to pull-up or down PDQS/NDQS signals. + Outp32( 0x10460018, 0x0000000f ); //- PHY1 : LP_CON0(0x18), Active HIGH signal to pull-up or down PDQS/NDQS signals. + + Outp32( 0x10420064, 0x0000000E ); //- PHY0 : LP_DDR_CON3.cmd_read[12:0]=0x000E (LPDDR2/LPDDR3) + Outp32( 0x10460064, 0x0000000E ); //- PHY1 : LP_DDR_CON3.cmd_read[12:0]=0x000E (LPDDR2/LPDDR3) + + Outp32( 0x10420068, 0x0000000F ); //- PHY0 : LP_DDR_CON4.cmd_default[12:0]=0x000F (LPDDR2/LPDDR3) + Outp32( 0x10460068, 0x0000000F ); //- PHY1 : LP_DDR_CON4.cmd_default[12:0]=0x000F (LPDDR2/LPDDR3) + + //- Execute ZQ calibration + // Note : Don't execute ZQ calibration for PHY0 + // Note : It needs to execute ZQ calibration for only PHY1 + Outp32( 0x10420000+0x00C0, 0xE0C7304 ); //- Set PHY0.ZQ_CON0.zq_mode_dds[26:24]=0x6, PHY0.ZQ_CON0.zq_manual_mode[3:2]=1 + + Outp32( 0x10460000+0x00C0, 0xE0C7304 ); //- Set PHY1.ZQ_CON0.zq_mode_dds[26:24]=0x6, PHY1.ZQ_CON0.zq_manual_mode[3:2]=1 + Outp32( 0x10460000+0x00C0, 0xE0C7306 ); //- Set PHY1.ZQ_CON0.zq_manual_str[1]=1 + do{ + if(loop_cnt==100000){ //- Just Delay + loop_cnt=0; + break; + } + else loop_cnt++; + }while( ( Inp32( 0x10460000+0x00C4 ) & 0x1 ) != 0x1 ); //- Wait for PHY1.ZQ_CON1.zq_done[0] + Outp32( 0x10460000+0x00C0, 0xE0C7304 ); //- Set PHY1.ZQ_CON0.zq_manual_str[1]=0 + + //- Update DLL Information for CH0 + Outp32( 0x10420000+0x0050, 0x1000000 ); //- PHY0 ctrl_resync=1 + Outp32( 0x10420000+0x0050, 0x0 ); //- PHY0 ctrl_resync=0 + //- Update DLL Information for CH1 + Outp32( 0x10460000+0x0050, 0x1000000 ); //- PHY1 ctrl_resync=1 + Outp32( 0x10460000+0x0050, 0x0 ); //- PHY1 ctrl_resync=0 + + Outp32( 0x10420000+0x00C4, 0x3f0000 ); //- Set PHY0.ZQ_CON1.zq_vref[21:16]=0x20 + Outp32( 0x10460000+0x00C4, 0x3f0000 ); //- Set PHY1.ZQ_CON1.zq_vref[21:16]=0x20 + Outp32( 0x1042000c, 0x42101000 ); //- PHY0 : CAL_CON2(0x0C), ctrl_shgate=1 + Outp32( 0x1046000c, 0x42101000 ); //- PHY1 : CAL_CON2(0x0C), ctrl_shgate=1 + + + //-Setting ODT feature in DREX side for Memory ODT(LPDDR3) + + if(initial == true) + { + #if 0 + //- Disable Off after forcing max lock_value(0x1FF) + Outp32( 0x10420000+0x00B0, 0x1010FFF0 ); //- PHY0. ctrl_force[15:7]=0x1FF + Outp32( 0x10420000+0x00B0, 0x1010FFD0 ); //- disable ctrl_dll_on & ctrl_start for PHY0. + Outp32( 0x10460000+0x00B0, 0x1010FFF0 ); //- PHY1. ctrl_force[15:7]=0x1FF + Outp32( 0x10460000+0x00B0, 0x1010FFD0 ); //- disable ctrl_dll_on & ctrl_start for PHY1. + + //- Update DLL Information for CH0 + Outp32( 0x10420000+0x0050, 0x1000070 ); //- PHY0 ctrl_resync=1 + Outp32( 0x10420000+0x0050, 0x70 ); //- PHY0 ctrl_resync=0 + //- Update DLL Information for CH1 + Outp32( 0x10460000+0x0050, 0x1000070 ); //- PHY1 ctrl_resync=1 + Outp32( 0x10460000+0x0050, 0x70 ); //- PHY1 ctrl_resync=0 + #endif + } + Outp32( 0x10400000+0x0000, 0xFFF1100 ); //- set CA Swap mode for CH0. + Outp32( 0x10440000+0x0000, 0xFFF1100 ); //- set CA Swap mode for CH1. + + Outp32( 0x10400000+0x0018, 0x3080 ); //- Set Resync Enable During PAUSE handshaking for CH0. + Outp32( 0x10440000+0x0018, 0x3080 ); //- Set Resync Enable During PAUSE handshaking for CH1. + + Outp32( 0x10400000+0x0000, 0x1FFF1100 ); //- assert dfi_init_start for CH0 + loop_cnt=0; + do{ + if(loop_cnt==100000){ //- Just Delay + loop_cnt=0; + break; + } + else loop_cnt++; + }while( ( Inp32( 0x10400000+0x0040 ) & 0x8 ) != 0x8 ); //- Wait for DMC.dfi_init_complete_ch0 + Outp32( 0x10400000+0x0000, 0xFFF1100 ); //- deassert dfi_init_start for CH0 + + Outp32( 0x10440000+0x0000, 0x1FFF1100 ); //- assert dfi_init_start for CH1 + loop_cnt=0; + do{ + if(loop_cnt==100000){ //- Just Delay + loop_cnt=0; + break; + } + else loop_cnt++; + }while( ( Inp32( 0x10440000+0x0040 ) & 0x8 ) != 0x8 ); //- Wait for DMC.dfi_init_complete_ch1 + Outp32( 0x10440000+0x0000, 0xFFF1100 ); //- deassert dfi_init_start for CH1 + + //- Update DLL Information for CH0 + Outp32( 0x10420000+0x0050, 0x1000000 ); //- PHY0 ctrl_resync=1 + Outp32( 0x10420000+0x0050, 0x0 ); //- PHY0 ctrl_resync=0 + //- Update DLL Information for CH1 + Outp32( 0x10460000+0x0050, 0x1000000 ); //- PHY1 ctrl_resync=1 + Outp32( 0x10460000+0x0050, 0x0 ); //- PHY1 ctrl_resync=0 + + Outp32( 0x10400000+0x0018, 0x5080 ); //- Set Recovery Time From PHY clock Gate for CH0. + Outp32( 0x10440000+0x0018, 0x5080 ); //- Set Recovery Time From PHY clock Gate for CH1. + + //Outp32( 0x10400000+0x0018, 0x5084 ); //- Drive Memory DQ Signals Enable for CH0. + //Outp32( 0x10440000+0x0018, 0x5084 ); //- Drive Memory DQ Signals Enable for CH1. + + Outp32( 0x10400004, 0x28312700 ); //- DREX0 : num_chunk[19:18]=0x0 (1 chunk enable) + Outp32( 0x10440004, 0x28312700 ); //- DREX1 : num_chunk[19:18]=0x0 (1 chunk enable) + + //*** Setting MemConfig0/1 : Interleaving/CHIP_MAP/COL/ROW/BANK bits *** + //------------------------------------------------------------------------- + //- Address Map : Split Column Interleaving(default) + //- bank_lsb : LSB of Bank Bit Position in Complex Interleaved Mapping + //- 0x0 = bit position [8](column low size = 256B) + //- 0x1 = bit position [9](column low size = 512B) + //- 0x2 = bit position [10](column low size = 1KB) + //- 0x3 = bit position [11](column low size = 2KB) + //- 0x4 = bit position [12](column low size = 4KB) + //- 0x5 = bit position [13](column low size = 8KB) + + //- If bit_sel_en=1 (Randomized Interleaving Enable) + //- bit_sel : Bit Selection for Randomized Interleaved Address mapping + //- 0x0: bit position = [14:12] (if rank_inter_en is enabled, [15:12]) + //- 0x1: bit position = [20:18] (if rank_inter_en is enabled, [21:18]) + //- 0x2: bit position = [24:22] (if rank_inter_en is enabled, [25:22]) + //- 0x3: bit position = [26:24] (if rank_inter_en is enabled, [27:24]) + //------------------------------------------------------------------------- + #if 1 + if(uPopOption==1) + { +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = 0x10410f10; + reg_arr.set0.val = 0x462333; + reg_arr.set1.addr = 0x10410f14; + reg_arr.set1.val = 0x462333; + reg_arr.set4.addr = 0x10450f10; + reg_arr.set4.val = 0x462333; + reg_arr.set5.addr = 0x10450f14; + reg_arr.set5.val = 0x462333; + reg_arr.set2.addr = 0x10410f00; + reg_arr.set2.val = 0x00010006; + reg_arr.set6.addr = 0x10450f00; + reg_arr.set6.val = 0x00010006; + reg_arr.set3.addr = 0x10410f20; + reg_arr.set3.val = 0x00000002; + reg_arr.set7.addr = 0x10450f20; + reg_arr.set7.val = 0x00000002; + set_secure_reg((u32)®_arr, 8); +#else + Outp32( 0x10410000+0x0f10, 0x462333 ); //- CH0. MemConfig0 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + Outp32( 0x10410000+0x0f14, 0x462333 ); //- CH0. MemConfig1 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + Outp32( 0x10450000+0x0f10, 0x462333 ); //- CH1. MemConfig0 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + Outp32( 0x10450000+0x0f14, 0x462333 ); //- CH1. MemConfig1 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + + Outp32( 0x10410f00, 0x00010006 ); //- DREX0 chunk_start[23:16]=0x1 means that chunk base is 0x2(0x20000000), chunk_end[7:0]=0x6 means that chunk base is 0xD(0xD0000000) + Outp32( 0x10450f00, 0x00010006 ); //- DREX1 chunk_start[23:16]=0x1 means that chunk base is 0x2(0x20000000), chunk_end[7:0]=0x6 means that chunk base is 0xD(0xD0000000) + + Outp32( 0x10410f20, 0x00000002 ); //- DREX0 chip0_size[7:0]=0x2 (chip size is 768MB) + Outp32( 0x10450f20, 0x00000002 ); //- DREX1 chip0_size[7:0]=0x2 (chip size is 768MB) +#endif + Outp32( 0x10400020, 0x00002626 ); //- DREX0 : ACLK/CCLK=400MHz, CLK2X=825MHz(on SILICON), t_rfcpb1[13:8]=60ns/2.5ns=24(0x18)(for timing set #1), t_rfcpb0[5:0]=60ns/2.5ns=24(0x18)(for timing set #0) + Outp32( 0x10440020, 0x00002626 ); //- DREX1 : ACLK/CCLK=400MHz, CLK2X=825MHz(on SILICON), t_rfcpb1[13:8]=60ns/2.5ns=24(0x18)(for timing set #1), t_rfcpb0[5:0]=60ns/2.5ns=24(0x18)(for timing set #0) + } + else + { +#if defined(CONFIG_SMC_CMD) + reg_arr.set0.addr = 0x10410f10; + reg_arr.set0.val = 0x462323; + reg_arr.set1.addr = 0x10410f14; + reg_arr.set1.val = 0x462323; + reg_arr.set4.addr = 0x10450f10; + reg_arr.set4.val = 0x462323; + reg_arr.set5.addr = 0x10450f14; + reg_arr.set5.val = 0x462323; + reg_arr.set2.addr = 0x10410f00; + reg_arr.set2.val = 0x00010004; + reg_arr.set6.addr = 0x10450f00; + reg_arr.set6.val = 0x00010004; + reg_arr.set3.addr = 0x10410f20; + reg_arr.set3.val = 0x00000001; + reg_arr.set7.addr = 0x10450f20; + reg_arr.set7.val = 0x00000001; + set_secure_reg((u32)®_arr, 8); +#else + Outp32( 0x10410000+0x0f10, 0x462323 ); //- CH0. MemConfig0 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + Outp32( 0x10410000+0x0f14, 0x462323 ); //- CH0. MemConfig1 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + Outp32( 0x10450000+0x0f10, 0x462323 ); //- CH1. MemConfig0 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + Outp32( 0x10450000+0x0f14, 0x462323 ); //- CH1. MemConfig1 : bank_lsb=0x4, rank_inter_en=0x0, bit_sel_en=0x0, bit_sel=0x2 + + Outp32( 0x10410f00, 0x00010004 ); //- DREX0 chunk_start[23:16]=0x1 means that chunk base is 0x2(0x20000000), chunk_end[7:0]=0x4 means that chunk base is 0x9(0x90000000) + Outp32( 0x10450f00, 0x00010004 ); //- DREX1 chunk_start[23:16]=0x1 means that chunk base is 0x2(0x20000000), chunk_end[7:0]=0x6 means that chunk base is 0x9(0x90000000) + + Outp32( 0x10410f20, 0x00000001 ); //- DREX0 chip0_size[7:0]=0x1 (chip size is 512MB) + Outp32( 0x10450f20, 0x00000001 ); //- DREX1 chip0_size[7:0]=0x1 (chip size is 512MB) +#endif + Outp32( 0x10400020, 0x00001919 ); //- DREX0 : ACLK/CCLK=400MHz, CLK2X=825MHz(on SILICON), t_rfcpb1[13:8]=60ns/2.5ns=24(0x18)(for timing set #1), t_rfcpb0[5:0]=60ns/2.5ns=24(0x18)(for timing set #0) + Outp32( 0x10440020, 0x00001919 ); //- DREX1 : ACLK/CCLK=400MHz, CLK2X=825MHz(on SILICON), t_rfcpb1[13:8]=60ns/2.5ns=24(0x18)(for timing set #1), t_rfcpb0[5:0]=60ns/2.5ns=24(0x18)(for timing set #0) + } + #endif + + Outp32( 0x104000E0, 0x00000000 ); //- DREX0 Timing Parameter Set #0 Enable + Outp32( 0x104400E0, 0x00000000 ); //- DREX1 Timing Parameter Set #0 Enable + + Outp32( 0x10400030, 0x0005002E ); //- DREX0 : rclk=24MHz, t_refipb=0x5, t_refi=0x2E + Outp32( 0x10440030, 0x0005002E ); //- DREX1 : rclk=24MHz, t_refipb=0x5, t_refi=0x2E + + Outp32( 0x10400044, 0x00002270 ); //- DREX0, ETCTIMING, t_mrr[13:12]=0x2(for LPDDR3), t_srr[11:10]=0x2(for WideIO), t_src[7:4]=0x7(for WideIO) + Outp32( 0x10440044, 0x00002270 ); //- DREX1, ETCTIMING, t_mrr[13:12]=0x2(for LPDDR3), t_srr[11:10]=0x2(for WideIO), t_src[7:4]=0x7(for WideIO) + + Outp32( 0x1040004C, 0x00000003 ); //- DREX0, RDFETCH0(timing parameter set #0) + Outp32( 0x1044004C, 0x00000003 ); //- DREX1, RDFETCH0(timing parameter set #0) + + Outp32( 0x10400034, 0x575A9713 ); //- TIMINGROW0 : DREX0, CLK2X=825MHz + Outp32( 0x10440034, 0x575A9713 ); //- TIMINGROW0 : DREX1, CLK2X=825MHz + Outp32( 0x10400038, 0x4740085E ); //- TIMINGDATA0 : DREX0, CLK2X=825MHz + Outp32( 0x10440038, 0x4740085E ); //- TIMINGDATA0 : DREX1, CLK2X=825MHz + Outp32( 0x1040003C, 0x545B0446 ); //- TIMINGPOWER0 : DREX0, CLK2X=825MHz + Outp32( 0x1044003C, 0x545B0446 ); //- TIMINGPOWER0 : DREX1, CLK2X=825MHz + + Outp32( 0x10400058, 0x50000000 ); //- TermControl0 : DREX0, CLK2X=800MHz + Outp32( 0x10440058, 0x50000000 ); //- TermControl0 : DREX1, CLK2X=800MHz + + Outp32( 0x10400050, 0x00000003 ); //- DREX0, RDFETCH1(timing parameter set #1) + Outp32( 0x10440050, 0x00000003 ); //- DREX1, RDFETCH1(timing parameter set #1) + + Outp32( 0x104000E4, 0x575A9713 ); //- TIMINGROW1 : DREX0, CLK2X=825MHz + Outp32( 0x104400E4, 0x575A9713 ); //- TIMINGROW1 : DREX1, CLK2X=825MHz + Outp32( 0x104000E8, 0x4740085E ); //- TIMINGDATA1 : DREX0, CLK2X=825MHz + Outp32( 0x104400E8, 0x4740085E ); //- TIMINGDATA1 : DREX1, CLK2X=825MHz + Outp32( 0x104000EC, 0x545B0446 ); //- TIMINGPOWER1 : DREX0, CLK2X=825MHz + Outp32( 0x104400EC, 0x545B0446 ); //- TIMINGPOWER1 : DREX1, CLK2X=825MHz + + Outp32( 0x1040005C, 0x50000000 ); //- TermControl1 : DREX0, CLK2X=800MHz + Outp32( 0x1044005C, 0x50000000 ); //- TermControl1 : DREX1, CLK2X=800MHz + + #if 0 + Outp32( 0x10400060, 0x00ff4b20 ); //- DREX0 : Setting QOSCONTROL0 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10400068, 0x00ffc0c0 ); //- DREX0 : Setting QOSCONTROL1 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10400070, 0x00ff5d10 ); //- DREX0 : Setting QOSCONTROL2 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10400078, 0x00ffb130 ); //- DREX0 : Setting QOSCONTROL3 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10400080, 0x00ff61f0 ); //- DREX0 : Setting QOSCONTROL4 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10400088, 0x00ff0fc0 ); //- DREX0 : Setting QOSCONTROL5 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10400090, 0x00fff680 ); //- DREX0 : Setting QOSCONTROL6 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10400098, 0x00ff2160 ); //- DREX0 : Setting QOSCONTROL7 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000a0, 0x00ff6dd0 ); //- DREX0 : Setting QOSCONTROL8 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000a8, 0x00ff93c0 ); //- DREX0 : Setting QOSCONTROL9 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000b0, 0x00ff2330 ); //- DREX0 : Setting QOSCONTROL10 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000b8, 0x00fffd60 ); //- DREX0 : Setting QOSCONTROL11 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000c0, 0x00ff48f0 ); //- DREX0 : Setting QOSCONTROL12 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000c8, 0x00ffd750 ); //- DREX0 : Setting QOSCONTROL13 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000d0, 0x00ff4580 ); //- DREX0 : Setting QOSCONTROL14 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104000d8, 0x000f6920 ); //- DREX0 : Setting QOSCONTROL15 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440060, 0x00ff4b20 ); //- DREX1 : Setting QOSCONTROL0 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440068, 0x00ffc0c0 ); //- DREX1 : Setting QOSCONTROL1 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440070, 0x00ff5d10 ); //- DREX1 : Setting QOSCONTROL2 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440078, 0x00ffb130 ); //- DREX1 : Setting QOSCONTROL3 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440080, 0x00ff61f0 ); //- DREX1 : Setting QOSCONTROL4 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440088, 0x00ff0fc0 ); //- DREX1 : Setting QOSCONTROL5 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440090, 0x00fff680 ); //- DREX1 : Setting QOSCONTROL6 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x10440098, 0x00ff2160 ); //- DREX1 : Setting QOSCONTROL7 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400a0, 0x00ff6dd0 ); //- DREX1 : Setting QOSCONTROL8 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400a8, 0x00ff93c0 ); //- DREX1 : Setting QOSCONTROL9 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400b0, 0x00ff2330 ); //- DREX1 : Setting QOSCONTROL10 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400b8, 0x00fffd60 ); //- DREX1 : Setting QOSCONTROL11 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400c0, 0x00ff48f0 ); //- DREX1 : Setting QOSCONTROL12 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400c8, 0x00ffd750 ); //- DREX1 : Setting QOSCONTROL13 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400d0, 0x00ff4580 ); //- DREX1 : Setting QOSCONTROL14 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + Outp32( 0x104400d8, 0x000f6920 ); //- DREX1 : Setting QOSCONTROL15 : [27:16]=cfg_qos_th, [11:0]=cfg_qos + #endif + + Outp32( 0x10400000+0x0100, 0x0 ); //- CH0 brbrsvcontrol + Outp32( 0x10440000+0x0100, 0x0 ); //- CH1 brbrsvcontrol + Outp32( 0x10400000+0x0104, 0x88888888 ); //- CH0 brbrsvconfig + Outp32( 0x10440000+0x0104, 0x88888888 ); //- CH1 brbrsvconfig + + //----------------------------------------------------------------------- + //--- PHASE 2 : Issuing DIRECTCMD, for LPDDR3 @ 0x800 --- + //----------------------------------------------------------------------- + //if((initial == true)&&(!sw_n_warm_reset)) // That means that sleep & wakeup is not , or This is for all reset state + if(initial == true) + { + //*** Setting Memory Driver Strength & ODT Termination *** + //--------------------------------------------------------------- + //- DS : 0x1 : 34.3 ohm typical pull-down/pull-up + //- DS : 0x2 : 40 ohm typical pull-down/pull-up (default) + //- DS : 0x3 : 48 ohm typical pull-down/pull-up + //- DS : 0x9 : 34.3 ohm typical pull-down/40 ohm typical pull-up + //- DS : 0xA : 40 ohm typical pull-down/48 ohm typical pull-up + //- DS : 0xB : 34.3 ohm typical pull-down/48 ohm typical pull-up + + //- ODT Term : 0x0 : Disable (disable) + //- ODT Term : 0x1 : RZQ/4(60 ohm, for 933MHz / 1066MHz) + //- ODT Term : 0x2 : RZQ/2(120 ohm) + //- ODT Term : 0x3 : RZQ/1(240 ohm) + //--------------------------------------------------------------- + //- Selection of Memory Option : DS -> 0x2, ODT Termination -> 0x0 + + #if 1 + re=Init_Mem(2,0); + #else + //- [DREX0] + //------------------------------------------- + //- [CS0] + Outp32( 0x10400010, 0x07000000 ); //- NOP + DMC_Delay(200); //- Wait for 200us + Outp32( 0x10400010, 0x00071C00 ); //- MR63(MA[7:0]=0x3F), Reset + DMC_Delay(1); //- Wait for 1us + re=Check_MRStatus(0,0); //- Check if DAI is complete. + Outp32( 0x10400010, 0x00010BFC ); //- MR10(MA[7:0]=0x0A), Calibration, OP[7:0]=0xFF(Calibration command after initialization) + DMC_Delay(1); //- Wait for 1us + Outp32( 0x10400010, 0x00000870 ); //- MR2 (MA[7:0]=0x02), RL/WL , RL&WL=OP[3:0]=0xC(RL/WL=14/8,for 825MHz), nWRE=OP[4]=1 (WR > 9(667MHz)) + Outp32( 0x10400010, 0x0000060C ); //- MR1 (MA[7:0]=0x01), nWR , BL=OP[2:0]=0x3, nWR=OP[7:5]=4 (for 825MHz) + + //- [CS1] + Outp32( 0x10400010, 0x07100000 ); //- NOP + DMC_Delay(200); //- Wait for 200us + Outp32( 0x10400010, 0x00171C00 ); //- MR63(MA[7:0]=0x3F), Reset + DMC_Delay(1); //- Wait for 1us + re=Check_MRStatus(0,1); //- Check if DAI is complete. + Outp32( 0x10400010, 0x00110BFC ); //- MR10(MA[7:0]=0x0A), Calibration, OP[7:0]=0xFF(Calibration command after initialization) + DMC_Delay(1); //- Wait for 1us + Outp32( 0x10400010, 0x00100870 ); //- MR2 (MA[7:0]=0x02), RL/WL , RL&WL=OP[3:0]=0xC(RL/WL=14/8,for 825MHz), nWRE=OP[4]=1 (WR > 9(667MHz)) + Outp32( 0x10400010, 0x0010060C ); //- MR1 (MA[7:0]=0x01), nWR , BL=OP[2:0]=0x3, nWR=OP[7:5]=4 (for 825MHz) + //------------------------------------------- + + //- [DREX1] + //------------------------------------------- + //- [CS0] + Outp32( 0x10440010, 0x07000000 ); //- NOP + DMC_Delay(200); //- Wait for 200us + Outp32( 0x10440010, 0x00071C00 ); //- MR63(MA[7:0]=0x3F), Reset + DMC_Delay(1); //- Wait for 1us + re=Check_MRStatus(1,0); //- Check if DAI is complete. + Outp32( 0x10440010, 0x00010BFC ); //- MR10(MA[7:0]=0x0A), Calibration, OP[7:0]=0xFF(Calibration command after initialization) + DMC_Delay(1); //- Wait for 1us + Outp32( 0x10440010, 0x00000870 ); //- MR2 (MA[7:0]=0x02), RL/WL , RL&WL=OP[3:0]=0xA(RL/WL=12/6,for 800MHz), nWRE=OP[4]=1 (WR > 9(600MHz)) + Outp32( 0x10440010, 0x0000060C ); //- MR1 (MA[7:0]=0x01), nWR , BL=OP[2:0]=0x3, nWR=OP[7:5]=2 (for 800MHz) + + //- [CS1] + Outp32( 0x10440010, 0x07100000 ); //- NOP + DMC_Delay(200); //- Wait for 200us + Outp32( 0x10440010, 0x00171C00 ); //- MR63(MA[7:0]=0x3F), Reset + DMC_Delay(1); //- Wait for 1us + re=Check_MRStatus(1,1); //- Check if DAI is complete. + Outp32( 0x10440010, 0x00110BFC ); //- MR10(MA[7:0]=0x0A), Calibration, OP[7:0]=0xFF(Calibration command after initialization) + DMC_Delay(1); //- Wait for 1us + Outp32( 0x10440010, 0x00100870 ); //- MR2 (MA[7:0]=0x02), RL/WL , RL&WL=OP[3:0]=0xA(RL/WL=12/6,for 800MHz), nWRE=OP[4]=1 (WR > 9(600MHz)) + Outp32( 0x10440010, 0x0010060C ); //- MR1 (MA[7:0]=0x01), nWR , BL=OP[2:0]=0x3, nWR=OP[7:5]=2 (for 800MHz) + //------------------------------------------- + + + //*** Setting Memory Driver Strength & ODT Termination *** + //--------------------------------------------------------------- + //- DS : 0x1 : 34.3 ohm typical pull-down/pull-up + //- DS : 0x2 : 40 ohm typical pull-down/pull-up (default) + //- DS : 0x3 : 48 ohm typical pull-down/pull-up + //- DS : 0x9 : 34.3 ohm typical pull-down/40 ohm typical pull-up + //- DS : 0xA : 40 ohm typical pull-down/48 ohm typical pull-up + //- DS : 0xB : 34.3 ohm typical pull-down/48 ohm typical pull-up + + //- ODT Term : 0x0 : Disable (disable) + //- ODT Term : 0x1 : RZQ/4(60 ohm, for 933MHz / 1066MHz) + //- ODT Term : 0x2 : RZQ/2(120 ohm) + //- ODT Term : 0x3 : RZQ/1(240 ohm) + //--------------------------------------------------------------- + //- Selection of Memory Option : DS -> 0x2, ODT Termination -> 0x0 + Outp32( (0x10400000+0x0010), 0xC08 ); //- CH0, CS0. mr3 command + DMC_Delay(0x100); //- wait 1ms + Outp32( (0x10400000+0x0010), 0x10C00 ); //- CH0, CS0. mr11 command + DMC_Delay(0x10000); //- wait 100ms + Outp32( (0x10400000+0x0010), 0x100C08 ); //- CH0, CS1. mr3 command + DMC_Delay(0x100); //- wait 1ms + Outp32( (0x10400000+0x0010), 0x110C00 ); //- CH0, CS1. mr11 command + DMC_Delay(0x10000); //- wait 100ms + Outp32( (0x10440000+0x0010), 0xC08 ); //- CH1, CS0. mr3 command + DMC_Delay(0x100); //- wait 1ms + Outp32( (0x10440000+0x0010), 0x10C00 ); //- CH1, CS0. mr11 command + DMC_Delay(0x10000); //- wait 100ms + Outp32( (0x10440000+0x0010), 0x100C08 ); //- CH1, CS1. mr3 command + DMC_Delay(0x100); //- wait 1ms + Outp32( (0x10440000+0x0010), 0x110C00 ); //- CH1, CS1. mr11 command + DMC_Delay(0x10000); //- wait 100ms + #endif + } + else{ //- Sleep & Wakeup, SW reset, Warm Reset + Outp32( (0x10400000+0x0010), 0x08000000 ); //- CH0, CS0. Self Refresh Exit Command for only sleep & wakeup + Outp32( (0x10400000+0x0010), 0x08100000 ); //- CH0, CS0. Self Refresh Exit Command for only sleep & wakeup + Outp32( (0x10440000+0x0010), 0x08000000 ); //- CH0, CS0. Self Refresh Exit Command for only sleep & wakeup + Outp32( (0x10440000+0x0010), 0x08100000 ); //- CH0, CS0. Self Refresh Exit Command for only sleep & wakeup + } + + Outp32( 0x10420020, 0x0 ); //- PHY0 : OFFSETR_CON0 : offsetr3=0x08,offsetr2=0x08,offsetr1=0x08,offsetr0=0x08 + Outp32( 0x10420030, 0x0 ); //- PHY0 : OFFSETW_CON0 : offsetw3=0x08,offsetw2=0x08,offsetw1=0x08,offsetw0=0x08 + Outp32( 0x10420050, 0x0 ); //- PHY0 OFFSETD_CON0(0x50).upd_mode=0(PHY-Initiated Update Mode), offsetd=0x08 + Outp32( 0x10460020, 0x0 ); //- PHY1 : OFFSETR_CON0 : offsetr3=0x08,offsetr2=0x08,offsetr1=0x08,offsetr0=0x08 + Outp32( 0x10460030, 0x0 ); //- PHY1 : OFFSETW_CON0 : offsetw3=0x08,offsetw2=0x08,offsetw1=0x08,offsetw0=0x08 + Outp32( 0x10460050, 0x0 ); //- PHY1 OFFSETD_CON0(0x50).upd_mode=0(PHY-Initiated Update Mode), offsetd=0x08 + + //- Update DLL Information for CH0 + Outp32( 0x10420000+0x0050, 0x1000000 ); //- PHY0 ctrl_resync=1 + Outp32( 0x10420000+0x0050, 0x0 ); //- PHY0 ctrl_resync=0 + //- Update DLL Information for CH1 + Outp32( 0x10460000+0x0050, 0x1000000 ); //- PHY1 ctrl_resync=1 + Outp32( 0x10460000+0x0050, 0x0 ); //- PHY1 ctrl_resync=0 + + + //----------------------------------------------------------------------- + //--- Executing DLL locking Process --- + //--- And Then, --- + //--- If training is required, Please execute it. --- + //----------------------------------------------------------------------- + if(initial == true) + { + InitMemClk(825); + } + + Outp32( 0x10420000+0x00B0, 0x10100010|(0xF<<1) ); //- PHY0 : ctrl_dll_on[5] = 0, ctrl_start = 0, ctrl_ref=0xF + Outp32( 0x10420000+0x00B0, 0x10100030|(0xF<<1) ); //- PHY0 : ctrl_dll_on[5] = 1, ctrl_ref=0xF + Outp32( 0x10420000+0x00B0, 0x10100070|(0xF<<1) ); //- PHY0 : ctrl_start[6] = 1, ctrl_ref=0xF + loop_cnt=0; + do{ + if(loop_cnt==100000){ //- Just Delay + loop_cnt=0; + break; + } + else loop_cnt++; + }while( ( Inp32( 0x10420000+0x00B4 ) & 0x5 ) != 0x5 ); //- Wait until PHY0. DLL is locked! + + if (nEnableForce == TRUE) + { + //ڡڡ Open for only EVT0 Silicon, the code below is to force lock value for System Power Mode + Outp32(0x10420000+0x00B0, Inp32(0x10420000+0x00B0)&~(0x1<<5)); //- PHY0 : ctrl_dll_on=0 + lock_val=(Inp32(0x10420000+0x00B4)>>8)&0x1FF; + Outp32(0x10420000+0x00B0, (Inp32(0x10420000+0x00B0)&~(0x1FF<<7))|(lock_val<<7)); //- PHY0 : forcing lock value + } + + Outp32( 0x10460000+0x00B0, 0x10100010|(0xF<<1) ); //- PHY1 : ctrl_dll_on[5] = 0, ctrl_start = 0 + Outp32( 0x10460000+0x00B0, 0x10100030|(0xF<<1) ); //- PHY1 : ctrl_dll_on[5] = 1 + Outp32( 0x10460000+0x00B0, 0x10100070|(0xF<<1) ); //- PHY1 : ctrl_start[6] = 1 + loop_cnt=0; + do{ + if(loop_cnt==100000){ //- Just Delay + loop_cnt=0; + break; + } + else loop_cnt++; + }while( ( Inp32( 0x10460000+0x00B4 ) & 0x5 ) != 0x5 ); //- Wait until PHY1. DLL is locked! + + if (nEnableForce == TRUE) + { + //ڡڡ Open for only EVT0 Silicon, the code below is to force lock value for System Power Mode + Outp32(0x10460000+0x00B0, Inp32(0x10460000+0x00B0)&~(0x1<<5)); //- PHY1 : ctrl_dll_on=0 + lock_val=(Inp32(0x10460000+0x00B4)>>8)&0x1FF; + Outp32(0x10460000+0x00B0, (Inp32(0x10460000+0x00B0)&~(0x1FF<<7))|(lock_val<<7)); //- PHY1 : forcing lock value + } + + //- Update DLL Information for CH0 + Outp32( 0x10420000+0x0050, 0x1000000 ); //- PHY0 ctrl_resync=1 + Outp32( 0x10420000+0x0050, 0x0 ); //- PHY0 ctrl_resync=0 + //- Update DLL Information for CH1 + Outp32( 0x10460000+0x0050, 0x1000000 ); //- PHY1 ctrl_resync=1 + Outp32( 0x10460000+0x0050, 0x0 ); //- PHY1 ctrl_resync=0 + + + Outp32( 0x10400000+0x0014, 0x0 ); //- DMC.PrechConfig0.tp_en=0x0, port_policy=0x0 + Outp32( 0x10400000+0x001C, 0xFFFFFFFF ); //- DMC.PrechConfig1 : tp_cnt3=0xFF, tp_cnt2=0xFF, tp_cnt1=0xFF, tp_cnt0=0xFF + Outp32( 0x10440000+0x0014, 0x0 ); //- DMC.PrechConfig0.tp_en=0x0, port_policy=0x0 + Outp32( 0x10440000+0x001C, 0xFFFFFFFF ); //- DMC.PrechConfig1 : tp_cnt3=0xFF, tp_cnt2=0xFF, tp_cnt1=0xFF, tp_cnt0=0xFF + + Outp32( 0x10400000+0x0028, 0x1FFF000D ); //- DMC.PWRDNCONFIG.dsref_cnt=0x1FFF000D + Outp32( 0x10400000+0x0004, 0x28312720 ); //- Set DMC.MEMCONTROL.dsref_en=0x20 + Outp32( 0x10440000+0x0028, 0x1FFF000D ); //- DMC.PWRDNCONFIG.dsref_cnt=0x1FFF000D + Outp32( 0x10440000+0x0004, 0x28312720 ); //- Set DMC.MEMCONTROL.dsref_en=0x20 + + Outp32( 0x10400000+0x0028, 0x1FFF000D ); //- Set Channel0. DMC.PWRDNCONFIG.dpwrdn_cyc=0xD + Outp32( 0x10400000+0x0004, 0x28312722 ); //- Set Channel0. DMC.MEMCONTROL.dpwrdn_en=0x2, dpwrdn_type=0x0 + Outp32( 0x10440000+0x0028, 0x1FFF000D ); //- Set Channel1. DMC.PWRDNCONFIG.dpwrdn_cyc=0xD + Outp32( 0x10440000+0x0004, 0x28312722 ); //- Set Channel1. DMC.MEMCONTROL.dpwrdn_en=0x2, dpwrdn_type=0x0 + + Outp32( 0x10400000+0x0004, 0x20312723 ); //- Channel0. DMC.MEMCONTROL.clk_stop_en=0x1 + Outp32( 0x10440000+0x0004, 0x20312723 ); //- Channel1. DMC.MEMCONTROL.clk_stop_en=0x1 + + Outp32( 0x10400000+0x0018, 0x5082 ); //- CH0. DMC.PHYCONTROL0.sl_dll_dyn_con=0x1 + Outp32( 0x10440000+0x0018, 0x5082 ); //- CH1. DMC.PHYCONTROL0.sl_dll_dyn_con=0x1 + + Outp32( 0x10400000+0x0000, 0xFFF1180 ); //- Set CH0. DMC.PHYCONTROL.io_pd_con=0x2 + Outp32( 0x10440000+0x0000, 0xFFF1180 ); //- Set CH1. DMC.PHYCONTROL.io_pd_con=0x2 + + Outp32( 0x10400000+0x0000, 0xFFF11A0 ); //- CH0. aref enabled + Outp32( 0x10440000+0x0000, 0xFFF11A0 ); //- CH1. aref enabled + + Outp32( 0x10400000+0x0400, 0x1 ); //- CH0. all init complete! + Outp32( 0x10440000+0x0400, 0x1 ); //- CH1. all init complete! + + Outp32( 0x10400000+0x0008, 0x3F ); //- CH0 Clock Gating Setting! + Outp32( 0x10400000+0x0004, 0x28312722 ); //- Channel0. DMC.MEMCONTROL.clk_stop_en=0x0 + Outp32( 0x10440000+0x0008, 0x3F ); //- CH1 Clock Gating Setting! + Outp32( 0x10440000+0x0004, 0x28312722 ); //- Channel1. DMC.MEMCONTROL.clk_stop_en=0x0 + + //- Gating PHY0,1 clock source for SFR and logic not changing after DRAM initialization + //- The function above is possible to reduce dynamic power consumption of PHY0,1 + //- Actually, Clock Source fof idle logic & SFR during dynamic operation is gated. + //- When DRAM operation is idle, CG gating function of DREX operate to reduce MIF Power during idle. + Outp32( 0x10420000+0x0018, 0x100F ); //- PHY0. Wrapper Power Mode Setting : LP_CON0[12] = wrapper_pd = 0x1 + Outp32( 0x10460000+0x0018, 0x100F ); //- PHY1. Wrapper Power Mode Setting : LP_CON0[12] = wrapper_pd = 0x1 + + return re; +} + +void mif_dvfs_init(void) +{ + unsigned int tmp; + + /* enable drex pause */ + tmp = Inp32(0x105B0000 + 0x1008); + tmp |= 0x1; + Outp32(0x105B0000 + 0x1008, tmp); + + /* Configuring Automatic Direct Command Operation */ + tmp = 0x00130010; + Outp32(0x105E0000 + 0x1020, tmp); + + /* Decision for Timing Parameter Set Switch Control */ + tmp = 0x0; + Outp32(0x10400000 + 0x00E0, tmp); + Outp32(0x10440000 + 0x00E0, tmp); + + /* Setting DVFS Mode Control of PHY */ + tmp = 0x0C0C2121; + Outp32(0x10420000 + 0x00BC, tmp); + tmp = 0x0C0C2121; + Outp32(0x10460000 + 0x00BC, tmp); +} + +void mem_ctrl_init(void) +{ + unsigned int wakeup_stat; + + wakeup_stat = readl(EXYNOS5430_POWER_WAKEUP_STAT); + wakeup_stat &= WAKEUP_MASK; + + if (wakeup_stat) { + DMCInit_For_LPDDR3(0, FALSE, GetPOPType()); + } else { + DMCInit_For_LPDDR3(1, FALSE, GetPOPType()); + } + + /* prepare mif dvfs */ + mif_dvfs_init(); +} diff --git a/board/samsung/xyref5430/lowlevel_init.S b/board/samsung/xyref5430/lowlevel_init.S new file mode 100644 index 000000000..c718b4b1f --- /dev/null +++ b/board/samsung/xyref5430/lowlevel_init.S @@ -0,0 +1,363 @@ +/* + * Lowlevel setup for XYREF5430 board based on EXYNOS5430 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* Multi Core Timer */ +#define G_TCON_OFFSET 0x0240 +#define GLOBAL_FRC_ENABLE 0x100 + +#define PSHOLD_CONTROL_OFFSET 0x330C +#define GPA2_PUD 0x0048 +#define GPF5_CON 0x0280 +#define GPF5_DAT 0x0284 + +/* cpu_state flag */ +#define RESET (1 << 0) +#define RESERVED (1 << 1) +#define HOTPLUG (1 << 2) +#define C2_STATE (1 << 3) +#define SWITCH (1 << 4) + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE + + .globl lowlevel_init +lowlevel_init: + /* use iRAM stack in bl2 */ + ldr sp, =CONFIG_IRAM_STACK + stmdb r13!, {ip,lr} + + /* check warm reset status */ + bl check_warm_reset + + /* check reset status */ + ldr r0, =(EXYNOS5430_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + + /* AFTR wakeup reset */ + ldr r2, =S5P_CHECK_DIDLE + cmp r1, r2 + beq exit_wakeup + + /* LPA wakeup reset */ + ldr r2, =S5P_CHECK_LPA + cmp r1, r2 + beq exit_wakeup + + /* Sleep wakeup reset */ + ldr r2, =S5P_CHECK_SLEEP + cmp r1, r2 + beq wakeup_reset + + /* PS-Hold high */ + ldr r0, =(EXYNOS5430_POWER_BASE + PSHOLD_CONTROL_OFFSET) + ldr r1, =0x5300 + str r1, [r0] + + bl pmic_gpio_init + +#if defined(CONFIG_PM) + bl pmic_enable_peric_dev +#endif + + bl read_om + + /* + * If U-boot is already running in RAM, no need to relocate U-Boot. + * Memory controller must be configured before relocating U-Boot + * in ram. + */ + ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ + bic r1, pc, r0 /* pc <- current addr of code */ + /* r1 <- unmasked bits of pc */ + ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ + bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ + cmp r1, r2 /* compare r1, r2 */ + beq 1f /* r0 == r1 then skip sdram init */ + + bl set_cpu_state + + /* relocate nscode to non-secure region */ + bl relocate_code + +#if defined(CONFIG_PM) + bl pmic_init +#endif + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +#if defined(CONFIG_TZPC) + bl tzpc_init +#endif + +1: + ldmia r13!, {ip,pc} + +wakeup_reset: + bl start_mct_frc + + bl read_om + + bl set_cpu_state + + /* relocate nscode to non-secure region */ + bl relocate_code + + /* If eMMC booting */ + ldr r0, =(EXYNOS5430_POWER_BASE + INFORM3_OFFSET) + ldr r1, [r0] + cmp r1, #BOOT_EMMC_4_4 + bleq emmc_endbootop + + /* init system clock */ + bl system_clock_init + + /* Memory initialize */ + bl mem_ctrl_init + +exit_wakeup: + /* W/A for abnormal MMC interrupt */ + ldr r0, =0x1554009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + ldr r0, =0x1555009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + ldr r0, =0x1556009c + ldr r1, [r0] + orr r1, r1, #(1 << 11) + str r1, [r0] + + b warmboot + +pmic_gpio_init: + /* nPOWER(EINT23) pull-up-down disable */ + ldr r0, =(EXYNOS5430_GPIO_ALIVE_BASE + GPA2_PUD) + ldr r1, [r0] + bic r1, r1, #0x4000 + str r1, [r0] + + /* Set PMIC WRSTBI(GPF5_4) to Output */ + ldr r0, =(EXYNOS5430_GPIO_PERIC_BASE + GPF5_CON) + ldr r1, [r0] + bic r2, r1, #0xF0000 + and r1, r1, r2 + orr r1, r1, #0x10000 + str r1, [r0] + + /* Set PMIC WRSTBI(GPF5_4) to High */ + ldr r0, =(EXYNOS5430_GPIO_PERIC_BASE + GPF5_DAT) + ldr r1, [r0] + orr r1, r1, #0x10 + str r1, [r0] + + mov pc, lr + +read_om: + /* Read booting information */ + ldr r0, =(EXYNOS5430_POWER_BASE + OM_STATUS_OFFSET) + ldr r1, [r0] + bic r2, r1, #0xffffffc1 + + /* SD/MMC BOOT */ + cmp r2, #0x4 + moveq r3, #BOOT_MMCSD + + /* eMMC BOOT */ + cmp r2, #0x0 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x8 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x10 + moveq r3, #BOOT_EMMC_4_4 + cmp r2, #0x18 + moveq r3, #BOOT_EMMC_4_4 + + ldr r0, =(EXYNOS5430_POWER_BASE + INFORM3_OFFSET) + str r3, [r0] + + mov pc, lr + +set_cpu_state: + /* read boot cluster */ + adr r0, _cpu_state + mrc p15, 0, r1, c0, c0, 5 @ read MPIDR + ubfx r1, r1, #8, #4 @ r1 = cluster id + + /* set reset flag at _cpu_state of boot cpu */ + ldr r2, =RESET + str r2, [r0, r1, lsl #4] + + mov pc, lr + +check_warm_reset: + /* check reset status */ + ldr r0, =(EXYNOS5430_POWER_BASE + RST_STAT_OFFSET) + ldr r1, [r0] + and r1, r1, #WRESET + cmp r1, #WRESET @ check warm reset + /* clear reset_status */ + ldreq r0, =(EXYNOS5430_POWER_BASE + INFORM1_OFFSET) + moveq r1, #0x0 + streq r1, [r0] + + mov pc, lr + +.globl smc_image_info_base +smc_image_info_base: + .word CONFIG_SMC_IMAGE_INFORM_BASE + +.globl second_boot_info_base +second_boot_info_base: + .word CONFIG_SECOND_BOOT_INFORM_BASE + +start_mct_frc: + ldr r0, =(EXYNOS5430_MCT_BASE + G_TCON_OFFSET) + ldr r1, [r0] + orr r1, r1, #GLOBAL_FRC_ENABLE + str r1, [r0] + + mov pc, lr + +/* + * Relocate code + */ +relocate_code: + adr r0, nscode_base @ r0: source address (start) + adr r1, nscode_end @ r1: source address (end) + ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address + +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + + .word 0xF57FF04F @dsb sy + .word 0xF57FF06F @isb sy + + mov pc, lr + +/******************************************************************************/ +/* + * CPU1, 2, 3, 4, 5 waits here until CPU0 wake it up. + * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory. + */ + +nscode_base: + b 1f + nop @ for backward compatibility + + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 +_switch_addr: + .word 0x0 @ REG4: SWITCH_ADDR +_hotplug_addr: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6 +_c2_addr: + .word 0x0 @ REG7: REG_C2_ADDR +_cpu_state: + .word HOTPLUG @ CLUSTER0_CORE0_STATE + .word HOTPLUG @ CLUSTER0_CORE1_STATE + .word HOTPLUG @ CLUSTER0_CORE2_STATE + .word HOTPLUG @ CLUSTER0_CORE3_STATE + .word HOTPLUG @ CLUSTER1_CORE0_STATE + .word HOTPLUG @ CLUSTER1_CORE1_STATE + .word HOTPLUG @ CLUSTER1_CORE2_STATE + .word HOTPLUG @ CLUSTER1_CORE3_STATE + .word 0x0 @ CLUSTER0_STATE + .word 0x0 @ CLUSTER1_STATE + +1: + adr r0, _cpu_state + + mrc p15, 0, r7, c0, c0, 5 @ read MPIDR + ubfx r8, r7, #8, #4 @ r8 = cluster id + and r7, r7, #0xf @ r7 = cpu id + add r7, r7, r8, lsl #2 + + /* read the current cpu state */ + ldr r10, [r0, r7, lsl #2] + + /* HYP entry */ + + /* + * Set the HYP spsr to itself, so that the entry point + * does not see the difference between a function call + * and an exception return. + */ + mrs r4, cpsr + msr spsr_cxsf, r4 + + bic r6, r4, #0x1f + orr r6, r6, #0x13 + msr spsr_cxsf, r6 /* Setup SPSR to jump to NS SVC mode */ + add r4, pc, #12 + .word 0xe12ef304 /* msr elr_hyp, r4 */ + .word 0xF57FF04F /* dsb sy */ + .word 0xF57FF06F /* isb sy */ + .word 0xe160006e /* ERET */ +ns_svc_entry: + nop + tst r10, #SWITCH + adrne r0, _switch_addr + bne wait_for_addr + tst r10, #C2_STATE + adrne r0, _c2_addr + bne wait_for_addr + + /* clear INFORM1 for security reason */ + ldr r0, =(EXYNOS5430_POWER_BASE + INFORM1_OFFSET) + ldr r1, [r0] + cmp r1, #0x0 + movne r1, #0x0 + strne r1, [r0] + ldrne r1, =(EXYNOS5430_POWER_BASE + INFORM0_OFFSET) + ldrne pc, [r1] + + tst r10, #RESET + ldrne pc, =CONFIG_SYS_TEXT_BASE + + adr r0, _hotplug_addr +wait_for_addr: + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + wfe + b wait_for_addr + .ltorg +nscode_end: diff --git a/board/samsung/xyref5430/mmc_boot.c b/board/samsung/xyref5430/mmc_boot.c new file mode 100644 index 000000000..d2b8cfaa9 --- /dev/null +++ b/board/samsung/xyref5430/mmc_boot.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * 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 <config.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/mmc.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/clk.h> +#include <asm/arch/smc.h> +#include "setup.h" + +/* 1st_dev: eMMC, 2nd_dev: SD/MMC */ +#define SDMMC_SECOND_DEV0 0x10 +#define SDMMC_SECOND_DEV1 0x18 +#define USB_SECOND_DEV 0x0 +#define SECOND_BOOT_MODE 0xFEED0002 +#define UBOOT 0x1 +#define TZSW 0x2 +#define SIGNATURE_CHECK_FAIL -1 +#define OM_STAT_MASK 0x1E + +/* find boot device for secondary booting */ +static int find_second_boot_dev(void) +{ + struct exynos5430_power *pmu = (struct exynos5430_power *)EXYNOS5430_POWER_BASE; + unsigned int om_status = readl(&pmu->om_stat) & OM_STAT_MASK; + int ret = -1; + + switch(om_status) { + case SDMMC_SECOND_DEV0: + case SDMMC_SECOND_DEV1: + writel(0x1, second_boot_info_base); + ret = BOOT_SEC_DEV; + break; + case USB_SECOND_DEV: + writel(0x2, second_boot_info_base); + ret = BOOT_USB; + break; + default: + ret = -1; + } + + return ret; +} + +static unsigned int device(unsigned int boot_dev) +{ + switch(boot_dev) { + case BOOT_MMCSD: + case BOOT_SEC_DEV: + boot_dev = SDMMC_CH2; + break; + case BOOT_EMMC_4_4: + boot_dev = EMMC; + break; + case BOOT_USB: + boot_dev = USB; + break; + default: + while(1); + } + return boot_dev; +} + +static int ld_image_from_2nd_dev(int image) +{ + int ret = SIGNATURE_CHECK_FAIL; + unsigned int boot_dev = 0; + + boot_dev = find_second_boot_dev(); + + /* sdmmc enumerate */ + if (device(boot_dev) == SDMMC_CH2) + sdmmc_enumerate(); + + switch (image) { + case UBOOT: + /* load uboot from 2nd dev */ + ret = load_uboot_image(device(boot_dev)); + break; + case TZSW: + /* load uboot from 2nd dev */ + ret = coldboot(device(boot_dev)); + break; + } + + if (ret == SIGNATURE_CHECK_FAIL) + while(1); + + return boot_dev; +} + +void jump_to_uboot(void) +{ + unsigned int om_status = readl(EXYNOS5430_POWER_BASE + INFORM3_OFFSET); + unsigned int boot_dev = 0; + int ret = 0; + + /* TODO : find second boot function */ + if (find_second_boot() == SECOND_BOOT_MODE) + boot_dev = find_second_boot_dev(); + + if (!boot_dev) + boot_dev = om_status; + + /* Load u-boot image to ram */ + ret = load_uboot_image(device(boot_dev)); + if (ret == SIGNATURE_CHECK_FAIL) + boot_dev = ld_image_from_2nd_dev(UBOOT); + + /* Load tzsw image & U-Boot boot */ + ret = coldboot(device(boot_dev)); + if (ret == SIGNATURE_CHECK_FAIL) + ld_image_from_2nd_dev(TZSW); + +} + +void board_init_f(unsigned long bootflag) +{ + /* Jump to U-Boot image */ + jump_to_uboot(); + + /* Never returns Here */ +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /* Function attribute is no-return */ + /* This Function never executes */ + while (1) + ; +} + +void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} diff --git a/board/samsung/xyref5430/pmic.c b/board/samsung/xyref5430/pmic.c new file mode 100644 index 000000000..b4baedb0b --- /dev/null +++ b/board/samsung/xyref5430/pmic.c @@ -0,0 +1,385 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include "pmic.h" + +extern u32 uEglAsvGrpVolt; +extern u32 uKfcAsvGrpVolt; +extern u32 uMifAsvGrpVolt; +extern u32 uIntAsvGrpVolt; +extern u32 uG3dAsvGrpVolt; + +void Delay(void) +{ + unsigned long i; + for (i = 0; i < DELAY; i++) + ; +} + +void IIC0_SCLH_SDAH(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLH_SDAL(void) +{ + IIC0_ESCL_Hi; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_SCLL_SDAH(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + Delay(); +} + +void IIC0_SCLL_SDAL(void) +{ + IIC0_ESCL_Lo; + IIC0_ESDA_Lo; + Delay(); +} + +void IIC0_ELow(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLH_SDAL(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EHigh(void) +{ + IIC0_SCLL_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAH(); + IIC0_SCLL_SDAH(); +} + +void IIC0_EStart(void) +{ + IIC0_SCLH_SDAH(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLL_SDAL(); +} + +void IIC0_EEnd(void) +{ + IIC0_SCLL_SDAL(); + IIC0_SCLH_SDAL(); + Delay(); + IIC0_SCLH_SDAH(); +} + +void IIC0_EAck_write(void) +{ + unsigned long ack; + + /* Function <- Input */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + Delay(); + ack = GPD2DAT; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Hi; + Delay(); + + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + ack = (ack>>0)&0x1; + + IIC0_SCLL_SDAL(); +} + +void IIC0_EAck_read(void) +{ + /* Function <- Output */ + IIC0_ESDA_OUTP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + IIC0_ESDA_Hi; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + /* Function <- Input (SDA) */ + IIC0_ESDA_INP; + + IIC0_SCLL_SDAL(); +} + +void IIC0_ESetport(void) +{ + /* Pull Up/Down Disable SCL, SDA */ + GPD2PUD &= ~(0xf<<0); + + IIC0_ESCL_Hi; + IIC0_ESDA_Hi; + + /* Function <- Output (SCL) */ + IIC0_ESCL_OUTP; + /* Function <- Output (SDA) */ + IIC0_ESDA_OUTP; + + Delay(); +} + +void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. data. */ + for (i = 8; i > 0; i--) { + if ((IicData >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EEnd(); +} + +void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* write */ + IIC0_ELow(); + + /* ACK */ + IIC0_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* ACK */ + IIC0_EAck_write(); + + IIC0_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC0_EHigh(); + else + IIC0_ELow(); + } + + /* read */ + IIC0_EHigh(); + /* ACK */ + IIC0_EAck_write(); + + /* read reg. data. */ + IIC0_ESDA_INP; + + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + for (i = 8; i > 0; i--) { + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + reg = GPD2DAT; + IIC0_ESCL_Hi; + IIC0_ESCL_Hi; + Delay(); + IIC0_ESCL_Lo; + IIC0_ESCL_Lo; + Delay(); + + reg = (reg >> 0) & 0x1; + + data |= reg << (i-1); + } + + /* ACK */ + IIC0_EAck_read(); + IIC0_ESDA_OUTP; + + IIC0_EEnd(); + + *IicData = data; +} + +void pmic_init(void) +{ + unsigned char pmic_id; + unsigned char rtc_ctrl; + unsigned char wrstbi_ctrl; + unsigned char ldo_ctrl; + unsigned char buck6_ctrl; + + Get_ASV_Group(); + + IIC0_ESetport(); + + /* read pmic revision number */ + IIC0_ERead(S2MPS13_ADDR, PMIC_ID, &pmic_id); + + /* LDO DVS VTHR control */ + /* set INT LDO DVS VTHR : 0.9V */ + IIC0_EWrite(S2MPS13_ADDR, LDO_DVS1, 0xCC); + /* set KFC LDO DVS VTHR : 0.9V */ + IIC0_EWrite(S2MPS13_ADDR, LDO_DVS2, 0xCC); + /* set G3D LDO DVS VTHR : 0.9V */ + IIC0_EWrite(S2MPS13_ADDR, LDO_DVS3, 0xCC); + + /* enable low_jitter, 32kHz BT, CP, AP at RTC_BUF */ + IIC0_ERead(S2MPS13_ADDR, RTC_BUF, &rtc_ctrl); + rtc_ctrl |= (LOW_JITTER_EN | BT_32KHZ_EN | CP_32KHZ_EN | AP_32KHZ_EN); + IIC0_EWrite(S2MPS13_ADDR, RTC_BUF, rtc_ctrl); + + /* enable WRSTBI detection */ + IIC0_ERead(S2MPS13_ADDR, WRSTBI_CTRL, &wrstbi_ctrl); + wrstbi_ctrl |= WRSTBI_EN; + IIC0_EWrite(S2MPS13_ADDR, WRSTBI_CTRL, wrstbi_ctrl); + + /* power control for peri device */ + /* enable LDO6 : VDD_HSIF_1.0V_AP */ + IIC0_ERead(S2MPS13_ADDR, LDO6_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS13_ADDR, LDO6_CTRL, ldo_ctrl); + + /* enable LDO7 : VDD_HSIF_1.8V_AP */ + IIC0_ERead(S2MPS13_ADDR, LDO7_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS13_ADDR, LDO7_CTRL, ldo_ctrl); + + /* enable LDO27 : VCC_LCD_3.0V */ + IIC0_ERead(S2MPS13_ADDR, LDO27_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS13_ADDR, LDO27_CTRL, ldo_ctrl); + + /* enable LDO28 : VCC_LCD_1.8V */ + IIC0_ERead(S2MPS13_ADDR, LDO28_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS13_ADDR, LDO28_CTRL, ldo_ctrl); + + if (pmic_id == REV_00) { + /* BUCK Control */ + IIC0_EWrite(S2MPS13_ADDR, BUCK1_OUT, + WR_BUCK_VOLT(uMifAsvGrpVolt/10000 - VDD_BASE)); + IIC0_EWrite(S2MPS13_ADDR, BUCK2_OUT, + WR_BUCK_VOLT(uEglAsvGrpVolt/10000 - VDD_BASE)); + IIC0_EWrite(S2MPS13_ADDR, BUCK3_OUT, + WR_BUCK_VOLT(uKfcAsvGrpVolt/10000 - VDD_BASE)); + IIC0_EWrite(S2MPS13_ADDR, BUCK4_OUT, + WR_BUCK_VOLT(uIntAsvGrpVolt/10000 - VDD_BASE)); + + /* BUCK6 : set pwm mode */ + IIC0_ERead(S2MPS13_ADDR, BUCK6_CTRL, &buck6_ctrl); + buck6_ctrl |= (PWM_MODE << MODE_B); + IIC0_EWrite(S2MPS13_ADDR, BUCK6_CTRL, buck6_ctrl); + + IIC0_EWrite(S2MPS13_ADDR, BUCK6_OUT, + WR_BUCK_VOLT(uG3dAsvGrpVolt/10000 - VDD_BASE)); + + /* BUCK6 : set auto mode */ + IIC0_ERead(S2MPS13_ADDR, BUCK6_CTRL, &buck6_ctrl); + buck6_ctrl &= ~(PWM_MODE << MODE_B); + buck6_ctrl |= (AUTO_MODE << MODE_B); + IIC0_EWrite(S2MPS13_ADDR, BUCK6_CTRL, buck6_ctrl); + } else { + /* BUCK Control */ + IIC0_EWrite(S2MPS13_ADDR, BUCK1_OUT, + WR_BUCK_VOLT(uMifAsvGrpVolt/10000)); + IIC0_EWrite(S2MPS13_ADDR, BUCK2_OUT, + WR_BUCK_VOLT(uEglAsvGrpVolt/10000)); + IIC0_EWrite(S2MPS13_ADDR, BUCK3_OUT, + WR_BUCK_VOLT(uKfcAsvGrpVolt/10000)); + IIC0_EWrite(S2MPS13_ADDR, BUCK4_OUT, + WR_BUCK_VOLT(uIntAsvGrpVolt/10000)); + IIC0_EWrite(S2MPS13_ADDR, BUCK6_OUT, + WR_BUCK_VOLT(uG3dAsvGrpVolt/10000)); + } +} + +void pmic_enable_peric_dev(void) +{ + unsigned char ldo_ctrl; + + IIC0_ESetport(); + + /* enable LDO19 : VCC_1.8V_PERI */ + IIC0_ERead(S2MPS13_ADDR, LDO19_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS13_ADDR, LDO19_CTRL, ldo_ctrl); + + /* enable LDO20 : VCC_2.8V_PERI */ + IIC0_ERead(S2MPS13_ADDR, LDO20_CTRL, &ldo_ctrl); + ldo_ctrl |= OUTPUT_PWREN_ON; + IIC0_EWrite(S2MPS13_ADDR, LDO20_CTRL, ldo_ctrl); +} diff --git a/board/samsung/xyref5430/pmic.h b/board/samsung/xyref5430/pmic.h new file mode 100644 index 000000000..63f365eab --- /dev/null +++ b/board/samsung/xyref5430/pmic.h @@ -0,0 +1,143 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __PMIC_H__ +#define __PMIC_H__ + +#define GPD2CON *(volatile unsigned long *)(0x14CC0120) +#define GPD2DAT *(volatile unsigned long *)(0x14CC0124) +#define GPD2PUD *(volatile unsigned long *)(0x14CC0128) + +#define IIC0_ESCL_Hi GPD2DAT |= (0x1<<1) +#define IIC0_ESCL_Lo GPD2DAT &= ~(0x1<<1) +#define IIC0_ESDA_Hi GPD2DAT |= (0x1<<0) +#define IIC0_ESDA_Lo GPD2DAT &= ~(0x1<<0) + +#define IIC0_ESCL_INP GPD2CON &= ~(0xf<<4) +#define IIC0_ESCL_OUTP GPD2CON = (GPD2CON & ~(0xf<<4))|(0x1<<4) + +#define IIC0_ESDA_INP GPD2CON &= ~(0xf<<0) +#define IIC0_ESDA_OUTP GPD2CON = (GPD2CON & ~(0xf<<0))|(0x1<<0) + +#define DELAY 100 + +/* S2MPA01 slave address */ +#define S2MPS13_ADDR 0xCC + +#define VDD_BASE_VOLT 40000 +#define VDD_VOLT_STEP 625 +#define MIN_VOLT 600 +#define MAX_RD_VAL 0x90 +#define RD_BUCK_VOLT(x) (((x > MAX_RD_VAL) ? 0 : \ + ((x * VDD_VOLT_STEP) + VDD_BASE_VOLT) / 100)) +#define WR_BUCK_VOLT(x) ((x < MIN_VOLT) ? 0 : \ + ((((x) * 100) - VDD_BASE_VOLT) / VDD_VOLT_STEP)) + +#define VDD_BASE (200) +#define VDD_REG_VALUE_BASE ((VDD_BASE * 100) / VDD_VOLT_STEP) + +/* S2MPA01 Revision ID */ +#define REV_00 0x00 + +/* S2MPA01 Register Address */ +#define PMIC_ID 0x00 +#define RTC_BUF 0x0C +#define WRSTBI_CTRL 0x18 +#define BUCK1_CTRL 0x19 +#define BUCK1_OUT 0x1A +#define BUCK2_CTRL 0x1B +#define BUCK2_OUT 0x1C +#define BUCK3_CTRL 0x1D +#define BUCK3_OUT 0x1E +#define BUCK4_CTRL 0x1F +#define BUCK4_OUT 0x20 +#define BUCK5_CTRL 0x21 +#define BUCK5_OUT 0x22 +#define BUCK6_CTRL 0x23 +#define BUCK6_OUT 0x24 +#define BUCK7_CTRL 0x25 +#define BUCK7_SW 0x26 +#define BUCK7_OUT 0x27 +#define BUCK8_CTRL 0x28 +#define BUCK8_OUT 0x29 +#define BUCK9_CTRL 0x2A +#define BUCK9_OUT 0x2B +#define BUCK10_CTRL 0x2C +#define BUCK10_OUT 0x2D + +/* LDO DVS Control Register */ +#define LDO_DVS1 0x32 +#define LDO_DVS2 0x33 +#define LDO_DVS3 0x34 +#define LDO_DVS4 0x35 + +#define LDO6_CTRL 0x3B +#define LDO7_CTRL 0x3C +#define LDO19_CTRL 0x48 +#define LDO20_CTRL 0x49 +#define LDO27_CTRL 0x50 +#define LDO28_CTRL 0x51 + +/* LDO CTRL bit */ +#define OFF (0x0) +#define ON (0x1) +#define OUTPUT_OFF (~(3 << 6)) +#define OUTPUT_PWREN_ON (1 << 6) +#define OUTPUT_LOWPWR_MODE (2 << 6) +#define OUTPUT_NORMAL_MODE (3 << 6) + +/* + * BUCK control + */ +#define BUCK_EN (0x6) +#define REMOTE_EN (0x5) +#define DSCH_B (0x4) +#define MODE_B (0x2) +#define AVP_EN (0x1) +/* BUCK_EN */ +#define ALWAYS_OFF (0x0) +#define PWREN_CTRL (0x1) +#define ALWAYS_ON (0x3) +/* REMOTE_EN */ +#define REMOTE_SENSE_OFF (0x0) +#define REMOTE_SENSE_ON (0x1) +/* DSCH */ +#define NO_ACTIVE_DISCHARGE (0x0) +#define ACTIVE_DISCHARGE (0x1) +/* MODE */ +#define AUTO_MODE (0x2) +#define PWM_MODE (0x3) +/* AVP(Adaptive Voltage position) */ +#define ACP_OFF (0x0) +#define ACP_ON (0x1) + +/* + * RTC_BUF + */ +#define LOW_JITTER_EN (0x1 << 4) +#define BT_32KHZ_EN (0x1 << 2) +#define CP_32KHZ_EN (0x1 << 1) +#define AP_32KHZ_EN (0x1 << 0) + +/* + * WRSTBI + */ +#define WRSTBI_EN (0x1 << 5) + +extern void pmic_init(void); +extern void IIC0_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData); +extern void IIC0_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData); + +#endif /*__PMIC_H__*/ + diff --git a/board/samsung/xyref5430/pmic_lm3560.c b/board/samsung/xyref5430/pmic_lm3560.c new file mode 100644 index 000000000..b2608d1fe --- /dev/null +++ b/board/samsung/xyref5430/pmic_lm3560.c @@ -0,0 +1,285 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include "pmic_lm3560.h" + +static void Delay(void) +{ + unsigned long i; + for (i = 0; i < DELAY; i++) + ; +} + +void IIC2_SCLH_SDAH(void) +{ + IIC2_ESCL_Hi; + IIC2_ESDA_Hi; + Delay(); +} + +void IIC2_SCLH_SDAL(void) +{ + IIC2_ESCL_Hi; + IIC2_ESDA_Lo; + Delay(); +} + +void IIC2_SCLL_SDAH(void) +{ + IIC2_ESCL_Lo; + IIC2_ESDA_Hi; + Delay(); +} + +void IIC2_SCLL_SDAL(void) +{ + IIC2_ESCL_Lo; + IIC2_ESDA_Lo; + Delay(); +} + +void IIC2_ELow(void) +{ + IIC2_SCLL_SDAL(); + IIC2_SCLH_SDAL(); + IIC2_SCLH_SDAL(); + IIC2_SCLL_SDAL(); +} + +void IIC2_EHigh(void) +{ + IIC2_SCLL_SDAH(); + IIC2_SCLH_SDAH(); + IIC2_SCLH_SDAH(); + IIC2_SCLL_SDAH(); +} + +void IIC2_EStart(void) +{ + IIC2_SCLH_SDAH(); + IIC2_SCLH_SDAL(); + Delay(); + IIC2_SCLL_SDAL(); +} + +void IIC2_EEnd(void) +{ + IIC2_SCLL_SDAL(); + IIC2_SCLH_SDAL(); + Delay(); + IIC2_SCLH_SDAH(); +} + +void IIC2_EAck_write(void) +{ + unsigned long ack; + + /* Function <- Input */ + IIC2_ESDA_INP; + + IIC2_ESCL_Lo; + Delay(); + IIC2_ESCL_Hi; + Delay(); + ack = GPD5DAT; + IIC2_ESCL_Hi; + Delay(); + IIC2_ESCL_Hi; + Delay(); + + /* Function <- Output (SDA) */ + IIC2_ESDA_OUTP; + + ack = (ack>>2)&0x1; + + IIC2_SCLL_SDAL(); +} + +void IIC2_EAck_read(void) +{ + /* Function <- Output */ + IIC2_ESDA_OUTP; + + IIC2_ESCL_Lo; + IIC2_ESCL_Lo; + IIC2_ESDA_Hi; + IIC2_ESCL_Hi; + IIC2_ESCL_Hi; + /* Function <- Input (SDA) */ + IIC2_ESDA_INP; + + IIC2_SCLL_SDAL(); +} + +void IIC2_ESetport(void) +{ + /* Pull Up/Down Disable SCL, SDA */ + GPD5PUD &= ~(0xf<<8); + + IIC2_ESCL_Hi; + IIC2_ESDA_Hi; + + /* Function <- Output (SCL) */ + IIC2_ESCL_OUTP; + /* Function <- Output (SDA) */ + IIC2_ESDA_OUTP; + + Delay(); +} + +void IIC2_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData) +{ + unsigned long i; + + IIC2_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC2_EHigh(); + else + IIC2_ELow(); + } + + /* write */ + IIC2_ELow(); + + /* ACK */ + IIC2_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC2_EHigh(); + else + IIC2_ELow(); + } + + /* ACK */ + IIC2_EAck_write(); + + /* write reg. data. */ + for (i = 8; i > 0; i--) { + if ((IicData >> (i-1)) & 0x0001) + IIC2_EHigh(); + else + IIC2_ELow(); + } + + /* ACK */ + IIC2_EAck_write(); + + IIC2_EEnd(); +} + +void IIC2_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData) +{ + unsigned long i, reg; + unsigned char data = 0; + + IIC2_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC2_EHigh(); + else + IIC2_ELow(); + } + + /* write */ + IIC2_ELow(); + + /* ACK */ + IIC2_EAck_write(); + + /* write reg. addr. */ + for (i = 8; i > 0; i--) { + if ((IicAddr >> (i-1)) & 0x0001) + IIC2_EHigh(); + else + IIC2_ELow(); + } + + /* ACK */ + IIC2_EAck_write(); + + IIC2_EStart(); + + /* write chip id */ + for (i = 7; i > 0; i--) { + if ((ChipId >> i) & 0x0001) + IIC2_EHigh(); + else + IIC2_ELow(); + } + + /* read */ + IIC2_EHigh(); + /* ACK */ + IIC2_EAck_write(); + + /* read reg. data. */ + IIC2_ESDA_INP; + + IIC2_ESCL_Lo; + IIC2_ESCL_Lo; + Delay(); + + for (i = 8; i > 0; i--) { + IIC2_ESCL_Lo; + IIC2_ESCL_Lo; + Delay(); + IIC2_ESCL_Hi; + IIC2_ESCL_Hi; + Delay(); + reg = GPD5DAT; + IIC2_ESCL_Hi; + IIC2_ESCL_Hi; + Delay(); + IIC2_ESCL_Lo; + IIC2_ESCL_Lo; + Delay(); + + reg = (reg >> 2) & 0x1; + + data |= reg << (i-1); + } + + /* ACK */ + IIC2_EAck_read(); + IIC2_ESDA_OUTP; + + IIC2_EEnd(); + + *IicData = data; +} + +void pmic_init_lm3560(void) +{ + unsigned char pmic_id; + + IIC2_ESetport(); + + /* read pmic revision number */ + IIC2_ERead(LM3560_ADDR, 0x10, &pmic_id); + + /* enable low_jitter, 32kHz BT, CP, AP at RTC_BUF */ + //IIC2_ERead(LM3560_ADDR, RTC_BUF, &rtc_ctrl); + //rtc_ctrl |= (LOW_JITTER_EN | BT_32KHZ_EN | CP_32KHZ_EN | AP_32KHZ_EN); + //IIC2_EWrite(LM3560_ADDR, RTC_BUF, rtc_ctrl); +} + diff --git a/board/samsung/xyref5430/pmic_lm3560.h b/board/samsung/xyref5430/pmic_lm3560.h new file mode 100644 index 000000000..311e2b9a9 --- /dev/null +++ b/board/samsung/xyref5430/pmic_lm3560.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2013 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __PMIC_LM3560_H__ +#define __PMIC_LM3560_H__ + +#define GPD5CON *(volatile unsigned long *)(0x14CC0160) +#define GPD5DAT *(volatile unsigned long *)(0x14CC0164) +#define GPD5PUD *(volatile unsigned long *)(0x14CC0168) + +#define IIC2_ESCL_Hi GPD5DAT |= (0x1<<3) +#define IIC2_ESCL_Lo GPD5DAT &= ~(0x1<<3) +#define IIC2_ESDA_Hi GPD5DAT |= (0x1<<2) +#define IIC2_ESDA_Lo GPD5DAT &= ~(0x1<<2) + +#define IIC2_ESCL_INP GPD5CON &= ~(0xf<<12) +#define IIC2_ESCL_OUTP GPD5CON = (GPD5CON & ~(0xf<<12))|(0x1<<12) + +#define IIC2_ESDA_INP GPD5CON &= ~(0xf<<8) +#define IIC2_ESDA_OUTP GPD5CON = (GPD5CON & ~(0xf<<8))|(0x1<<8) + +#define DELAY 100 + +/* LM3560 slave address */ +#define LM3560_ADDR 0xA6 + +/* LM3560 Register Address */ +#define ENABLE_REGISTER 0x10 + +extern void pmic_init(void); +extern void IIC2_ERead(unsigned char ChipId, + unsigned char IicAddr, unsigned char *IicData); +extern void IIC2_EWrite(unsigned char ChipId, + unsigned char IicAddr, unsigned char IicData); + +#endif /*__PMIC_H__*/ + diff --git a/board/samsung/xyref5430/setup.h b/board/samsung/xyref5430/setup.h new file mode 100644 index 000000000..53567bea7 --- /dev/null +++ b/board/samsung/xyref5430/setup.h @@ -0,0 +1,66 @@ +/* + * Machine Specific Values for XYREF5430 board based on EXYNOS5 + * + * Copyright (C) 2012 Samsung Electronics + * + * 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 _XYREF5430_SETUP_H +#define _XYREF5430_SETUP_H + +#include <config.h> +#include <version.h> +#include <asm/arch/cpu.h> + +/* TZPC : Register Offsets */ +#define TZPC0_BASE 0x10100000 +#define TZPC1_BASE 0x10110000 +#define TZPC2_BASE 0x10120000 +#define TZPC3_BASE 0x10130000 +#define TZPC4_BASE 0x10140000 +#define TZPC5_BASE 0x10150000 +#define TZPC6_BASE 0x10160000 +#define TZPC7_BASE 0x10170000 +#define TZPC8_BASE 0x10180000 +#define TZPC9_BASE 0x10190000 +#define TZPC10_BASE 0x100D0000 +#define TZPC11_BASE 0x100E0000 +#define TZPC12_BASE 0x100F0000 + +/* + * TZPC Register Value : + * R0SIZE: 0x0 : Size of secured ram + */ +#define R0SIZE 0x0 + +/* + * TZPC Decode Protection Register Value : + * DECPROTXSET: 0xFF : Set Decode region to non-secure + */ +#define DECPROTXSET 0xFF + +void sdelay(unsigned long); +void mem_ctrl_init(void); +void system_clock_init(void); +extern void check_pll_unlock(unsigned int addr); +extern void check_mux_stat(unsigned int addr, unsigned int mask_bit); +extern unsigned int second_boot_info_base; +extern unsigned int smc_image_info_base; +#endif diff --git a/board/samsung/xyref5430/smc.c b/board/samsung/xyref5430/smc.c new file mode 100644 index 000000000..db677e071 --- /dev/null +++ b/board/samsung/xyref5430/smc.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * "SMC CALL COMMAND" + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <asm/arch/smc.h> +#include "setup.h" + +static inline u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = arg1; + register u32 reg2 __asm__("r2") = arg2; + register u32 reg3 __asm__("r3") = arg3; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) + + ); + + return reg0; +} + +static inline u32 exynos_smc_read(u32 cmd) +{ + register u32 reg0 __asm__("r0") = cmd; + register u32 reg1 __asm__("r1") = 0; + + __asm__ volatile ( + "smc 0\n" + : "+r"(reg0), "+r"(reg1) + + ); + + return reg1; +} + + +unsigned int load_uboot_image(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) ((u32)smc_image_info_base); + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_UBOOT_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_UBOOT_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_UBOOT_BASE; + + } else if (boot_device == USB) { + + /* USB buffer, under 3 KB size, non-secure region */ + info_image->bootdev.usb.read_buffer = CONFIG_PHY_IRAM_NS_BASE + 0x800; + + } + + info_image->image_base_addr = CONFIG_PHY_UBOOT_BASE; + info_image->size = (MOVI_UBOOT_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_UBOOT_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_LOAD_UBOOT, + boot_device, (u32)info_image, 0); +#else + if (boot_device == SDMMC_CH2) { + + u32 (*copy_uboot)(u32, u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + SDMMC_DEV_OFFSET); + + copy_uboot(MOVI_UBOOT_POS, + MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } else if (boot_device == EMMC) { + + u32 (*copy_uboot)(u32, u32) = (void *) + *(u32 *)(IROM_FNPTR_BASE + EMMC_DEV_OFFSET ); + + copy_uboot(MOVI_UBOOT_BLKCNT, CONFIG_SYS_TEXT_BASE); + + } + +#endif +} + +unsigned int coldboot(u32 boot_device) +{ +#if defined(CONFIG_SMC_CMD) + image_info *info_image; + + info_image = (image_info *) ((u32)smc_image_info_base); + + if (boot_device == SDMMC_CH2) { + + info_image->bootdev.sdmmc.image_pos = MOVI_TZSW_POS; + info_image->bootdev.sdmmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.sdmmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == EMMC) { + + info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT; + info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE; + + } else if (boot_device == USB) { + + /* default USB buffer of BL0, under 3 KB size, secure region */ + info_image->bootdev.usb.read_buffer = CONFIG_PHY_IRAM_BASE + 0xc00; + + } + + info_image->image_base_addr = CONFIG_PHY_TZSW_BASE; + info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE); + info_image->secure_context_base = SMC_SECURE_CONTEXT_BASE; + info_image->signature_size = SMC_TZSW_SIGNATURE_SIZE; + + return exynos_smc(SMC_CMD_COLDBOOT, + boot_device, (u32)info_image, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*uboot)(void); + + /* Jump to U-Boot image */ + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); +#endif + /* Never returns Here */ +} + +void warmboot(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_WARMBOOT, 0, 0, CONFIG_PHY_IRAM_NS_BASE); +#else + __attribute__((noreturn)) void (*wakeup_kernel)(void); + + /* Jump to kernel for wakeup */ + wakeup_kernel = (void *)readl(EXYNOS5430_POWER_BASE + INFORM0_OFFSET); + (*wakeup_kernel)(); + /* Never returns Here */ +#endif +} + +unsigned int find_second_boot(void) +{ +#if defined(CONFIG_SMC_CMD) + return exynos_smc_read(SMC_CMD_CHECK_SECOND_BOOT); +#else + return readl(IROM_FNPTR_BASE + SECCOND_BOOT_INFORM_OFFSET); +#endif +} + +void emmc_endbootop(void) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_EMMC_ENDBOOTOP, 0, 0, 0); +#else + void (*emmc_endboot_op)(void) = (void *) + *(u32 *)(IROM_FNPTR_BASE + EMMC_ENDBOOTOP_OFFSET); + + emmc_endboot_op(); +#endif +} + +void sdmmc_enumerate(void) +{ + exynos_smc(SMC_CMD_SDMMC_ENUMERATE, 0, 0, 0); +} + +void set_secure_reg(u32 reg_val, u32 num) +{ +#if defined(CONFIG_SMC_CMD) + exynos_smc(SMC_CMD_SET_SECURE_REG, reg_val, num, 0); +#else + +#endif +} diff --git a/board/samsung/xyref5430/tzpc_init.c b/board/samsung/xyref5430/tzpc_init.c new file mode 100644 index 000000000..446f4a26b --- /dev/null +++ b/board/samsung/xyref5430/tzpc_init.c @@ -0,0 +1,45 @@ +/* + * Lowlevel setup for XYREF5430 board based on EXYNOS5430 + * + * Copyright (C) 2013 Samsung Electronics + * + * 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 <asm/arch/tzpc.h> +#include"setup.h" + +/* Setting TZPC[TrustZone Protection Controller] */ +void tzpc_init(void) +{ + struct exynos_tzpc *tzpc; + unsigned int addr; + + for (addr = TZPC10_BASE; addr <= TZPC9_BASE; addr += TZPC_BASE_OFFSET) { + tzpc = (struct exynos_tzpc *)addr; + + if (addr == TZPC0_BASE) + writel(R0SIZE, &tzpc->r0size); + + writel(DECPROTXSET, &tzpc->decprot0set); + writel(DECPROTXSET, &tzpc->decprot1set); + writel(DECPROTXSET, &tzpc->decprot2set); + writel(DECPROTXSET, &tzpc->decprot3set); + } +} diff --git a/board/samsung/xyref5430/xyref5430.c b/board/samsung/xyref5430/xyref5430.c new file mode 100644 index 000000000..5ceba816b --- /dev/null +++ b/board/samsung/xyref5430/xyref5430.c @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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 <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/clock.h> +#include <asm/arch/power.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/pmu.h> +#include <asm/arch/sromc.h> +#include <asm/arch/sysreg.h> +#include "pmic.h" +#ifndef CONFIG_MACH_UNIVERSAL5430 +#include "pmic_lm3560.h" +#endif +#include "setup.h" + +#define DEBOUNCE_DELAY 10000 + +#define Inp32(addr) (*(volatile u32 *)(addr)) +#define GetBits(uAddr, uBaseBit, uMaskValue) \ + ((Inp32(uAddr)>>(uBaseBit))&(uMaskValue)) +#define GetPOPType() (GetBits(0x10000004, 4, 0x3)) + +DECLARE_GLOBAL_DATA_PTR; +unsigned int pmic; + +static void display_bl1_version(void) +{ + char bl1_version[9] = {0}; + + /* display BL1 version */ +#if defined(CONFIG_TRUSTZONE_ENABLE) + printf("\nTrustZone Enabled BSP"); + strncpy(&bl1_version[0], (char *)CONFIG_BL1_VERSION_INFORM, 8); + printf("\nBL1 version: %s\n", &bl1_version[0]); +#endif +} + +static void display_chip_id(void) +{ +#if defined(CONFIG_DISPLAY_CHIPID) + s5p_chip_id[0] = readl(EXYNOS5430_PRO_ID + CHIPID0_OFFSET); + s5p_chip_id[1] = (readl(EXYNOS5430_PRO_ID + CHIPID1_OFFSET) & 0xFFFF); + + printf("\nChip ID : %04x%08x\n", s5p_chip_id[1], s5p_chip_id[0]); +#endif +} + +static void display_pmic_info(void) +{ +#if defined(CONFIG_PM) + unsigned char pmic_id = 0; + unsigned char rtc_ctrl = 0; + unsigned char wrstbi_ctrl = 0; + unsigned char read_vol_mif = 0; + unsigned char read_vol_egl = 0; + unsigned char read_vol_kfc = 0; + unsigned char read_vol_int = 0; + unsigned char read_vol_g3d = 0; + unsigned char ldo6 = 0, ldo7 = 0; + unsigned char ldo19 = 0, ldo20 = 0; + unsigned char ldo27 = 0, ldo28 = 0; + unsigned char ldo_dvs1 = 0, ldo_dvs2 = 0, ldo_dvs3 = 0; +#ifndef CONFIG_MACH_UNIVERSAL5430 + unsigned char enable_reg = 0; +#endif + + /* Read PMIC register value */ + IIC0_ERead(S2MPS13_ADDR, PMIC_ID, &pmic_id); + IIC0_ERead(S2MPS13_ADDR, RTC_BUF, &rtc_ctrl); + IIC0_ERead(S2MPS13_ADDR, WRSTBI_CTRL, &wrstbi_ctrl); + IIC0_ERead(S2MPS13_ADDR, LDO_DVS1, &ldo_dvs1); + IIC0_ERead(S2MPS13_ADDR, LDO_DVS2, &ldo_dvs2); + IIC0_ERead(S2MPS13_ADDR, LDO_DVS3, &ldo_dvs3); + IIC0_ERead(S2MPS13_ADDR, LDO6_CTRL, &ldo6); + IIC0_ERead(S2MPS13_ADDR, LDO7_CTRL, &ldo7); + IIC0_ERead(S2MPS13_ADDR, LDO19_CTRL, &ldo19); + IIC0_ERead(S2MPS13_ADDR, LDO20_CTRL, &ldo20); + IIC0_ERead(S2MPS13_ADDR, LDO27_CTRL, &ldo27); + IIC0_ERead(S2MPS13_ADDR, LDO28_CTRL, &ldo28); + IIC0_ERead(S2MPS13_ADDR, BUCK1_OUT, &read_vol_mif); + IIC0_ERead(S2MPS13_ADDR, BUCK2_OUT, &read_vol_egl); + IIC0_ERead(S2MPS13_ADDR, BUCK3_OUT, &read_vol_kfc); + IIC0_ERead(S2MPS13_ADDR, BUCK4_OUT, &read_vol_int); + IIC0_ERead(S2MPS13_ADDR, BUCK6_OUT, &read_vol_g3d); + + printf("\nPMIC: S2MPS13(REV%x)\n", pmic_id); + /* print BUCK voltage */ + if (pmic_id == REV_00) { + read_vol_mif += VDD_REG_VALUE_BASE; + read_vol_egl += VDD_REG_VALUE_BASE; + read_vol_kfc += VDD_REG_VALUE_BASE; + read_vol_int += VDD_REG_VALUE_BASE; + read_vol_g3d += VDD_REG_VALUE_BASE; + } + printf("MIF: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_mif)); + printf("EGL: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_egl)); + printf("KFC: %dmV\t\n", RD_BUCK_VOLT((unsigned int)read_vol_kfc)); + printf("INT: %dmV\t", RD_BUCK_VOLT((unsigned int)read_vol_int)); + printf("G3D: %dmV\t\n", RD_BUCK_VOLT((unsigned int)read_vol_g3d)); + /* print rtc_buf & wrstbi register value */ + printf("RTC_BUF: 0x%x, WRSTBI: 0x%x\n", rtc_ctrl, wrstbi_ctrl); + /* print ldo register value */ + printf("LDO6: 0x%x, LDO7: 0x%x\n", ldo6, ldo7); + printf("LDO19: 0x%x, LDO20: 0x%x\n", ldo19, ldo20); + printf("LDO27: 0x%x, LDO28: 0x%x\n", ldo27, ldo28); + printf("LDO_DVS1: 0x%x, LDO_DVS2: 0x%x, LDO_DVS3: 0x%x\n", + ldo_dvs1, ldo_dvs2, ldo_dvs3); + +#ifndef CONFIG_MACH_UNIVERSAL5430 + /* setup PMIC lm3560 */ + IIC2_ESetport(); + /* set GPC0[2], GPC0[3] output low */ + *(unsigned int *)0x14CC0040 &= ~0xFF00; + *(unsigned int *)0x14CC0040 |= 0x1100; + *(unsigned int *)0x14CC0044 &= ~0xC; + /* set GPF0[1] output high */ + *(unsigned int *)0x14CC01E0 &= ~0xF0; + *(unsigned int *)0x14CC01E0 |= 0x10; + *(unsigned int *)0x14CC01E4 |= 0x2; + + IIC2_EWrite(LM3560_ADDR, 0xE0, 0xEF); + IIC2_EWrite(LM3560_ADDR, 0xC0, 0xFF); + IIC2_EWrite(LM3560_ADDR, 0x11, 0x78); +#endif +#endif +} + +static void display_boot_device_info(void) +{ + struct exynos5430_power *pmu = (struct exynos5430_power *)EXYNOS5430_POWER_BASE; + int OmPin; + + OmPin = readl(&pmu->inform3); + + printf("\nChecking Boot Mode ..."); + + if (OmPin == BOOT_MMCSD) { + printf(" SDMMC\n"); + } else if (OmPin == BOOT_EMMC) { + printf(" EMMC\n"); + } else if (OmPin == BOOT_EMMC_4_4) { + printf(" EMMC\n"); + } else { + printf(" Please check OM_pin\n"); + } +} + +int board_init(void) +{ + display_bl1_version(); + + display_chip_id(); + + display_pmic_info(); + + display_boot_device_info(); + + gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE) + + get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE) + + get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_5_SIZE) + + get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_4_SIZE) + + get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_5_SIZE) + + get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_6_SIZE); + + gd->ram_size += get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_END_SIZE); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1, + PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2, + PHYS_SDRAM_2_SIZE); + gd->bd->bi_dram[2].start = PHYS_SDRAM_3; + gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3, + PHYS_SDRAM_3_SIZE); + gd->bd->bi_dram[3].start = PHYS_SDRAM_4; + gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4, + PHYS_SDRAM_4_SIZE); + gd->bd->bi_dram[4].start = PHYS_SDRAM_5; + gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5, + PHYS_SDRAM_5_SIZE); + gd->bd->bi_dram[5].start = PHYS_SDRAM_6; + gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6, + PHYS_SDRAM_6_SIZE); + gd->bd->bi_dram[6].start = PHYS_SDRAM_7; + gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7, + PHYS_SDRAM_7_SIZE); + if (GetPOPType() == 0) { + gd->bd->bi_dram[7].start = PHYS_SDRAM_8; + gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8, + PHYS_SDRAM_8_END_SIZE - CONFIG_UBOOT_ATAG_RESERVED_DRAM); + } else if (GetPOPType() == 1) { + gd->bd->bi_dram[7].start = PHYS_SDRAM_8; + gd->bd->bi_dram[7].size = PHYS_SDRAM_8_SIZE; + gd->bd->bi_dram[8].start = PHYS_SDRAM_9; + gd->bd->bi_dram[8].size = PHYS_SDRAM_9_SIZE; + gd->bd->bi_dram[9].start = PHYS_SDRAM_10; + gd->bd->bi_dram[9].size = PHYS_SDRAM_10_SIZE; + gd->bd->bi_dram[10].start = PHYS_SDRAM_11; + gd->bd->bi_dram[10].size = PHYS_SDRAM_11_SIZE; + gd->bd->bi_dram[11].start = PHYS_SDRAM_12; + gd->bd->bi_dram[11].size = PHYS_SDRAM_12_SIZE - CONFIG_UBOOT_ATAG_RESERVED_DRAM; + } +} + +int board_eth_init(bd_t *bis) +{ + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ +#if defined(CONFIG_MACH_UNIVERSAL5430) + printf("\nBoard: UNIVERSAL5430\n"); +#else + printf("\nBoard: XYREF5430\n"); +#endif + + return 0; +} +#endif + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + struct exynos5430_power *pmu = (struct exynos5430_power *)EXYNOS5430_POWER_BASE; + int err, OmPin; + + OmPin = readl(&pmu->inform3); + + err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); + if (err) { + debug("SDMMC2 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); + if (err) { + debug("MSHC0 not configured\n"); + return err; + } + + switch (OmPin) { + case BOOT_EMMC_4_4: +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif + break; + default: +#if defined(USE_MMC2) + set_mmc_clk(PERIPH_ID_SDMMC2, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC2, 4); +#endif +#if defined(USE_MMC0) + set_mmc_clk(PERIPH_ID_SDMMC0, 1); + + err = s5p_mmc_init(PERIPH_ID_SDMMC0, 8); +#endif + break; + } + + return err; +} +#endif + +static int board_uart_init(void) +{ + int err; + + err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE); + if (err) { + debug("UART0 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE); + if (err) { + debug("UART1 not configured\n"); + return err; + } + + err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE); + if (err) { + debug("UART2 not configured\n"); + return err; + } + + return 0; +} + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f(void) +{ +#ifdef CONFIG_PREP_BOARDCONFIG_FOR_KERNEL + /* power off domain */ + writel(0x00000000, EXYNOS5430_POWER_G2D_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_GSCL_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_MSCL_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_G3D_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_AUD_CONFIGURATION); + //writel(0x00000000, EXYNOS5430_POWER_FSYS_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_MFC0_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_MFC1_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_HEVC_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_ISP_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_CAM0_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_CAM1_CONFIGURATION); + writel(0x00000000, EXYNOS5430_POWER_DISP_CONFIGURATION); +#endif + + return board_uart_init(); +} +#endif + +int board_late_init(void) +{ + struct exynos5430_power *pmu = (struct exynos5430_power *)EXYNOS5430_POWER_BASE; + unsigned int rst_stat = 0; + + rst_stat = readl(&pmu->rst_stat); + printf("rst_stat : 0x%x\n", rst_stat); +#ifdef CONFIG_RAMDUMP_MODE +#ifndef CONFIG_MACH_UNIVERSAL5430 + struct exynos5430_gpio_alive *gpio_alive = + (struct exynos5430_gpio_alive *) exynos5430_get_base_gpio_alive(); + unsigned int gpio_debounce_cnt = 0; + int err; + + err = exynos_pinmux_config(PERIPH_ID_INPUT_X2_0, PINMUX_FLAG_NONE); + if (err) { + debug("GPX2_0 INPUT not configured\n"); + return err; + } + while (s5p_gpio_get_value(&gpio_alive->a2, 0) == 0) { + /* wait for 50ms */ + if (gpio_debounce_cnt < 5) { + udelay(DEBOUNCE_DELAY); + gpio_debounce_cnt++; + } else { + /* run fastboot */ + run_command("fastboot", 0); + break; + } + } +#endif + /* check reset status for ramdump */ + if ((rst_stat & (WRESET | CORTEXA7_WDTRESET | CORTEXA15_WDTRESET)) + || (readl(&pmu->sysip_dat0) == CONFIG_RAMDUMP_MODE) + || (readl(CONFIG_RAMDUMP_SCRATCH) == CONFIG_RAMDUMP_MODE)) { + /* run fastboot */ + run_command("fastboot", 0); + } +#endif +#ifdef CONFIG_RECOVERY_MODE + u32 second_boot_info = readl(second_boot_info_base); + + if (second_boot_info == 1) { + printf("###Recovery Mode###\n"); + writel(0x0, second_boot_info_base); + setenv("bootcmd", CONFIG_RECOVERYCOMMAND); + } +#endif + + if ((readl(&pmu->sysip_dat0)) == CONFIG_FACTORY_RESET_MODE) { + writel(0x0, &pmu->sysip_dat0); + setenv("bootcmd", CONFIG_FACTORY_RESET_BOOTCOMMAND); + } + return 0; +} + +#ifdef CONFIG_PREP_BOARDCONFIG_FOR_KERNEL +void prep_boardconfig_for_kernel(void) +{ + /* power on domain */ + writel(0x0000000f, EXYNOS5430_POWER_G2D_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_GSCL_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_MSCL_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_G3D_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_AUD_CONFIGURATION); + //writel(0x0000000f, EXYNOS5430_POWER_FSYS_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_MFC0_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_MFC1_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_HEVC_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_ISP_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_CAM0_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_CAM1_CONFIGURATION); + writel(0x0000000f, EXYNOS5430_POWER_DISP_CONFIGURATION); +} +#endif + +unsigned int get_board_rev(void) +{ + struct exynos5430_power *pmu = (struct exynos5430_power *)EXYNOS5430_POWER_BASE; + unsigned int rev = 0; + int adc_val = 0; + unsigned int timeout, con; + + return (rev | pmic); +} diff --git a/boards.cfg b/boards.cfg index 2d36d8333..1e50b7a6b 100644 --- a/boards.cfg +++ b/boards.cfg @@ -250,6 +250,19 @@ origen arm armv7 origen samsung exynos s5pc210_universal arm armv7 universal_c210 samsung exynos smdk5250 arm armv7 smdk5250 samsung exynos smdkv310 arm armv7 smdkv310 samsung exynos +espresso3250 arm armv7 espresso3250 samsung exynos +universal3250 arm armv7 espresso3250 samsung exynos +shiri arm armv7 espresso3250 samsung exynos +smdk4412 arm armv7 smdk4x12 samsung exynos +smdk4212 arm armv7 smdk4x12 samsung exynos +smdk5410 arm armv7 smdk5410 samsung exynos +smdk5412 arm armv7 smdk5412 samsung exynos +universal5412 arm armv7 smdk5412 samsung exynos +xyref4415 arm armv7 xyref4415 samsung exynos +xyref5260 arm armv7 xyref5260 samsung exynos +xyref5430 arm armv7 xyref5430 samsung exynos +universal5260 arm armv7 xyref5260 samsung exynos +universal5430 arm armv7 xyref5430 samsung exynos trats arm armv7 trats samsung exynos harmony arm armv7 harmony nvidia tegra2 seaboard arm armv7 seaboard nvidia tegra2 diff --git a/common/Makefile b/common/Makefile index 483eb4daa..e3cfee9de 100644 --- a/common/Makefile +++ b/common/Makefile @@ -80,6 +80,8 @@ ifdef CONFIG_POST COBJS-$(CONFIG_CMD_DIAG) += cmd_diag.o endif COBJS-$(CONFIG_CMD_DISPLAY) += cmd_display.o +COBJS-$(CONFIG_CMD_LCD) += cmd_lcd.o +COBJS-$(CONFIG_CMD_LCDTEXT) += cmd_lcdtext.o COBJS-$(CONFIG_CMD_DTT) += cmd_dtt.o COBJS-$(CONFIG_CMD_ECHO) += cmd_echo.o COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o @@ -121,7 +123,9 @@ ifdef CONFIG_PHYLIB COBJS-$(CONFIG_CMD_MII) += cmd_mdio.o endif COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o +COBJS-$(CONFIG_CMD_MMC) += cmd_movi.o COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o +COBJS-$(CONFIG_CMD_MMC) += cmd_mmc_fdisk.o COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o COBJS-$(CONFIG_MP) += cmd_mp.o COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o @@ -159,6 +163,10 @@ COBJS-y += cmd_usb.o COBJS-y += usb.o usb_hub.o COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif +COBJS-$(CONFIG_S3C_USBD) += cmd_usbd.o +COBJS-$(CONFIG_EXYNOS_USBD3) += cmd_usbd3.o +COBJS-$(CONFIG_FASTBOOT) += cmd_fastboot.o +COBJS-$(CONFIG_FASTBOOT) += decompress_ext4.o COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 45e726af8..6db2e3b5c 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -582,6 +582,13 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ulong load_end = 0; int ret; boot_os_fn *boot_fn; + +#ifdef CONFIG_SECURE_BOOT +#ifndef CONFIG_SPL_BUILD + security_check(); +#endif +#endif + #ifdef CONFIG_NEEDS_MANUAL_RELOC static int relocated = 0; @@ -1585,10 +1592,15 @@ static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc, return 0; } -static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bootm_headers_t images; +#ifdef CONFIG_SECURE_BOOT +#ifndef CONFIG_SPL_BUILD + security_check(); +#endif +#endif if (bootz_start(cmdtp, flag, argc, argv, &images)) return 1; @@ -1616,7 +1628,6 @@ static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) fixup_silent_linux(); #endif arch_preboot_os(); - do_bootm_linux(0, argc, argv, &images); #ifdef DEBUG puts("\n## Control returned to monitor - resetting...\n"); diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c index 79b1e2fb6..5b5f1f01b 100644 --- a/common/cmd_ext2.c +++ b/common/cmd_ext2.c @@ -48,6 +48,11 @@ #error DOS or EFI partition support must be selected #endif +enum _FS_TYPE{ + FS_TYPE_EXT2, + FS_TYPE_EXT3 +}; + /* #define EXT2_DEBUG */ #ifdef EXT2_DEBUG @@ -258,3 +263,71 @@ U_BOOT_CMD( " - load binary file 'filename' from 'dev' on 'interface'\n" " to address 'addr' from ext2 filesystem" ); + +int ext_format (int argc, char *argv[], char filesystem_type) +{ + int dev=0; + int part=1; + char *ep; + block_dev_desc_t *dev_desc=NULL; + + if (argc < 2) { + printf("usage : ext2format <interface> <dev[:part]>\n"); + return (0); + } + dev = (int)simple_strtoul (argv[2], &ep, 16); + dev_desc=get_dev(argv[1],dev); + if (dev_desc==NULL) { + puts ("\n** Invalid boot device **\n"); + return 1; + } + if (*ep) { + if (*ep != ':') { + puts ("\n** Invalid boot device, use 'dev[:part]' **\n"); + return 1; + } + part = (int)simple_strtoul(++ep, NULL, 16); + if (part > 4 || part < 1) { + puts ("** Partition Number shuld be 1 ~ 4 **\n"); + return 1; + } + } + printf("Start format MMC%d partition%d ....\n", dev, part); + + switch (filesystem_type) { + case FS_TYPE_EXT3: + case FS_TYPE_EXT2: + if (ext2fs_format(dev_desc, part, filesystem_type) != 0) + printf("Format failure!!!\n"); + break; + + default: + printf("FileSystem Type Value is not invalidate=%d \n", filesystem_type); + break; + } + return 0; +} + +int do_ext2_format (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + return ext_format(argc, argv, FS_TYPE_EXT2); +} + +U_BOOT_CMD( + ext2format, 3, 0, do_ext2_format, + "ext2format - disk format by ext2\n", + "<interface(only support mmc)> <dev:partition num>\n" + " - format by ext2 on 'interface'\n" +); + +int do_ext3_format (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + return ext_format(argc, argv, FS_TYPE_EXT3); +} + +U_BOOT_CMD( + ext3format, 3, 0, do_ext3_format, + "ext3format - disk format by ext3\n", + "<interface(only support mmc)> <dev:partition num>\n" + " - format by ext3 on 'interface'\n" +); diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c new file mode 100644 index 000000000..feebba670 --- /dev/null +++ b/common/cmd_fastboot.c @@ -0,0 +1,2243 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd + * + * Many parts of this program were copied from the work of Windriver. + * Major modifications are as follows: + * - Adding default partition table. + * - Supporting OneNAND device. + * - Supporting SDMMC device. + * - Adding new command, sdfuse. + * - Removing Lock scheme. + * - Removing direct flash operations because they are implemented at others. + * - Fixing several bugs + * This program is under the same License with the their work. + * + * This is their Copyright: + * + * (C) Copyright 2008 - 2009 + * Windriver, <www.windriver.com> + * Tom Rix <Tom.Rix@windriver.com> + * + * 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 + * + * Part of the rx_handler were copied from the Android project + * Specifically rx command parsing in the usb_rx_data_complete + * function of the file bootable/bootloader/legacy/usbloader/usbloader.c + * + * The logical naming of flash comes from the Android project + * Thse structures and functions that look like fastboot_flash_* + * They come from bootable/bootloader/legacy/libboot/flash.c + * + * This is their Copyright: + * + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <asm/byteorder.h> +#include <common.h> +#include <command.h> +#include <asm/arch/movi_partition.h> +#include <fastboot.h> +#if defined(CFG_FASTBOOT_SDMMCBSP) +#include <mmc.h> +#endif +#include <decompress_ext4.h> + +#if defined(CONFIG_S5P6450) +DECLARE_GLOBAL_DATA_PTR; +#endif + +#if defined(CONFIG_EXYNOS4X12) +#define OmPin readl(EXYNOS4_POWER_BASE + INFORM3_OFFSET) +#elif defined(CONFIG_CPU_EXYNOS4415) || defined(CONFIG_CPU_EXYNOS3250) +#define OmPin readl(EXYNOS4_POWER_BASE + INFORM3_OFFSET) +#elif defined(CONFIG_CPU_EXYNOS5260) +#define OmPin readl(EXYNOS5260_POWER_BASE + INFORM3_OFFSET) +#elif defined(CONFIG_CPU_EXYNOS5430) +#define OmPin readl(EXYNOS5430_POWER_BASE + INFORM3_OFFSET) +#else +#define OmPin readl(EXYNOS5_POWER_BASE + INFORM3_OFFSET) +#endif + +#if defined(CONFIG_FASTBOOT) + +/* Use do_reset for fastboot's 'reboot' command */ +//extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +/* Use do_fat_fsload for direct image fusing from sd card */ +//extern int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +/* Use do_setenv and do_saveenv to permenantly save data */ +int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int do_setenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +/* Use do_bootm and do_go for fastboot's 'boot' command */ +//int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +#if defined(CFG_FASTBOOT_ONENANDBSP) +#define CFG_FASTBOOT_FLASHCMD do_onenand +/* Use do_onenand for fastboot's flash commands */ +extern int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +#elif defined(CFG_FASTBOOT_NANDBSP) +#define CFG_FASTBOOT_FLASHCMD do_nand +/* Use do_nand for fastboot's flash commands */ +extern int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +#endif + +#if defined(CFG_FASTBOOT_SDMMCBSP) +int do_movi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +int do_mmcops(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +int do_mmcops_secure(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); +int get_mmc_part_info(char *device_name, int part_num, int *start, int *count, unsigned char *pid); +struct mmc *find_mmc_device(int dev_num); +#endif + +#ifdef CONFIG_USE_LCD +extern void Display_Turnoff(void); +extern void LCD_setfgcolor(unsigned int color); +extern void LCD_setleftcolor(unsigned int color); +extern void LCD_setprogress(int percentage); +#endif + +/* Forward decl */ +static int rx_handler (const unsigned char *buffer, unsigned int buffer_size); +static void reset_handler (void); + +/* cmd_fastboot_interface in fastboot.h */ +static struct cmd_fastboot_interface interface = +{ + .rx_handler = rx_handler, + .reset_handler = reset_handler, + .product_name = NULL, + .serial_no = NULL, + .nand_block_size = 0, + .transfer_buffer = (unsigned char *)0xffffffff, + .transfer_buffer_size = 0, +}; +#if defined(CONFIG_RAMDUMP_MODE) +static unsigned int is_ramdump = 0; +#endif +static unsigned int download_size; +static unsigned int download_bytes; +//static unsigned int download_bytes_unpadded; +static unsigned int download_error; + +/* To support the Android-style naming of flash */ +#define MAX_PTN 16 +static fastboot_ptentry ptable[MAX_PTN]; +static unsigned int pcount; +static int static_pcount = -1; +static unsigned int gflag_reboot; + +/* Default partition table (see cpu/.../fastboot.c) */ +extern fastboot_ptentry *ptable_default; +extern unsigned int ptable_default_size; + +static void set_env(char *var, char *val) +{ + char *setenv[4] = { "setenv", NULL, NULL, NULL, }; + + setenv[1] = var; + setenv[2] = val; + + do_env_set(NULL, 0, 3, setenv); +} + +static void save_env(struct fastboot_ptentry *ptn, + char *var, char *val) +{ +#ifndef CFG_FASTBOOT_SDMMCBSP + char start[32], length[32]; + char ecc_type[32]; + + char *lock[5] = { "nand", "lock", NULL, NULL, NULL, }; + char *unlock[5] = { "nand", "unlock", NULL, NULL, NULL, }; + char *ecc[4] = { "nand", "ecc", NULL, NULL, }; + char *saveenv[2] = { "setenv", NULL, }; + + lock[2] = unlock[2] = start; + lock[3] = unlock[3] = length; + + set_env (var, val); + + /* Some flashing requires the nand's ecc to be set */ + ecc[2] = ecc_type; + if ((ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) && + (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC)) { + /* Both can not be true */ + printf("Warning can not do hw and sw ecc for partition '%s'\n", ptn->name); + printf("Ignoring these flags\n"); + } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC) { + sprintf(ecc_type, "hw"); + CFG_FASTBOOT_FLASHCMD(NULL, 0, 3, ecc); + } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC) { + sprintf(ecc_type, "sw"); + CFG_FASTBOOT_FLASHCMD(NULL, 0, 3, ecc); + } + sprintf(start, "0x%x", ptn->start); + sprintf(length, "0x%x", ptn->length); + + /* This could be a problem is there is an outstanding lock */ + CFG_FASTBOOT_FLASHCMD(NULL, 0, 4, unlock); + do_saveenv(NULL, 0, 1, saveenv); + CFG_FASTBOOT_FLASHCMD(NULL, 0, 4, lock); +#endif +} + +static void reset_handler () +{ + /* If there was a download going on, bail */ + download_size = 0; + download_bytes = 0; + //download_bytes_unpadded = 0; + download_error = 0; +} + + +/* When save = 0, just parse. The input is unchanged + When save = 1, parse and do the save. The input is changed */ +static int parse_env(void *ptn, char *err_string, int save, int debug) +{ + int ret = 1; + unsigned int sets = 0; + unsigned int comment_start = 0; + char *var = NULL; + char *var_end = NULL; + char *val = NULL; + char *val_end = NULL; + unsigned int i; + + char *buff = (char *)interface.transfer_buffer; + //unsigned int size = download_bytes_unpadded; + unsigned int size = download_bytes; + + /* The input does not have to be null terminated. + This will cause a problem in the corner case + where the last line does not have a new line. + Put a null after the end of the input. + + WARNING : Input buffer is assumed to be bigger + than the size of the input */ + if (save) + buff[size] = 0; + + for (i = 0; i < size; i++) { + + if (NULL == var) { + + /* + * Check for comments, comment ok only on + * mostly empty lines + */ + if (buff[i] == '#') + comment_start = 1; + + if (comment_start) { + if ((buff[i] == '\r') || + (buff[i] == '\n')) { + comment_start = 0; + } + } else { + if (!((buff[i] == ' ') || + (buff[i] == '\t') || + (buff[i] == '\r') || + (buff[i] == '\n'))) { + /* + * Normal whitespace before the + * variable + */ + var = &buff[i]; + } + } + + } else if (((NULL == var_end) || (NULL == val)) && + ((buff[i] == '\r') || (buff[i] == '\n'))) { + + /* This is the case when a variable + is unset. */ + + if (save) { + /* Set the var end to null so the + normal string routines will work + + WARNING : This changes the input */ + buff[i] = '\0'; + + save_env(ptn, var, val); + + if (debug) + printf("Unsetting %s\n", var); + } + + /* Clear the variable so state is parse is back + to initial. */ + var = NULL; + var_end = NULL; + sets++; + } else if (NULL == var_end) { + if ((buff[i] == ' ') || + (buff[i] == '\t')) + var_end = &buff[i]; + } else if (NULL == val) { + if (!((buff[i] == ' ') || + (buff[i] == '\t'))) + val = &buff[i]; + } else if (NULL == val_end) { + if ((buff[i] == '\r') || + (buff[i] == '\n')) { + /* look for escaped cr or ln */ + if ('\\' == buff[i - 1]) { + /* check for dos */ + if ((buff[i] == '\r') && + (buff[i+1] == '\n')) + buff[i + 1] = ' '; + buff[i - 1] = buff[i] = ' '; + } else { + val_end = &buff[i]; + } + } + } else { + sprintf(err_string, "Internal Error"); + + if (debug) + printf("Internal error at %s %d\n", + __FILE__, __LINE__); + return 1; + } + /* Check if a var / val pair is ready */ + if (NULL != val_end) { + if (save) { + /* Set the end's with nulls so + normal string routines will + work. + + WARNING : This changes the input */ + *var_end = '\0'; + *val_end = '\0'; + + save_env(ptn, var, val); + + if (debug) + printf("Setting %s %s\n", var, val); + } + + /* Clear the variable so state is parse is back + to initial. */ + var = NULL; + var_end = NULL; + val = NULL; + val_end = NULL; + + sets++; + } + } + + /* Corner case + Check for the case that no newline at end of the input */ + if ((NULL != var) && + (NULL == val_end)) { + if (save) { + /* case of val / val pair */ + if (var_end) + *var_end = '\0'; + /* else case handled by setting 0 past + the end of buffer. + Similar for val_end being null */ + save_env(ptn, var, val); + + if (debug) { + if (var_end) + printf("Trailing Setting %s %s\n", var, val); + else + printf("Trailing Unsetting %s\n", var); + } + } + sets++; + } + /* Did we set anything ? */ + if (0 == sets) + sprintf(err_string, "No variables set"); + else + ret = 0; + + return ret; +} + +static int saveenv_to_ptn(struct fastboot_ptentry *ptn, char *err_string) +{ + int ret = 1; + int save = 0; + int debug = 0; + + /* err_string is only 32 bytes + Initialize with a generic error message. */ + sprintf(err_string, "%s", "Unknown Error"); + + /* Parse the input twice. + Only save to the enviroment if the entire input if correct */ + save = 0; + if (0 == parse_env(ptn, err_string, save, debug)) { + save = 1; + ret = parse_env(ptn, err_string, save, debug); + } + return ret; +} + +#if defined(CFG_FASTBOOT_ONENANDBSP) || defined(CFG_FASTBOOT_NANDBSP) +static int write_to_ptn(struct fastboot_ptentry *ptn, unsigned int addr, unsigned int size) +{ + int ret = 1; + char start[32], length[32]; + char wstart[32], wlength[32], wbuffer[32]; + char write_type[32]; + + /* do_nand and do_onenand do not check argv[0] */ + char *argv_erase[5] = { NULL, "erase", NULL, NULL, NULL, }; + char *argv_write[6] = { NULL, NULL, NULL, NULL, NULL, NULL, }; + + argv_erase[2] = start; + argv_erase[3] = length; + + argv_write[1] = write_type; + argv_write[2] = wbuffer; + argv_write[3] = wstart; + argv_write[4] = wlength; + + printf("flashing '%s'\n", ptn->name); + + sprintf(start, "0x%x", ptn->start); + if (ptn->length == 0) + { + CFG_FASTBOOT_FLASHCMD(NULL, 0, 3, argv_erase); + } + else + { + if (strcmp(ptn->name, "bootloader")) + { + sprintf(length, "0x%x", ptn->length); + CFG_FASTBOOT_FLASHCMD(NULL, 0, 4, argv_erase); + } + } + /* Which flavor of write to use */ + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS) + { + sprintf(write_type, "write.yaffs"); + sprintf(wlength, "0x%x", size); + } + else + { + sprintf(write_type, "write"); + if (interface.nand_block_size && + (size % interface.nand_block_size)) + { + size = (size + interface.nand_block_size - 1) + / interface.nand_block_size * interface.nand_block_size; + } + + sprintf(wlength, "0x%x", size); + } + sprintf(wbuffer, "0x%x", addr); + sprintf(wstart, "0x%x", ptn->start); + + if (!strcmp(ptn->name, "bootloader")) + { + argv_write[2] = "u-boot"; + sprintf(wstart, "0x%x", addr); + } + + ret = CFG_FASTBOOT_FLASHCMD(NULL, 0, 5, argv_write); + +#if 0 + if (0 == repeat) { + if (ret) /* failed */ + save_block_values(ptn, 0, 0); + else /* success */ + save_block_values(ptn, ptn->start, download_bytes); + } +#endif + + return ret; +} +#endif + +#if defined(CFG_FASTBOOT_SDMMCBSP) +#if defined(CONFIG_S5P6450) && !defined(CONFIG_EMMC_4_4) +#define DEV_NUM 1 +#else +#define DEV_NUM 0 +#endif +static int write_to_ptn_sdmmc(struct fastboot_ptentry *ptn, unsigned int addr, unsigned int size) +{ + int ret = 1; + char cmd[32], device[32], part[32], part2[32]; + char start[32], length[32], buffer[32], run_cmd[32]; + char dev_num[2]; + char *argv[6] = { NULL, NULL, NULL, NULL, NULL, NULL, }; + int argc = 0; + char *nul_buf; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + char *nul_buf_align; +#endif + struct mmc *mmc; + + if ((ptn->length != 0) && (size > ptn->length)) + { + printf("Error: Image size is larger than partition size!\n"); + return 1; + } + + printf("flashing '%s'\n", ptn->name); + + argv[1] = cmd; + sprintf(cmd, "write"); + + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD) + { + if (check_compress_ext4((char*)addr,ptn->length) != 0) { + argv[2] = device; + argv[3] = buffer; + argv[4] = start; + argv[5] = length; + + sprintf(device, "mmc %d", DEV_NUM); + sprintf(buffer, "0x%x", addr); + sprintf(start, "0x%x", (ptn->start / CFG_FASTBOOT_SDMMC_BLOCKSIZE)); + sprintf(length, "0x%x", (ptn->length / CFG_FASTBOOT_SDMMC_BLOCKSIZE)); + + ret = do_mmcops(NULL, 0, 6, argv); + } else { + uint bl_st = ptn->start / CFG_FASTBOOT_SDMMC_BLOCKSIZE; + uint bl_cnt = ptn->length / CFG_FASTBOOT_SDMMC_BLOCKSIZE; + + printf("Compressed ext4 image\n"); + +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + nul_buf_align = calloc(sizeof(char), 512*1024 + 4); + if (((unsigned int)nul_buf_align % 8) == 0) + nul_buf = nul_buf_align; + else + nul_buf = nul_buf_align + 4; +#else + nul_buf = calloc(sizeof(char), 512*1024); +#endif + if (nul_buf == NULL) { + printf("Error: calloc failed for nul_buf\n"); + ret = 1; + return ret; + } + + mmc = find_mmc_device(DEV_NUM); + + if (bl_st&0x3ff) + { + mmc->block_dev.block_write(DEV_NUM, bl_st, 1024 -(bl_st&0x3ff), nul_buf); + + printf("*** erase start block 0x%x ***\n", bl_st); + + bl_cnt = bl_cnt - (1024-(bl_st&0x3ff)); + bl_st = (bl_st&(~0x3ff))+1024; + } + + if (bl_cnt&0x3ff) + { + mmc->block_dev.block_write(DEV_NUM, bl_st+bl_cnt-(bl_cnt&0x3ff), bl_cnt&0x3ff, nul_buf); + + printf("*** erase block length 0x%x ***\n", bl_cnt); + + bl_cnt = bl_cnt - (bl_cnt&0x3ff); + } + +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + free(nul_buf_align); +#else + free(nul_buf); +#endif + + if (bl_cnt>>10) + { + argv[2] = buffer; + argv[3] = device; + argv[4] = start; + argv[5] = length; + + sprintf(cmd, "erase"); + sprintf(buffer, "user"); + sprintf(device, "%d", DEV_NUM); + sprintf(start, "%x", bl_st); + sprintf(length, "%x", bl_cnt); + printf("mmc %s %s %s %s %s\n", argv[1], argv[2], argv[3], argv[4], argv[5]); + + ret = do_mmcops(NULL, 0, 6, argv); + } + else + { + printf("*** erase block length too small ***\n"); + } + ret = write_compressed_ext4((char*)addr, + ptn->start / CFG_FASTBOOT_SDMMC_BLOCKSIZE); + } + } + else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD) + { + argv[2] = part; + argv[3] = dev_num; + argv[4] = buffer; + sprintf(dev_num, "%d", DEV_NUM); + + argc = 5; + + /* use the partition name that can be understood by a command, movi */ + if (!strcmp(ptn->name, "bootloader")) + { + if (OmPin == 7){ + argv[2] = part2; + argv[3] = part; + argv[4] = dev_num; + argv[5] = buffer; + argc = 6; + strncpy(part2, "zero", 7); + strncpy(part, "u-boot", 7); + sprintf(run_cmd,"emmc open 0"); + run_command(run_cmd, 0); + } + else + strncpy(part, "u-boot", 7); + + } + else if (!strcmp(ptn->name, "fwbl1")) + { + if (OmPin == 7){ + argv[2] = part2; + argv[3] = ptn->name; + argv[4] = dev_num; + argv[5] = buffer; + argc = 6; + strncpy(part2, "zero", 7); + sprintf(run_cmd,"emmc open 0"); + run_command(run_cmd, 0); + } + else + argv[2] = ptn->name; + + } + else if (!strcmp(ptn->name, "bl2")) + { + if (OmPin == 7){ + argv[2] = part2; + argv[3] = ptn->name; + argv[4] = dev_num; + argv[5] = buffer; + argc = 6; + strncpy(part2, "zero", 7); + sprintf(run_cmd,"emmc open 0"); + run_command(run_cmd, 0); + } + else + argv[2] = ptn->name; + + } + else if (!strcmp(ptn->name, "tzsw")) + { + if (OmPin == 7){ + argv[2] = part2; + argv[3] = ptn->name; + argv[4] = dev_num; + argv[5] = buffer; + argc = 6; + strncpy(part2, "zero", 7); + sprintf(run_cmd,"emmc open 0"); + run_command(run_cmd, 0); + } + else + argv[2] = ptn->name; + + } + else if (!strcmp(ptn->name, "ramdisk")) + { + strncpy(part, "rootfs", 7); + argv[5] = length; + sprintf(length, "0x%x", + ((size + CFG_FASTBOOT_SDMMC_BLOCKSIZE - 1) + / CFG_FASTBOOT_SDMMC_BLOCKSIZE ) * CFG_FASTBOOT_SDMMC_BLOCKSIZE); + +#ifdef CONFIG_ROOTFS_ATAGS + char ramdisk_size[32]; +#ifdef CONFIG_SECURE_ROOTFS + sprintf(ramdisk_size, "0x%x", size - 256); +#else + sprintf(ramdisk_size, "0x%x", size); +#endif + setenv("rootfslen", ramdisk_size); + saveenv_one_variable("rootfslen", ramdisk_size); +#endif + + argc++; + } +#ifdef CONFIG_CHARGER_LOGO + else if (!strcmp(ptn->name, "charger")) + { + argv[2] = part; + strncpy(part, "charger", 7); + } +#endif +#ifdef CONFIG_BOOT_LOGO + else if (!strcmp(ptn->name, "bootlogo")) + { + argv[2] = part; + strncpy(part, "logo", 7); + } +#endif + else /* kernel */ + { + argv[2] = ptn->name; + } + sprintf(buffer, "0x%x", addr); + + ret = do_movi(NULL, 0, argc, argv); + + if (OmPin == 7 && (!strcmp(ptn->name, "fwbl1") || !strcmp(ptn->name, "bootloader") || + !strcmp(ptn->name, "bl2") || !strcmp(ptn->name, "tzsw"))){ + sprintf(run_cmd,"emmc close 0"); + run_command(run_cmd, 0); + } + + /* the return value of do_movi is different from usual commands. Hence the followings. */ + ret = 1 - ret; + } + + return ret; +} +#endif + +#if defined(CONFIG_RAMDUMP_MODE) +static void start_ramdump(void *buf) +{ + unsigned *args; + args = (unsigned *)buf; + + printf("\nramdump start address is [0x%x]\n", *args); + printf("ramdump size is [0x%x]\n", *(args + 1)); + + if (!fastboot_tx_mem((const char *)*args, *(args + 1))) + printf("Failed ramdump~! \n"); + else + printf("Finished ramdump~! \n"); +} +#endif + +static int rx_handler (const unsigned char *buffer, unsigned int buffer_size) +{ + int ret = 1; + + /* Use 65 instead of 64 + null gets dropped + strcpy's need the extra byte */ + char response[65]; + + if (download_size) + { + /* Something to download */ + + if (buffer_size) + { + /* Handle possible overflow */ + unsigned int transfer_size = download_size - download_bytes; + + if (buffer_size < transfer_size) + transfer_size = buffer_size; + + /* Save the data to the transfer buffer */ + memcpy (interface.transfer_buffer + download_bytes, + buffer, transfer_size); + + download_bytes += transfer_size; + + /* Check if transfer is done */ + if (download_bytes >= download_size) + { + /* Reset global transfer variable, + Keep download_bytes because it will be + used in the next possible flashing command */ + download_size = 0; + + if (download_error) + { + /* There was an earlier error */ + sprintf(response, "ERROR"); + } + else + { + /* Everything has transferred, + send the OK response */ + sprintf(response, "OKAY"); + } + fastboot_tx_status(response, strlen(response), FASTBOOT_TX_ASYNC); + + printf("\ndownloading of %d bytes finished\n", download_bytes); +#ifdef CONFIG_USE_LCD + LCD_setprogress(0); +#endif +#if defined(CONFIG_RAMDUMP_MODE) + if (is_ramdump) { + is_ramdump = 0; + start_ramdump((void *)buffer); + } +#endif + } + + /* Provide some feedback */ + if (download_bytes && download_size && + 0 == (download_bytes & (0x100000 - 1))) + { + /* Some feeback that the download is happening */ + if (download_error) + printf("X"); + else + printf("."); + if (0 == (download_bytes % + (80 * 0x100000))) + printf("\n"); +#ifdef CONFIG_USE_LCD + LCD_setfgcolor(0x2E8B57); + LCD_setprogress(download_bytes / (download_size/100)); +#endif + } + } + else + { + /* Ignore empty buffers */ + printf("Warning empty download buffer\n"); + printf("Ignoring\n"); + } + ret = 0; + } + else + { + /* A command */ + + /* Cast to make compiler happy with string functions */ + const char *cmdbuf = (char *) buffer; + + /* Generic failed response */ + sprintf(response, "FAIL"); + + /* reboot + Reboot the board. */ + if (memcmp(cmdbuf, "reboot", 6) == 0) + { + if (!strcmp(cmdbuf + 6, "-bootloader")) + { + gflag_reboot = 1; + return 0; + } + else + { + memset(interface.transfer_buffer, 0x0, FASTBOOT_REBOOT_MAGIC_SIZE); + } + + sprintf(response,"OKAY"); + fastboot_tx_status(response, strlen(response), FASTBOOT_TX_SYNC); + //udelay (1000000); /* 1 sec */ + +#ifdef CONFIG_USE_LCD + /* Turning LCD off before SW reset. */ + Display_Turnoff(); +#endif + do_reset (NULL, 0, 0, NULL); + + /* This code is unreachable, + leave it to make the compiler happy */ + return 0; + } + + /* getvar + Get common fastboot variables + Board has a chance to handle other variables */ + if (memcmp(cmdbuf, "getvar:", 7) == 0) + { + strcpy(response,"OKAY"); + + if (!strcmp(cmdbuf + 7, "version")) + { + strcpy(response + 4, FASTBOOT_VERSION); + } + else if (!strcmp(cmdbuf + 7, "product")) + { + if (interface.product_name) + strcpy(response + 4, interface.product_name); + } + else if (!strcmp(cmdbuf + 7, "serialno")) + { + if (interface.serial_no) + strcpy(response + 4, interface.serial_no); + } + else if (!strcmp(cmdbuf + 7, "downloadsize")) + { + if (interface.transfer_buffer_size) + sprintf(response + 4, "%08x", interface.transfer_buffer_size); + } +#ifdef CONFIG_MACH_SHIRI + else if (!strcmp(cmdbuf + 7, "fdisk")) + { + ret = run_command("fdisk -c 0 400 2600 200", 0); + if(ret == 0) + { + strcpy(response + 4, "fdisk ok"); + } + else + { + strcpy(response + 4, "fdisk fail"); + } + } + else if (!strcmp(cmdbuf + 7, "ok")) + { + ret = run_command("fatformat mmc 0:1;ext3format mmc 0:2;ext3format mmc 0:3;ext3format mmc 0:4;", 0); + if(ret == 0) + { + strcpy(response + 4, "formati ok"); + } + else + { + strcpy(response + 4, "format fail"); + } + } +#endif + + else + { + fastboot_getvar(cmdbuf + 7, response + 4); + } + ret = 0; + goto send_tx_status; + } + + /* erase + Erase a register flash partition + Board has to set up flash partitions */ + if (memcmp(cmdbuf, "erase:", 6) == 0) + { + struct fastboot_ptentry *ptn; + + ptn = fastboot_flash_find_ptn(cmdbuf + 6); + if (ptn == 0) + { + sprintf(response, "FAILpartition does not exist"); + ret = 0; + goto send_tx_status; + } + + char start[32], length[32]; + int status; + + if (OmPin == BOOT_MMCSD) { + printf("erasing(formatting) '%s'\n", ptn->name); + } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) { + printf("erasing '%s'\n", ptn->name); + } else if (OmPin == BOOT_ONENAND) { + printf("erasing '%s'\n", ptn->name); + } + +#ifdef CONFIG_USE_LCD + LCD_setfgcolor(0x7FFFD4); + LCD_setprogress(100); +#endif + + if (OmPin == BOOT_MMCSD) { + // Temporary (but, simplest) implementation + char run_cmd[80]; + status = 1; + if (!strcmp(ptn->name, "userdata")) + { + sprintf(run_cmd, "ext3format mmc 0:3"); + status = run_command(run_cmd, 0); + } + else if (!strcmp(ptn->name, "cache")) + { + sprintf(run_cmd, "ext3format mmc 0:4"); + status = run_command(run_cmd, 0); + } + else if (!strcmp(ptn->name, "fat")) + { + sprintf(run_cmd, "fatformat mmc 0:1"); + status = run_command(run_cmd, 0); + } + } else if(OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) { + char run_cmd[80]; + status = 1; + if (!strcmp(ptn->name, "userdata")) { + sprintf(run_cmd, "ext3format mmc 0:3"); + status = run_command(run_cmd, 0); + } else if (!strcmp(ptn->name, "cache")) { + sprintf(run_cmd, "ext3format mmc 0:4"); + status = run_command(run_cmd, 0); + } else if (!strcmp(ptn->name, "fat")) { + sprintf(run_cmd, "fatformat mmc 0:1"); + status = run_command(run_cmd, 0); + } + } +//#else + else if(OmPin == BOOT_ONENAND) { +#if defined(CFG_FASTBOOT_ONENANDBSP) + int argc_erase = 4; + /* do_nand and do_onenand do not check argv[0] */ + char *argv_erase[5] = { NULL, "erase", NULL, NULL, NULL, }; + + argv_erase[2] = start; + argv_erase[3] = length; + + sprintf(start, "0x%x", ptn->start); + sprintf(length, "0x%x", ptn->length); + + if (ptn->length == 0) + argc_erase = 3; + + status = CFG_FASTBOOT_FLASHCMD(NULL, 0, argc_erase, argv_erase); +#endif + } + + if (status) + { + sprintf(response,"FAILfailed to erase partition"); + } + else + { + printf("partition '%s' erased\n", ptn->name); + sprintf(response, "OKAY"); + } + ret = 0; + goto send_tx_status; + } + + /* download + download something .. + What happens to it depends on the next command after data */ + if (memcmp(cmdbuf, "download:", 9) == 0) + { + /* save the size */ + download_size = simple_strtoul(cmdbuf + 9, NULL, 16); + /* Reset the bytes count, now it is safe */ + download_bytes = 0; + /* Reset error */ + download_error = 0; + + printf("Starting download of %d bytes\n", download_size); + + if (0 == download_size) + { + /* bad user input */ + sprintf(response, "FAILdata invalid size"); + } + else if (download_size > interface.transfer_buffer_size) + { + /* set download_size to 0 because this is an error */ + download_size = 0; + sprintf(response, "FAILdata too large"); + } + else + { + /* The default case, the transfer fits + completely in the interface buffer */ + sprintf(response, "DATA%08x", download_size); + } + ret = 0; + goto send_tx_status; + } + + /* boot + boot what was downloaded + + WARNING WARNING WARNING + + This is not what you expect. + The fastboot client does its own packaging of the + kernel. The layout is defined in the android header + file bootimage.h. This layeout is copiedlooks like this, + + ** + ** +-----------------+ + ** | boot header | 1 page + ** +-----------------+ + ** | kernel | n pages + ** +-----------------+ + ** | ramdisk | m pages + ** +-----------------+ + ** | second stage | o pages + ** +-----------------+ + ** + + What is a page size ? + The fastboot client uses 2048 + + The is the default value of CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE + */ + if (memcmp(cmdbuf, "boot", 4) == 0) + { + if ((download_bytes) && + (CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE < download_bytes)) + { + /* Note: We store zImage and ramdisk at different partitions */ + char addr_kernel[32]; + char addr_ramdisk[32]; + int pageoffset_ramdisk; + + char *bootz[3] = { "bootz", NULL, NULL, }; + //char *go[3] = { "go", NULL, NULL, }; + + /* + * Use this later to determine if a command line was passed + * for the kernel. + */ + struct fastboot_boot_img_hdr *fb_hdr = + (struct fastboot_boot_img_hdr *) interface.transfer_buffer; + + /* Skip the mkbootimage header */ + image_header_t *hdr = + (image_header_t *) + &interface.transfer_buffer[CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE]; + + printf("Kernel size: %08x\n", fb_hdr->kernel_size); + printf("Ramdisk size: %08x\n", fb_hdr->ramdisk_size); + + pageoffset_ramdisk = 1 + (fb_hdr->kernel_size + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE - 1) / CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE; + + bootz[1] = addr_kernel; + sprintf(addr_kernel, "0x%x", CFG_FASTBOOT_ADDR_KERNEL); + memcpy((void *)CFG_FASTBOOT_ADDR_KERNEL, + interface.transfer_buffer + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE, + fb_hdr->kernel_size); + bootz[2] = addr_ramdisk; + sprintf(addr_ramdisk, "0x%x", CFG_FASTBOOT_ADDR_RAMDISK); + memcpy((void *)CFG_FASTBOOT_ADDR_RAMDISK, interface.transfer_buffer + + (pageoffset_ramdisk * CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE), + fb_hdr->ramdisk_size); + + /* Execution should jump to kernel so send the response + now and wait a bit. */ + sprintf(response, "OKAY"); + fastboot_tx_status(response, strlen(response), FASTBOOT_TX_SYNC); + udelay (1000000); /* 1 sec */ + +#ifdef CONFIG_ROOTFS_ATAGS + char ramdisk_size[32]; + sprintf(ramdisk_size, "0x%x", fb_hdr->ramdisk_size); + setenv("rootfslen", ramdisk_size); +#endif + if (ntohl(hdr->ih_magic) == IH_MAGIC) { + /* Looks like a kernel.. */ + printf("Booting kernel..\n"); + + /* + * Check if the user sent a bootargs down. + * If not, do not override what is already there + */ + if (strlen ((char *) &fb_hdr->cmdline[0])) + set_env ("bootargs", (char *) &fb_hdr->cmdline[0]); + + do_bootz (NULL, 0, 2, bootz); + } else { + /* Raw image, maybe another uboot */ + printf("Booting raw image..\n"); + + //do_go (NULL, 0, 2, go); + do_bootz (NULL, 0, 3, bootz); + } + printf("ERROR : bootting failed\n"); + printf("You should reset the board\n"); + } + sprintf(response, "FAILinvalid boot image"); + ret = 0; + } + + /* flash + Flash what was downloaded */ + if (memcmp(cmdbuf, "flash:", 6) == 0) + { + if (download_bytes == 0) + { + sprintf(response, "FAILno image downloaded"); + ret = 0; + goto send_tx_status; + } + + struct fastboot_ptentry *ptn; + +#ifdef CONFIG_USE_LCD + LCD_setfgcolor(0x8B4500); + LCD_setprogress(100); +#endif + + /* Special case: boot.img */ + if (!strcmp("boot", cmdbuf + 6)) + { + int pageoffset_ramdisk; + + struct fastboot_boot_img_hdr *fb_hdr = + (struct fastboot_boot_img_hdr *) interface.transfer_buffer; + image_header_t *hdr = + (image_header_t *) + &interface.transfer_buffer[CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE]; + + printf("Kernel size: %08x\n", fb_hdr->kernel_size); + printf("Ramdisk size: %08x\n", fb_hdr->ramdisk_size); + + ptn = fastboot_flash_find_ptn("kernel"); + if (ptn->length && fb_hdr->kernel_size > ptn->length) + { + sprintf(response, "FAILimage too large for partition"); + goto send_tx_status; + } + + if (OmPin == BOOT_ONENAND) { +#if defined(CFG_FASTBOOT_ONENANDBSP) + ret = write_to_ptn(ptn, + (unsigned int)interface.transfer_buffer + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE, + fb_hdr->kernel_size); +#endif + } else if (OmPin == BOOT_MMCSD) { + ret = write_to_ptn_sdmmc(ptn, + (unsigned int)interface.transfer_buffer + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE, + fb_hdr->kernel_size); + } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) { + ret = write_to_ptn_sdmmc(ptn, + (unsigned int)interface.transfer_buffer + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE, + fb_hdr->kernel_size); + } + + pageoffset_ramdisk = + 1 + (fb_hdr->kernel_size + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE - 1) + / CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE; + ptn = fastboot_flash_find_ptn("ramdisk"); + if (ptn->length && fb_hdr->ramdisk_size > ptn->length) + { + sprintf(response, "FAILimage too large for partition"); + goto send_tx_status; + } + + if (OmPin == BOOT_ONENAND) { +#if defined(CFG_FASTBOOT_ONENANDBSP) + ret |= write_to_ptn(ptn, + (unsigned int)interface.transfer_buffer + (pageoffset_ramdisk * CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE), + fb_hdr->ramdisk_size); +#endif + } else if (OmPin == BOOT_MMCSD) { + ret |= write_to_ptn_sdmmc(ptn, + (unsigned int)interface.transfer_buffer + (pageoffset_ramdisk * CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE), + fb_hdr->ramdisk_size); + } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) { + ret |= write_to_ptn_sdmmc(ptn, + (unsigned int)interface.transfer_buffer + (pageoffset_ramdisk * CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE), + fb_hdr->ramdisk_size); + } + if (ret) + { + printf("flashing '%s' failed\n", "kernel+ramdisk"); + sprintf(response, "FAILfailed to flash partition"); + } + else + { + printf("partition '%s' flashed\n", "kernel+ramdisk"); + sprintf(response, "OKAY"); + } + + ret = 0; + goto send_tx_status; + } + + ptn = fastboot_flash_find_ptn(cmdbuf + 6); + if (ptn == 0) + { + sprintf(response, "FAILpartition does not exist"); + } + else if ((download_bytes > ptn->length) && (ptn->length != 0) && + !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) + { + sprintf(response, "FAILimage too large for partition"); + /* TODO : Improve check for yaffs write */ + } + else + { + /* Check if this is not really a flash write + but rather a saveenv */ + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) + { + /* Since the response can only be 64 bytes, + there is no point in having a large error message. */ + char err_string[32]; + if (saveenv_to_ptn(ptn, &err_string[0])) + { + printf("savenv '%s' failed : %s\n", ptn->name, err_string); + sprintf(response, "FAIL%s", err_string); + } + else + { + printf("partition '%s' saveenv-ed\n", ptn->name); + sprintf(response, "OKAY"); + } + } + else + { + /* Normal case */ + if (OmPin == BOOT_ONENAND) { +#if defined(CFG_FASTBOOT_ONENANDBSP) + if (write_to_ptn(ptn, (unsigned int)interface.transfer_buffer, download_bytes)) + { + printf("flashing '%s' failed\n", ptn->name); + sprintf(response, "FAILfailed to flash partition"); + } + else + { + printf("partition '%s' flashed\n", ptn->name); + sprintf(response, "OKAY"); + } +#endif + } else if (OmPin == BOOT_MMCSD) { + if (write_to_ptn_sdmmc(ptn, (unsigned int)interface.transfer_buffer, download_bytes)) + { + printf("flashing '%s' failed\n", ptn->name); + sprintf(response, "FAILfailed to flash partition"); + } + else + { + printf("partition '%s' flashed\n", ptn->name); + sprintf(response, "OKAY"); + } + + } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) { + if (write_to_ptn_sdmmc(ptn, (unsigned int)interface.transfer_buffer, download_bytes)) { + printf("flashing '%s' failed\n", ptn->name); + sprintf(response, "FAILfailed to flash partition"); + } else { + printf("partition '%s' flashed\n", ptn->name); + sprintf(response, "OKAY"); + } + + } + + } + } + ret = 0; + goto send_tx_status; + } + + /* verify */ + /* continue */ + /* powerdown */ + + /* oem + oem command. */ + if (memcmp(cmdbuf, "oem", 3) == 0) + { + sprintf(response,"INFOunknown OEM command"); + fastboot_tx_status(response, strlen(response), FASTBOOT_TX_ASYNC); + + sprintf(response,"OKAY"); + fastboot_tx_status(response, strlen(response), FASTBOOT_TX_ASYNC); + + return 0; + } + +#if defined(CONFIG_RAMDUMP_MODE) + if (memcmp(cmdbuf, "ramdump:", 8) == 0) + { + printf("\nGot ramdump command\n"); + is_ramdump = 1; + /* save the size */ + download_size = simple_strtoul(cmdbuf + 8, NULL, 16); + /* Reset the bytes count, now it is safe */ + download_bytes = 0; + /* Reset error */ + download_error = 0; + + printf("Starting download of %d bytes\n", download_size); + + if (0 == download_size) + { + /* bad user input */ + sprintf(response, "FAILdata invalid size"); + } + else if (download_size > interface.transfer_buffer_size) + { + /* set download_size to 0 because this is an error */ + download_size = 0; + sprintf(response, "FAILdata too large"); + } + else + { + /* The default case, the transfer fits + completely in the interface buffer */ + sprintf(response, "DATA%08x", download_size); + } + ret = 0; + goto send_tx_status; + } +#endif +send_tx_status: + fastboot_tx_status(response, strlen(response), FASTBOOT_TX_ASYNC); + +#ifdef CONFIG_USE_LCD + LCD_setprogress(0); +#endif + } /* End of command */ + + return ret; +} + + +static int check_against_static_partition(struct fastboot_ptentry *ptn) +{ + int ret = 0; + struct fastboot_ptentry *c; + int i; + + for (i = 0; i < static_pcount; i++) { + c = fastboot_flash_get_ptn((unsigned int) i); + + if (0 == ptn->length) + break; + + if ((ptn->start >= c->start) && + (ptn->start < c->start + c->length)) + break; + + if ((ptn->start + ptn->length > c->start) && + (ptn->start + ptn->length <= c->start + c->length)) + break; + + if ((0 == strcmp(ptn->name, c->name)) && + (0 == strcmp(c->name, ptn->name))) + break; + } + + if (i >= static_pcount) + ret = 1; + return ret; +} + + +static unsigned long long memparse(char *ptr, char **retptr) +{ + char *endptr; /* local pointer to end of parsed string */ + + unsigned long ret = simple_strtoul(ptr, &endptr, 0); + + switch (*endptr) { + case 'M': + case 'm': + ret <<= 10; + case 'K': + case 'k': + ret <<= 10; + endptr++; + default: + break; + } + + if (retptr) + *retptr = endptr; + + return ret; +} + + +static int add_partition_from_environment(char *s, char **retptr) +{ + unsigned long size; + unsigned long offset = 0; + char *name; + int name_len; + int delim; + unsigned int flags; + struct fastboot_ptentry part; + + size = memparse(s, &s); + if (0 == size) { + printf("Error:FASTBOOT size of parition is 0\n"); + return 1; + } + + /* fetch partition name and flags */ + flags = 0; /* this is going to be a regular partition */ + delim = 0; + /* check for offset */ + if (*s == '@') { + s++; + offset = memparse(s, &s); + } else { + printf("Error:FASTBOOT offset of parition is not given\n"); + return 1; + } + + /* now look for name */ + if (*s == '(') + delim = ')'; + + if (delim) { + char *p; + + name = ++s; + p = strchr((const char *)name, delim); + if (!p) { + printf("Error:FASTBOOT no closing %c found in partition name\n", delim); + return 1; + } + name_len = p - name; + s = p + 1; + } else { + printf("Error:FASTBOOT no partition name for \'%s\'\n", s); + return 1; + } + + /* test for options */ + while (1) { + if (strncmp(s, "i", 1) == 0) { + flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_I; + s += 1; + } else if (strncmp(s, "yaffs", 5) == 0) { + /* yaffs */ + flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS; + s += 5; + } else if (strncmp(s, "swecc", 5) == 0) { + /* swecc */ + flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC; + s += 5; + } else if (strncmp(s, "hwecc", 5) == 0) { + /* hwecc */ + flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC; + s += 5; + } else { + break; + } + if (strncmp(s, "|", 1) == 0) + s += 1; + } + + /* enter this partition (offset will be calculated later if it is zero at this point) */ + part.length = size; + part.start = offset; + part.flags = flags; + + if (name) { + if (name_len >= sizeof(part.name)) { + printf("Error:FASTBOOT partition name is too long\n"); + return 1; + } + strncpy(&part.name[0], name, name_len); + /* name is not null terminated */ + part.name[name_len] = '\0'; + } else { + printf("Error:FASTBOOT no name\n"); + return 1; + } + + + /* Check if this overlaps a static partition */ + if (check_against_static_partition(&part)) { + printf("Adding: %s, offset 0x%8.8x, size 0x%8.8x, flags 0x%8.8x\n", + part.name, part.start, part.length, part.flags); + fastboot_flash_add_ptn(&part); + } + + /* return (updated) pointer command line string */ + *retptr = s; + + /* return partition table */ + return 0; +} + +#if defined(CONFIG_FASTBOOT) +static int set_partition_table() +{ + char fbparts[4096], *env; + + /* + * Place the runtime partitions at the end of the + * static paritions. First save the start off so + * it can be saved from run to run. + */ + if (static_pcount >= 0) + { + /* Reset */ + pcount = static_pcount; + } + else + { + /* Save */ + static_pcount = pcount; + } + env = getenv("fbparts"); + if (env) + { + unsigned int len; + len = strlen(env); + if (len && len < 4096) + { + char *s, *e; + + memcpy(&fbparts[0], env, len + 1); + printf("Fastboot: Adding partitions from environment\n"); + s = &fbparts[0]; + e = s + len; + while (s < e) + { + if (add_partition_from_environment(s, &s)) + { + printf("Error:Fastboot: Abort adding partitions\n"); + /* reset back to static */ + pcount = static_pcount; + break; + } + /* Skip a bunch of delimiters */ + while (s < e) + { + if ((' ' == *s) || + ('\t' == *s) || + ('\n' == *s) || + ('\r' == *s) || + (',' == *s)) { + s++; + } + else + { + break; + } + } + } + } + } + else if (ptable_default_size >= sizeof(fastboot_ptentry)) + { + printf("Fastboot: employ default partition information\n"); + //memcpy(ptable, ptable_default, ptable_default_size); + memcpy((void*)ptable, (void*)&ptable_default, ptable_default_size); + pcount = ptable_default_size / sizeof(fastboot_ptentry); + } + else + { + printf("No partition informations!"); + return 0; + } + +#if 1 // Debug + fastboot_flash_dump_ptn(); +#endif +#ifdef CONFIG_USE_LCD + LCD_setleftcolor(0x1024C0); +#endif + return 0; +} +#endif + +#if defined(CFG_FASTBOOT_SDMMCBSP) +static int set_partition_table_sdmmc() +{ + unsigned long long start, count; + unsigned char pid; + char dev_num[2]; + + sprintf(dev_num, "%d", DEV_NUM); + + pcount = 0; + + /* FW BL1 for fused chip */ + strcpy(ptable[pcount].name, "fwbl1"); + ptable[pcount].start = 0; + ptable[pcount].length = 0; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; + + /* BL2 */ + strcpy(ptable[pcount].name, "bl2"); + ptable[pcount].start = 0; + ptable[pcount].length = 0; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; + + /* Bootloader */ + strcpy(ptable[pcount].name, "bootloader"); + ptable[pcount].start = 0; + ptable[pcount].length = 0; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; + + /* TrustZone S/W */ + strcpy(ptable[pcount].name, "tzsw"); + ptable[pcount].start = 0; + ptable[pcount].length = 0; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; + + /* Kernel */ + strcpy(ptable[pcount].name, "kernel"); + ptable[pcount].start = 0; + ptable[pcount].length = 0; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; + + /* Ramdisk */ + strcpy(ptable[pcount].name, "ramdisk"); + ptable[pcount].start = 0; + ptable[pcount].length = PART_SIZE_ROOTFS; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; + +#ifdef CONFIG_CHARGER_LOGO + strcpy(ptable[pcount].name, "charger"); + ptable[pcount].start = 0; + ptable[pcount].length = PART_SIZE_CHARGER_LOGO; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; +#endif +#ifdef CONFIG_BOOT_LOGO + strcpy(ptable[pcount].name, "bootlogo"); + ptable[pcount].start = 0; + ptable[pcount].length = PART_SIZE_BOOT_LOGO; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD; + pcount++; +#endif + /* System */ + get_mmc_part_info(dev_num, 2, &start, &count, &pid); + if (pid != 0x83) + goto part_type_error; + strcpy(ptable[pcount].name, "system"); + ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD; + pcount++; + + /* Data */ + get_mmc_part_info(dev_num, 3, &start, &count, &pid); + if (pid != 0x83) + goto part_type_error; + strcpy(ptable[pcount].name, "userdata"); + ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD; + pcount++; + + /* Cache */ + get_mmc_part_info(dev_num, 4, &start, &count, &pid); + if (pid != 0x83) + goto part_type_error; + strcpy(ptable[pcount].name, "cache"); + ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD; + pcount++; + + /* fat */ + get_mmc_part_info(dev_num, 1, &start, &count, &pid); + if (pid != 0xc) + goto part_type_error; + strcpy(ptable[pcount].name, "fat"); + ptable[pcount].start = start * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].length = count * CFG_FASTBOOT_SDMMC_BLOCKSIZE; + ptable[pcount].flags = FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD; + pcount++; + +#if 1 // Debug + fastboot_flash_dump_ptn(); +#endif +#ifdef CONFIG_USE_LCD + LCD_setleftcolor(0x8a2be2); +#endif + return 0; + +part_type_error: + printf("Error: No MBR is found at SD/MMC.\n"); + printf("Hint: use fdisk command to make partitions.\n"); + + return -1; +} +#endif + +int do_fastboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int ret = 1; + int check_timeout = 0; + uint64_t timeout_endtime = 0; + uint64_t timeout_ticks = 0; + long timeout_seconds = -1; + int continue_from_disconnect = 0; + struct fastboot_ptentry *ptn; + unsigned int addr, size; + gflag_reboot = 0; +/* checking boot mode before to set partition table */ + switch(OmPin) { + case BOOT_ONENAND: + if (set_partition_table()) { + return 1; + } + break; + case BOOT_MMCSD: + case BOOT_EMMC_4_4: + case BOOT_EMMC: + if (set_partition_table_sdmmc()) { + return 1; + } + break; + case BOOT_NAND: + if (set_partition_table()) { + return 1; + } + break; + } + +#if 0 + if (set_partition_table()) + return 1; +#endif + + if ((argc > 1) && (0 == strcmp(argv[1], "flash"))){ + ptn = fastboot_flash_find_ptn(argv[2]); + if(ptn == NULL) { + printf("undefined image name !\n"); + return -1; + } + size = 0; + if(ptn->name[0] == 'r') + size = PART_SIZE_ROOTFS; + addr = simple_strtoul(argv[3], NULL, 16); + write_to_ptn_sdmmc(ptn, addr, size); + return 1; + } + + /* Time out */ + if (2 == argc) + { + long try_seconds; + char *try_seconds_end; + /* Check for timeout */ + try_seconds = simple_strtol(argv[1], &try_seconds_end, 10); + if ((try_seconds_end != argv[1]) && (try_seconds >= 0)) + { + check_timeout = 1; + timeout_seconds = try_seconds; + printf("Fastboot inactivity timeout %ld seconds\n", timeout_seconds); + } + } + + if (1 == check_timeout) + { + timeout_ticks = (uint64_t) (timeout_seconds * get_tbclk()); + } + + + do + { + continue_from_disconnect = 0; + + /* Initialize the board specific support */ + if (0 == fastboot_init(&interface)) + { + int poll_status; + + /* If we got this far, we are a success */ + ret = 0; + + timeout_endtime = get_ticks(); + timeout_endtime += timeout_ticks; + + while (1) + { + uint64_t current_time = 0; + poll_status = fastboot_poll(); + + if (1 == check_timeout) + current_time = get_ticks(); + + /* Check if the user wanted to terminate with ^C */ + if ( ((poll_status != FASTBOOT_OK) && (ctrlc())) || gflag_reboot) + { + printf("Fastboot ended by user\n"); + continue_from_disconnect = 0; + break; + } + + if (FASTBOOT_ERROR == poll_status) + { + /* Error */ + printf("Fastboot error \n"); + break; + } + else if (FASTBOOT_DISCONNECT == poll_status) + { + /* break, cleanup and re-init */ + printf("Fastboot disconnect detected\n"); + continue_from_disconnect = 1; + break; + } + else if ((1 == check_timeout) && + (FASTBOOT_INACTIVE == poll_status)) + { + /* No activity */ + if (current_time >= timeout_endtime) + { + printf("Fastboot inactivity detected\n"); + break; + } + } + else + { + /* Something happened */ + /* Actual works of parsing are done by rx_handler */ + if (1 == check_timeout) + { + /* Update the timeout endtime */ + timeout_endtime = current_time; + timeout_endtime += timeout_ticks; + } + } + } /* while (1) */ + } + + /* Reset the board specific support */ + fastboot_shutdown(); + +#ifdef CONFIG_USE_LCD + LCD_setfgcolor(0x000010); + LCD_setleftcolor(0x000010); + LCD_setprogress(100); +#endif + + /* restart the loop if a disconnect was detected */ + } while (continue_from_disconnect); + + return ret; +} + +U_BOOT_CMD( + fastboot, 4, 1, do_fastboot, + "fastboot- use USB Fastboot protocol\n", + "[inactive timeout]\n" + " - Run as a fastboot usb device.\n" + " - The optional inactive timeout is the decimal seconds before\n" + " - the normal console resumes\n" +); + + +#undef CONFIG_FASTBOOT_SDFUSE // sdfuse is not implemented yet. +#ifdef CONFIG_FASTBOOT_SDFUSE + +#include <part.h> +#include <fat.h> +#define CFG_FASTBOOT_SDFUSE_DIR "/sdfuse" +#ifdef CFG_FASTBOOT_SDMMCBSP +#define CFG_FASTBOOT_SDFUSE_MMCDEV 0 +#else +#define CFG_FASTBOOT_SDFUSE_MMCDEV 0 +#endif +#define CFG_FASTBOOT_SDFUSE_MMCPART 1 +/* + * part : partition name (This should be a defined name at ptable) + * file : file to read + */ +static int update_from_sd (char *part, char *file) +{ + int ret = 1; + + /* Read file */ + if (file != NULL) + { + long size; + unsigned long offset; + unsigned long count; + char filename[32]; + block_dev_desc_t *dev_desc=NULL; + + printf("Partition: %s, File: %s/%s\n", part, CFG_FASTBOOT_SDFUSE_DIR, file); +#ifdef CONFIG_USE_LCD + LCD_setfgcolor(0x2E8B57); + LCD_setprogress(100); +#endif + dev_desc = get_dev("mmc", CFG_FASTBOOT_SDFUSE_MMCDEV); + if (dev_desc == NULL) { + printf("** Invalid boot device **\n"); + return 1; + } + if (fat_register_device(dev_desc, CFG_FASTBOOT_SDFUSE_MMCPART) != 0) { + printf("** Invalid partition **\n"); + return 1; + } + sprintf(filename, "%s/%s", CFG_FASTBOOT_SDFUSE_DIR, file); + offset = CFG_FASTBOOT_TRANSFER_BUFFER; + count = 0; + size = file_fat_read (filename, (unsigned char *) offset, count); + + if (size == -1) { + printf("Failed to read %s\n", filename); + return 1; + } + + download_size = 0; // should be 0 + download_bytes = size; + + printf("%ld (0x%08x) bytes read\n", size, size); + } + else { + printf("Partition: %s\n", part); + + download_size = 0; // should be 0 + download_bytes = 0; + } + + /* Write image into partition */ + /* If file is empty or NULL, just erase the part. */ + { + char command[32]; + + if (download_bytes == 0) + sprintf(command, "%s:%s", "erase", part); + else + sprintf(command, "%s:%s", "flash", part); + + ret = rx_handler(command, sizeof(command)); + } + + return ret; +} + +/* SD Fusing : read images from FAT partition of SD Card, and write it to boot device. + * + * NOTE + * - sdfuse is not a original code of fastboot + * - Fusing image from SD Card is not a original part of Fastboot protocol. + * - This command implemented at this file to re-use an existing code of fastboot */ +int do_sdfuse (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int ret = 1; + int enable_reset = 0; + struct mmc *mmc = find_mmc_device(CFG_FASTBOOT_SDFUSE_MMCDEV); + + interface.nand_block_size = CFG_FASTBOOT_PAGESIZE * 64; + interface.transfer_buffer = (unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER; + interface.transfer_buffer_size = CFG_FASTBOOT_TRANSFER_BUFFER_SIZE; + + printf("[Fusing Image from SD Card.]\n"); + + if (set_partition_table()) + return 1; + + if ((argc == 2) && !strcmp(argv[1], "info")) + { + printf("sdfuse will read images from the followings:\n"); + printf(" sd/mmc device : mmc %d:%d\n", + CFG_FASTBOOT_SDFUSE_MMCDEV, CFG_FASTBOOT_SDFUSE_MMCPART); + printf(" directory : %s\n", CFG_FASTBOOT_SDFUSE_DIR); + printf(" booting device : %s\n", +#if defined(CFG_FASTBOOT_ONENANDBSP) + "OneNAND" +#elif defined(CFG_FASTBOOT_NANDBSP) + "NAND" +#elif defined(CFG_FASTBOOT_SDMMCBSP) + "MoviNAND" +#else +#error "Unknown booting device!" +#endif +#if defined(CONFIG_FUSED) + " (on eFused Chip)" +#endif + ); + return 0; + } + else if ((argc == 2) && !strcmp(argv[1], "flashall")) + { +#ifdef CONFIG_USE_LCD + LCD_turnon(); +#endif + + if (update_from_sd("boot", "boot.img")) + goto err_sdfuse; + if (update_from_sd("system", "system.img")) + goto err_sdfuse; + if (update_from_sd("userdata", NULL)) + goto err_sdfuse; + if (update_from_sd("cache", NULL)) + goto err_sdfuse; + + enable_reset = 1; + ret = 0; + } + else if ((argc == 4) && !strcmp(argv[1], "flash")) + { +#ifdef CONFIG_USE_LCD + LCD_turnon(); +#endif + + if (update_from_sd(argv[2], argv[3])) + goto err_sdfuse; + + ret = 0; + } + else if ((argc == 3) && !strcmp(argv[1], "erase")) + { +#ifdef CONFIG_USE_LCD + LCD_turnon(); +#endif + + if (update_from_sd(argv[2], NULL)) + goto err_sdfuse; + + ret = 0; + } + else + { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + + +err_sdfuse: +#ifdef CONFIG_USE_LCD + LCD_setfgcolor(0x000010); + LCD_setleftcolor(0x000010); + LCD_setprogress(100); +#endif + + if (enable_reset) + do_reset (NULL, 0, 0, NULL); + + return ret; +} + +U_BOOT_CMD( + sdfuse, 4, 1, do_sdfuse, + "sdfuse - read images from FAT partition of SD card and write them to booting device.\n", + "info - print primitive infomation.\n" + "sdfuse flashall - flash boot.img, system.img,\n" + " erase userdata, cache, and reboot.\n" + "sdfuse flash <partition> [ <filename> ] - write a file to a partition.\n" + "sdfuse erase <partition> - erase (format) a partition.\n" +); +#endif // CONFIG_FASTBOOT_SDFUSE + + +/* + * Android style flash utilties */ +void fastboot_flash_add_ptn(fastboot_ptentry *ptn) +{ + if (pcount < MAX_PTN) + { + memcpy(ptable + pcount, ptn, sizeof(*ptn)); + pcount++; + } +} + +void fastboot_flash_dump_ptn(void) +{ + unsigned int n; + + printf("[Partition table on "); + + switch(OmPin) { + case BOOT_ONENAND: + printf("OneNAND"); + break; + case BOOT_MMCSD: + case BOOT_EMMC_4_4: + case BOOT_EMMC: + printf("MoviNAND"); + break; + case BOOT_NAND: + printf("NAND"); + break; + } + printf("]\n"); + + for (n = 0; n < pcount; n++) + { + fastboot_ptentry *ptn = ptable + n; +#if 0 /* old format - decimal */ + printf("ptn %d name='%s' start=%d len=%d\n", + n, ptn->name, ptn->start, ptn->length); +#else + printf("ptn %d name='%s' ", n, ptn->name); + if (n == 0 || ptn->start) + printf("start=0x%X ", ptn->start); + else + printf("start=N/A "); + if (ptn->length) + printf("len=0x%X(~%dKB) ", ptn->length, ptn->length>>10); + else + printf("len=N/A "); + + if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS) + printf("(Yaffs)\n"); + else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD) + printf("(use hard-coded info. (cmd: movi))\n"); + else + printf("\n"); +#endif + } +} + + +fastboot_ptentry *fastboot_flash_find_ptn(const char *name) +{ + unsigned int n; + + for (n = 0; n < pcount; n++) + { + /* Make sure a substring is not accepted */ + if (strlen(name) == strlen(ptable[n].name)) + { + if (0 == strcmp(ptable[n].name, name)) + return ptable + n; + } + } + return 0; +} + +fastboot_ptentry *fastboot_flash_get_ptn(unsigned int n) +{ + if (n < pcount) { + return ptable + n; + } else { + return 0; + } +} + +unsigned int fastboot_flash_get_ptn_count(void) +{ + return pcount; +} + + + +#endif /* CONFIG_FASTBOOT */ + + diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 559a16d61..f0205d5f7 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -241,3 +241,48 @@ U_BOOT_CMD( " to 'dev' on 'interface'" ); #endif + +int do_fat_format(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int dev = 0; + int part = 1; + char *ep; + block_dev_desc_t *dev_desc = NULL; + + if (argc < 2) { + printf ("usage : fatformat <interface> <dev[:part]>\n"); + return(0); + } + + dev = (int)simple_strtoul (argv[2], &ep, 16); + dev_desc = get_dev(argv[1], dev); + + if (dev_desc == NULL) { + puts ("\n ** Invalid boot device **\n"); + return 1; + } + + if (*ep) { + if (*ep != ':') { + puts ("\n **Invald boot device,use 'dev[:part]'**\n"); + return 1; + } + part = (int)simple_strtoul(++ep, NULL, 16); + if (part > 4 || part <1) { + puts ("** Partition Number should be 1 ~ 4 **\n"); + } + } + printf("Start format MMC&d partition&d ...\n", dev, part); + if (fat_format_device(dev_desc, part) != 0) { + printf("Format failure!!!\n"); + } + + return 0; +} + +U_BOOT_CMD( + fatformat, 3, 0, do_fat_format, + "fatformat - disk format by FAT32\n", + "<interface(only support mmc)> <dev:partition num>\n" + " - format by FAT32 on 'interface'\n" +); diff --git a/common/cmd_lcd.c b/common/cmd_lcd.c new file mode 100644 index 000000000..f3ce777a4 --- /dev/null +++ b/common/cmd_lcd.c @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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 <command.h> +#include <led-display.h> + +#undef DEBUG_LCD + +#ifdef CONFIG_USE_LCD +extern void Lcd_read_bootlogo(void); +extern void Backlight_Turnon(void); +extern void Display_Turnon(void); +extern void Display_Turnoff(void); +extern void s5p_lcd_draw_bootlogo(void); +extern void LCD_setprogress(int percentage); +extern void LCD_clear_content(void); +#endif + +int do_lcd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char cmd; + + if (argc < 2) + return (0); + + cmd=argv[1][0]; + + switch(cmd-'0') + { + case 0: + printf("turnon\n"); + Display_Turnon(); + Lcd_read_bootlogo(); + s5p_lcd_draw_bootlogo(); + Backlight_Turnon(); + break; + case 1: + printf("turnoff\n"); + Display_Turnoff(); + break; + case 2: + printf("clear with black color\n"); + LCD_clear_content(); + break; + case 3: + printf("showprog with 100%\n"); + LCD_setprogress(100); + break; + case 4: + printf("turnon_clear_black\n"); + Display_Turnon(); + LCD_clear_content(); + Backlight_Turnon(); + break; + default: + switch(cmd-'a') + { + default: + printf("unknown command\n"); + return (0); + } + } + + return (0); +} + +/***************************************************/ + +U_BOOT_CMD( + lcd, CONFIG_SYS_MAXARGS, 2, do_lcd, + "control lcd for MIPI", + "<command number> [argument]\n" + " - turnon : 0\n" + " - turnoff : 1\n" + " - clear : 2, clear with 0x00000000 color\n" + " - showprog : 3, arguments is percentage, decimal\n" + " - clear_turnon : 4, turnon and clear with black color\n" +); diff --git a/common/cmd_lcdtext.c b/common/cmd_lcdtext.c new file mode 100644 index 000000000..6278b217b --- /dev/null +++ b/common/cmd_lcdtext.c @@ -0,0 +1,206 @@ +/* + * (C) Copyright 2014 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <command.h> + +#include <video_font.h> +#include <video_font_data.h> + +#define DEBUG_CMD_LCDTEXT +#undef DEBUG_CMD_LCDTEXT + +#ifdef DEBUG_CMD_LCDTEXT +#define dbg(x...) printf(x) +#else +#define dbg(x...) do { } while (0) +#endif + +#ifdef CONFIG_FB_ADDR +#define CFG_LCD_FBUFFER CONFIG_FB_ADDR +#else +#define CFG_LCD_FBUFFER (0x59000000) +#endif +#define LCD_WIDTH 240 +#define LCD_HEIGHT 240 + +#define RGB2888(r, g, b) (unsigned int)((r) << 16 | (g) << 8 | (b)) + +#define RGB2PIXEL(r, g, b) RGB2888(r, g, b) + +#define COLOR_INVALID (RGB2PIXEL(9, 1, 1)) +static unsigned int s_text_color = RGB2PIXEL(58, 110, 165); +static unsigned int s_text_color_bg = COLOR_INVALID; + +static int s_last_x = 0; +static int s_last_y = 0; + +static const unsigned char * getGlyph(unsigned char ascii) +{ + return video_fontdata + ((int)ascii * 16); //size 8x16 +} + +int do_draw_text (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int x, y, w, h, strike, i, j, k; + + unsigned int * data, * base; + unsigned char str[256]; //256 characters buffer! + unsigned char * glyph; + + base = CFG_LCD_FBUFFER; + w = LCD_WIDTH; + h = LCD_HEIGHT; + strike = w; + + if(argc == 2) + { + x = s_last_x; + y = s_last_y + 20; + str[0] = '\0'; + for(i = 1; i < argc; i++) + { + if(argv[i]) + { + strcat(str, argv[i]); + strcat(str, " "); + } + } + + } + else if(argc == 4) + { + x = simple_strtoul(argv[1], NULL, 10); + y = simple_strtoul(argv[2], NULL, 10); + + str[0] = '\0'; + for(i = 3; i < argc; i++) + { + if(argv[i]) + { + strcat(str, argv[i]); + strcat(str, " "); + } + } + } + else + { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + s_last_x = x; + s_last_y = y; + + + printf ("lcdtext draw: %s\n", str); + + if(x > w || y > h) + { + printf ("out of range, x=%d, y=%d, width=%d, height=%d\n", x, y, w, h); + return 1; + } + + if(!argv[3]) + { + printf ("no string input\n"); + return 1; + } + + for(i = 0; str[i] != '\0'; i++) + { + x += VIDEO_FONT_WIDTH; + x += 2; + if(x > w - 32) + break; //draw end + + data = base + y * strike + x; + glyph = getGlyph(str[i]); + for(j = 0; j < VIDEO_FONT_HEIGHT; j++) + { + unsigned char mask = 0x80; + for(k = 0; k < VIDEO_FONT_WIDTH; k++) + { + if(glyph[j] & mask) + { + data[k] = s_text_color; + dbg("#"); + } + else + { + if(s_text_color_bg != COLOR_INVALID) + data[k] = s_text_color_bg; + dbg(" "); + } + mask >>= 1; + } + data += strike; + dbg("\n"); + } + } +#ifdef CONFIG_MACH_SHIRI + SWTrigger_for_te(); +#endif + return 0; +} + +int do_set_text_color (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int r, g, b; + if (argc < 4) + { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + r = simple_strtoul(argv[1], NULL, 10); + g = simple_strtoul(argv[2], NULL, 10); + b = simple_strtoul(argv[3], NULL, 10); + s_text_color = RGB2PIXEL(r, g, b); + printf ("set text color to [%d, %d, %d]\n", r, g, b); + return 0; +} + +int do_set_text_bg_color (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int r, g, b; + if (argc < 4) + { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + r = simple_strtoul(argv[1], NULL, 10); + g = simple_strtoul(argv[2], NULL, 10); + b = simple_strtoul(argv[3], NULL, 10); + s_text_color_bg = RGB2PIXEL(r, g, b); + printf ("set text background color to [%d, %d, %d]\n", r, g, b); + return 0; +} + +U_BOOT_CMD( + lcdtext, CONFIG_SYS_MAXARGS, 1, do_draw_text, + "lcdtext - lcdtext [your text]\nlcdtext - lcdtext [x] [y] [your text]\n", + "draw text on screen, default font 8x8 ascii, color[58, 110, 165]\n" +); + +U_BOOT_CMD( + lcdtextcolor, CONFIG_SYS_MAXARGS, 1, do_set_text_color, + "lcdtextcolor - lcdtextcolor [R] [G] [B]\n", + "set text color in RGB\n" +); + +U_BOOT_CMD( + lcdtextcolorbg, CONFIG_SYS_MAXARGS, 1, do_set_text_bg_color, + "lcdtextcolorbg - lcdtextcolorbg [R] [G] [B]\n", + "set text background color in RGB\n" +); diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 750509da5..888e3c979 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -112,38 +112,51 @@ static void print_mmcinfo(struct mmc *mmc) puts("Capacity: "); print_size(mmc->capacity, "\n"); - printf("Bus Width: %d-bit\n", mmc->bus_width); + printf("Bus Width: %d-bit %s\n", mmc->bus_width, + mmc->ddr ? "DDR" : "SDR"); } int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct mmc *mmc; + int dev_num, err; - if (curr_device < 0) { - if (get_mmc_num() > 0) + if (argc == 2) + dev_num = simple_strtoul(argv[1], NULL, 10); + else if (curr_device < 0) { + if (get_mmc_num() > 0) { curr_device = 0; + dev_num = curr_device; + } else { puts("No MMC device available\n"); return 1; } } - mmc = find_mmc_device(curr_device); + mmc = find_mmc_device(dev_num); if (mmc) { - mmc_init(mmc); + mmc->has_init = 0; + + err = mmc_init(mmc); + if (err) { + printf("no mmc device at slot %x\n", dev_num); + return err; + } print_mmcinfo(mmc); return 0; } else { - printf("no mmc device at slot %x\n", curr_device); + printf("no mmc device at slot %x\n", dev_num); return 1; } } U_BOOT_CMD( - mmcinfo, 1, 0, do_mmcinfo, + mmcinfo, 2, 0, do_mmcinfo, "display MMC info", + "mmcinfo [dev_num]\n" " - device number of the device to dislay info of\n" "" ); @@ -261,10 +274,16 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) state = MMC_INVALID; if (state != MMC_INVALID) { - struct mmc *mmc = find_mmc_device(curr_device); - int idx = 2; - u32 blk, cnt, n; + int idx = 3; + if (state == MMC_ERASE) + idx = 4; + int dev = simple_strtoul(argv[idx - 1], NULL, 10); + struct mmc *mmc = find_mmc_device(dev); + u32 blk, cnt, count, n; void *addr; + int part, err; + + curr_device = dev; if (state != MMC_ERASE) { addr = (void *)simple_strtoul(argv[idx], NULL, 16); @@ -296,7 +315,47 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) cnt, addr); break; case MMC_ERASE: + + /* Select erase partition */ + if (strcmp(argv[2], "boot") == 0) { + part = 0; + /* Read Boot partition size. */ + count = mmc->boot_size_multi / mmc->read_bl_len; + } else if (strcmp(argv[2], "user") == 0) { + part = 1; + /* Read User partition size. */ + count = mmc->capacity / mmc->read_bl_len; + } else { + part = 1; + count = mmc->capacity / mmc->read_bl_len; + printf("Default erase user partition\n"); + } + + /* If input counter is larger than max counter */ + if ((blk + cnt) > count) { + cnt = (count - blk) - 1; + printf("Block count is Too BIG!!\n"); + } + + /* If input counter is 0 */ + if (!cnt ) { + cnt = (count - blk) - 1; + printf("Erase all from %d block\n", blk); + } + + if (part == 0) { + err = emmc_boot_open(mmc); + if (err) + printf("eMMC OPEN Failed.!!\n"); + } + n = mmc->block_dev.block_erase(curr_device, blk, cnt); + + if (part == 0) { + err = emmc_boot_close(mmc); + if (err) + printf("eMMC CLOSE Failed.!!\n"); + } break; default: BUG(); @@ -313,11 +372,124 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( mmc, 6, 1, do_mmcops, "MMC sub system", - "read addr blk# cnt\n" - "mmc write addr blk# cnt\n" - "mmc erase blk# cnt\n" + "mmc read [dev] addr blk# cnt\n" + "mmc write [dev] addr blk# cnt\n" + "mmc erase [boot | user] [dev] blk# cnt\n" "mmc rescan\n" "mmc part - lists available partition on current mmc device\n" "mmc dev [dev] [part] - show or set current mmc device [partition]\n" "mmc list - lists available devices"); + +int do_emmc(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int rc = 0; + u32 dev; + + switch (argc) { + case 5: + if (strcmp(argv[1], "partition") == 0) { + dev = simple_strtoul(argv[2], NULL, 10); + struct mmc *mmc = find_mmc_device(dev); + u32 bootsize = simple_strtoul(argv[3], NULL, 10); + u32 rpmbsize = simple_strtoul(argv[4], NULL, 10); + + if (!mmc) + rc = 1; + + rc = emmc_boot_partition_size_change(mmc, bootsize, rpmbsize); + if (rc == 0) { + printf("eMMC boot partition Size is %d MB.!!\n", bootsize); + printf("eMMC RPMB partition Size is %d MB.!!\n", rpmbsize); + } else { + printf("eMMC boot partition Size change Failed.!!\n"); + } + } else { + printf("Usage:\n%s\n", cmdtp->usage); + rc =1; + } + break; + + case 4: + if (strcmp(argv[1], "boot") == 0) { + int dev = simple_strtoul(argv[3], NULL, 10); + struct mmc *mmc = find_mmc_device(dev); + + if (!mmc) + rc = 1; + if (strcmp(argv[2], "on") == 0) { + rc = emmc_boot_control(mmc, 1); + if (rc == 0) + printf("eMMC boot mode enable\n"); + } else if (strcmp(argv[2], "off") == 0) { + rc = emmc_boot_control(mmc, 0); + if (rc == 0) + printf("eMMC boot mode disable\n"); + } else { + printf("Usage:\n%s\n", cmdtp->usage); + rc =1; + } + } else { + printf("Usage:\n%s\n", cmdtp->usage); + rc =1; + } + break; + + case 3: + if (strcmp(argv[1], "open") == 0) { + int dev = simple_strtoul(argv[2], NULL, 10); + struct mmc *mmc = find_mmc_device(dev); + + if (!mmc) + rc = 1; + + rc = emmc_boot_open(mmc); + + if (rc == 0) { + printf("eMMC OPEN Success.!!\n"); + printf("\t\t\t!!!Notice!!!\n"); + printf("!You must close eMMC boot Partition after all image writing!\n"); + printf("!eMMC boot partition has continuity at image writing time.!\n"); + printf("!So, Do not close boot partition, Before, all images is written.!\n"); + } else { + printf("eMMC OPEN Failed.!!\n"); + } + } else if (strcmp(argv[1], "close") == 0) { + int dev = simple_strtoul(argv[2], NULL, 10); + struct mmc *mmc = find_mmc_device(dev); + + if (!mmc) + rc = 1; + + rc = emmc_boot_close(mmc); + + if (rc == 0) { + printf("eMMC CLOSE Success.!!\n"); + } else { + printf("eMMC CLOSE Failed.!!\n"); + } + } else { + printf("Usage:\n%s\n", cmdtp->usage); + rc =1; + } + break; + case 0: + case 1: + case 2: + default: + printf("Usage:\n%s\n", cmdtp->usage); + rc = 1; + break; + } + + return rc; +} + + +U_BOOT_CMD( + emmc, 5, 0, do_emmc, + "Open/Close eMMC boot Partition", + "emmc open <device num> \n" + "emmc close <device num> \n" + "emmc boot on/off <device num> \n" + "emmc partition <device num> <boot partiton size MB> <RPMB partition size MB>\n"); #endif diff --git a/common/cmd_mmc_fdisk.c b/common/cmd_mmc_fdisk.c new file mode 100644 index 000000000..a37a817b5 --- /dev/null +++ b/common/cmd_mmc_fdisk.c @@ -0,0 +1,536 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * fdisk command for U-boot + * + * 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. + */ + +#include <common.h> +#include <command.h> +#include <mmc.h> + +#define BLOCK_SIZE 512 +#define BLOCK_END 0xFFFFFFFF +#define _10MB (10*1024*1024) +#define _100MB (100*1024*1024) +#define _8_4GB (1023*254*63) + +#define SYSTEM_PART_SIZE (400*1024*1024) +#define USER_DATA_PART_SIZE (2917*1024*1024UL) +#define CACHE_PART_SIZE (200*1024*1024) + +#define CHS_MODE 0 +#define LBA_MODE !(CHS_MODE) + +typedef struct +{ + int C_start; + int H_start; + int S_start; + + int C_end; + int H_end; + int S_end; + + int available_block; + int unit; + int total_block_count; + int addr_mode; // LBA_MODE or CHS_MODE +} SDInfo; + +typedef struct +{ + unsigned char bootable; + unsigned char partitionId; + + int C_start; + int H_start; + int S_start; + + int C_end; + int H_end; + int S_end; + + int block_start; + int block_count; + int block_end; +} PartitionInfo; + +///////////////////////////////////////////////////////////////// +int calc_unit(unsigned long long length, SDInfo sdInfo) +{ + if (sdInfo.addr_mode == CHS_MODE) + return ( (length / BLOCK_SIZE / sdInfo.unit + 1 ) * sdInfo.unit); + else + return ( (length / BLOCK_SIZE) ); +} + +///////////////////////////////////////////////////////////////// +void encode_chs(int C, int H, int S, unsigned char *result) +{ + *result++ = (unsigned char) H; + *result++ = (unsigned char) ( S + ((C & 0x00000300) >> 2) ); + *result = (unsigned char) (C & 0x000000FF); +} + +///////////////////////////////////////////////////////////////// +void encode_partitionInfo(PartitionInfo partInfo, unsigned char *result) +{ + *result++ = partInfo.bootable; + + encode_chs(partInfo.C_start, partInfo.H_start, partInfo.S_start, result); + result +=3; + *result++ = partInfo.partitionId; + + encode_chs(partInfo.C_end, partInfo.H_end, partInfo.S_end, result); + result += 3; + + memcpy(result, (unsigned char *)&(partInfo.block_start), 4); + result += 4; + + memcpy(result, (unsigned char *)&(partInfo.block_count), 4); +} + +///////////////////////////////////////////////////////////////// +void decode_partitionInfo(unsigned char *in, PartitionInfo *partInfo) +{ + partInfo->bootable = *in; + partInfo->partitionId = *(in + 4); + + memcpy((unsigned char *)&(partInfo->block_start), (in + 8), 4); + memcpy((unsigned char *)&(partInfo->block_count), (in +12), 4); +} + +///////////////////////////////////////////////////////////////// +void get_SDInfo(int block_count, SDInfo *sdInfo) +{ + int C, H, S; + + int C_max = 1023, H_max = 255, S_max = 63; + int H_start = 1, S_start = 1; + int diff_min = 0, diff = 0; + + if(block_count >= _8_4GB) + sdInfo->addr_mode = LBA_MODE; + else + sdInfo->addr_mode = CHS_MODE; + +//----------------------------------------------------- + if (sdInfo->addr_mode == CHS_MODE) + { + diff_min = C_max; + + for (H = H_start; H <= H_max; H++) + for (S = S_start; S <= S_max; S++) + { + C = block_count / (H * S); + + if ( (C <= C_max) ) + { + diff = C_max - C; + if (diff <= diff_min) + { + diff_min = diff; + sdInfo->C_end = C; + sdInfo->H_end = H; + sdInfo->S_end = S; + } + } + } + } +//----------------------------------------------------- + else + { + sdInfo->C_end = 1023; + sdInfo->H_end = 254; + sdInfo->S_end = 63; + } + +//----------------------------------------------------- + sdInfo->C_start = 0; + sdInfo->H_start = 1; + sdInfo->S_start = 1; + + sdInfo->total_block_count = block_count; + sdInfo->available_block = sdInfo->C_end * sdInfo->H_end * sdInfo->S_end; + sdInfo->unit = sdInfo->H_end * sdInfo->S_end; +} + +///////////////////////////////////////////////////////////////// +void make_partitionInfo(int LBA_start, int count, SDInfo sdInfo, PartitionInfo *partInfo) +{ + int temp = 0; + int _10MB_unit; + + partInfo->block_start = LBA_start; + +//----------------------------------------------------- + if (sdInfo.addr_mode == CHS_MODE) + { + partInfo->C_start = partInfo->block_start / (sdInfo.H_end * sdInfo.S_end); + temp = partInfo->block_start % (sdInfo.H_end * sdInfo.S_end); + partInfo->H_start = temp / sdInfo.S_end; + partInfo->S_start = temp % sdInfo.S_end + 1; + + if (count == BLOCK_END) + { + _10MB_unit = calc_unit(CFG_PARTITION_START, sdInfo); + partInfo->block_end = sdInfo.C_end * sdInfo.H_end * sdInfo.S_end - _10MB_unit - 1; + partInfo->block_count = partInfo->block_end - partInfo->block_start + 1; + + partInfo->C_end = partInfo->block_end / sdInfo.unit; + partInfo->H_end = sdInfo.H_end - 1; + partInfo->S_end = sdInfo.S_end; + } + else + { + partInfo->block_count = count; + + partInfo->block_end = partInfo->block_start + count - 1; + partInfo->C_end = partInfo->block_end / sdInfo.unit; + + temp = partInfo->block_end % sdInfo.unit; + partInfo->H_end = temp / sdInfo.S_end; + partInfo->S_end = temp % sdInfo.S_end + 1; + } + } +//----------------------------------------------------- + else + { + partInfo->C_start = 0; + partInfo->H_start = 1; + partInfo->S_start = 1; + + partInfo->C_end = 1023; + partInfo->H_end = 254; + partInfo->S_end = 63; + + if (count == BLOCK_END) + { + _10MB_unit = calc_unit(CFG_PARTITION_START, sdInfo); + partInfo->block_end = sdInfo.total_block_count - _10MB_unit - 1; + partInfo->block_count = partInfo->block_end - partInfo->block_start + 1; + + } + else + { + partInfo->block_count = count; + partInfo->block_end = partInfo->block_start + count - 1; + } + } +} + +///////////////////////////////////////////////////////////////// +int make_mmc_partition(int total_block_count, unsigned char *mbr, int flag, char *argv[]) +{ + int block_start = 0, block_offset; + + SDInfo sdInfo; + PartitionInfo partInfo[4]; + +/////////////////////////////////////////////////////////// + memset((unsigned char *)&sdInfo, 0x00, sizeof(SDInfo)); + +/////////////////////////////////////////////////////////// + get_SDInfo(total_block_count, &sdInfo); + +/////////////////////////////////////////////////////////// +// ݵ Unit Ѵ. + block_start = calc_unit(CFG_PARTITION_START, sdInfo); + if (flag) + block_offset = calc_unit((unsigned long long)simple_strtoul(argv[3], NULL, 0)*1024*1024, sdInfo); + else + block_offset = calc_unit(SYSTEM_PART_SIZE, sdInfo); + + partInfo[0].bootable = 0x00; + partInfo[0].partitionId = 0x83; + + make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[0]); + +/////////////////////////////////////////////////////////// + block_start += block_offset; + if (flag) + block_offset = calc_unit((unsigned long long)simple_strtoul(argv[4], NULL, 0)*1024*1024, sdInfo); + else + block_offset = calc_unit(USER_DATA_PART_SIZE, sdInfo); + + partInfo[1].bootable = 0x00; + partInfo[1].partitionId = 0x83; + + make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[1]); + +/////////////////////////////////////////////////////////// + block_start += block_offset; + if (flag) + block_offset = calc_unit((unsigned long long)simple_strtoul(argv[5], NULL, 0)*1024*1024, sdInfo); + else + block_offset = calc_unit(CACHE_PART_SIZE, sdInfo); + + partInfo[2].bootable = 0x00; + partInfo[2].partitionId = 0x83; + + make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[2]); + +/////////////////////////////////////////////////////////// + block_start += block_offset; + block_offset = BLOCK_END; + + partInfo[3].bootable = 0x00; + partInfo[3].partitionId = 0x0C; + + make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[3]); + +/////////////////////////////////////////////////////////// + memset(mbr, 0x00, sizeof(mbr)); + mbr[510] = 0x55; mbr[511] = 0xAA; + + encode_partitionInfo(partInfo[0], &mbr[0x1CE]); + encode_partitionInfo(partInfo[1], &mbr[0x1DE]); + encode_partitionInfo(partInfo[2], &mbr[0x1EE]); + encode_partitionInfo(partInfo[3], &mbr[0x1BE]); + + return 0; +} + +///////////////////////////////////////////////////////////////// +int get_mmc_block_count(char *device_name) +{ + int rv; + struct mmc *mmc; + int block_count = 0; + int dev_num; + + dev_num = simple_strtoul(device_name, NULL, 0); + + mmc = find_mmc_device(dev_num); + if (!mmc) + { + printf("mmc/sd device is NOT founded.\n"); + return -1; + } + + block_count = mmc->capacity / mmc->read_bl_len; + +// printf("block_count = %d\n", block_count); + return block_count; +} + +///////////////////////////////////////////////////////////////// +int get_mmc_mbr(char *device_name, unsigned char *mbr) +{ + int rv; + struct mmc *mmc; + int dev_num; + + dev_num = simple_strtoul(device_name, NULL, 0); + + mmc = find_mmc_device(dev_num); + if (!mmc) + { + printf("mmc/sd device is NOT founded.\n"); + return -1; + } + + rv = mmc->block_dev.block_read(dev_num, 0, 1, mbr); + + if(rv == 1) + return 0; + else + return -1; +} + +///////////////////////////////////////////////////////////////// +int put_mmc_mbr(unsigned char *mbr, char *device_name) +{ + int rv; + struct mmc *mmc; + int dev_num, err; + + dev_num = simple_strtoul(device_name, NULL, 0); + + mmc = find_mmc_device(dev_num); + if (!mmc) + { + printf("mmc/sd device is NOT founded.\n"); + return -1; + } + + rv = mmc->block_dev.block_write(dev_num, 0, 1, mbr); + + /* + * TODO : set boot partition size for emmc + * mmc->ext_csd.boot_size_multi = 0; + */ + err = mmc_init(mmc); + if (err) { + printf("Card NOT detected or Init Failed!!\n"); + return err; + } + + if(rv == 1) + return 0; + else + return -1; +} + +///////////////////////////////////////////////////////////////// +int get_mmc_part_info(char *device_name, int part_num, unsigned long long *block_start, unsigned long long *block_count, unsigned char *part_Id) +{ + int rv; + PartitionInfo partInfo; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mbr, 512); +#else + unsigned char mbr[512]; +#endif + + rv = get_mmc_mbr(device_name, mbr); + if(rv !=0) + return -1; + + switch(part_num) + { + case 1: + decode_partitionInfo(&mbr[0x1BE], &partInfo); + *block_start = partInfo.block_start; + *block_count = partInfo.block_count; + *part_Id = partInfo.partitionId; + break; + case 2: + decode_partitionInfo(&mbr[0x1CE], &partInfo); + *block_start = partInfo.block_start; + *block_count = partInfo.block_count; + *part_Id = partInfo.partitionId; + break; + + case 3: + decode_partitionInfo(&mbr[0x1DE], &partInfo); + *block_start = partInfo.block_start; + *block_count = partInfo.block_count; + *part_Id = partInfo.partitionId; + break; + case 4: + decode_partitionInfo(&mbr[0x1EE], &partInfo); + *block_start = partInfo.block_start; + *block_count = partInfo.block_count; + *part_Id = partInfo.partitionId; + break; + default: + return -1; + } + + return 0; +} + +///////////////////////////////////////////////////////////////// +int print_mmc_part_info(int argc, char *argv[]) +{ + int rv; + + PartitionInfo partInfo[4]; + + rv = get_mmc_part_info(argv[2], 1, &(partInfo[0].block_start), &(partInfo[0].block_count), + &(partInfo[0].partitionId) ); + + rv = get_mmc_part_info(argv[2], 2, &(partInfo[1].block_start), &(partInfo[1].block_count), + &(partInfo[1].partitionId) ); + + rv = get_mmc_part_info(argv[2], 3, &(partInfo[2].block_start), &(partInfo[2].block_count), + &(partInfo[2].partitionId) ); + + rv = get_mmc_part_info(argv[2], 4, &(partInfo[3].block_start), &(partInfo[3].block_count), + &(partInfo[3].partitionId) ); + + printf("\n"); + printf("partion # size(MB) block start # block count partition_Id \n"); + + if ( (partInfo[0].block_start !=0) && (partInfo[0].block_count != 0) ) + printf(" 1 %6d %8d %8d 0x%.2X \n", + (partInfo[0].block_count / 2048), partInfo[0].block_start, + partInfo[0].block_count, partInfo[0].partitionId); + + if ( (partInfo[1].block_start !=0) && (partInfo[1].block_count != 0) ) + printf(" 2 %6d %8d %8d 0x%.2X \n", + (partInfo[1].block_count / 2048), partInfo[1].block_start, + partInfo[1].block_count, partInfo[1].partitionId); + + if ( (partInfo[2].block_start !=0) && (partInfo[2].block_count != 0) ) + printf(" 3 %6d %8d %8d 0x%.2X \n", + (partInfo[2].block_count / 2048), partInfo[2].block_start, + partInfo[2].block_count, partInfo[2].partitionId); + + if ( (partInfo[3].block_start !=0) && (partInfo[3].block_count != 0) ) + printf(" 4 %6d %8d %8d 0x%.2X \n", + (partInfo[3].block_count / 2048), partInfo[3].block_start, + partInfo[3].block_count, partInfo[3].partitionId); + + return 1; +} + +///////////////////////////////////////////////////////////////// +int create_mmc_fdisk(int argc, char *argv[]) +{ + int rv; + int total_block_count; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mbr, 512); +#else + unsigned char mbr[512]; +#endif + struct mmc *mmc; + int dev_num; + + dev_num = simple_strtoul(argv[2], NULL, 0); + mmc = find_mmc_device(dev_num); + + memset(mbr, 0x00, 512); + + total_block_count = get_mmc_block_count(argv[2]); + if (total_block_count < 0) + return -1; + + make_mmc_partition(total_block_count, mbr, (argc==6?1:0), argv); + + rv = put_mmc_mbr(mbr, argv[2]); + if (rv != 0) + return -1; + + init_part(&mmc->block_dev); + + printf("fdisk is completed\n"); + + argv[1][1] = 'p'; + print_mmc_part_info(argc, argv); + return 0; +} + +///////////////////////////////////////////////////////////////// +int do_fdisk(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + if ( argc == 3 || argc ==6 ) + { + if ( strcmp(argv[1], "-c") == 0 ) + return create_mmc_fdisk(argc, argv); + + else if ( strcmp(argv[1], "-p") == 0 ) + return print_mmc_part_info(argc, argv); + } + else + { + printf("Usage:\nfdisk <-p> <device_num>\n"); + printf("fdisk <-c> <device_num> [<sys. part size(MB)> <user data part size> <cache part size>]\n"); + } + return 0; +} + +U_BOOT_CMD( + fdisk, 6, 0, do_fdisk, + "fdisk\t- fdisk for sd/mmc.\n", + "fdisk -p <device_num>\t- print partition information\n" + "fdisk -c <device_num> [<sys. part size(MB)> <user data part size> <cache part size>]\t- create partition.\n" +); + diff --git a/common/cmd_movi.c b/common/cmd_movi.c new file mode 100644 index 000000000..225dfcc5a --- /dev/null +++ b/common/cmd_movi.c @@ -0,0 +1,297 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <command.h> +#include <mmc.h> +#include <asm/arch/movi_partition.h> + +int do_movi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + char *cmd; + ulong addr, start_blk, blkcnt; + uint rfs_size; + char run_cmd[100]; + uint rw = 0, attribute = -1; + int i; + member_t *image; + struct mmc *mmc; + int dev_num = 0; + int location = 1; + + cmd = argv[1]; + + switch (cmd[0]) { + case 'i': + if(argv[2]==NULL) + { + dev_num = 0; + } else { + dev_num = simple_strtoul(argv[2], NULL, 10); + } + + sprintf(run_cmd,"mmcinfo %d", dev_num); + run_command(run_cmd, dev_num); + return 1; + case 'r': + rw = 0; /* read case */ + break; + case 'w': + rw = 1; /* write case */ + break; + default: + goto usage; + } + + cmd = argv[2]; + + switch (cmd[0]) { + case 'z': + location = 0; + break; + default: + location = 1; + break; + } + + dev_num = simple_strtoul(argv[4 - location], NULL, 10); + cmd = argv[3 - location]; + + switch (cmd[0]) { + + case 'f': + if (argc != (6 - location)) + goto usage; + attribute = 0x0; + break; + case 'b': + if (argc != (6 - location)) + goto usage; + attribute = 0x1; + break; + case 'u': + if (argc != (6 - location)) + goto usage; + attribute = 0x2; + break; + case 't': + if (argc != (6 - location)) + goto usage; + attribute = 0x3; + break; + case 'k': + if (argc != 5) + goto usage; + attribute = 0x5; + break; + case 'r': + if (argc != 6) + goto usage; + attribute = 0x6; + break; +#ifdef CONFIG_CHARGER_LOGO + case 'c': + if (argc != (6 - location)) + goto usage; + attribute = 0x7; + break; +#endif +#ifdef CONFIG_BOOT_LOGO + case 'l': + if (argc != (6 - location)) + goto usage; + attribute = 0x8; + break; +#endif + default: + goto usage; + } + + addr = simple_strtoul(argv[5 - location], NULL, 16); + + mmc = find_mmc_device(dev_num); + + init_raw_area_table(&mmc->block_dev, location); + + /* firmware BL1 r/w */ + if (attribute == 0x0) { + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + + start_blk = image[i].start_blk; + blkcnt = image[i].used_blk; + printf("%s FWBL1 ..device %d Start %ld, Count %ld ", rw ? "writing":"reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd,"mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write":"read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } + /* BL2 r/w */ + if (attribute == 0x1) { + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + start_blk = image[i].start_blk; + blkcnt = image[i].used_blk; + printf("%s BL2 ..device %d Start %ld, Count %ld ", rw ? "writing":"reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd,"mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write":"read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } + /* u-boot r/w */ + if (attribute == 0x2) { + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + start_blk = image[i].start_blk; + blkcnt = image[i].used_blk; + printf("%s bootloader..device %d Start %ld, Count %ld ", rw ? "writing":"reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd,"mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write":"read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } + + /* TrustZone S/W */ + if (attribute == 0x3) { + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + start_blk = image[i].start_blk; + blkcnt = image[i].used_blk; + printf("%s %d TrustZone S/W.. Start %ld, Count %ld ", rw ? "writing" : "reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd, "mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write" : "read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } + + /* kernel r/w */ + if (attribute == 0x5) { + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + start_blk = image[i].start_blk; + blkcnt = image[i].used_blk; + printf("%s kernel..device %d Start %ld, Count %ld ", rw ? "writing" : "reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd, "mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write" : "read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } + + /* root file system r/w */ + if (attribute == 0x6) { + rfs_size = simple_strtoul(argv[5], NULL, 16); + + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + start_blk = image[i].start_blk; + blkcnt = rfs_size/MOVI_BLKSIZE + + ((rfs_size&(MOVI_BLKSIZE-1)) ? 1 : 0); + image[i].used_blk = blkcnt; + printf("%s RFS..device %d Start %ld, Count %ld ", rw ? "writing":"reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd,"mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write":"read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } + +#ifdef CONFIG_CHARGER_LOGO + if (attribute == 0x7) { + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + start_blk = image[i].start_blk; + blkcnt = image[i].used_blk; + printf("%s charger logo..device %d Start %ld, Count %ld ", rw ? "writing" : "reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd, "mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write" : "read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } +#endif +#ifdef CONFIG_BOOT_LOGO + if (attribute == 0x8) { + for (i=0, image = raw_area_control.image; i<15; i++) { + if (image[i].attribute == attribute) + break; + } + start_blk = image[i].start_blk; + blkcnt = image[i].used_blk; + printf("%s bootlogo.. %d Start %ld, Count %ld ", rw ? "writing" : "reading", + dev_num, start_blk, blkcnt); + sprintf(run_cmd, "mmc %s %d 0x%lx 0x%lx 0x%lx", + rw ? "write" : "read", dev_num, + addr, start_blk, blkcnt); + run_command(run_cmd, dev_num); + printf("completed\n"); + return 1; + } +#endif + return 1; + +usage: + printf("Usage:\n%s\n", cmdtp->usage); + return -1; +} + +U_BOOT_CMD( + movi, 7, 0, do_movi, + "movi\t- sd/mmc r/w sub system for SMDK board", + "init - Initialize moviNAND and show card info\n" + "#eMMC#\n" + "movi read zero {fwbl1 | bl2 | u-boot | tzsw} {device_number} {addr} - Read data from emmc\n" + "movi write zero {fwbl1 | bl2 | u-boot | tzsw} {device_number} {addr} - Read data from emmc\n" + "#SD/MMC#\n" + "movi read {fwbl1 | bl2 | u-boot | tzsw} {device_number} {addr} - Read data from sd/mmc\n" + "movi write {fwbl1 | bl2 | u-boot | tzsw} {device_number} {addr} - Read data from sd/mmc\n" + "#COMMON#\n" + "movi read kernel {device_number} {addr} - Read data from device\n" + "movi write kernel {device_number} {addr} - Write data to device\n" + "movi read rootfs {device_number} {addr} [bytes(hex)] - Read rootfs data from device by size\n" + "movi write rootfs {device_number} {addr} [bytes(hex)] - Write rootfs data to device by size\n" + "movi read {sector#} {device_number} {bytes(hex)} {addr} - instead of this, you can use \"mmc read\"\n" + "movi write {sector#} {device_number} {bytes(hex)} {addr} - instead of this, you can use \"mmc write\"\n" +); + diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index fd05e725d..dddc7cc68 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -944,6 +944,18 @@ static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_USAGE; } +int do_saveenvone(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc != 3) { + printf("Usage:%s \n", cmdtp->usage); + return -1; + } + + saveenv_one_variable(argv[1], argv[2]); + + return 0; +} + U_BOOT_CMD( env, CONFIG_SYS_MAXARGS, 1, do_env, "environment handling commands", @@ -1038,3 +1050,9 @@ U_BOOT_CMD_COMPLETE( var_complete ); #endif + +U_BOOT_CMD( + saveenvone, 3, 0, do_saveenvone, + "saveenvone\t- save only one env variable.", + "Example\t- \"saveenvone <env name> <env value>\"" +); diff --git a/common/cmd_usbd.c b/common/cmd_usbd.c new file mode 100644 index 000000000..c7b7fd8a6 --- /dev/null +++ b/common/cmd_usbd.c @@ -0,0 +1,215 @@ +/* + * common/cmd_usbd.c + * + * $Id: cmd_usbd.c,v 1.2 2009/01/28 00:11:42 dark0351 Exp $ + * + * (C) Copyright 2007 + * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com. + * - support for S3C2412, S3C2443 and S3C6400 + * + * (C) Copyright SAMSUNG Electronics + * SW.LEE <hitchcar@samsung.com> + * - add USB device fo S3C2440A, S3C24A0A + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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. + */ + +/* + * Memory Functions + * + * Copied from FADS ROM, Dan Malek (dmalek@jlc.net) + */ + +#include <common.h> +#include <command.h> + +#ifdef CONFIG_S3C_USBD + +#include <asm/arch/cpu.h> +#include <asm/arch/usb2.h> + +#if defined(CONFIG_EXYNOS4X12) || defined(CONFIG_ARCH_EXYNOS) +#include "../drivers/usb/gadget/usbd-otg-hs.h" +#else +#error "* CFG_ERROR : you have to setup right Samsung CPU configuration" +#endif + +#include <dnw.h> + +int s3c_usbctl_init(void); +#undef CMD_USBD_DEBUG +#ifdef CMD_USBD_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +extern int g_dnw_version; +extern unsigned int exynos_boot_da; +static const char pszMe[] = "usbd: "; + +#ifdef CONFIG_DNW_VERSION +int usdbd_dnw_start_usb(void){ + s3c_usbctl_init(); + + if (!s3c_usb_wait_cable_insert()) { + printf("%s, usb conneciton ok\n", __func__); + } + mdelay(10); + printf("[dnw] after delay \n"); + + /* when operation is done, usbd must be stopped */ + s3c_usb_stop(); + mdelay(500); // for slow computer +} + +int usbd_dnw_v10( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int ret = 1; + uint64_t timeout_endtime = 0; + uint64_t timeout_ticks = 0; + int check_timeout = 0; + int continue_from_disconnect = 0; + char fboot_cmd[20]; + + printf("[dnw] Starting dnw \n"); + setenv("bootcmd", CONFIG_BOOTCOMMAND); // for bootcmd recovery + + if ((argc > 1) && (0 == strcmp(argv[1], "v10"))){ // dnw v.1.0 + g_dnw_version = DNW_v10; + }else if ((argc > 1) && (0 == strcmp(argv[1], "v05"))){ // dnw v.0.5 + sprintf(fboot_cmd, "fastboot dnw"); + g_dnw_version = DNW_v05; + return run_command(fboot_cmd, 0); + } + + + do{ + + /* Initialize the board specific support */ + if (0 == dnw_init()) + { + int poll_status; + + /* If we got this far, we are a success */ + ret = 0; + + timeout_endtime = get_ticks(); + timeout_endtime += timeout_ticks; + +#ifdef CONFIG_USE_LCD + LCD_turnon(); +#endif + + while (1) + { + uint64_t current_time = 0; + poll_status = dnw_poll(); + + if (1 == check_timeout) + current_time = get_ticks(); + + if ( (poll_status != DNW_OK) && (ctrlc())) + { + printf("DNW ended by user\n"); + continue_from_disconnect = 0; + break; + } + + if (serial_tstc()) { + serial_getc(); + break; + } + } + } + /* Reset the board specific support */ + dnw_shutdown(); + + /* restart the loop if a disconnect was detected */ + } while (continue_from_disconnect); + +} +#endif /* CONFIG_DNW_VERSION */ +int do_usbd_dnw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +#ifdef CONFIG_DNW_VERSION + if (((argc > 1) && (0 == strcmp(argv[1], "v10")) ) // dnw v.1.0 + || ((argc > 1) && (0 == strcmp(argv[1], "v05"))) ){ // dnw v.0.5 + return usbd_dnw_v10(cmdtp, flag, argc, argv); + } +#endif /* CONFIG_DNW_VERSION */ + + if (argv[0][0] == 'u') { + DNW = 0; + } + else { + DNW = 1; + s3c_got_header = 0; + } + + switch (argc) { + case 1 : + s3c_usbd_dn_addr = USBD_DOWN_ADDR; /* Default Address */ + break; + case 2 : + s3c_usbd_dn_addr = simple_strtoul(argv[1], NULL, 16); + break; + default: + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + s3c_receive_done = 0; + + s3c_usbctl_init(); + s3c_usbc_activate(); + + PRINTF("Download address 0x%08x\n", s3c_usbd_dn_addr); + printf("Now, Waiting for DNW to transmit data\n"); + + while (1) { + if (S3C_USBD_DETECT_IRQ()) { + s3c_udc_int_hndlr(); + S3C_USBD_CLEAR_IRQ(); + } + + if (s3c_receive_done) + break; + + if (serial_tstc()) { + serial_getc(); + break; + } + } + + /* when operation is done, usbd must be stopped */ + s3c_usb_stop(); + + return 0; +} + +#if 0 /* ud command not support yet */ +U_BOOT_CMD( + ud, 3, 0, do_usbd_dnw, + "ud - initialize USB device and ready to receive for LINUX server (specific)\n", + "[download address]\n" +); +#endif + +U_BOOT_CMD( + dnw, 3, 0, do_usbd_dnw, + "dnw - initialize USB device and ready to receive for Windows server (specific)\n", + "[download address]\n" +); + +#endif /* CONFIG_S3C_USBD */ + diff --git a/common/cmd_usbd3.c b/common/cmd_usbd3.c new file mode 100644 index 000000000..f9bacfa07 --- /dev/null +++ b/common/cmd_usbd3.c @@ -0,0 +1,154 @@ +/* + * common/cmd_usbd3.c + * + * $Id: cmd_usbd3.c,v 1.2 2009/01/28 00:11:42 dark0351 Exp $ + * + * (C) Copyright 2011 + * Yulgon Kim, Samsung Erectronics, bjlee@samsung.com. + * - support for Exynos5210 + * + * (C) Copyright 2007 + * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com. + * - support for S3C2412, S3C2443 and S3C6400 + * + * (C) Copyright SAMSUNG Electronics + * SW.LEE <hitchcar@samsung.com> + * - add USB device fo S3C2440A, S3C24A0A + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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. + */ + +/* + * Memory Functions + * + * Copied from FADS ROM, Dan Malek (dmalek@jlc.net) + */ + +#include <common.h> +#include <command.h> + +#ifdef CONFIG_EXYNOS_USBD3 + +#include <asm/arch/cpu.h> + +#if defined(CONFIG_ARCH_EXYNOS5) +#include "../drivers/usb/gadget/usbd3-ss.h" +#else +#error "* CFG_ERROR : you have to setup right Samsung CPU configuration" +#endif + +static const char pszMe[] = "usbd: "; + +int do_usbd_dnw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + + if (argv[0][0] == 'u') { + DNW = 0; + } + else { + DNW = 1; + exynos_got_header = 0; + } + + switch (argc) { + case 1 : + exynos_usbd_dn_addr = USBD_DOWN_ADDR; /* Default Address */ + break; + case 2 : + exynos_usbd_dn_addr = simple_strtoul(argv[1], NULL, 16); + break; + default: + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + exynos_receive_done = 0; + exynoy_usb_phy_on(); + + printf("Download address 0x%08x\n", exynos_usbd_dn_addr); + printf("Now, Waiting for DNW to transmit data\n"); + + while (1) { + if (!exynos_usb_wait_cable_insert()) { + exynos_usbctl_init(); + exynos_usbc_activate(); + } + if (EXYNOS_USBD_DETECT_IRQ()) { + exynos_udc_int_hndlr(); + EXYNOS_USBD_CLEAR_IRQ(); + } + + if (exynos_receive_done) + break; + + if (serial_tstc()) { + serial_getc(); + break; + } + } + + /* when operation is done, usbd must be stopped */ + exynos_usb_stop(); + + return 0; +} + +U_BOOT_CMD( + dnw, 3, 0, do_usbd_dnw, + "dnw - initialize USB device and ready to receive for Windows server (specific)\n", + "[download address]\n" +); + +#if defined(CONFIG_RAMDUMP_MODE) +int do_ramdump(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + + exynos_usbd_dn_addr = USBD_DOWN_ADDR; /* Default Address */ + + exynos_receive_done = 0; + + exynos_usbctl_init(); + exynos_usbc_activate(); + + printf("Now, Waiting for USB RAMDUMP\n"); + + while (1) { + if (EXYNOS_USBD_DETECT_IRQ()) { + exynos_udc_int_hndlr(); + EXYNOS_USBD_CLEAR_IRQ(); + } + + if (exynos_receive_done) + break; + + if (serial_tstc()) { + serial_getc(); + break; + } + } + + /* when operation is done, usbd must be stopped */ + exynos_usb_stop(); + + printf("Finished RAMDUMP\n"); + + return 0; +} + +U_BOOT_CMD( + ramdump, 1, 0, do_ramdump, + "ramdump - initialize USB device and dump Memory\n", + "\n" +); +#endif +#endif /* CONFIG_S3C_USBD */ + diff --git a/common/console.c b/common/console.c index 1177f7d39..e29980520 100644 --- a/common/console.c +++ b/common/console.c @@ -415,6 +415,9 @@ int printf(const char *fmt, ...) va_list args; uint i; char printbuffer[CONFIG_SYS_PBSIZE]; +#ifdef CONFIG_RAMDUMP_MODE + uint last_buf; +#endif #ifndef CONFIG_PRE_CONSOLE_BUFFER if (!gd->have_console) @@ -430,6 +433,15 @@ int printf(const char *fmt, ...) va_end(args); /* Print the string */ +#ifdef CONFIG_RAMDUMP_MODE + last_buf = readl(CONFIG_RAMDUMP_LASTBUF); + if (((last_buf >> 24) != (CONFIG_RAMDUMP_BASE >> 24)) || + ((CONFIG_RAMDUMP_LOGBUF + CONFIG_RAMDUMP_LOGSZ) < (last_buf + i))) + last_buf = CONFIG_RAMDUMP_LOGBUF; + strncpy((char *)last_buf, printbuffer, i); + last_buf += i; + writel(last_buf, CONFIG_RAMDUMP_LASTBUF); +#endif puts(printbuffer); return i; } diff --git a/common/decompress_ext4.c b/common/decompress_ext4.c new file mode 100644 index 000000000..12c75aa49 --- /dev/null +++ b/common/decompress_ext4.c @@ -0,0 +1,136 @@ +/* copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * 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. +*/ + +#include <common.h> +#include <asm/io.h> +#include <asm/types.h> +#include <environment.h> +#include <command.h> +#include <fastboot.h> + +#include <asm/errno.h> +#include <decompress_ext4.h> +#include <mmc.h> + +#define SECTOR_BITS 9 /* 512B */ + +#define ext4_printf(args, ...) + +static int write_raw_chunk(char* data, unsigned int sector, unsigned int sector_size); + + +int check_compress_ext4(char *img_base, unsigned long long parti_size) { + ext4_file_header *file_header; + + file_header = (ext4_file_header*)img_base; + + if (file_header->magic != EXT4_FILE_HEADER_MAGIC) { + return -1; + } + + if (file_header->major != EXT4_FILE_HEADER_MAJOR) { + printf("Invalid Version Info! 0x%2x\n", file_header->major); + return -1; + } + + if (file_header->file_header_size != EXT4_FILE_HEADER_SIZE) { + printf("Invalid File Header Size! 0x%8x\n", + file_header->file_header_size); + return -1; + } + + if (file_header->chunk_header_size != EXT4_CHUNK_HEADER_SIZE) { + printf("Invalid Chunk Header Size! 0x%8x\n", + file_header->chunk_header_size); + return -1; + } + + if (file_header->block_size != EXT4_FILE_BLOCK_SIZE) { + printf("Invalid Block Size! 0x%8x\n", file_header->block_size); + return -1; + } + + if ((parti_size/file_header->block_size) < file_header->total_blocks) { + printf("Invalid Volume Size! Image is bigger than partition size!\n"); + printf("partion size %lld , image size %d \n", + (parti_size/file_header->block_size), file_header->total_blocks); + while(1); + } + + /* image is compressed ext4 */ + return 0; +} + +int write_raw_chunk(char* data, unsigned int sector, unsigned int sector_size) { + char run_cmd[64]; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + unsigned char *tmp_align; + + if (((unsigned int)data % 8) != 0) { + tmp_align = (char *)CFG_FASTBOOT_MMC_BUFFER; + memcpy((unsigned char *)tmp_align, (unsigned char *)data, sector_size * 512); + data = tmp_align; + } +#endif + ext4_printf("write raw data in %d size %d \n", sector, sector_size); + sprintf(run_cmd,"mmc write 0 0x%x 0x%x 0x%x", (int)data, sector, sector_size); + run_command(run_cmd, 0); + + return 0; +} + +int write_compressed_ext4(char* img_base, unsigned int sector_base) { + unsigned int sector_size; + int total_chunks; + ext4_chunk_header *chunk_header; + ext4_file_header *file_header; + + file_header = (ext4_file_header*)img_base; + total_chunks = file_header->total_chunks; + + ext4_printf("total chunk = %d \n", total_chunks); + + img_base += EXT4_FILE_HEADER_SIZE; + + while(total_chunks) { + chunk_header = (ext4_chunk_header*)img_base; + sector_size = (chunk_header->chunk_size * file_header->block_size) >> SECTOR_BITS; + + switch(chunk_header->type) + { + case EXT4_CHUNK_TYPE_RAW: + ext4_printf("raw_chunk \n"); + write_raw_chunk(img_base + EXT4_CHUNK_HEADER_SIZE, + sector_base, sector_size); + sector_base += sector_size; + break; + + case EXT4_CHUNK_TYPE_FILL: + printf("*** fill_chunk ***\n"); + sector_base += sector_size; + break; + + case EXT4_CHUNK_TYPE_NONE: + ext4_printf("none chunk \n"); + sector_base += sector_size; + break; + + default: + printf("*** unknown chunk type ***\n"); + sector_base += sector_size; + break; + } + total_chunks--; + ext4_printf("remain chunks = %d \n", total_chunks); + + img_base += chunk_header->total_size; + }; + + ext4_printf("write done \n"); + return 0; +} diff --git a/common/env_common.c b/common/env_common.c index d9e990dbb..253fffb36 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -199,6 +199,30 @@ void set_default_env(const char *s) gd->flags |= GD_FLG_ENV_READY; } +void set_default_env_htab(const char *s, struct hsearch_data *htab_temp) +{ + if (sizeof(default_environment) > ENV_SIZE) { + puts("*** Error - default environment is too large\n\n"); + return; + } + + if (s) { + if (*s == '!') { + printf("*** Warning - %s, " + "using default environment\n\n", + s + 1); + } else { + puts(s); + } + } else { + puts("Using default environment\n\n"); + } + + if (himport_r(htab_temp, (char *)default_environment, + sizeof(default_environment), '\0', 0) == 0) + error("Environment import failed: errno = %d\n", errno); +} + /* * Check if CRC is valid and (if yes) import the environment. * Note that "buf" may or may not be aligned. @@ -230,6 +254,32 @@ int env_import(const char *buf, int check) return 0; } +int env_import_htab(const char *buf, int check, struct hsearch_data *htab_temp) +{ + env_t *ep = (env_t *)buf; + + if (check) { + uint32_t crc; + + memcpy(&crc, &ep->crc, sizeof(crc)); + + if (crc32(0, ep->data, ENV_SIZE) != crc) { + set_default_env_htab("!bad CRC", htab_temp); + return 0; + } + } + + if (himport_r(htab_temp, (char *)ep->data, ENV_SIZE, '\0', 0)) { + return 1; + } + + error("Cannot import environment: errno = %d\n", errno); + + set_default_env_htab("!import failed", htab_temp); + + return 0; +} + void env_relocate(void) { #if defined(CONFIG_NEEDS_MANUAL_RELOC) diff --git a/common/env_mmc.c b/common/env_mmc.c index be2f2be20..a183e9368 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -153,3 +153,74 @@ void env_relocate_spec(void) env_import(buf, 1); #endif } + +#ifdef CONFIG_CMD_SAVEENV +struct hsearch_data env_htab_temp; + +void env_read_from_emmc_to_htab(struct hsearch_data *htab_temp, u32 *offset) +{ +#if !defined(ENV_IS_EMBEDDED) + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); + + if (init_mmc_for_env(mmc) || mmc_get_env_addr(mmc, offset)) + set_default_env_htab("mmc init error", htab_temp); + + if (read_env(mmc, CONFIG_ENV_SIZE, *offset, buf)) + set_default_env_htab("read env failed", htab_temp); + + if (!env_import_htab(buf, 1, htab_temp)) + printf("error import env to htab\n"); +#endif +} + +int env_write_from_htab_to_emmc(struct hsearch_data *htab_temp, u32 *offset) +{ + ssize_t len; + char *res; + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); + + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); + + res = (char *)&env_new->data; + + len = hexport_r(htab_temp, '\0', &res, ENV_SIZE, 0, NULL); + if (len < 0) { + error("Cannot export environment: errno = %d\n", errno); + return 1; + } + + env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); + if (write_env(mmc, CONFIG_ENV_SIZE, *offset, (u_char *)env_new)) { + puts("failed\n"); + return 1; + } + + puts("done\n"); + return 0; +} + +int saveenv_one_variable(const char *env_name, const char *env_data) +{ + ssize_t len; + char *res; + u32 offset; + ENTRY e, *ep; + int retval; + + env_read_from_emmc_to_htab(&env_htab_temp, &offset); + + e.key = env_name; + e.data = env_data; + + hsearch_r(e, ENTER, &ep, &env_htab_temp); + if (ep == NULL) { + printf("## Error inserting \"%s\" variable, error=%d\n", env_name, errno); + return 1; + } + + retval = env_write_from_htab_to_emmc(&env_htab_temp, &offset); + + return retval; +} +#endif diff --git a/common/image.c b/common/image.c index 91954ac54..b3ac5ffa6 100644 --- a/common/image.c +++ b/common/image.c @@ -1004,9 +1004,21 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, } else #endif { - puts("Wrong Ramdisk Image Format\n"); - rd_data = rd_len = rd_load = 0; - return 1; + +#ifdef CONFIG_ROOTFS_ATAGS + char *rootfs_len = getenv("rootfslen"); + if(rootfs_len != NULL) { + rd_data = simple_strtoul(argv[2], + NULL, 16); + rd_len = simple_strtoul(rootfs_len, + NULL, 16); + } else +#endif + { + puts("Wrong Ramdisk Image Format\n"); + rd_data = rd_len = rd_load = 0; + return 1; + } } } } else if (images->legacy_hdr_valid && diff --git a/common/main.c b/common/main.c index a93335798..b03b4a360 100644 --- a/common/main.c +++ b/common/main.c @@ -83,6 +83,14 @@ int do_mdm_init = 0; extern void mdm_init(void); /* defined in board.c */ #endif +#ifdef CONFIG_USE_LCD +extern void Lcd_read_bootlogo(void); +extern void Backlight_Turnon(void); +extern void Display_Turnon(void); +extern void Display_Turnoff(void); +extern void s5p_lcd_draw_bootlogo(void); +#endif + /*************************************************************************** * Watch for 'delay' seconds for autoboot stop or autoboot delay string. * returns: 0 - no key string, allow autoboot 1 - got key string, abort @@ -345,6 +353,13 @@ void main_loop (void) update_tftp (0UL); #endif /* CONFIG_UPDATE_TFTP */ +#ifdef CONFIG_USE_LCD // display turnon + Display_Turnon(); + Lcd_read_bootlogo(); + s5p_lcd_draw_bootlogo(); + Backlight_Turnon(); +#endif + #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) s = getenv ("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; @@ -372,11 +387,16 @@ void main_loop (void) } else #endif /* CONFIG_BOOTCOUNT_LIMIT */ - s = getenv ("bootcmd"); + s = getenv ("bootcmd"); debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>"); if (bootdelay >= 0 && s && !abortboot (bootdelay)) { +#ifdef CONFIG_USE_LCD // display turnoff +#ifdef CONFIG_S5P_LCD_INIT + Display_Turnoff(); +#endif +#endif # ifdef CONFIG_AUTOBOOT_KEYED int prev = disable_ctrlc(1); /* disable Control C checking */ # endif diff --git a/common/memsize.c b/common/memsize.c index 963e4f35b..f33cf250c 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -46,7 +46,7 @@ long get_ram_size(long *base, long maxsize) long size; int i = 0; - for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) { + for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ sync (); save[i++] = *addr; @@ -59,25 +59,31 @@ long get_ram_size(long *base, long maxsize) save[i] = *addr; sync (); *addr = 0; + i = 0; sync (); if ((val = *addr) != 0) { /* Restore the original data before leaving the function. */ sync (); - *addr = save[i]; for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { addr = base + cnt; sync (); - *addr = save[--i]; + *addr = save[i++]; } + + addr = base; + sync (); + *addr = save[i]; + sync (); + return (0); } for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ val = *addr; - *addr = save[--i]; + *addr = save[i++]; if (val != ~cnt) { size = cnt * sizeof (long); /* Restore the original data before leaving the function. @@ -90,5 +96,10 @@ long get_ram_size(long *base, long maxsize) } } + addr = base; + sync (); + *addr = save[i]; + sync (); + return (maxsize); } diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c index 47f321392..de8672d35 100644 --- a/drivers/gpio/s5p_gpio.c +++ b/drivers/gpio/s5p_gpio.c @@ -36,6 +36,24 @@ #define RATE_MASK(x) (0x1 << (x + 16)) #define RATE_SET(x) (0x1 << (x + 16)) +#ifdef CONFIG_GPIO_DAT_MASK +void s5p_gpio_dat_mask(struct s5p_gpio_bank *bank, unsigned int *dat) +{ + unsigned int i, con, dat_mask=0; + + con = readl(&bank->con); + for (i = 0; i < 8; i++) + { + if (((con >> (i * 4)) & 0xf) == GPIO_OUTPUT) + dat_mask |= 1 << i; + } + + *dat &= dat_mask; +} +#else +void s5p_gpio_dat_mask(struct s5p_gpio_bank *bank, unsigned int *dat) {} +#endif + void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg) { unsigned int value; @@ -56,6 +74,7 @@ void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en) value &= ~DAT_MASK(gpio); if (en) value |= DAT_SET(gpio); + s5p_gpio_dat_mask(bank, &value); writel(value, &bank->dat); } @@ -72,6 +91,7 @@ void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en) value &= ~DAT_MASK(gpio); if (en) value |= DAT_SET(gpio); + s5p_gpio_dat_mask(bank, &value); writel(value, &bank->dat); } diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index c56773701..c8d9e340c 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -41,6 +41,7 @@ COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o COBJS-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o COBJS-$(CONFIG_SDHCI) += sdhci.o COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o +COBJS-$(CONFIG_S5P_MSHC) += s5p_mshc.o COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c1c286298..d5d3d956b 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -37,6 +37,10 @@ #define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535 #endif +#ifdef CONFIG_CMD_MOVINAND +extern int init_raw_area_table (block_dev_desc_t * dev_desc, int location); +#endif + static struct list_head mmc_devices; static int cur_dev_num = -1; @@ -204,7 +208,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) int mmc_send_status(struct mmc *mmc, int timeout) { struct mmc_cmd cmd; - int err, retries = 5; + int err; #ifdef CONFIG_MMC_TRACE int status; #endif @@ -227,9 +231,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) cmd.response[0]); return COMM_ERR; } - } else if (--retries < 0) - return err; - + } udelay(1000); } while (timeout--); @@ -275,7 +277,30 @@ struct mmc *find_mmc_device(int dev_num) return NULL; } -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) +int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) +{ + struct mmc_cmd cmd; + int timeout = 1000; + int ret; + + cmd.cmdidx = MMC_CMD_SWITCH; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (index << 16) | + (value << 8); + cmd.flags = 0; + + ret = mmc_send_cmd(mmc, &cmd, NULL); + + /* Waiting for the ready status */ + if (!ret) + ret = mmc_send_status(mmc, timeout); + + return ret; + +} + +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, int sec) { struct mmc_cmd cmd; ulong end; @@ -312,8 +337,16 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) if (err) goto err_out; + if (sec) { + /* The sanitize operation is supported at v4.5 only */ + if (mmc->sec_feature_support & EXT_CSD_SEC_SANITIZE) + cmd.cmdarg = NORMAL_ERASE; + else + cmd.cmdarg = SECURE_ERASE; + } else + cmd.cmdarg = NORMAL_ERASE; + cmd.cmdidx = MMC_CMD_ERASE; - cmd.cmdarg = SECURE_ERASE; cmd.resp_type = MMC_RSP_R1b; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -321,7 +354,6 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) goto err_out; return 0; - err_out: puts("mmc erase failed\n"); return err; @@ -331,6 +363,7 @@ static unsigned long mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt) { int err = 0; + int sec = 0; /* support secure erase */ struct mmc *mmc = find_mmc_device(dev_num); lbaint_t blk = 0, blk_r = 0; int timeout = 1000; @@ -345,18 +378,45 @@ mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt) ((start + blkcnt + mmc->erase_grp_size) & ~(mmc->erase_grp_size - 1)) - 1); + printf("\nMMC erasing start = %ld, end = %ld ", start, start + blkcnt); + + /* If the area which want to be erased is half of the card whole capacity, + * We want to use the secure Erase + */ + if (!IS_SD(mmc) && start == 0 && + ((mmc->capacity / mmc->write_bl_len) / 2) < blkcnt) { + if (mmc->sec_feature_support & EXT_CSD_SEC_SANITIZE) + printf("by secure mode(sanitize)\n"); + else + printf("by secure mode\n"); + sec = 1; + } else { + printf("by normal\n"); + sec = 0; + } + while (blk < blkcnt) { blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? mmc->erase_grp_size : (blkcnt - blk); - err = mmc_erase_t(mmc, start + blk, blk_r); + err = mmc_erase_t(mmc, start + blk, blk_r, sec); if (err) break; blk += blk_r; /* Waiting for the ready status */ - if (mmc_send_status(mmc, timeout)) - return 0; + err = mmc_send_status(mmc, timeout); + if (err) + break; + + printf("."); + } + + if (sec && mmc->sec_feature_support & EXT_CSD_SEC_SANITIZE) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_SANITIZE_START, 1); + if (err) + printf("\n\n Error! Sanitize operation is failed\n\n"); } return blk; @@ -375,10 +435,12 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) return 0; } - if (blkcnt > 1) - cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; - else + if (blkcnt == 0) + return 0; + else if (blkcnt == 1) cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; + else + cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; if (mmc->high_capacity) cmd.cmdarg = start; @@ -398,6 +460,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) return 0; } +#if !defined(CONFIG_SKIP_MMC_STOP_CMD) /* SPI multiblock writes terminate using a special * token, not a STOP_TRANSMISSION request. */ @@ -411,7 +474,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) return 0; } } - +#endif /* Waiting for the ready status */ if (mmc_send_status(mmc, timeout)) return 0; @@ -428,8 +491,12 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src) if (!mmc) return 0; - if (mmc_set_blocklen(mmc, mmc->write_bl_len)) +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + if (((unsigned int)src % 8) != 0) { + printf("\n MMC WRITE : Align error !!! \n"); return 0; + } +#endif do { cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; @@ -447,6 +514,10 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) { struct mmc_cmd cmd; struct mmc_data data; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + unsigned char *tmp_align = (unsigned char *)CFG_FASTBOOT_MMC_BUFFER; + unsigned char tmp_flag = 0; +#endif if (blkcnt > 1) cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; @@ -461,7 +532,16 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) cmd.resp_type = MMC_RSP_R1; cmd.flags = 0; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + if (((unsigned int)dst % 8) != 0) { + data.dest = tmp_align; + tmp_flag = 1; + } + else + data.dest = dst; +#else data.dest = dst; +#endif data.blocks = blkcnt; data.blocksize = mmc->read_bl_len; data.flags = MMC_DATA_READ; @@ -469,6 +549,7 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) if (mmc_send_cmd(mmc, &cmd, &data)) return 0; +#if !defined(CONFIG_SKIP_MMC_STOP_CMD) if (blkcnt > 1) { cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; @@ -479,7 +560,11 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) return 0; } } - +#endif +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + if (tmp_flag) + memcpy(dst, tmp_align, blkcnt * 512); +#endif return blkcnt; } @@ -500,9 +585,6 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst) return 0; } - if (mmc_set_blocklen(mmc, mmc->read_bl_len)) - return 0; - do { cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo; if(mmc_read_blocks(mmc, dst, start, cur) != cur) @@ -695,30 +777,6 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) return err; } - -int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) -{ - struct mmc_cmd cmd; - int timeout = 1000; - int ret; - - cmd.cmdidx = MMC_CMD_SWITCH; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (index << 16) | - (value << 8); - cmd.flags = 0; - - ret = mmc_send_cmd(mmc, &cmd, NULL); - - /* Waiting for the ready status */ - if (!ret) - ret = mmc_send_status(mmc, timeout); - - return ret; - -} - int mmc_change_freq(struct mmc *mmc) { ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); @@ -757,7 +815,9 @@ int mmc_change_freq(struct mmc *mmc) return 0; /* High Speed is set, there are two types: 52MHz and 26MHz */ - if (cardtype & MMC_HS_52MHZ) + if ((cardtype & MMC_HS_52MHZ_1_8V_3V_IO) || (cardtype & MMC_HS_52MHZ_1_2V_IO)) + mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_DDR; + else if (cardtype & MMC_HS_52MHZ) mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; else mmc->card_caps |= MMC_MODE_HS; @@ -1144,7 +1204,9 @@ int mmc_startup(struct mmc *mmc) if ((capacity >> 20) > 2 * 1024) mmc->capacity = capacity; } - + /* store to support the security feature of emmc */ + mmc->sec_feature_support = + ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; /* * Check whether GROUP_DEF is set, if yes, read out * group size from ext_csd directly, or calculate @@ -1161,6 +1223,10 @@ int mmc_startup(struct mmc *mmc) * (erase_gmul + 1); } + /* store the partition size info of emmc */ + mmc->boot_size_multi = ext_csd[EXT_CSD_BOOT_SIZE_MULTI] * 128 + * 1024; + /* store the partition info of emmc */ if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; @@ -1177,6 +1243,9 @@ int mmc_startup(struct mmc *mmc) /* Restrict card's capabilities by what the host can do */ mmc->card_caps &= mmc->host_caps; + if (mmc_set_blocklen(mmc, mmc->write_bl_len)) + return 0; + if (IS_SD(mmc)) { if (mmc->card_caps & MMC_MODE_4BIT) { cmd.cmdidx = MMC_CMD_APP_CMD; @@ -1204,38 +1273,29 @@ int mmc_startup(struct mmc *mmc) else mmc->tran_speed = 25000000; } else { - width = ((mmc->host_caps & MMC_MODE_MASK_WIDTH_BITS) >> - MMC_MODE_WIDTH_BITS_SHIFT); - for (; width >= 0; width--) { - /* Set the card to use 4 bit*/ - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, width); + /* check mmc bus width */ + if ((mmc->host_caps & MMC_MODE_MASK_WIDTH_BITS) == + MMC_MODE_MASK_WIDTH_BITS) + width = MMC_MODE_8BIT >> MMC_MODE_WIDTH_BITS_SHIFT; + else + width = ((mmc->host_caps & MMC_MODE_MASK_WIDTH_BITS) >> + MMC_MODE_WIDTH_BITS_SHIFT); - if (err) - continue; + if (mmc->card_caps & MMC_MODE_DDR) + mmc->ddr = 4; + else + mmc->ddr = 0; - if (!width) { - mmc_set_bus_width(mmc, 1); - break; - } else - mmc_set_bus_width(mmc, 4 * width); - - err = mmc_send_ext_csd(mmc, test_csd); - if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \ - == test_csd[EXT_CSD_PARTITIONING_SUPPORT] - && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \ - == test_csd[EXT_CSD_ERASE_GROUP_DEF] \ - && ext_csd[EXT_CSD_REV] \ - == test_csd[EXT_CSD_REV] - && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \ - == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] - && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \ - &test_csd[EXT_CSD_SEC_CNT], 4) == 0) { - - mmc->card_caps |= width; - break; - } - } + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BUS_WIDTH, (width + mmc->ddr)); + + if (err) + printf("ERROR: Switch error!!!\n"); + + if (!width) + mmc_set_bus_width(mmc, 1); + else + mmc_set_bus_width(mmc, 4 * width); if (mmc->card_caps & MMC_MODE_HS) { if (mmc->card_caps & MMC_MODE_HS_52MHz) @@ -1261,6 +1321,9 @@ int mmc_startup(struct mmc *mmc) (mmc->cid[2] >> 24) & 0xf); init_part(&mmc->block_dev); +#ifdef CONFIG_CMD_MOVINAND + init_raw_area_table(&mmc->block_dev, 0); +#endif return 0; } @@ -1297,6 +1360,7 @@ int mmc_register(struct mmc *mmc) mmc->block_dev.block_read = mmc_bread; mmc->block_dev.block_write = mmc_bwrite; mmc->block_dev.block_erase = mmc_berase; + if (!mmc->b_max) mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; @@ -1340,6 +1404,9 @@ int mmc_init(struct mmc *mmc) mmc_set_bus_width(mmc, 1); mmc_set_clock(mmc, 1); + /* For Nsc */ + udelay(500); + /* Reset the Card */ err = mmc_go_idle(mmc); @@ -1417,5 +1484,142 @@ int mmc_initialize(bd_t *bis) print_mmc_devices(','); +#if defined(CONFIG_MMC_EARLY_INIT) + struct mmc *mmc; + int err, dev; + + for (dev = 0; dev < MMC_MAX_CHANNEL; dev++) { + printf("MMC Device %d: ", dev); + mmc = find_mmc_device(dev); + if (mmc) { + err = mmc_init(mmc); + } else { + /* Can not find no more channels */ + break; + } + if (err) + return err; + print_size(mmc->capacity, "\n"); + } +#endif + return 0; +} + +int emmc_boot_partition_size_change(struct mmc *mmc, u32 bootsize, u32 rpmbsize) +{ + int err; + struct mmc_cmd cmd; + + /* Only use this command for raw eMMC moviNAND */ + /* Enter backdoor mode */ + cmd.cmdidx = 62; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = 0xefac62ec; + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + /* Boot partition changing mode */ + cmd.cmdidx = 62; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = 0xcbaea7; + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + bootsize = ((bootsize*1024)/128); + + /* Arg: boot partition size */ + cmd.cmdidx = 62; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = bootsize; + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + rpmbsize = ((rpmbsize*1024)/128); + + /* Arg: RPMB partition size */ + cmd.cmdidx = 62; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = rpmbsize; + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + return 0; +} +int emmc_boot_open(struct mmc *mmc) +{ + int err; + struct mmc_cmd cmd; + + /* Boot ack enable, boot partition enable , boot partition access */ + cmd.cmdidx = MMC_CMD_SWITCH; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = ((3<<24)|(179<<16)|(((1<<6)|(1<<3)|(1<<0))<<8)); + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + /* 4bit transfer mode at booting time. */ + cmd.cmdidx = MMC_CMD_SWITCH; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = ((3<<24)|(177<<16)|((1<<0)<<8)); + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + return 0; +} + +int emmc_boot_close(struct mmc *mmc) +{ + int err; + struct mmc_cmd cmd; + + /* Boot ack enable, boot partition enable , boot partition access */ + cmd.cmdidx = MMC_CMD_SWITCH; + cmd.resp_type = MMC_RSP_R1b; + cmd.cmdarg = ((3<<24)|(179<<16)|(((1<<6)|(1<<3)|(0<<0))<<8)); + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + + return 0; +} + +int emmc_boot_control(struct mmc *mmc, int control) +{ + int err; + struct mmc_cmd cmd; + + /* Boot ack enable, boot partition enable , boot partition access */ + cmd.cmdidx = MMC_CMD_SWITCH; + cmd.resp_type = MMC_RSP_R1b; + if (control) + cmd.cmdarg = ((3<<24)|(179<<16)|(((1<<6)|(1<<3)|(0<<0))<<8)); + else + cmd.cmdarg = ((3<<24)|(179<<16)|(((1<<6)|(0<<3)|(0<<0))<<8)); + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + if (err) + return err; + return 0; } diff --git a/drivers/mmc/s5p_mshc.c b/drivers/mmc/s5p_mshc.c new file mode 100644 index 000000000..1bbea987c --- /dev/null +++ b/drivers/mmc/s5p_mshc.c @@ -0,0 +1,768 @@ +/* + * Copyright 2007, Freescale Semiconductor, Inc + * Andy Fleming + * + * Based vaguely on the pxa mmc code: + * (C) Copyright 2003 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 <config.h> +#include <common.h> +#include <command.h> +#include <part.h> +#include <malloc.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mmc.h> +#include <asm/arch/clk.h> + +#include "s5p_mshc.h" + +DECLARE_GLOBAL_DATA_PTR; +//#define DEBUG_S5P_MSHC +#ifdef DEBUG_S5P_MSHC +#define dbg(x...) printf(x) +#else +#define dbg(x...) do { } while (0) +#endif + +#ifndef mdelay +#define mdelay(x) udelay(1000*x) +#endif + +#define MHZ 1000000 +#define KHZ 1000 + +struct mmc mshc_channel[MMC_MAX_CHANNEL]; + +struct mshci_host mshc_host[MMC_MAX_CHANNEL]; + +/* it can cover to transfer 256MB at a time */ +static struct mshci_idmac idmac_desc[0x10000]; + +extern unsigned int OmPin; + +static void mshci_dumpregs_err(struct mshci_host *host) +{ + dbg("mshci: ============== REGISTER DUMP ==============\n"); + dbg("mshci: MSHCI_CTRL: 0x%08x\n", + mshci_readl(host, MSHCI_CTRL)); + dbg("mshci: MSHCI_PWREN: 0x%08x\n", + mshci_readl(host, MSHCI_PWREN)); + dbg("mshci: MSHCI_CLKDIV: 0x%08x\n", + mshci_readl(host, MSHCI_CLKDIV)); + dbg("mshci: MSHCI_CLKSRC: 0x%08x\n", + mshci_readl(host, MSHCI_CLKSRC)); + dbg("mshci: MSHCI_CLKENA: 0x%08x\n", + mshci_readl(host, MSHCI_CLKENA)); + dbg("mshci: MSHCI_TMOUT: 0x%08x\n", + mshci_readl(host, MSHCI_TMOUT)); + dbg("mshci: MSHCI_CTYPE: 0x%08x\n", + mshci_readl(host, MSHCI_CTYPE)); + dbg("mshci: MSHCI_BLKSIZ: 0x%08x\n", + mshci_readl(host, MSHCI_BLKSIZ)); + dbg("mshci: MSHCI_BYTCNT: 0x%08x\n", + mshci_readl(host, MSHCI_BYTCNT)); + dbg("mshci: MSHCI_INTMSK: 0x%08x\n", + mshci_readl(host, MSHCI_INTMSK)); + dbg("mshci: MSHCI_CMDARG: 0x%08x\n", + mshci_readl(host, MSHCI_CMDARG)); + dbg("mshci: MSHCI_CMD: 0x%08x\n", + mshci_readl(host, MSHCI_CMD)); + dbg("mshci: MSHCI_MINTSTS: 0x%08x\n", + mshci_readl(host, MSHCI_MINTSTS)); + dbg("mshci: MSHCI_RINTSTS: 0x%08x\n", + mshci_readl(host, MSHCI_RINTSTS)); + dbg("mshci: MSHCI_STATUS: 0x%08x\n", + mshci_readl(host, MSHCI_STATUS)); + dbg("mshci: MSHCI_FIFOTH: 0x%08x\n", + mshci_readl(host, MSHCI_FIFOTH)); + dbg("mshci: MSHCI_CDETECT: 0x%08x\n", + mshci_readl(host, MSHCI_CDETECT)); + dbg("mshci: MSHCI_WRTPRT: 0x%08x\n", + mshci_readl(host, MSHCI_WRTPRT)); + dbg("mshci: MSHCI_GPIO: 0x%08x\n", + mshci_readl(host, MSHCI_GPIO)); + dbg("mshci: MSHCI_TCBCNT: 0x%08x\n", + mshci_readl(host, MSHCI_TCBCNT)); + dbg("mshci: MSHCI_TBBCNT: 0x%08x\n", + mshci_readl(host, MSHCI_TBBCNT)); + dbg("mshci: MSHCI_DEBNCE: 0x%08x\n", + mshci_readl(host, MSHCI_DEBNCE)); + dbg("mshci: MSHCI_USRID: 0x%08x\n", + mshci_readl(host, MSHCI_USRID)); + dbg("mshci: MSHCI_VERID: 0x%08x\n", + mshci_readl(host, MSHCI_VERID)); + dbg("mshci: MSHCI_HCON: 0x%08x\n", + mshci_readl(host, MSHCI_HCON)); + dbg("mshci: MSHCI_UHS_REG: 0x%08x\n", + mshci_readl(host, MSHCI_UHS_REG)); + dbg("mshci: MSHCI_BMOD: 0x%08x\n", + mshci_readl(host, MSHCI_BMOD)); + dbg("mshci: MSHCI_PLDMND: 0x%08x\n", + mshci_readl(host, MSHCI_PLDMND)); + dbg("mshci: MSHCI_DBADDR: 0x%08x\n", + mshci_readl(host, MSHCI_DBADDR)); + dbg("mshci: MSHCI_IDSTS: 0x%08x\n", + mshci_readl(host, MSHCI_IDSTS)); + dbg("mshci: MSHCI_IDINTEN: 0x%08x\n", + mshci_readl(host, MSHCI_IDINTEN)); + dbg("mshci: MSHCI_DSCADDR: 0x%08x\n", + mshci_readl(host, MSHCI_DSCADDR)); + dbg("mshci: MSHCI_BUFADDR: 0x%08x\n", + mshci_readl(host, MSHCI_BUFADDR)); + dbg("mshci: MSHCI_WAKEUPCON: 0x%08x\n", + mshci_readl(host, MSHCI_WAKEUPCON)); + dbg("mshci: MSHCI_CLOCKCON: 0x%08x\n", + mshci_readl(host, MSHCI_CLOCKCON)); + dbg("mshci: MSHCI_FIFODAT: 0x%08x\n", + mshci_readl(host, MSHCI_FIFODAT(host->data_offset))); + dbg("mshci: ===========================================\n"); +} + +static void mshci_reset_ciu(struct mshci_host *host) +{ + u32 timeout = 100; + u32 ier; + + ier = readl(host->ioaddr + MSHCI_CTRL); + ier |= CTRL_RESET; + + writel(ier, host->ioaddr + MSHCI_CTRL); + + while (readl(host->ioaddr + MSHCI_CTRL) & CTRL_RESET) { + if (timeout == 0) { + printf("Reset CTRL never completed.\n"); + return; + } + timeout--; + mdelay(1); + } +} + +static void mshci_reset_fifo(struct mshci_host *host) +{ + u32 timeout = 100; + u32 ier; + + ier = readl(host->ioaddr + MSHCI_CTRL); + ier |= FIFO_RESET; + + writel(ier, host->ioaddr + MSHCI_CTRL); + while (readl(host->ioaddr + MSHCI_CTRL) & FIFO_RESET) { + if (timeout == 0) { + printf("Reset FIFO never completed.\n"); + return; + } + timeout--; + mdelay(1); + } +} + +static void mshci_reset_dma(struct mshci_host *host) +{ + u32 timeout = 100; + u32 ier; + + ier = readl(host->ioaddr + MSHCI_CTRL); + ier |= DMA_RESET; + + writel(ier, host->ioaddr + MSHCI_CTRL); + while (readl(host->ioaddr + MSHCI_CTRL) & DMA_RESET) { + if (timeout == 0) { + printf("Reset DMA never completed.\n"); + return; + } + timeout--; + mdelay(1); + } +} + +static void mshci_reset_all(struct mshci_host *host) +{ + int count; + + /* Wait max 100 ms */ + count = 10000; + + /* before reset ciu, it should check DATA0. if when DATA0 is low and + it resets ciu, it might make a problem */ + while (mshci_readl(host, MSHCI_STATUS) & (1 << 9)) { + printf("Count: %d\n", count); + if (count == 0) { + printf("Controller never released \ + data0 before reset ciu.\n"); + return; + } + count--; + udelay(10); + } + + mshci_reset_ciu(host); + mshci_reset_fifo(host); + mshci_reset_dma(host); +} + + + +static void mshci_set_mdma_desc(u8 *desc_vir, u8 *desc_phy, + u32 des0, u32 des1, u32 des2) +{ + ((struct mshci_idmac *)(desc_vir))->des0 = des0; + ((struct mshci_idmac *)(desc_vir))->des1 = des1; + ((struct mshci_idmac *)(desc_vir))->des2 = des2; + ((struct mshci_idmac *)(desc_vir))->des3 = (u32)desc_phy + + sizeof(struct mshci_idmac); +} + + +static void mshci_prepare_data(struct mshci_host *host, struct mmc_data *data) +{ + u32 i; + u32 data_cnt; + u32 des_flag; + u32 blksz; + + struct mshci_idmac *pdesc_dmac; + + mshci_reset_fifo(host); + + pdesc_dmac = idmac_desc; + + blksz = data->blocksize; + data_cnt = data->blocks; + + for (i = 0;; i++) { + des_flag = (MSHCI_IDMAC_OWN | MSHCI_IDMAC_CH); + des_flag |= (i == 0) ? MSHCI_IDMAC_FS : 0; + if (data_cnt <= 8) { + des_flag |= MSHCI_IDMAC_LD; + mshci_set_mdma_desc((u8 *)pdesc_dmac, + (u8 *)virt_to_phys((u32)pdesc_dmac), + des_flag, blksz * data_cnt, + (u32)(virt_to_phys((u32)data->dest)) + + (u32)(i * 0x1000)); + break; + } + /* max transfer size is 4KB per a description. */ + mshci_set_mdma_desc((u8 *)pdesc_dmac, + (u8 *)virt_to_phys((u32)pdesc_dmac), + des_flag, blksz * 8, + virt_to_phys((u32)data->dest) + (u32)(i * 0x1000)); + + data_cnt -= 8; + pdesc_dmac++; + } + + writel((u32)virt_to_phys((u32)idmac_desc), + host->ioaddr + MSHCI_DBADDR); + + if (data->blocks > 1) + writel(readl(host->ioaddr + MSHCI_CTRL) | SEND_AS_CCSD, + host->ioaddr + MSHCI_CTRL); + + /* enable DMA, IDMAC */ + writel((readl(host->ioaddr + MSHCI_CTRL) | + ENABLE_IDMAC|DMA_ENABLE), host->ioaddr + MSHCI_CTRL); + writel((readl(host->ioaddr + MSHCI_BMOD) | + (BMOD_IDMAC_ENABLE|BMOD_IDMAC_FB)), + host->ioaddr + MSHCI_BMOD); + + writel(data->blocksize, host->ioaddr + MSHCI_BLKSIZ); + writel((data->blocksize * data->blocks), host->ioaddr + MSHCI_BYTCNT); + +} + +static int mshci_set_transfer_mode(struct mshci_host *host, + struct mmc_data *data) +{ + int mode = 0; + + /* this cmd has data to transmit */ + mode |= CMD_DATA_EXP_BIT; +#if defined(CONFIG_SKIP_MMC_STOP_CMD) + if (data->blocks > 1) + mode |= CMD_SENT_AUTO_STOP_BIT; +#endif + if (data->flags & MMC_DATA_WRITE) + mode |= CMD_RW_BIT; + + return mode; +} + +#define COMMAND_TIMEOUT (0x200000) + +/* + * Sends a command out on the bus. Takes the mmc pointer, + * a command pointer, and an optional data pointer. + */ +static int +s5p_mshc_send_command(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct mshci_host *host = mmc->priv; + + int flags = 0, i; + u32 mask; + unsigned long timeout; + + /* Wait max 1000 ms */ + timeout = 1000; + + if (cmd->cmdidx != MMC_CMD_SEND_STATUS) { + /*We shouldn't wait for data inihibit for stop commands, even + * though they might use busy signaling */ + while (mshci_readl(host, MSHCI_STATUS) & (1 << 9)) { + if (timeout == 0) { + printf("Controller never released data busy!!\n"); + return -1; + } + timeout--; + mdelay(1); + } + } + + if (mshci_readl(host, MSHCI_RINTSTS)) { + if (mshci_readl(host, MSHCI_RINTSTS) & + ~((0xffff << 16) | (1 << 2) | (1 << 14))) + printf("there are pending interrupts 0x%08x\n", + mshci_readl(host, MSHCI_RINTSTS)); + } + /* It clears all pending interrupts before sending a command*/ + mshci_writel(host, INTMSK_ALL, MSHCI_RINTSTS); + + if (data) + mshci_prepare_data(host, data); + + dbg("CMD[%2d]\t", cmd->cmdidx); + dbg("ARG: %08x\n", cmd->cmdarg); + + writel(cmd->cmdarg, host->ioaddr + MSHCI_CMDARG); + + if (data) + flags = mshci_set_transfer_mode(host, data); + + if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY)) + /* this is out of SD spec */ + return -1; + + if (cmd->resp_type & MMC_RSP_PRESENT) { + flags |= CMD_RESP_EXP_BIT; + if (cmd->resp_type & MMC_RSP_136) + flags |= CMD_RESP_LENGTH_BIT; + } + + if (cmd->resp_type & MMC_RSP_CRC) + flags |= CMD_CHECK_CRC_BIT; + + flags |= (cmd->cmdidx | CMD_STRT_BIT | + host->use_hold_reg | CMD_WAIT_PRV_DAT_BIT); + + mask = mshci_readl(host, MSHCI_CMD); + if (mask & CMD_STRT_BIT) + printf("[ERROR] CMD busy. current cmd %d. last cmd reg 0x%x\n", + cmd->cmdidx, mask); + + mshci_writel(host, flags, MSHCI_CMD); + + /* wait for clearing start bit */ + for (i = 0; i < COMMAND_TIMEOUT; i++) { + mask = readl(host->ioaddr + MSHCI_CMD); + if (!(mask & CMD_STRT_BIT)) + break; + } + /* wait for idle state of command FSM */ + for (; i < COMMAND_TIMEOUT; i++) { + mask = readl(host->ioaddr + MSHCI_STATUS); + if (!(mask & CMD_FSMSTAT)) + break; + } + /* wait for command complete by busy waiting. */ + for (; i < COMMAND_TIMEOUT; i++) { + mask = readl(host->ioaddr + MSHCI_RINTSTS); + if (mask & INTMSK_CDONE) { + if (!data) + writel(mask, host->ioaddr + MSHCI_RINTSTS); + break; + } + } + + /* timeout for command complete. */ + if (COMMAND_TIMEOUT == i) { + printf("FAIL: waiting for status update.\n"); + return TIMEOUT; + } + + if (mask & INTMSK_RTO) { + if (((cmd->cmdidx == 8 || cmd->cmdidx == 41 || + cmd->cmdidx == 55)) == 0) { + printf("[ERROR] response timeout error : %08x cmd %d\n", + mask, cmd->cmdidx); + } + return TIMEOUT; + } else if (mask & INTMSK_RE) { + printf("[ERROR] response error : %08x cmd %d\n", + mask, cmd->cmdidx); + return -1; + } else if (mask & INTMSK_RCRC) { + printf("[ERROR] response CRC error : %08x cmd %d\n", + mask, cmd->cmdidx); + return -1; + } + + if (cmd->resp_type & MMC_RSP_PRESENT) { + if (cmd->resp_type & MMC_RSP_136) { + /* CRC is stripped so we need to do some shifting. */ + cmd->response[0] = mshci_readl(host, MSHCI_RESP3); + cmd->response[1] = mshci_readl(host, MSHCI_RESP2); + cmd->response[2] = mshci_readl(host, MSHCI_RESP1); + cmd->response[3] = mshci_readl(host, MSHCI_RESP0); + dbg("\tcmd->response[0]: 0x%08x\n", cmd->response[0]); + dbg("\tcmd->response[1]: 0x%08x\n", cmd->response[1]); + dbg("\tcmd->response[2]: 0x%08x\n", cmd->response[2]); + dbg("\tcmd->response[3]: 0x%08x\n", cmd->response[3]); + } else { + cmd->response[0] = readl(host->ioaddr + MSHCI_RESP0); + dbg("\tcmd->response[0]: 0x%08x\n", cmd->response[0]); + } + } + + if (data) { + while (!(mask & (DATA_ERR | DATA_TOUT | INTMSK_DTO))) + mask = readl(host->ioaddr + MSHCI_RINTSTS); + + writel(mask, host->ioaddr + MSHCI_RINTSTS); + if (mask & (DATA_ERR | DATA_TOUT)) { + printf("error during transfer: 0x%08x\n", mask); + + /* make sure disable IDMAC and IDMAC_Interrupts */ + mshci_writel(host, (mshci_readl(host, MSHCI_CTRL) & + ~(DMA_ENABLE|ENABLE_IDMAC)), MSHCI_CTRL); + /* mask all interrupt source of IDMAC */ + mshci_writel(host, 0x0, MSHCI_IDINTEN); + + return -1; + } else if (mask & INTMSK_DTO) + dbg("MSHCI_INT_DMA_END\n"); + else + printf("unexpected condition 0x%x\n", mask); + + /* make sure disable IDMAC and IDMAC_Interrupts */ + mshci_writel(host, (mshci_readl(host, MSHCI_CTRL) & + ~(DMA_ENABLE|ENABLE_IDMAC)), MSHCI_CTRL); + /* mask all interrupt source of IDMAC */ + mshci_writel(host, 0x0, MSHCI_IDINTEN); + } + return 0; +} + +static void mshci_clock_onoff(struct mshci_host *host, int val) +{ + u32 loop_count = 0x100000; + + if (val) { + mshci_writel(host, (0x1 << 0), MSHCI_CLKENA); + mshci_writel(host, 0, MSHCI_CMD); + mshci_writel(host, CMD_ONLY_CLK, MSHCI_CMD); + do { + if (!(mshci_readl(host, MSHCI_CMD) & CMD_STRT_BIT)) + break; + loop_count--; + } while (loop_count); + } else { + mshci_writel(host, (0x0 << 0), MSHCI_CLKENA); + mshci_writel(host, 0, MSHCI_CMD); + mshci_writel(host, CMD_ONLY_CLK, MSHCI_CMD); + do { + if (!(mshci_readl(host, MSHCI_CMD) & CMD_STRT_BIT)) + break; + loop_count--; + } while (loop_count); + } + if (loop_count == 0) + printf("Clock %s has been failed.\n ", val ? "ON" : "OFF"); +} + +static void mshci_change_clock(struct mshci_host *host, uint clock) +{ + int div, dev_index; + u32 mpll_clock; + u32 div_mmc, div_mmc_pre, sclk_mmc; + u32 loop_count; + + if (clock == 0) + return; + + /* befor changing clock. clock needs to be off. */ + mshci_clock_onoff(host, CLK_DISABLE); + + /* If Input clock is high more than MAXUMUM CLK */ + if (clock > host->max_clk) { + dbg("Input CLK is too high. CLK: %dMHz\n", clock / MHZ); + clock = host->max_clk; + dbg("Set CLK to %dMHz\n", clock / MHZ); + } + + /* Calculate SCLK_MMCx */ + dev_index = host->dev_index; + sclk_mmc = get_mmc_clk(dev_index); + + dbg("sclk_mmc: %dKHz\n", sclk_mmc / KHZ); + dbg("Phase Shift CLK: %dKHz\n", (sclk_mmc / host->phase_devide) / KHZ); + + /* CLKDIV */ + for (div = 1 ; div <= 0xFF; div++) { + if (((sclk_mmc / host->phase_devide) / (2 * div)) <= clock) { + mshci_writel(host, div, MSHCI_CLKDIV); + break; + } + } + dbg("div: %08d\n", div); + dbg("CLOCK:: %dKHz\n", + ((sclk_mmc / host->phase_devide) / (div * 2)) / KHZ); + + mshci_writel(host, div, MSHCI_CLKDIV); + + mshci_writel(host, 0, MSHCI_CMD); + mshci_writel(host, CMD_ONLY_CLK, MSHCI_CMD); + loop_count = 0x10000000; + + do { + if (!(mshci_readl(host, MSHCI_CMD) & CMD_STRT_BIT)) + break; + loop_count--; + } while (loop_count); + + if (loop_count == 0) + printf("Changing clock has been failed.\n "); + + mshci_writel(host, mshci_readl(host, MSHCI_CMD)&(~CMD_SEND_CLK_ONLY), + MSHCI_CMD); + mshci_clock_onoff(host, CLK_ENABLE); + host->clock = clock; + + return; +} + +static void s5p_mshc_set_ios(struct mmc *mmc) +{ + struct mshci_host *host = mmc->priv; + u32 mode = 0; + + if (mmc->clock > 0) + mshci_change_clock(host, mmc->clock); + + if (mmc->bus_width == 0x8) { + dbg("MMC_BUS_WIDTH_8\n"); + mshci_writel(host, (0x1<<16), MSHCI_CTYPE); + mode = (mmc->card_caps) & MMC_MODE_DDR; + } else if (mmc->bus_width == 0x4) { + dbg("MMC_BUS_WIDTH_4\n"); + mshci_writel(host, (0x1<<0), MSHCI_CTYPE); + mode = (mmc->card_caps) & MMC_MODE_DDR; + } else { + dbg("BUS_WIDTH_1\n"); + mshci_writel(host, (0x0<<0), MSHCI_CTYPE); + } + + /* Support DDR Mode */ + if (mode) { + dbg("MMC DDR MODE\n"); + mshci_writel(host, (0x1<<16), MSHCI_UHS_REG); + } else { + dbg("MMC SDR MODE\n"); + mshci_writel(host, + mshci_readl(host, MSHCI_UHS_REG) & ~(0x1<<16), + MSHCI_UHS_REG); + } + + if (host->version >= 0x240a) { + if (mode) { + dbg("Phase Shift Register: 0x%08x\n", host->ddr); + mshci_writel(host, host->ddr, MSHCI_CLKSEL); + } else { + dbg("Phase Shift Register: 0x%08x\n", host->sdr); + mshci_writel(host, host->sdr, MSHCI_CLKSEL); + } + } +} + +static void mshci_fifo_init(struct mshci_host *host) +{ + int fifo_val, fifo_depth, fifo_threshold; + + fifo_val = mshci_readl(host, MSHCI_FIFOTH); + + fifo_depth = 0x20; + + fifo_threshold = fifo_depth / 2; + + dbg("FIFO WMARK FOR RX 0x%x TX 0x%x.\n", + (fifo_threshold - 1), fifo_threshold); + + fifo_val &= ~(RX_WMARK | TX_WMARK | MSIZE_MASK); + fifo_val |= (fifo_threshold | ((fifo_threshold - 1) << 16)); + fifo_val |= MSIZE_8; + + mshci_writel(host, fifo_val, MSHCI_FIFOTH); +} + +static void mshci_init(struct mshci_host *host) +{ + /* Power Enable Register */ + mshci_writel(host, 1<<0, MSHCI_PWREN); + + mshci_reset_all(host); + mshci_fifo_init(host); + + /* It clears all pending interrupts */ + mshci_writel(host, INTMSK_ALL, MSHCI_RINTSTS); + /* It dose not use Interrupt. Disable all */ + mshci_writel(host, 0, MSHCI_INTMSK); +} + +static int s5c_mshc_init(struct mmc *mmc) +{ + struct mshci_host *host = (struct mshci_host *)mmc->priv; + u32 chip_version, main_rev, sub_rev; + u32 ier; + +#if defined(CONFIG_MMC_SMU_INIT) + if (host->dev_index != 2) { + mshci_writel(host, 0, MSHCI_MPSBEGIN0); + mshci_writel(host, 0xFFFFFFFF, MSHCI_MPSEND0); + mshci_writel(host, MPSCTRL_SECURE_READ_BIT | MPSCTRL_SECURE_WRITE_BIT | + MPSCTRL_NON_SECURE_READ_BIT | MPSCTRL_NON_SECURE_WRITE_BIT | + MPSCTRL_VALID, MSHCI_MPSCTRL0); + } +#endif + + host->version = GET_VERID(mshci_readl(host, MSHCI_VERID)); + dbg("MSHC version: %x\n", host->version); + + mshci_init(host); + + if (host->version >= 0x240a) + host->data_offset = MSHCI_240A_FIFODAT; + else + host->data_offset = MSHCI_220A_FIFODAT; + + host->max_clk = mmc->f_max; + host->phase_devide = PHASE_DEVIDER; + + if (host->version >= 0x240a) + host->use_hold_reg = CMD_USE_HOLD_REG; + + /* MSHC Version check */ + if (host->version >= 0x240a) { + chip_version = readl(0x10000000); + main_rev = (0xF & (chip_version >> 4)); + sub_rev = (0xF & chip_version); + dbg("AP REVISION: %d.%d\n", main_rev, sub_rev); + } + + if (host->version >= 0x240a) + mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | + MMC_MODE_HS_52MHz | MMC_MODE_HS | + MMC_MODE_HC | MMC_MODE_DDR; + else + mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | + MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC; + + mshci_change_clock(host, 400000); + + /* Set auto stop command */ + ier = readl(host->ioaddr + MSHCI_CTRL); + ier |= (1<<10); + writel(ier, host->ioaddr + MSHCI_CTRL); + + /* set debounce filter value*/ + mshci_writel(host, 0xfffff, MSHCI_DEBNCE); + + /* clear card type. set 1bit mode */ + mshci_writel(host, 0x0, MSHCI_CTYPE); + + /* set bus mode register for IDMAC */ + mshci_writel(host, BMOD_IDMAC_RESET, MSHCI_BMOD); + + /* disable all interrupt source of IDMAC */ + mshci_writel(host, 0x0, MSHCI_IDINTEN); + + /* set max timeout */ + writel(0xffffffff, host->ioaddr + MSHCI_TMOUT); + + return 0; +} + +int s5p_mshc_init(unsigned int regbase, unsigned int channel) +{ + struct mmc *mmc; + mmc = &mshc_channel[channel]; + + sprintf(mmc->name, "S5P_MSHC%d", channel); + mmc->priv = &mshc_host[channel]; + mmc->send_cmd = s5p_mshc_send_command; + mmc->set_ios = s5p_mshc_set_ios; + mmc->init = s5c_mshc_init; + + mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->f_min = 400000; + mmc->f_max = 50000000; + mshc_host[channel].clock = 0; + mshc_host[channel].dev_index = channel; + + switch (channel) { +#ifdef USE_MMC0 + case 0: + mshc_host[channel].ioaddr = (void *)regbase; + mshc_host[channel].sdr = SDR_CH0; + mshc_host[channel].ddr = DDR_CH0; + break; +#endif +#ifdef USE_MMC2 + case 2: + mshc_host[channel].ioaddr = (void *)regbase; + mshc_host[channel].sdr = SDR_CH2; + mshc_host[channel].ddr = DDR_CH2; + break; +#endif +#ifdef USE_MMC3 + case 3: + mshc_host[channel].ioaddr = (void *)regbase; + break; +#endif +#ifdef USE_MMC4 + case 4: + mshc_host[channel].ioaddr = (void *)regbase; + mshc_host[channel].sdr = SDR_CH4; + mshc_host[channel].ddr = DDR_CH4; + break; +#endif + default: + printf("mmc err: not supported channel %d\n", channel); + } + + return mmc_register(mmc); +} + diff --git a/drivers/mmc/s5p_mshc.h b/drivers/mmc/s5p_mshc.h new file mode 100644 index 000000000..b7e18364b --- /dev/null +++ b/drivers/mmc/s5p_mshc.h @@ -0,0 +1,419 @@ +/* + * (C) Copyright 2011 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef S5P_MSHC_H +#define S5P_MSHC_H + +#include <asm/io.h> +#include <mmc.h> + +/* + * linux/drivers/mmc/host/mshci.h - Secure Digital Host Controller Interface driver + * + * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. + * + * 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. + */ + +/* + * Controller registers + */ +/*****************************************************/ +/* MSHC Internal Registers */ +/*****************************************************/ + +#define MSHCI_CTRL 0x00 /* Control */ +#define MSHCI_PWREN 0x04 /* Power-enable */ +#define MSHCI_CLKDIV 0x08 /* Clock divider */ +#define MSHCI_CLKSRC 0x0C /* Clock source */ +#define MSHCI_CLKENA 0x10 /* Clock enable */ +#define MSHCI_TMOUT 0x14 /* Timeout */ +#define MSHCI_CTYPE 0x18 /* Card type */ +#define MSHCI_BLKSIZ 0x1C /* Block Size */ +#define MSHCI_BYTCNT 0x20 /* Byte count */ +#define MSHCI_INTMSK 0x24 /* Interrupt Mask */ +#define MSHCI_CMDARG 0x28 /* Command Argument */ +#define MSHCI_CMD 0x2C /* Command */ +#define MSHCI_RESP0 0x30 /* Response 0 */ +#define MSHCI_RESP1 0x34 /* Response 1 */ +#define MSHCI_RESP2 0x38 /* Response 2 */ +#define MSHCI_RESP3 0x3C /* Response 3 */ +#define MSHCI_MINTSTS 0x40 /* Masked interrupt status */ +#define MSHCI_RINTSTS 0x44 /* Raw interrupt status */ +#define MSHCI_STATUS 0x48 /* Status */ +#define MSHCI_FIFOTH 0x4C /* FIFO threshold */ +#define MSHCI_CDETECT 0x50 /* Card detect */ +#define MSHCI_WRTPRT 0x54 /* Write protect */ +#define MSHCI_GPIO 0x58 /* General Purpose IO */ +#define MSHCI_TCBCNT 0x5C /* Transferred CIU byte count */ +#define MSHCI_TBBCNT 0x60 /* Transferred host/DMA to/from byte count */ +#define MSHCI_DEBNCE 0x64 /* Card detect debounce */ +#define MSHCI_USRID 0x68 /* User ID */ +#define MSHCI_VERID 0x6C /* Version ID */ +#define MSHCI_HCON 0x70 /* Hardware Configuration */ +#define MSHCI_UHS_REG 0x74 /* UHS and DDR setting */ +#define MSHCI_BMOD 0x80 /* Bus mode register */ +#define MSHCI_PLDMND 0x84 /* Poll demand */ +#define MSHCI_DBADDR 0x88 /* Descriptor list base address */ +#define MSHCI_IDSTS 0x8C /* Internal DMAC status */ +#define MSHCI_IDINTEN 0x90 /* Internal DMAC interrupt enable */ +#define MSHCI_DSCADDR 0x94 /* Current host descriptor address */ +#define MSHCI_BUFADDR 0x98 /* Current host buffer address */ +#define MSHCI_CLKSEL 0x9C /* Drv/sample clock selection register */ +#define MSHCI_WAKEUPCON 0xA0 /* Wakeup control register */ +#define MSHCI_CLOCKCON 0xA4 /* Clock (delay) control register */ +#define MSHCI_FIFODAT(x) (x) /* FIFO data read write */ +#define MSHCI_EMMCP_BASE 0x1000 /* EMMCP base address offset */ +#define MSHCI_MPSECURITY 0x1010 +#define MSHCI_MPSBEGIN0 0x1200 +#define MSHCI_MPSEND0 0x1204 +#define MSHCI_MPSCTRL0 0x120C + + +/***************************************************** +* IP Version Control + *****************************************************/ +#define MSHCI_220A_FIFODAT 0x100 /* FIFO data read write */ +#define MSHCI_240A_FIFODAT 0x200 /* FIFO data read write */ + +#define VERID_240A 0x240a +#define GET_VERID(x) ((x) & 0xFFFF) + +/***************************************************** + * Control Register Register + * MSHCI_CTRL - offset 0x00 + *****************************************************/ + +#define CTRL_RESET (0x1<<0) /* Reset DWC_mobile_storage controller */ +#define FIFO_RESET (0x1<<1) /* Reset FIFO */ +#define DMA_RESET (0x1<<2) /* Reset DMA interface */ +#define INT_ENABLE (0x1<<4) /* Global interrupt enable/disable bit */ +#define DMA_ENABLE (0x1<<5) /* DMA transfer mode enable/disable bit */ +#define READ_WAIT (0x1<<6) /* For sending read-wait to SDIO cards */ +#define SEND_IRQ_RESP (0x1<<7) /* Send auto IRQ response */ +#define ABRT_READ_DATA (0x1<<8) +#define SEND_CCSD (0x1<<9) +#define SEND_AS_CCSD (0x1<<10) +#define CEATA_INTSTAT (0x1<<11) +#define CARD_VOLA (0xF<<16) +#define CARD_VOLB (0xF<<20) +#define ENABLE_OD_PULLUP (0x1<<24) +#define ENABLE_IDMAC (0x1<<25) + +#define MSHCI_RESET_ALL (0x1) + + +/***************************************************** + * Power Enable Register + * MSHCI_PWREN - offset 0x04 + *****************************************************/ +#define POWER_ENABLE (0x1<<0) + +/***************************************************** + * Clock Divider Register + * MSHCI_CLKDIV - offset 0x08 + *****************************************************/ +#define CLK_DIVIDER0 (0xFF<<0) +#define CLK_DIVIDER1 (0xFF<<8) +#define CLK_DIVIDER2 (0xFF<<16) +#define CLK_DIVIDER3 (0xFF<<24) + +/***************************************************** + * Clock Enable Register + * MSHCI_CLKENA - offset 0x10 + *****************************************************/ +#define CLK_SDMMC_MAX (48000000) /* 96Mhz. it SHOULDBE optimized */ +#define CLK_ENABLE (0x1<<0) +#define CLK_DISABLE (0x0<<0) + +/***************************************************** + * Timeout Register + * MSHCI_TMOUT - offset 0x14 + *****************************************************/ +#define RSP_TIMEOUT (0xFF<<0) +#define DATA_TIMEOUT (0xFFFFFF<<8) + +/***************************************************** + * Card Type Register + * MSHCI_CTYPE - offset 0x18 + *****************************************************/ +#define CARD_WIDTH14 (0xFFFF<<0) +#define CARD_WIDTH8 (0xFFFF<<16) + +/***************************************************** + * Block Size Register + * MSHCI_BLKSIZ - offset 0x1C + *****************************************************/ +#define BLK_SIZ (0xFFFF<<0) + +/***************************************************** + * Interrupt Mask Register + * MSHCI_INTMSK - offset 0x24 + *****************************************************/ +#define INT_MASK (0xFFFF<<0) +#define SDIO_INT_MASK (0xFFFF<<16) +#define SDIO_INT_ENABLE (0x1<<16) + +/* interrupt bits */ +#define INTMSK_ALL 0xFFFFFFFF +#define INTMSK_CDETECT (0x1<<0) +#define INTMSK_RE (0x1<<1) +#define INTMSK_CDONE (0x1<<2) +#define INTMSK_DTO (0x1<<3) +#define INTMSK_TXDR (0x1<<4) +#define INTMSK_RXDR (0x1<<5) +#define INTMSK_RCRC (0x1<<6) +#define INTMSK_DCRC (0x1<<7) +#define INTMSK_RTO (0x1<<8) +#define INTMSK_DRTO (0x1<<9) +#define INTMSK_HTO (0x1<<10) +#define INTMSK_FRUN (0x1<<11) +#define INTMSK_HLE (0x1<<12) +#define INTMSK_SBE (0x1<<13) +#define INTMSK_ACD (0x1<<14) +#define INTMSK_EBE (0x1<<15) +#define INTMSK_DMA (INTMSK_ACD|INTMSK_RXDR|INTMSK_TXDR) + +#define INT_SRC_IDMAC (0x0) +#define INT_SRC_MINT (0x1) + + +/***************************************************** + * Command Register + * MSHCI_CMD - offset 0x2C + *****************************************************/ + +#define CMD_RESP_EXP_BIT (0x1<<6) +#define CMD_RESP_LENGTH_BIT (0x1<<7) +#define CMD_CHECK_CRC_BIT (0x1<<8) +#define CMD_DATA_EXP_BIT (0x1<<9) +#define CMD_RW_BIT (0x1<<10) +#define CMD_TRANSMODE_BIT (0x1<<11) +#define CMD_SENT_AUTO_STOP_BIT (0x1<<12) +#define CMD_WAIT_PRV_DAT_BIT (0x1<<13) +#define CMD_ABRT_CMD_BIT (0x1<<14) +#define CMD_SEND_INIT_BIT (0x1<<15) +#define CMD_CARD_NUM_BITS (0x1F<<16) +#define CMD_SEND_CLK_ONLY (0x1<<21) +#define CMD_READ_CEATA (0x1<<22) +#define CMD_CCS_EXPECTED (0x1<<23) +#define CMD_USE_HOLD_REG (0x1<<29) +#define CMD_STRT_BIT (0x1<<31) +#define CMD_ONLY_CLK (CMD_STRT_BIT | CMD_SEND_CLK_ONLY | \ + CMD_WAIT_PRV_DAT_BIT) + +/***************************************************** + * Masked Interrupt Status Register + * MSHCI_MINTSTS - offset 0x40 + *****************************************************/ +/***************************************************** + * Raw Interrupt Register + * MSHCI_RINTSTS - offset 0x44 + *****************************************************/ +#define INT_STATUS (0xFFFF<<0) +#define SDIO_INTR (0xFFFF<<16) +#define DATA_ERR (INTMSK_EBE|INTMSK_SBE|INTMSK_HLE|INTMSK_FRUN |\ + INTMSK_EBE |INTMSK_DCRC) +#define DATA_TOUT (INTMSK_HTO|INTMSK_DRTO) +#define DATA_STATUS (DATA_ERR|DATA_TOUT|INTMSK_RXDR|INTMSK_TXDR|INTMSK_DTO) +#define CMD_STATUS (INTMSK_RTO|INTMSK_RCRC|INTMSK_CDONE|INTMSK_RE) +#define CMD_ERROR (INTMSK_RCRC|INTMSK_RTO|INTMSK_RE) + +/***************************************************** + * Status Register + * MSHCI_STATUS - offset 0x48 + *****************************************************/ +#define FIFO_RXWTRMARK (0x1<<0) +#define FIFO_TXWTRMARK (0x1<<1) +#define FIFO_EMPTY (0x1<<2) +#define FIFO_FULL (0x1<<3) +#define CMD_FSMSTAT (0xF<<4) +#define DATA_3STATUS (0x1<<8) +#define DATA_BUSY (0x1<<9) +#define DATA_MCBUSY (0x1<<10) +#define RSP_INDEX (0x3F<<11) +#define FIFO_COUNT (0x1FFF<<17) +#define DMA_ACK (0x1<<30) +#define DMA_REQ (0x1<<31) +#define FIFO_WIDTH (0x4) +#define FIFO_DEPTH (0x20) + +/*Command FSM status */ +#define FSM_IDLE (0 <<4) +#define FSM_SEND_INIT_SEQ (1 <<4) +#define FSM_TX_CMD_STARTBIT (2 <<4) +#define FSM_TX_CMD_TXBIT (3 <<4) +#define FSM_TX_CMD_INDEX_ARG (4 <<4) +#define FSM_TX_CMD_CRC7 (5 <<4) +#define FSM_TX_CMD_ENDBIT (6 <<4) +#define FSM_RX_RESP_STARTBIT (7 <<4) +#define FSM_RX_RESP_IRQRESP (8 <<4) +#define FSM_RX_RESP_TXBIT (9 <<4) +#define FSM_RX_RESP_CMDIDX (10<<4) +#define FSM_RX_RESP_DATA (11<<4) +#define FSM_RX_RESP_CRC7 (12<<4) +#define FSM_RX_RESP_ENDBIT (13<<4) +#define FSM_CMD_PATHWAITNCC (14<<4) +#define FSM_WAIT (15<<4) + +/***************************************************** + * FIFO Threshold Watermark Register + * MSHCI_FIFOTH - offset 0x4C + *****************************************************/ +#define TX_WMARK (0xFFF<<0) +#define RX_WMARK (0xFFF<<16) +#define MSIZE_MASK (0x7<<28) + +/* DW DMA Mutiple Transaction Size */ +#define MSIZE_1 (0<<28) +#define MSIZE_4 (1<<28) +#define MSIZE_8 (2<<28) +#define MSIZE_16 (3<<28) +#define MSIZE_32 (4<<28) +#define MSIZE_64 (5<<28) +#define MSIZE_128 (6<<28) +#define MSIZE_256 (7<<28) + +/***************************************************** + * FIFO Threshold Watermark Register + * MSHCI_FIFOTH - offset 0x4C + *****************************************************/ +#define GPI (0xFF<<0) +#define GPO (0xFFFF<<8) + + +/***************************************************** + * Card Detect Register + * MSHCI_CDETECT - offset 0x50 + * It assumes there is only one SD slot + *****************************************************/ +#define CARD_PRESENT (0x1<<0) + +/***************************************************** + * Write Protect Register + * MSHCI_WRTPRT - offset 0x54 + * It assumes there is only one SD slot + *****************************************************/ +#define WRTPRT_ON (0x1<<0) + +/***************************************************** + * Bus Mode Register + * MSHCI_BMOD - offset 0x80 + *****************************************************/ +#define BMOD_IDMAC_RESET (0x1<<0) +#define BMOD_IDMAC_FB (0x1<<1) +#define BMOD_IDMAC_ENABLE (0x1<<7) + +/***************************************************** + * Hardware Configuration Register + * MSHCI_HCON - offset 0x70 + *****************************************************/ +#define CARD_TYPE (0x1<<0) +#define NUM_CARDS (0x1F<<1) +#define H_BUS_TYPE (0x1<<6) +#define H_DATA_WIDTH (0x7<<7) +#define H_ADDR_WIDTH (0x3F<<10) +#define DMA_INTERFACE (0x3<<16) +#define GE_DMA_DATA_WIDTH (0x7<<18) +#define FIFO_RAM_INSIDE (0x1<<21) +#define UMPLEMENT_HOLD_REG (0x1<<22) +#define SET_CLK_FALSE_PATH (0x1<<23) +#define NUM_CLK_DIVIDER (0x3<<24) + +/***************************************************** + * Hardware Configuration Register + * MSHCI_IDSTS - offset 0x8c + *****************************************************/ +#define IDSTS_FSM (0xf<<13) +#define IDSTS_EB (0x7<<10) +#define IDSTS_AIS (0x1<<9) +#define IDSTS_NIS (0x1<<8) +#define IDSTS_CES (0x1<<5) +#define IDSTS_DU (0x1<<4) +#define IDSTS_FBE (0x1<<2) +#define IDSTS_RI (0x1<<1) +#define IDSTS_TI (0x1<<0) + +/***************************************************** + * Hardware Configuration Register + * MSHCI_IDSTS - offset 0x8c + *****************************************************/ +#define MPSCTRL_SECURE_READ_BIT (0x1<<7) +#define MPSCTRL_SECURE_WRITE_BIT (0x1<<6) +#define MPSCTRL_NON_SECURE_READ_BIT (0x1<<5) +#define MPSCTRL_NON_SECURE_WRITE_BIT (0x1<<4) +#define MPSCTRL_USE_FUSE_KEY (0x1<<3) +#define MPSCTRL_ECB_MODE (0x1<<2) +#define MPSCTRL_ENCRYPTION (0x1<<1) +#define MPSCTRL_VALID (0x1<<0) + +struct mshci_ops; + +struct mshci_idmac { + u32 des0; + u32 des1; + u32 des2; + u32 des3; +#define MSHCI_IDMAC_OWN (1<<31) +#define MSHCI_IDMAC_ER (1<<5) +#define MSHCI_IDMAC_CH (1<<4) +#define MSHCI_IDMAC_FS (1<<3) +#define MSHCI_IDMAC_LD (1<<2) +#define MSHCI_IDMAC_DIC (1<<1) +#define INTMSK_IDMAC_ALL (0x337) +#define INTMSK_IDMAC_ERROR (0x214) +}; + +#ifndef __iomem +#define __iomem +#endif + +struct mshci_host { + /* Data set by hardware interface driver */ + const char *hw_name; /* Hardware bus name */ + int irq; /* Device IRQ */ + void __iomem * ioaddr; /* Mapped address */ + int dev_index; + /* Internal data */ + struct mmc *mmc; /* MMC structure */ + u64 dma_mask; /* custom DMA mask */ + int flags; /* Host attributes */ +#define MSHCI_USE_IDMA (1<<1) /* Host is ADMA capable */ +#define MSHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */ +#define MSHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */ + unsigned int version; /* SDHCI spec. version */ + unsigned int data_offset; /* DATA offset */ + unsigned int max_clk; /* Max possible freq (MHz) */ + unsigned int timeout_clk; /* Timeout freq (KHz) */ + unsigned int clock; /* Current clock (MHz) */ + unsigned short power; /* Current voltage */ + dma_addr_t adma_addr; /* Mapped ADMA descr. table */ + unsigned int sdr; /* SDR Phase Shift */ + unsigned int ddr; /* DDR Phase Shift */ + unsigned int phase_devide; /* Phase Shift Auto Deviding */ + unsigned int use_hold_reg; /* Use hold register */ +}; + +static inline void mshci_writel(struct mshci_host *host, u32 val, int reg) +{ + writel(val, host->ioaddr + reg); +} + +static inline u32 mshci_readl(struct mshci_host *host, int reg) +{ + return readl(host->ioaddr + reg); +} +#endif + diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 1d4481b97..2708a2381 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -54,7 +54,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) * 00 = Delay3 (inverter delay) * 10 = Delay4 (inverter delay + 2ns) */ - val = SDHCI_CTRL3_FCSEL3 | SDHCI_CTRL3_FCSEL1; + val = SDHCI_CTRL3_FCSEL1 | SDHCI_CTRL3_FCSEL0; sdhci_writel(host, val, SDHCI_CONTROL3); /* diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1709643da..e028cdfd6 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -31,6 +31,60 @@ void *aligned_buffer; +static void sdhci_dumpregs_err(struct sdhci_host *host) +{ + printf("sdhci: ============== REGISTER DUMP ==============\n"); + printf("sdhci: SDHCI_DMA_ADDRESS:\t0x%08x\n", + sdhci_readl(host, SDHCI_DMA_ADDRESS)); + printf("sdhci: SDHCI_BLOCK_SIZE:\t0x%08x\n", + sdhci_readl(host, SDHCI_BLOCK_SIZE)); + printf("sdhci: SDHCI_ARGUMENT:\t\t0x%08x\n", + sdhci_readl(host, SDHCI_ARGUMENT)); + printf("sdhci: SDHCI_TRANSFER_MODE:\t0x%08x\n", + sdhci_readl(host, SDHCI_TRANSFER_MODE)); + printf("sdhci: SDHCI_COMMAND:\t\t0x%08x\n", + sdhci_readw(host, SDHCI_COMMAND)); + printf("sdhci: SDHCI_RESPONSE0:\t\t0x%08x\n", + sdhci_readl(host, SDHCI_RESPONSE)); + printf("sdhci: SDHCI_RESPONSE1:\t\t0x%08x\n", + sdhci_readl(host, SDHCI_RESPONSE + 0x4)); + printf("sdhci: SDHCI_RESPONSE2:\t\t0x%08x\n", + sdhci_readl(host, SDHCI_RESPONSE + 0x8)); + printf("sdhci: SDHCI_RESPONSE3:\t\t0x%08x\n", + sdhci_readl(host, SDHCI_RESPONSE + 0xC)); + printf("sdhci: SDHCI_BUFFER:\t\t0x%08x\n", + sdhci_readl(host, SDHCI_BUFFER)); + printf("sdhci: SDHCI_PRESENT_STATE:\t0x%08x\n", + sdhci_readl(host, SDHCI_PRESENT_STATE)); + printf("sdhci: SDHCI_HOST_CONTROL:\t0x%08x\n", + sdhci_readl(host, SDHCI_HOST_CONTROL)); + printf("sdhci: SDHCI_CLOCK_CONTROL:\t0x%08x\n", + sdhci_readl(host, SDHCI_CLOCK_CONTROL)); + printf("sdhci: SDHCI_INT_STATUS:\t0x%08x\n", + sdhci_readl(host, SDHCI_INT_STATUS)); + printf("sdhci: SDHCI_INT_ENABLE:\t0x%08x\n", + sdhci_readl(host, SDHCI_INT_ENABLE)); + printf("sdhci: SDHCI_SIGNAL_ENABLE:\t0x%08x\n", + sdhci_readl(host, SDHCI_SIGNAL_ENABLE)); + printf("sdhci: SDHCI_ACMD12_ERR:\t0x%08x\n", + sdhci_readl(host, SDHCI_ACMD12_ERR)); + printf("sdhci: SDHCI_CAPABILITIES:\t0x%08x\n", + sdhci_readl(host, SDHCI_CAPABILITIES)); + printf("sdhci: SDHCI_CAPABILITIES_1:\t0x%08x\n", + sdhci_readl(host, SDHCI_CAPABILITIES_1)); + printf("sdhci: SDHCI_MAX_CURRENT:\t0x%08x\n", + sdhci_readl(host, SDHCI_MAX_CURRENT)); + printf("sdhci: SDHCI_SET_ACMD12_ERROR:\t0x%08x\n", + sdhci_readl(host, SDHCI_SET_ACMD12_ERROR)); + printf("sdhci: SDHCI_ADMA_ERROR:\t0x%08x\n", + sdhci_readl(host, SDHCI_ADMA_ERROR)); + printf("sdhci: SDHCI_ADMA_ADDRESS:\t0x%08x\n", + sdhci_readl(host, SDHCI_ADMA_ADDRESS)); + printf("sdhci: SDHCI_SLOT_INT_STATUS:\t0x%08x\n", + sdhci_readl(host, SDHCI_SLOT_INT_STATUS)); + printf("sdhci: ===========================================\n"); +} + static void sdhci_reset(struct sdhci_host *host, u8 mask) { unsigned long timeout; @@ -110,7 +164,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, } #endif if (timeout-- > 0) - udelay(10); + mdelay(1); else { printf("Transfer data timeout\n"); return -1; @@ -138,7 +192,8 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, /* We shouldn't wait for data inihibit for stop commands, even though they might use busy signaling */ - if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) + if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION || + cmd->cmdidx == MMC_CMD_SEND_STATUS) mask &= ~SDHCI_DATA_INHIBIT; while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { @@ -174,7 +229,7 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, mode = SDHCI_TRNS_BLK_CNT_EN; trans_bytes = data->blocks * data->blocksize; if (data->blocks > 1) - mode |= SDHCI_TRNS_MULTI; + mode |= (SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12); if (data->flags == MMC_DATA_READ) mode |= SDHCI_TRNS_READ; diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 6819bb07b..881692051 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -87,13 +87,13 @@ int serial_init_dev(const int dev_index) { struct s5p_uart *const uart = s5p_get_base_uart(dev_index); - /* reset and enable FIFOs, set triggers to the maximum */ - writel(0, &uart->ufcon); + /* reset and enable FIFOs */ + writel(0x117, &uart->ufcon); writel(0, &uart->umcon); /* 8N1 */ writel(0x3, &uart->ulcon); /* No interrupts, no DMA, pure polling */ - writel(0x245, &uart->ucon); + writel(0x3c5, &uart->ucon); serial_setbrg_dev(dev_index); diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 87d1918cb..dfa4e698b 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -44,6 +44,9 @@ COBJS-$(CONFIG_OMAP1510) += omap1510_udc.o COBJS-$(CONFIG_OMAP1610) += omap1510_udc.o COBJS-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o COBJS-$(CONFIG_CPU_PXA27X) += pxa27x_udc.o +else +COBJS-$(CONFIG_EXYNOS_USBD3) += usbd3-ss.o +COBJS-$(CONFIG_S3C_USBD) += usbd-otg-hs.o endif endif diff --git a/drivers/usb/gadget/dnw.c b/drivers/usb/gadget/dnw.c new file mode 100644 index 000000000..8bbfbfb6d --- /dev/null +++ b/drivers/usb/gadget/dnw.c @@ -0,0 +1,467 @@ +#include <dnw.h> + +#if (CONFIG_DNW_VERSION > 0x09) + +/* Global variables */ +static struct dnw_devinfo g_devinfo={ +#if (CONFIG_DNW_VERSION == 0x0a) + .dnw_version = DNW_v10, +#else +#error dnw version mismatch +#endif +}; + +USBDNW g_usbdnw; + +#define DEVICE_STRING_CONFIG_INDEX 4 +#define DEVICE_STRING_INTERFACE_INDEX 5 +#define DEVICE_STRING_MANUFACTURER_INDEX 1 + +//static char *device_strings[DEVICE_STRING_MANUFACTURER_INDEX+1]; +//char* reply_msg; + +void dnw_usbctl_init(void) +{ + s3c_usbctl_init(); +} + +static void dnw_set_serial_number(void){ + +} + +int dnw_init(void){ + USBDNW *dnw = &g_usbdnw; + int ret = 1; + + memset(dnw, 0, sizeof(dnw)); + dnw->state = dnwNOTINIT; +// dnw->cmd.data = NULL; + + dnw->dnload.transfer_buffer = (unsigned char *)CFG_DNW_TRANSFER_BUFFER; + dnw->dnload.transfer_buffer_size = CFG_DNW_TRANSFER_BUFFER_SIZE; + + // usbd init + dnw_usbctl_init(); + s3c_usbc_activate(); + + device_strings[DEVICE_STRING_MANUFACTURER_INDEX] = "Samsung S.LSI"; + device_strings[DEVICE_STRING_PRODUCT_INDEX] = "exynos reference board"; + dnw_set_serial_number(); + /* These are just made up */ + device_strings[DEVICE_STRING_CONFIG_INDEX] = "DNW"; + device_strings[DEVICE_STRING_INTERFACE_INDEX] = "DNW"; + +// reply_msg = (char *)exynos_usb_malloc(512, USBDEV3_MDWIDTH/8); +// reply_msg = (char *)exynos_usb_malloc(512, 64/8); + + ret = 0; // This is a fake return value, because we do not initialize USB yet! + + dnw->state = dnwIDLE; + + return ret; + + +} + +#define DNW_USBD_IS_CONNECTED() (1) +#define DNW_USBD_DETECT_IRQ() S3C_USBD_DETECT_IRQ() +#define DNW_USBD_CLEAR_IRQ() S3C_USBD_CLEAR_IRQ() + +int dnw_usb_int_hndlr(void) +{ + return s3c_udc_int_hndlr(); +} + +#if 0 +int dnw_usb_int_bulkin(const char *buffer, unsigned int buffer_size) +{ + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + usbdev3_trb_ptr_t pBulkInTrb; + u32 usCapTrbBufSiz, uLastBufSize; + u32 i; + + // Set TRB for multiple Bulk IN Packet + usCapTrbBufSiz = TRB_BUF_SIZ_LIMIT/oUsbDev3.m_uBulkEPMaxPktSize*oUsbDev3.m_uBulkEPMaxPktSize; + g_uCntOfBulkInTrb = buffer_size/usCapTrbBufSiz; + + if ((buffer_size%usCapTrbBufSiz) != 0) + g_uCntOfBulkInTrb++; + + g_pBulkInTrb = (usbdev3_trb_ptr_t)exynos_usb_malloc(g_uCntOfBulkInTrb*sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + + if (g_pBulkInTrb == NULL) + Assert(0); + + pBulkInTrb = g_pBulkInTrb; + // Fill the Trbs + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 0; + usbdev3_trb_ctrl.b.chn = 1; + usbdev3_trb_ctrl.b.csp = 0; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_NORMAL; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 0; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + for(i=0;i<(g_uCntOfBulkInTrb-1);i++, pBulkInTrb++) + exynos_usb_fill_trb(pBulkInTrb, (u32)(buffer+usCapTrbBufSiz*i), usCapTrbBufSiz, usbdev3_trb_ctrl.data, 1); + + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.chn = 0; + usbdev3_trb_ctrl.b.ioc = 1; + uLastBufSize = buffer_size-usCapTrbBufSiz*i; + exynos_usb_fill_trb(pBulkInTrb, (u32)(buffer+usCapTrbBufSiz*i), uLastBufSize, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for multiple Bulk IN Packet + //------------------------------------ + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_IN, BULK_IN_EP, (u32)g_pBulkInTrb, 0, &oUsbDev3.m_uTriIn[BULK_IN_EP])) + { + return 0; + } + + return 1; +} +#endif + +u32 transfer_size=0; +u32 dnw_response_flag=0; + +int dnw_tx_status(const char *buffer, unsigned int buffer_size, const u32 need_sync_flag) +{ + /* dnw resp buffer */ + transfer_size = MIN(512, buffer_size); + + if (dnw_response_flag) + printf(" Response tx Warnning\n"); + +#if 0 + printf("%s, transfer_size: %d, msg size: %d\n", + __func__, transfer_size, sizeof(reply_msg)); //test +#endif +// memcpy(reply_msg, buffer, transfer_size); + dnw_response_flag=1; +// s3c_usb_int_bulkin(reply_msg, transfer_size); + + if (need_sync_flag) + { + while(dnw_response_flag) + dnw_poll(); + } + return 1; +} + +static int dnw_receive_data (const unsigned char *buffer, unsigned int buffer_size) +{ + USBDNW *dnw = &g_usbdnw; + int ret = 1; +// if (download_size) + { + /* Something to download */ + + if (buffer_size) + { + /* Handle possible overflow */ + unsigned int transfer_size = dnw->dnload.tot_size - dnw->dnload.downloaded_bytes; + + if (buffer_size < transfer_size) + transfer_size = buffer_size; + + /* Save the data to the transfer buffer */ + memcpy ((u32)(dnw->dnload.start_address + dnw->dnload.downloaded_bytes), + buffer, transfer_size); + + dnw->dnload.downloaded_bytes += transfer_size; + + /* Check if transfer is done */ + if (dnw->dnload.downloaded_bytes >= dnw->dnload.tot_size) + { + /* Reset global transfer variable, + Keep download_bytes because it will be + used in the next possible flashing command */ + dnw->dnload.tot_size = 0; + + if (dnw->dnload.dnload_error) + { + /* There was an earlier error */ +// sprintf(response, "ERROR"); + } + else + { + /* Everything has transferred, + send the OK response */ +// sprintf(response, "OKAY"); + ret = DNW_OK; + dnw->state = dnwIDLE; + } + + printf("\ndownloading of %ld bytes finished\n", dnw->dnload.downloaded_bytes); +// LCD_setprogress(0); + + } + + /* Provide some feedback */ + if (dnw->dnload.downloaded_bytes && dnw->dnload.tot_size && + 0 == (dnw->dnload.downloaded_bytes & (0x100000 - 1))) + { + /* Some feeback that the download is happening */ + if (dnw->dnload.dnload_error) + printf("X"); + else + printf("."); + if (0 == (dnw->dnload.downloaded_bytes % + (80 * 0x100000))) + printf("\n"); + +// LCD_setfgcolor(0x2E8B57); +// LCD_setprogress(download_bytes / (dnw->dnload.tot_size/100)); + } + } + else + { + /* Ignore empty buffers */ + printf("Warning empty download buffer\n"); + printf("Ignoring\n"); + } + ret = 0; + } + return ret; +} + + +//const char hex_asc[] = "0123456789abcdef"; +extern const char hex_asc[]; +#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] +#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] + +static inline char *pack_hex_byte(char *buf, u8 byte) +{ + *buf++ = hex_asc_hi(byte); + *buf++ = hex_asc_lo(byte); + return buf; +} + + +static int dnw_rx_handler (const unsigned char *buffer, unsigned int buffer_size) +{ + int ret = 1; + struct dnw_response *response=NULL; + const struct dnw_cmd *cmdbuf = (struct dnw_cmd*)buffer; + USBDNW *dnw = &g_usbdnw; + char hex_data[32]; + char *pbuf=NULL; //= *buffer; + /* Generic failed response */ + +// printf("%s, size: %d\n", __func__, buffer_size); + + response = malloc(sizeof(struct dnw_response)); + + response->cmd_status = ERR_UNKNOWN; + response->cmd = cmdbuf->cmd; + + if( cmdbuf->cmd < DNW_CMD_END){ + memcpy( &dnw->cmd, cmdbuf, sizeof(struct dnw_cmd)); + } + + if(dnw->dnload.tot_size){ + response->cmd_status = dnw_receive_data(buffer, buffer_size); + if(DNW_OK != response->cmd_status){ + return -1; // ret = -1; + }else if(dnwIDLE == dnw->state){ + goto send_tx_status; + }else{ + goto err_exit; + } + } + + printf("%s, cmd:%d, size: %d\n", __func__, cmdbuf->cmd, buffer_size); + printf("%s, state: %d\n", __func__, dnw->state); + + { + int i=0; + pbuf = hex_data; // buffer; + while(i < MIN(16, buffer_size)){ + pbuf = pack_hex_byte(pbuf, *(buffer + i)); + i++; + *pbuf++ = ' '; +// pbuf = pack_hex_byte(pbuf, *(buffer + (pbuf -hex_data)); + //snprintf(hex_data, 3, "%02x ", *pbuf); // buf, size, fmt, args...) + }; + } + printf("%s\n", hex_data); + + switch(cmdbuf->cmd){ + case DNW_GETSTATE: + response->data[0] = g_usbdnw.state; + response->cmd_status = DNW_OK; + response->length = 1; + ret = 0; + goto send_tx_status; + break; + case DNW_DEVINFO: + memcpy(response->data, &g_devinfo, sizeof(struct dnw_devinfo)); + response->cmd_status = DNW_OK; + response->length = sizeof(struct dnw_devinfo); + ret = 0; + goto send_tx_status; + break; + case DNW_DNLOAD: + { + struct dnw_subcmd_dnload *subcmd_dnload = NULL; + + subcmd_dnload = buffer + sizeof(struct dnw_cmd); + dnw->state = dnwDOWNLOADSYNC; + dnw->dn_stor.start_address = subcmd_dnload->start_address; + dnw->dn_stor.tot_size = subcmd_dnload->tot_size; + + dnw->dnload.start_address = CFG_DNW_TRANSFER_BUFFER; + dnw->dnload.tot_size = subcmd_dnload->tot_size; + dnw->dnload.packet_size = subcmd_dnload->packet_size; + + response->cmd_status = DNW_OK; + ret = 0; + goto send_tx_status; + } + break; + + case DNW_STORE: + { + struct dnw_subcmd_store *subcmd_store = NULL; + if(buffer_size < (sizeof(struct dnw_cmd) + sizeof(struct dnw_subcmd_store))){ // error + break; + } + subcmd_store = buffer + sizeof(struct dnw_cmd); + dnw->state = dnwDOWNLOADSYNC; + dnw->dnload.start_address = subcmd_store->start_address; + dnw->dnload.tot_size = subcmd_store->tot_size; +// dnw->dnload.packet_size = subcmd_store->packet_size; + + /* Reset the bytes count, now it is safe */ + dnw->dnload.downloaded_bytes = 0; + /* Reset error */ + dnw->dnload.dnload_error = 0; + + response->cmd_status = DNW_OK; + ret = 0; + printf("Storing data start:0x%08x, size:%08d bytes\n", + dnw->dnload.start_address, dnw->dnload.tot_size); + + goto send_tx_status; + } + break; + case DNW_REBOOT: + response->cmd_status = DNW_OK; + dnw_tx_status((char *)response, sizeof(struct dnw_response), 0); + do_reset (NULL, 0, 0, NULL); + break; + default: + response->cmd_status = ERR_UNKNOWN; + ret = -1; + break; + } + +send_tx_status: + printf("%s, send_tx_status, size: %d\n", __func__, sizeof(struct dnw_response)); + dnw_tx_status((char *)response, sizeof(struct dnw_response), 0); + if(response){ + free(response); + response = NULL; + } + +err_exit: + if(response){ + free(response); + response = NULL; + } +} + +#if 1 +void dnw_usb_handle_ep_in_xfer_complete(void) +{ + printf("%s, dnw_response_flag: %d\n", __func__, dnw_response_flag); + + if (dnw_response_flag) { +// exynos_usb_free((u32)g_pBulkInTrb); + dnw_response_flag=0; + } + + return; +} +#endif + +int dnw_usb_handle_ep_out_xfer_complete(void) +{ +#if 0 + u32 usRxCnt; + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + + // Check whether TRB was finished successfully or not + if ((g_pBulkOutTrb0->control.b.hwo != 0)||(g_pBulkOutTrb0->status.b.trb_sts != 0)) + { + Assert(0); + } + + usRxCnt = oUsbDev3.m_uBulkEPMaxPktSize - g_pBulkOutTrb0->status.b.buf_siz; + + if (usRxCnt < oUsbDev3.m_uBulkEPMaxPktSize) + g_ucTempDownBuf[usRxCnt] = 0; + + /* Pass this up to the interface's handler */ + dnw_rx_handler(g_ucTempDownBuf, usRxCnt); + + // . Set TRB for 1st Bulk Out Packet + //----------------------------- + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_NORMAL; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 1; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + exynos_usb_fill_trb(g_pBulkOutTrb0, (u32)g_ucTempDownBuf, oUsbDev3.m_uBulkEPMaxPktSize, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for 1st Bulk Out Packet + //------------------------------------ + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_OUT, BULK_OUT_EP, (u32)g_pBulkOutTrb0, 0, &oUsbDev3.m_uTriOut[BULK_OUT_EP])) + { + return 0; + } + + return 1; +#endif + s3c_usb_download_start(); +} + + +int dnw_poll(void) +{ + /* No activity */ + int ret = DNW_INACTIVE; + + if (!s3c_usb_wait_cable_insert() ) { + s3c_usbctl_init(); + s3c_usbc_activate(); + printf("%s, \n", __func__); + } + + /* A disconnect happended, this signals that the cable + has been disconnected, return immediately */ + if (!DNW_USBD_IS_CONNECTED()) { + return DNW_DISCONNECT; + } else if (DNW_USBD_DETECT_IRQ()) { + if (!dnw_usb_int_hndlr()) + ret = DNW_OK; + else + ret = ERR_USB; + DNW_USBD_CLEAR_IRQ(); + } + + return ret; +} + +void dnw_shutdown(void) +{ + /* when operation is done, usbd must be stopped */ + s3c_usb_stop(); +} + +#endif diff --git a/drivers/usb/gadget/fastboot-ss.c b/drivers/usb/gadget/fastboot-ss.c new file mode 100644 index 000000000..8372b248f --- /dev/null +++ b/drivers/usb/gadget/fastboot-ss.c @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Platform dependant code for Fastboot + * + * Base code of USB connection part is usbd-ss.c + * + * 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. + */ + +#include <fastboot.h> + +#if defined(CONFIG_FASTBOOT) + +/* S5PC110 Default Partition Table */ +fastboot_ptentry ptable_default[] = +{ + { + .name = "bootloader", + .start = 0x0, + .length = 0x100000, + .flags = 0 + }, + { + .name = "recovery", + .start = 0x100000, + .length = 0x500000, + .flags = 0 + }, + { + .name = "kernel", + .start = 0x600000, + .length = 0x500000, + .flags = 0 + }, + { + .name = "ramdisk", + .start = 0xB00000, + .length = 0x300000, + .flags = 0 + }, + { + .name = "system", + .start = 0xE00000, + .length = 0x6E00000, + .flags = FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS + }, + { + .name = "cache", + .start = 0x7C00000, + .length = 0x5000000, + .flags = FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS + }, + { + .name = "userdata", + .start = 0xCC00000, + .length = 0, + .flags = FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS + } +}; +unsigned int ptable_default_size = sizeof(ptable_default); + +#define FBOOT_USBD_IS_CONNECTED() (1) +#define FBOOT_USBD_DETECT_IRQ() EXYNOS_USBD_DETECT_IRQ() +#define FBOOT_USBD_CLEAR_IRQ() EXYNOS_USBD_CLEAR_IRQ() +#define VENDOR_ID 0x18D1 +#define PRODUCT_ID 0x0002 +#define FB_PKT_SZ 64 // full-speed mode +#define OK 0 +#define ERROR -1 + +#define FBOOT_CHIPID_SIZE 12 +#define FBOOT_STRING_DESC3_SIZE ((FBOOT_CHIPID_SIZE * 2) + 2) + +/* In high speed mode packets are 512 + In full speed mode packets are 64 */ +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200)//512 +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040)// 64 +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) + +/* String 0 is the language id */ +#define DEVICE_STRING_MANUFACTURER_INDEX 1 +#define DEVICE_STRING_PRODUCT_INDEX 2 +#define DEVICE_STRING_SERIAL_NUMBER_INDEX 3 +#define DEVICE_STRING_CONFIG_INDEX 4 +#define DEVICE_STRING_INTERFACE_INDEX 5 +#define DEVICE_STRING_MAX_INDEX DEVICE_STRING_MANUFACTURER_INDEX +#define DEVICE_STRING_LANGUAGE_ID 0x0409 /* English (United States) */ + +static char *device_strings[DEVICE_STRING_MANUFACTURER_INDEX+1]; +static struct cmd_fastboot_interface *fastboot_interface = NULL; +/* The packet size is dependend of the speed mode + In high speed mode packets are 512 + In full speed mode packets are 64 + Set to maximum of 512 */ + +/* Note: The start address must be double word aligned */ +char* reply_msg; +unsigned int transfer_size; +u32 fboot_response_flag=0; + +/* codes representing languages */ +const u8 fboot_string_desc1[] = /* Manufacturer */ +{ + (0x16+2), STRING_DESCRIPTOR, + 'G', 0x0, 'o', 0x0, 'o', 0x0, 'g', 0x0, 'l', 0x0, + 'e', 0x0, ',', 0x0, ' ', 0x0, 'I', 0x0, 'n', 0x0, + 'c', 0x0 +}; + +const u8 fboot_string_desc2[] = /* Product */ +{ + (0x16+2), STRING_DESCRIPTOR, + 'A', 0x0, 'n', 0x0, 'd', 0x0, 'r', 0x0, 'o', 0x0, + 'i', 0x0, 'd', 0x0, ' ', 0x0, '1', 0x0, '.', 0x0, + '0', 0x0 +}; + +u8 fboot_string_desc3[FBOOT_STRING_DESC3_SIZE] = /* Test Serial ID */ +{ + FBOOT_STRING_DESC3_SIZE, STRING_DESCRIPTOR, + 'A', 0x0, 'n', 0x0, 'd', 0x0, 'r', 0x0, 'o', 0x0, + 'i', 0x0, 'd', 0x0, ' ', 0x0, '1', 0x0, '.', 0x0, + '0', 0x0, ' ', 0x0 + +}; + +/* setting the device qualifier descriptor and a string descriptor */ +const u8 fboot_qualifier_desc[] = +{ + 0x0a, /* 0 desc size */ + 0x06, /* 1 desc type (DEVICE_QUALIFIER)*/ + 0x00, /* 2 USB release */ + 0x02, /* 3 => 2.00*/ + 0xFF, /* 4 class */ + 0x42, /* 5 subclass */ + 0x03, /* 6 protocol */ + 64, /* 7 max pack size */ + 0x01, /* 8 number of other-speed configuration */ + 0x00, /* 9 reserved */ +}; + +volatile usbdev3_trb_ptr_t g_pBulkInTrb; + +void fboot_usbctl_init(void) +{ + exynoy_usb_phy_on(); +} + +int fboot_usb_int_bulkin(const char *buffer, unsigned int buffer_size) +{ + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + usbdev3_trb_ptr_t pBulkInTrb; + u32 usCapTrbBufSiz, uLastBufSize; + u32 i; + + // Set TRB for multiple Bulk IN Packet + usCapTrbBufSiz = TRB_BUF_SIZ_LIMIT/oUsbDev3.m_uBulkEPMaxPktSize*oUsbDev3.m_uBulkEPMaxPktSize; + g_uCntOfBulkInTrb = buffer_size/usCapTrbBufSiz; + + if ((buffer_size%usCapTrbBufSiz) != 0) + g_uCntOfBulkInTrb++; + + g_pBulkInTrb = (usbdev3_trb_ptr_t)exynos_usb_malloc(g_uCntOfBulkInTrb*sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + + if (g_pBulkInTrb == NULL) + Assert(0); + + pBulkInTrb = g_pBulkInTrb; + // Fill the Trbs + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 0; + usbdev3_trb_ctrl.b.chn = 1; + usbdev3_trb_ctrl.b.csp = 0; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_NORMAL; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 0; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + for(i=0;i<(g_uCntOfBulkInTrb-1);i++, pBulkInTrb++) + exynos_usb_fill_trb(pBulkInTrb, (u32)(buffer+usCapTrbBufSiz*i), usCapTrbBufSiz, usbdev3_trb_ctrl.data, 1); + + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.chn = 0; + usbdev3_trb_ctrl.b.ioc = 1; + uLastBufSize = buffer_size-usCapTrbBufSiz*i; + exynos_usb_fill_trb(pBulkInTrb, (u32)(buffer+usCapTrbBufSiz*i), uLastBufSize, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for multiple Bulk IN Packet + //------------------------------------ + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_IN, BULK_IN_EP, (u32)g_pBulkInTrb, 0, &oUsbDev3.m_uTriIn[BULK_IN_EP])) + { + return 0; + } + + return 1; +} + +void fboot_usb_handle_ep_in_xfer_complete(void) +{ + if (fboot_response_flag) { + exynos_usb_free((u32)g_pBulkInTrb); + fboot_response_flag=0; + } + + return; +} + +int fboot_usb_handle_ep_out_xfer_complete(void) +{ + u32 usRxCnt; + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + + // Check whether TRB was finished successfully or not + if ((g_pBulkOutTrb0->control.b.hwo != 0)||(g_pBulkOutTrb0->status.b.trb_sts != 0)) + { + Assert(0); + } + + usRxCnt = oUsbDev3.m_uBulkEPMaxPktSize - g_pBulkOutTrb0->status.b.buf_siz; + + if (usRxCnt < oUsbDev3.m_uBulkEPMaxPktSize) + g_ucTempDownBuf[usRxCnt] = 0; + + /* Pass this up to the interface's handler */ + if (fastboot_interface && fastboot_interface->rx_handler) { + /* Call rx_handler at common/cmd_fastboot.c */ + if (!fastboot_interface->rx_handler(g_ucTempDownBuf, usRxCnt)) + ;//OK + } + + // . Set TRB for 1st Bulk Out Packet + //----------------------------- + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_NORMAL; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 1; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + exynos_usb_fill_trb(g_pBulkOutTrb0, (u32)g_ucTempDownBuf, oUsbDev3.m_uBulkEPMaxPktSize, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for 1st Bulk Out Packet + //------------------------------------ + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_OUT, BULK_OUT_EP, (u32)g_pBulkOutTrb0, 0, &oUsbDev3.m_uTriOut[BULK_OUT_EP])) + { + return 0; + } + + return 1; +} + +void fboot_usb_set_descriptors_tlb(void) +{ + /* Standard device descriptor */ + oUsbDev3.m_oDesc.oDescDevice.bLength=DEVICE_DESC_SIZE; /*0x12*/ + oUsbDev3.m_oDesc.oDescDevice.bDescriptorType=DEVICE_DESCRIPTOR; + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) { + oUsbDev3.m_oDesc.oDescDevice.bMaxPacketSize0=SUPER_SPEED_CONTROL_PKT_EXP_SZ; + } else { + oUsbDev3.m_oDesc.oDescDevice.bMaxPacketSize0=oUsbDev3.m_uControlEPMaxPktSize; + } + oUsbDev3.m_oDesc.oDescDevice.bDeviceClass=0x0; /* 0x0*/ + oUsbDev3.m_oDesc.oDescDevice.bDeviceSubClass=0x0; + oUsbDev3.m_oDesc.oDescDevice.bDeviceProtocol=0x0; + oUsbDev3.m_oDesc.oDescDevice.idVendorL=VENDOR_ID&0xff;//0xB4; /**/ + oUsbDev3.m_oDesc.oDescDevice.idVendorH=VENDOR_ID>>8;//0x0B; /**/ + oUsbDev3.m_oDesc.oDescDevice.idProductL=PRODUCT_ID&0xff;//0xFF; /**/ + oUsbDev3.m_oDesc.oDescDevice.idProductH=PRODUCT_ID>>8;//0x0F; /**/ + oUsbDev3.m_oDesc.oDescDevice.bcdDeviceL=0x00; + oUsbDev3.m_oDesc.oDescDevice.bcdDeviceH=0x01; + oUsbDev3.m_oDesc.oDescDevice.iManufacturer=DEVICE_STRING_MANUFACTURER_INDEX; /* index of string descriptor */ + oUsbDev3.m_oDesc.oDescDevice.iProduct=DEVICE_STRING_PRODUCT_INDEX; /* index of string descriptor */ + oUsbDev3.m_oDesc.oDescDevice.iSerialNumber=DEVICE_STRING_SERIAL_NUMBER_INDEX; + oUsbDev3.m_oDesc.oDescDevice.bNumConfigurations=0x1; + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) { + oUsbDev3.m_oDesc.oDescDevice.bcdUSBL=0x00; + oUsbDev3.m_oDesc.oDescDevice.bcdUSBH=0x03; // Ver 3.0 + } else if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_HIGH) { + oUsbDev3.m_oDesc.oDescDevice.bcdUSBL=0x00; + oUsbDev3.m_oDesc.oDescDevice.bcdUSBH=0x02; // Ver 2.0 + } else if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_FULL) { + oUsbDev3.m_oDesc.oDescDevice.bcdUSBL=0x10; + oUsbDev3.m_oDesc.oDescDevice.bcdUSBH=0x01; // Ver 2.0 + } + + /* Standard configuration descriptor */ + oUsbDev3.m_oDesc.oDescConfig.bLength=CONFIG_DESC_SIZE; /* 0x9 bytes */ + oUsbDev3.m_oDesc.oDescConfig.bDescriptorType=CONFIGURATION_DESCRIPTOR; + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) + oUsbDev3.m_oDesc.oDescConfig.wTotalLengthL=CONFIG_SS_DESC_TOTAL_SIZE; + else + oUsbDev3.m_oDesc.oDescConfig.wTotalLengthL=CONFIG_DESC_TOTAL_SIZE; + oUsbDev3.m_oDesc.oDescConfig.wTotalLengthH=0; + oUsbDev3.m_oDesc.oDescConfig.bNumInterfaces=1; + /* dbg descConf.bConfigurationValue=2; // why 2? There's no reason.*/ + oUsbDev3.m_oDesc.oDescConfig.bConfigurationValue=1; + oUsbDev3.m_oDesc.oDescConfig.iConfiguration=0; + oUsbDev3.m_oDesc.oDescConfig.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED; /* bus powered only.*/ + oUsbDev3.m_oDesc.oDescConfig.maxPower=25; /* draws 50mA current from the USB bus.*/ + + /* Standard interface descriptor */ + oUsbDev3.m_oDesc.oDescInterface.bLength=INTERFACE_DESC_SIZE; /* 9*/ + oUsbDev3.m_oDesc.oDescInterface.bDescriptorType=INTERFACE_DESCRIPTOR; + oUsbDev3.m_oDesc.oDescInterface.bInterfaceNumber=0x0; + oUsbDev3.m_oDesc.oDescInterface.bAlternateSetting=0x0; /* ?*/ + oUsbDev3.m_oDesc.oDescInterface.bNumEndpoints = 2; /* # of endpoints except EP0*/ + oUsbDev3.m_oDesc.oDescInterface.bInterfaceClass= FASTBOOT_INTERFACE_CLASS;// 0xff; /* 0x0 ?*/ + oUsbDev3.m_oDesc.oDescInterface.bInterfaceSubClass= FASTBOOT_INTERFACE_SUB_CLASS;// 0x42; + oUsbDev3.m_oDesc.oDescInterface.bInterfaceProtocol= FASTBOOT_INTERFACE_PROTOCOL;//0x03; + oUsbDev3.m_oDesc.oDescInterface.iInterface=0x0; + + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) { + /* Standard endpoint0 descriptor */ + oUsbDev3.m_oSSDesc.oDescEp0.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescEp0.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oSSDesc.oDescEp0.bEndpointAddress=BULK_IN_EP|EP_ADDR_IN; + oUsbDev3.m_oSSDesc.oDescEp0.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oSSDesc.oDescEp0.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oSSDesc.oDescEp0.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oSSDesc.oDescEp0.bInterval=0x0; /* not used */ + + oUsbDev3.m_oSSDesc.oDescEp0Comp.bLength=6; + oUsbDev3.m_oSSDesc.oDescEp0Comp.bDescriptorType=0x30; + oUsbDev3.m_oSSDesc.oDescEp0Comp.bMaxBurst=15; + oUsbDev3.m_oSSDesc.oDescEp0Comp.bmAttributes=0; + oUsbDev3.m_oSSDesc.oDescEp0Comp.wBytesPerInterval=0; + + /* Standard endpoint1 descriptor */ + oUsbDev3.m_oSSDesc.oDescEp1.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescEp1.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oSSDesc.oDescEp1.bEndpointAddress=BULK_OUT_EP|EP_ADDR_OUT; + oUsbDev3.m_oSSDesc.oDescEp1.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oSSDesc.oDescEp1.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oSSDesc.oDescEp1.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oSSDesc.oDescEp1.bInterval=0x0; /* not used */ + + oUsbDev3.m_oSSDesc.oDescEp1Comp.bLength=6; + oUsbDev3.m_oSSDesc.oDescEp1Comp.bDescriptorType=0x30; + oUsbDev3.m_oSSDesc.oDescEp1Comp.bMaxBurst=15; + oUsbDev3.m_oSSDesc.oDescEp1Comp.bmAttributes=0; + oUsbDev3.m_oSSDesc.oDescEp1Comp.wBytesPerInterval=0; + + // Standard BOS(Binary Object Store) descriptor + oUsbDev3.m_oSSDesc.oDescBos.bLength = BOS_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescBos.bDescriptorType = 0x0F; + oUsbDev3.m_oSSDesc.oDescBos.wTotalLength = BOS_DESC_TOTAL_SIZE; + oUsbDev3.m_oSSDesc.oDescBos.bNumDeviceCaps = 3; + + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bLength = USB20_EXT_CAP_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bDescriptorType = 0x10; + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bDevCapabilityType = USB_CAP_20_EXT; + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bmAttributes = 0x2; + + oUsbDev3.m_oSSDesc.oDescSuperCap.bLength = SUPER_CAP_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescSuperCap.bDescriptorType = 0x10; + oUsbDev3.m_oSSDesc.oDescSuperCap.bDevCapabilityType = USB_CAP_SS; + oUsbDev3.m_oSSDesc.oDescSuperCap.bmAttributes = 0x0; + oUsbDev3.m_oSSDesc.oDescSuperCap.wSpeedsSupported = 0xC; + oUsbDev3.m_oSSDesc.oDescSuperCap.bFunctionalitySupport = 2; + /* TODO: set correct value */ + oUsbDev3.m_oSSDesc.oDescSuperCap.bU1DevExitLat = 0x4; + oUsbDev3.m_oSSDesc.oDescSuperCap.wU2DevExitLat = 0x4; + + oUsbDev3.m_oSSDesc.oDescContainCap.bLength = CONTAIN_CAP_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescContainCap.bDescriptorType = 0x10; + oUsbDev3.m_oSSDesc.oDescContainCap.bDevCapabilityType = USB_CAP_CID; + oUsbDev3.m_oSSDesc.oDescContainCap.bReserved = 0x0; + memset(oUsbDev3.m_oSSDesc.oDescContainCap.containerID, 0x0, 16); + } + else { + /* Standard endpoint0 descriptor */ + oUsbDev3.m_oDesc.oDescEp0.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oDesc.oDescEp0.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oDesc.oDescEp0.bEndpointAddress=BULK_IN_EP|EP_ADDR_IN; + oUsbDev3.m_oDesc.oDescEp0.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oDesc.oDescEp0.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oDesc.oDescEp0.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oDesc.oDescEp0.bInterval=0x0; /* not used */ + + /* Standard endpoint1 descriptor */ + oUsbDev3.m_oDesc.oDescEp1.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oDesc.oDescEp1.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oDesc.oDescEp1.bEndpointAddress=BULK_OUT_EP|EP_ADDR_OUT; + oUsbDev3.m_oDesc.oDescEp1.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oDesc.oDescEp1.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oDesc.oDescEp1.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oDesc.oDescEp1.bInterval=0x0; /* not used */ + } +} + +int fboot_usb_int_hndlr(void) +{ + return exynos_udc_int_hndlr(); +} + +//----------------------------------------------------------------------------------- +// FASTBOOT codes +//----------------------------------------------------------------------------------- + +static void simple_hextostr(u32 hex, u8 *str) +{ + u8 i; + + for (i = 0; i < 8; i++) { + if ((hex & 0xF) > 9) + *str++ = 'a' + (hex & 0xF) - 10; + else + *str++ = '0' + (hex & 0xF); + + hex >>= 4; + } +} + +static void set_serial_number(void) +{ +#if defined(CFG_FASTBOOT_MULTI_ACESS) + u8 tmp_serial_id[16]; /* string for chip id */ + u8 i; + + simple_hextostr(s5p_chip_id[1], tmp_serial_id+8); + simple_hextostr(s5p_chip_id[0], tmp_serial_id); + + for (i = 0; i < FBOOT_CHIPID_SIZE; i++) + fboot_string_desc3[FBOOT_STRING_DESC3_SIZE-(i*2)-2] = tmp_serial_id[i]; +#else + char *dieid = getenv("dieid#"); + if (dieid == NULL) { + device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX] = "SLSI0123"; + } else { + static char serial_number[32]; + int len; + + memset(&serial_number[0], 0, 32); + len = strlen(dieid); + if (len > 30) + len = 30; + + strncpy(&serial_number[0], dieid, len); + + device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX] = + &serial_number[0]; + } +#endif +} + +/* Initizes the board specific fastboot + Returns 0 on success + Returns 1 on failure */ +int fastboot_init(struct cmd_fastboot_interface *interface) +{ + int ret = 1; + + // usbd init + fboot_usbctl_init(); + + device_strings[DEVICE_STRING_MANUFACTURER_INDEX] = "Samsung S.LSI"; + device_strings[DEVICE_STRING_PRODUCT_INDEX] = "smdk"; + set_serial_number(); + /* These are just made up */ + device_strings[DEVICE_STRING_CONFIG_INDEX] = "Android Fastboot"; + device_strings[DEVICE_STRING_INTERFACE_INDEX] = "Android Fastboot"; + + /* The interface structure */ + fastboot_interface = interface; + fastboot_interface->product_name = device_strings[DEVICE_STRING_PRODUCT_INDEX]; + fastboot_interface->serial_no = device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX]; + fastboot_interface->nand_block_size = CFG_FASTBOOT_PAGESIZE * 64; + fastboot_interface->transfer_buffer = (unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER; + fastboot_interface->transfer_buffer_size = CFG_FASTBOOT_TRANSFER_BUFFER_SIZE; + + memset((unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER, 0x0, FASTBOOT_REBOOT_MAGIC_SIZE); + + reply_msg = (char *)exynos_usb_malloc(512, USBDEV3_MDWIDTH/8); + + ret = 0; // This is a fake return value, because we do not initialize USB yet! + + return ret; +} + +/* Cleans up the board specific fastboot */ +void fastboot_shutdown(void) +{ + /* when operation is done, usbd must be stopped */ + exynos_usb_stop(); + is_fastboot = 0; +} + +int fastboot_fifo_size(void) +{ + return (oUsbDev3.m_eSpeed == USBDEV3_SPEED_HIGH) ? RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 : RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1; +} + +/* + * Handles board specific usb protocol exchanges + * Returns 0 on success + * Returns 1 on disconnects, break out of loop + * Returns 2 if no USB activity detected + * Returns -1 on failure, unhandled usb requests and other error conditions +*/ +int fastboot_poll(void) +{ + //printf("DEBUG: %s is called.\n", __FUNCTION__); + /* No activity */ + int ret = FASTBOOT_INACTIVE; + + if (!exynos_usb_wait_cable_insert() && !is_fastboot) { + exynos_usbctl_init(); + exynos_usbc_activate(); + is_fastboot = 1; + } + + /* A disconnect happended, this signals that the cable + has been disconnected, return immediately */ + if (!FBOOT_USBD_IS_CONNECTED()) { + return FASTBOOT_DISCONNECT; + } else if (FBOOT_USBD_DETECT_IRQ()) { + if (!fboot_usb_int_hndlr()) + ret = FASTBOOT_OK; + else + ret = FASTBOOT_ERROR; + FBOOT_USBD_CLEAR_IRQ(); + } + + return ret; +} + + +/* Send a status reply to the client app + buffer does not have to be null terminated. + buffer_size must be not be larger than what is returned by + fastboot_fifo_size + Returns 0 on success + Returns 1 on failure */ +int fastboot_tx_status(const char *buffer, unsigned int buffer_size, const u32 need_sync_flag) +{ + /* fastboot client only reads back at most 64 */ + transfer_size = MIN(64, buffer_size); + +//------------------------------ kdj + //printf(" Response - \"%s\" (%d bytes)\n", buffer, buffer_size); + if (fboot_response_flag) + printf(" Response tx Warnning\n"); + + memcpy(reply_msg, buffer, transfer_size); + fboot_response_flag=1; + fboot_usb_int_bulkin(reply_msg, transfer_size); + + if (need_sync_flag) + { + while(fboot_response_flag) + fastboot_poll(); + } + return 1; +} + +/* Returns 0 on success + Returns 1 on failure */ +int fastboot_tx_mem(const char *buffer, unsigned int buffer_size) +{ + if (!fboot_usb_int_bulkin(buffer, buffer_size)) + return 0; + return 1; +} + +/* A board specific variable handler. + The size of the buffers is governed by the fastboot spec. + rx_buffer is at most 57 bytes + tx_buffer is at most 60 bytes + Returns 0 on success + Returns 1 on failure */ +int fastboot_getvar(const char *rx_buffer, char *tx_buffer) +{ + /* Place board specific variables here */ + return 1; +} + +#endif /* CONFIG_FASTBOOT */ diff --git a/drivers/usb/gadget/fastboot.c b/drivers/usb/gadget/fastboot.c new file mode 100644 index 000000000..27471e0c8 --- /dev/null +++ b/drivers/usb/gadget/fastboot.c @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Platform dependant code for Fastboot + * + * Base code of USB connection part is usbd-otg-hs.c + * + * 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. + */ + +#include <fastboot.h> + +#if defined(CONFIG_FASTBOOT) + +/* S5PC110 Default Partition Table */ +fastboot_ptentry ptable_default[] = +{ + { + .name = "bootloader", + .start = 0x0, + .length = 0x100000, + .flags = 0 + }, + { + .name = "recovery", + .start = 0x100000, + .length = 0x500000, + .flags = 0 + }, + { + .name = "kernel", + .start = 0x600000, + .length = 0x500000, + .flags = 0 + }, + { + .name = "ramdisk", + .start = 0xB00000, + .length = 0x300000, + .flags = 0 + }, + { + .name = "system", + .start = 0xE00000, + .length = 0x6E00000, + .flags = FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS + }, + { + .name = "cache", + .start = 0x7C00000, + .length = 0x5000000, + .flags = FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS + }, + { + .name = "userdata", + .start = 0xCC00000, + .length = 0, + .flags = FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS + } +}; +unsigned int ptable_default_size = sizeof(ptable_default); + +#define FBOOT_USBD_IS_CONNECTED() (readl(S5P_OTG_GOTGCTL)&(B_SESSION_VALID|A_SESSION_VALID)) +#define FBOOT_USBD_DETECT_IRQ_CPUMODE() (readl(S5P_OTG_GINTSTS) & \ + (GINTSTS_WkUpInt|GINTSTS_OEPInt|GINTSTS_IEPInt| \ + GINTSTS_EnumDone|GINTSTS_USBRst|GINTSTS_USBSusp|GINTSTS_RXFLvl)) +#define FBOOT_USBD_DETECT_IRQ_DMAMODE() (readl(S5P_OTG_GINTSTS) & \ + (GINTSTS_WkUpInt|GINTSTS_OEPInt|GINTSTS_IEPInt| \ + GINTSTS_EnumDone|GINTSTS_USBRst|GINTSTS_USBSusp)) +#define FBOOT_USBD_CLEAR_IRQ() do { \ + writel(BIT_ALLMSK, (S5P_OTG_GINTSTS)); \ + } while (0) + +#define VENDOR_ID 0x18D1 +#define PRODUCT_ID 0x0002 +#define FB_PKT_SZ 64 // full-speed mode +#define OK 0 +#define ERROR -1 + +/* In high speed mode packets are 512 + In full speed mode packets are 64 */ +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200)//512 +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040)// 64 +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define TX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) + +/* String 0 is the language id */ +#define DEVICE_STRING_MANUFACTURER_INDEX 1 +#define DEVICE_STRING_PRODUCT_INDEX 2 +#define DEVICE_STRING_SERIAL_NUMBER_INDEX 3 +#define DEVICE_STRING_CONFIG_INDEX 4 +#define DEVICE_STRING_INTERFACE_INDEX 5 +#define DEVICE_STRING_MAX_INDEX DEVICE_STRING_INTERFACE_INDEX +#define DEVICE_STRING_LANGUAGE_ID 0x0409 /* English (United States) */ + +static char *device_strings[DEVICE_STRING_MAX_INDEX+1]; +static struct cmd_fastboot_interface *fastboot_interface = NULL; +/* The packet size is dependend of the speed mode + In high speed mode packets are 512 + In full speed mode packets are 64 + Set to maximum of 512 */ + +/* Note: The start address must be double word aligned */ +static u8 fastboot_bulk_fifo[0x0200+1]; //__attribute__ ((aligned(0x4))); +const char* reply_msg; +unsigned int transfer_size; +u32 fboot_response_flag=0; +u8 is_fboot_ramdump; + +struct fboot_ramdump +{ + u8 *start_buffer; + u32 cur_pos; + u32 size; +}; + +struct fboot_ramdump fboot_ramdump_info; + +/* codes representing languages */ +const u8 fboot_string_desc1[] = /* Manufacturer */ +{ + (0x16+2), STRING_DESCRIPTOR, + 'G', 0x0, 'o', 0x0, 'o', 0x0, 'g', 0x0, 'l', 0x0, + 'e', 0x0, ',', 0x0, ' ', 0x0, 'I', 0x0, 'n', 0x0, + 'c', 0x0 +}; + +const u8 fboot_string_desc2[] = /* Product */ +{ + (0x16+2), STRING_DESCRIPTOR, + 'A', 0x0, 'n', 0x0, 'd', 0x0, 'r', 0x0, 'o', 0x0, + 'i', 0x0, 'd', 0x0, ' ', 0x0, '1', 0x0, '.', 0x0, + '0', 0x0 +}; + +const u8 fboot_string_desc3[] = /* Test Serial ID */ +{ + (0x16+2), STRING_DESCRIPTOR, + 'S', 0x0, 'M', 0x0, 'D', 0x0, 'K', 0x0, +#if defined(CONFIG_EXYNOS4X12) || defined(CONFIG_ARCH_EXYNOS) + 'E', 0x0,'X', 0x0, 'Y', 0x0, 'N', 0x0, 'O', 0x0, 'S', 0x0, '-', 0x0, '0', 0x0, '1', 0x0 +#elif defined(CONFIG_S5PC210) + 'C', 0x0,'2', 0x0, '1', 0x0, '0', 0x0, '-', 0x0, '0', 0x0, '1', 0x0 +#elif defined(CONFIG_S5PV310) + 'V', 0x0,'3', 0x0, '1', 0x0, '0', 0x0, '-', 0x0, '0', 0x0, '1', 0x0 +#elif defined(CONFIG_S5PC110) + 'C', 0x0,'1', 0x0, '1', 0x0, '0', 0x0, '-', 0x0, '0', 0x0, '1', 0x0 +#elif defined(CONFIG_S5P6450) + '6', 0x0,'4', 0x0, '5', 0x0, '0', 0x0, '-', 0x0, '0', 0x0, '1', 0x0 +#else +#error "* CFG_ERROR : you have to select proper CPU for Android Fastboot" +#endif +}; + +/* setting the device qualifier descriptor and a string descriptor */ +const u8 fboot_qualifier_desc[] = +{ + 0x0a, /* 0 desc size */ + 0x06, /* 1 desc type (DEVICE_QUALIFIER)*/ + 0x00, /* 2 USB release */ + 0x02, /* 3 => 2.00*/ + 0xFF, /* 4 class */ + 0x42, /* 5 subclass */ + 0x03, /* 6 protocol */ + 64, /* 7 max pack size */ + 0x01, /* 8 number of other-speed configuration */ + 0x00, /* 9 reserved */ +}; + +int fboot_usbctl_init(void) +{ + s3c_usbctl_init(); + is_fastboot = 1; + return 0; +} + +void fboot_usb_int_bulkin(void) +{ + u32 tmp; + + DBG_BULK0("~~~~~~~~~~~~~~~~ bulkin Function ~~~~~~~~~~~~\n"); + + if ((fboot_response_flag==1)&&(reply_msg)) { + +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1, strlen(reply_msg)); + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkin_max_pktsize<<0, S5P_OTG_DIEPCTL_IN); + + s3c_usb_write_in_fifo((u8 *)reply_msg,strlen(reply_msg)); +#else + s3c_usb_bulk_inep_setdma((u8 *)reply_msg, strlen(reply_msg)); +#endif + + fboot_response_flag=0; + } + else if (fboot_response_flag==0) + { + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + //writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkin_max_pktsize<<0, S5P_OTG_DIEPCTL_IN); + //writel((DEPCTL_SNAK|DEPCTL_BULK_TYPE), S5P_OTG_DIEPCTL_IN); + // NAK should be cleared. why?? + tmp = readl(S5P_OTG_DOEPCTL0+0x20*BULK_OUT_EP); + tmp |= (DEPCTL_CNAK); + writel(tmp, S5P_OTG_DOEPCTL0+0x20*BULK_OUT_EP); + } + //DBG_BULK1("fboot_response_flag=%d S5P_OTG_DIEPCTL_IN=0x%x\n",fboot_response_flag,DIEPCTL_IN); + + return; +} + +#ifdef CONFIG_USB_CPUMODE +void fboot_usb_int_bulkout(u32 fifo_cnt_byte) +#else +void fboot_usb_int_bulkout( void ) +#endif +{ + DBG_BULK0("@@\n Bulk Out Function : otg.dn_filesize=0x%x\n", otg.dn_filesize); + +#ifdef CONFIG_USB_CPUMODE + s3c_usb_read_out_fifo((u8 *)fastboot_bulk_fifo, fifo_cnt_byte); + if (fifo_cnt_byte<64) { + fastboot_bulk_fifo[fifo_cnt_byte] = 0x00; // append null + printf("Received %d bytes: %s\n",fifo_cnt_byte, fastboot_bulk_fifo); + } + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkout_max_pktsize<<0, + S5P_OTG_DOEPCTL_OUT); +#else + u32 xfer_size, cnt_byte; + xfer_size = readl(S5P_OTG_DOEPTSIZ_OUT) & 0x7FFF; + cnt_byte = HS_BULK_PKT_SIZE - xfer_size; + if(cnt_byte < HS_BULK_PKT_SIZE) + tmp_buf[cnt_byte] = 0x00; +#endif + + /* Pass this up to the interface's handler */ + if (fastboot_interface && fastboot_interface->rx_handler) { + /* Call rx_handler at common/cmd_fastboot.c */ +#ifdef CONFIG_USB_CPUMODE + if (!fastboot_interface->rx_handler(&fastboot_bulk_fifo[0], fifo_cnt_byte));//OK + } +#else + if (!fastboot_interface->rx_handler(&tmp_buf, cnt_byte)); + } + s3c_usb_bulk_outep_setdma(tmp_buf, HS_BULK_PKT_SIZE); +#endif +} + +void fboot_usb_set_descriptors(void) +{ + /* Standard device descriptor */ + otg.desc.dev.bLength=DEVICE_DESC_SIZE; /*0x12*/ + otg.desc.dev.bDescriptorType=DEVICE_DESCRIPTOR; + otg.desc.dev.bMaxPacketSize0=otg.ctrl_max_pktsize; + otg.desc.dev.bDeviceClass=0x0; /* 0x0*/ + otg.desc.dev.bDeviceSubClass=0x0; + otg.desc.dev.bDeviceProtocol=0x0; + otg.desc.dev.idVendorL=VENDOR_ID&0xff;//0xB4; /**/ + otg.desc.dev.idVendorH=VENDOR_ID>>8;//0x0B; /**/ + otg.desc.dev.idProductL=PRODUCT_ID&0xff;//0xFF; /**/ + otg.desc.dev.idProductH=PRODUCT_ID>>8;//0x0F; /**/ + otg.desc.dev.bcdDeviceL=0x00; + otg.desc.dev.bcdDeviceH=0x01; + otg.desc.dev.iManufacturer=DEVICE_STRING_MANUFACTURER_INDEX; /* index of string descriptor */ + otg.desc.dev.iProduct=DEVICE_STRING_PRODUCT_INDEX; /* index of string descriptor */ + otg.desc.dev.iSerialNumber=DEVICE_STRING_SERIAL_NUMBER_INDEX; + otg.desc.dev.bNumConfigurations=0x1; + if (otg.speed == USB_FULL) { + otg.desc.dev.bcdUSBL=0x10; + otg.desc.dev.bcdUSBH=0x01; /* Ver 1.10*/ + } + else { + otg.desc.dev.bcdUSBL=0x00; + //otg.desc.dev.bcdUSBL=0x10; + otg.desc.dev.bcdUSBH=0x02; /* Ver 2.0*/ + } + + /* Standard configuration descriptor */ + otg.desc.config.bLength=CONFIG_DESC_SIZE; /* 0x9 bytes */ + otg.desc.config.bDescriptorType=CONFIGURATION_DESCRIPTOR; + otg.desc.config.wTotalLengthL=CONFIG_DESC_TOTAL_SIZE; + otg.desc.config.wTotalLengthH=0; + otg.desc.config.bNumInterfaces=1; + /* dbg descConf.bConfigurationValue=2; // why 2? There's no reason.*/ + otg.desc.config.bConfigurationValue=1; + otg.desc.config.iConfiguration=0; + otg.desc.config.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED; /* bus powered only.*/ + otg.desc.config.maxPower=25; /* draws 50mA current from the USB bus.*/ + + /* Standard interface descriptor */ + otg.desc.intf.bLength=INTERFACE_DESC_SIZE; /* 9*/ + otg.desc.intf.bDescriptorType=INTERFACE_DESCRIPTOR; + otg.desc.intf.bInterfaceNumber=0x0; + otg.desc.intf.bAlternateSetting=0x0; /* ?*/ + otg.desc.intf.bNumEndpoints = 2; /* # of endpoints except EP0*/ + otg.desc.intf.bInterfaceClass= FASTBOOT_INTERFACE_CLASS;// 0xff; /* 0x0 ?*/ + otg.desc.intf.bInterfaceSubClass= FASTBOOT_INTERFACE_SUB_CLASS;// 0x42; + otg.desc.intf.bInterfaceProtocol= FASTBOOT_INTERFACE_PROTOCOL;//0x03; + otg.desc.intf.iInterface=0x0; + + /* Standard endpoint0 descriptor */ + otg.desc.ep1.bLength=ENDPOINT_DESC_SIZE; + otg.desc.ep1.bDescriptorType=ENDPOINT_DESCRIPTOR; + otg.desc.ep1.bEndpointAddress=BULK_IN_EP|EP_ADDR_IN; + otg.desc.ep1.bmAttributes=EP_ATTR_BULK; + otg.desc.ep1.wMaxPacketSizeL=(u8)otg.bulkin_max_pktsize; /* 64*/ + otg.desc.ep1.wMaxPacketSizeH=(u8)(otg.bulkin_max_pktsize>>8); + otg.desc.ep1.bInterval=0x0; /* not used */ + + /* Standard endpoint1 descriptor */ + otg.desc.ep2.bLength=ENDPOINT_DESC_SIZE; + otg.desc.ep2.bDescriptorType=ENDPOINT_DESCRIPTOR; + otg.desc.ep2.bEndpointAddress=BULK_OUT_EP|EP_ADDR_OUT; + otg.desc.ep2.bmAttributes=EP_ATTR_BULK; + otg.desc.ep2.wMaxPacketSizeL=(u8)otg.bulkout_max_pktsize; /* 64*/ + otg.desc.ep2.wMaxPacketSizeH=(u8)(otg.bulkout_max_pktsize>>8); + otg.desc.ep2.bInterval=0x0; /* not used */ +} + +int fboot_usb_int_hndlr(void) +{ + return s3c_udc_int_hndlr(); +} + +//----------------------------------------------------------------------------------- +// FASTBOOT codes +//----------------------------------------------------------------------------------- + +static void set_serial_number(void) +{ + char *dieid = getenv("dieid#"); + if (dieid == NULL) { + device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX] = "SLSI0123"; + } else { + static char serial_number[32]; + int len; + + memset(&serial_number[0], 0, 32); + len = strlen(dieid); + if (len > 30) + len = 30; + + strncpy(&serial_number[0], dieid, len); + + device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX] = + &serial_number[0]; + } +} + +/* Initizes the board specific fastboot + Returns 0 on success + Returns 1 on failure */ +int fastboot_init(struct cmd_fastboot_interface *interface) +{ + int ret = 1; + + // usbd init + fboot_usbctl_init(); + + device_strings[DEVICE_STRING_MANUFACTURER_INDEX] = "Samsung S.LSI"; + device_strings[DEVICE_STRING_PRODUCT_INDEX] = "smdk"; + set_serial_number(); + /* These are just made up */ + device_strings[DEVICE_STRING_CONFIG_INDEX] = "Android Fastboot"; + device_strings[DEVICE_STRING_INTERFACE_INDEX] = "Android Fastboot"; + + /* The interface structure */ + fastboot_interface = interface; + fastboot_interface->product_name = device_strings[DEVICE_STRING_PRODUCT_INDEX]; + fastboot_interface->serial_no = device_strings[DEVICE_STRING_SERIAL_NUMBER_INDEX]; + fastboot_interface->nand_block_size = CFG_FASTBOOT_PAGESIZE * 64; + fastboot_interface->transfer_buffer = (unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER; + fastboot_interface->transfer_buffer_size = CFG_FASTBOOT_TRANSFER_BUFFER_SIZE; + + memset((unsigned char *) CFG_FASTBOOT_TRANSFER_BUFFER, 0x0, FASTBOOT_REBOOT_MAGIC_SIZE); + + /* Fastboot ramdump initialize */ + fboot_ramdump_info.start_buffer = NULL; + fboot_ramdump_info.cur_pos = 0; + fboot_ramdump_info.size = 0; + is_fboot_ramdump = 0; + + ret = 0; // This is a fake return value, because we do not initialize USB yet! + + return ret; +} + +/* Cleans up the board specific fastboot */ +void fastboot_shutdown(void) +{ + /* when operation is done, usbd must be stopped */ + s3c_usb_stop(); + is_fastboot = 0; + g_dnw_version = -1; +} +int fastboot_fifo_size(void) +{ + return (otg.speed== USB_HIGH) ? RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 : RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1; +} + +/* + * Handles board specific usb protocol exchanges + * Returns 0 on success + * Returns 1 on disconnects, break out of loop + * Returns 2 if no USB activity detected + * Returns -1 on failure, unhandled usb requests and other error conditions +*/ +int fastboot_poll(void) +{ + //printf("DEBUG: %s is called.\n", __FUNCTION__); + /* No activity */ + int ret = FASTBOOT_INACTIVE; + + u32 intrusb; + + /* Look at the interrupt registers */ + intrusb = readl(S5P_OTG_GINTSTS); + + /* A disconnect happended, this signals that the cable + has been disconnected, return immediately */ + if (!FBOOT_USBD_IS_CONNECTED()) + return FASTBOOT_DISCONNECT; + +#ifdef CONFIG_USB_CPUMODE + else if (FBOOT_USBD_DETECT_IRQ_CPUMODE()) { +#else + else if (FBOOT_USBD_DETECT_IRQ_DMAMODE()) { + +#endif + if (!fboot_usb_int_hndlr()) + ret = FASTBOOT_OK; + else + ret = FASTBOOT_ERROR; + FBOOT_USBD_CLEAR_IRQ(); + } + + return ret; +} + + +/* Send a status reply to the client app + buffer does not have to be null terminated. + buffer_size must be not be larger than what is returned by + fastboot_fifo_size + Returns 0 on success + Returns 1 on failure */ +int fastboot_tx_status(const char *buffer, unsigned int buffer_size, const u32 need_sync_flag) +{ + /* fastboot client only reads back at most 64 */ + transfer_size = MIN(64, buffer_size); + +//------------------------------ kdj + //printf(" Response - \"%s\" (%d bytes)\n", buffer, buffer_size); + reply_msg = buffer; + fboot_response_flag=1; +#ifndef CONFIG_USB_CPUMODE + fboot_usb_int_bulkin(); +#endif + if (need_sync_flag) + { + while(fboot_response_flag) + fastboot_poll(); + } + return 1; +} + +/* Returns 1 on success + Returns 0 on failure */ +int fastboot_tx_mem(const char *buffer, unsigned int buffer_size) +{ + if (buffer_size > BULK_XFER_SIZE) { + written_bytes = BULK_XFER_SIZE; + is_fboot_ramdump = 1; + + fboot_ramdump_info.start_buffer = buffer; + fboot_ramdump_info.size = buffer_size; + fboot_ramdump_info.cur_pos = 0; + } else { + written_bytes = buffer_size; + is_fboot_ramdump = 0; + } + + s3c_usb_bulk_inep_setdma(buffer, written_bytes); + return 1; +} + +void fastboot_tx_continue(void) +{ + u32 xfer_size, remain_size; + u32 left; + u8 *buffer; + + if (!is_fboot_ramdump) + return; + + xfer_size = readl(S5P_OTG_DIEPTSIZ_IN) & 0x7FFF; + if (xfer_size) { + printf("%s:%x\n", __FUNCTION__, xfer_size); + return; + } + + fboot_ramdump_info.cur_pos += (written_bytes - xfer_size); + buffer = fboot_ramdump_info.start_buffer + fboot_ramdump_info.cur_pos; + left = fboot_ramdump_info.size - fboot_ramdump_info.cur_pos; + + if (left > BULK_XFER_SIZE) { + written_bytes = BULK_XFER_SIZE; + } else { + written_bytes = left; + is_fboot_ramdump = 0; + fboot_ramdump_info.start_buffer = NULL; + fboot_ramdump_info.size = 0; + fboot_ramdump_info.cur_pos = 0; + } + + s3c_usb_bulk_inep_setdma(buffer, written_bytes); +} + +/* A board specific variable handler. + The size of the buffers is governed by the fastboot spec. + rx_buffer is at most 57 bytes + tx_buffer is at most 60 bytes + Returns 0 on success + Returns 1 on failure */ +int fastboot_getvar(const char *rx_buffer, char *tx_buffer) +{ + /* Place board specific variables here */ + return 1; +} + +#endif /* CONFIG_FASTBOOT */ + diff --git a/drivers/usb/gadget/usbd-otg-hs.c b/drivers/usb/gadget/usbd-otg-hs.c new file mode 100644 index 000000000..cf8aed6f1 --- /dev/null +++ b/drivers/usb/gadget/usbd-otg-hs.c @@ -0,0 +1,2388 @@ +/* + * cpu/s5pc1xx/usbd-otg-hs.c + * + * (C) Copyright 2007 + * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com. + * - only support for S5PC100 + * + * 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> + +#if defined(CONFIG_EXYNOS4X12) || defined(CONFIG_ARCH_EXYNOS) +#include <command.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/usb2.h> +#include "usbd-otg-hs.h" + +#if defined(CONFIG_S5P6450) + DECLARE_GLOBAL_DATA_PTR; +#endif + +#undef USB_OTG_DEBUG_SETUP +#ifdef USB_OTG_DEBUG_SETUP +#define DBG_SETUP0(fmt, args...) printf("[%s:%d] " fmt, __FUNCTION__, __LINE__, ##args) +#define DBG_SETUP1(fmt, args...) printf("\t" fmt, ##args) +#define DBG_SETUP2(fmt, args...) printf(fmt, ##args) +#else +#define DBG_SETUP0(fmt, args...) do { } while (0) +#define DBG_SETUP1(fmt, args...) do { } while (0) +#define DBG_SETUP2(fmt, args...) do { } while (0) +#endif + +#undef USB_OTG_DEBUG_BULK +#ifdef USB_OTG_DEBUG_BULK +#define DBG_BULK0(fmt, args...) printf("[%s:%d] " fmt, __FUNCTION__, __LINE__, ##args) +#define DBG_BULK1(fmt, args...) printf("\t" fmt, ##args) +#else +#define DBG_BULK0(fmt, args...) do { } while (0) +#define DBG_BULK1(fmt, args...) do { } while (0) +#endif + +#define USB_CHECKSUM_EN + +#define TRUE 1 +#define FALSE 0 +#define SUSPEND_RESUME_ON FALSE + + +u32 s3c_usbd_dn_addr = 0; +u32 s3c_usbd_dn_cnt = 0; +u32 remode_wakeup; + +#ifdef CONFIG_USB_CPUMODE +u16 config_value; +#else +u16 config_value __attribute__((aligned(8))); +u8 zlp_buf __attribute__((aligned(8))); +#endif + +int DNW; +int is_fastboot = 0; +int s3c_receive_done = 0; +int s3c_got_header = 0; +int g_dnw_version = -1; + +#ifdef CONFIG_USB_CPUMODE +USB_OPMODE op_mode = USB_CPU; +#else +USB_OPMODE op_mode = USB_DMA; +#endif +USB_SPEED speed = USB_HIGH; + +otg_dev_t otg; +get_status_t get_status; +get_intf_t get_intf; + +enum EP_INDEX +{ + EP0, EP1, EP2, EP3, EP4 +}; + +/*------------------------------------------------*/ +/* EP0 state */ +enum EP0_STATE +{ + EP0_STATE_INIT = 0, + EP0_STATE_GD_DEV_0 = 11, + EP0_STATE_GD_DEV_1 = 12, + EP0_STATE_GD_DEV_2 = 13, + EP0_STATE_GD_CFG_0 = 21, + EP0_STATE_GD_CFG_1 = 22, + EP0_STATE_GD_CFG_2 = 23, + EP0_STATE_GD_CFG_3 = 24, + EP0_STATE_GD_CFG_4 = 25, + EP0_STATE_GD_STR_I0 = 30, + EP0_STATE_GD_STR_I1 = 31, + EP0_STATE_GD_STR_I2 = 32, + EP0_STATE_GD_STR_I3 = 133, + EP0_STATE_GD_DEV_QUALIFIER = 33, + EP0_STATE_INTERFACE_GET = 34, + EP0_STATE_GET_STATUS0 = 35, + EP0_STATE_GET_STATUS1 = 36, + EP0_STATE_GET_STATUS2 = 37, + EP0_STATE_GET_STATUS3 = 38, + EP0_STATE_GET_STATUS4 = 39, + EP0_STATE_GD_OTHER_SPEED = 40, + EP0_STATE_GD_CFG_ONLY_0 = 41, + EP0_STATE_GD_CFG_ONLY_1 = 42, + EP0_STATE_GD_IF_ONLY_0 = 44, + EP0_STATE_GD_IF_ONLY_1 = 45, + EP0_STATE_GD_EP0_ONLY_0 = 46, + EP0_STATE_GD_EP1_ONLY_0 = 47, + EP0_STATE_GD_EP2_ONLY_0 = 48, + EP0_STATE_GD_EP3_ONLY_0 = 49, + EP0_STATE_GD_OTHER_SPEED_HIGH_1 = 51, + EP0_STATE_GD_OTHER_SPEED_HIGH_2 = 52, + EP0_STATE_GD_OTHER_SPEED_HIGH_3 = 53 +}; + +/*definitions related to CSR setting */ + +/* S5P_OTG_GOTGCTL*/ +#define B_SESSION_VALID (0x1<<19) +#define A_SESSION_VALID (0x1<<18) + +/* S5P_OTG_GAHBCFG*/ +#define PTXFE_HALF (0<<8) +#define PTXFE_ZERO (1<<8) +#define NPTXFE_HALF (0<<7) +#define NPTXFE_ZERO (1<<7) +#define MODE_SLAVE (0<<5) +#define MODE_DMA (1<<5) +#define BURST_SINGLE (0<<1) +#define BURST_INCR (1<<1) +#define BURST_INCR4 (3<<1) +#define BURST_INCR8 (5<<1) +#define BURST_INCR16 (7<<1) +#define GBL_INT_UNMASK (1<<0) +#define GBL_INT_MASK (0<<0) + +/* S5P_OTG_GRSTCTL*/ +#define AHB_MASTER_IDLE (1u<<31) +#define CORE_SOFT_RESET (0x1<<0) + +/* S5P_OTG_GINTSTS/S5P_OTG_GINTMSK core interrupt register */ +#define INT_RESUME (1u<<31) +#define INT_DISCONN (0x1<<29) +#define INT_CONN_ID_STS_CNG (0x1<<28) +#define INT_OUT_EP (0x1<<19) +#define INT_IN_EP (0x1<<18) +#define INT_ENUMDONE (0x1<<13) +#define INT_RESET (0x1<<12) +#define INT_SUSPEND (0x1<<11) +#define INT_TX_FIFO_EMPTY (0x1<<5) +#define INT_RX_FIFO_NOT_EMPTY (0x1<<4) +#define INT_SOF (0x1<<3) +#define INT_DEV_MODE (0x0<<0) +#define INT_HOST_MODE (0x1<<1) + +/* S5P_OTG_GRXSTSP STATUS*/ +#define GLOBAL_OUT_NAK (0x1<<17) +#define OUT_PKT_RECEIVED (0x2<<17) +#define OUT_TRNASFER_COMPLETED (0x3<<17) +#define SETUP_TRANSACTION_COMPLETED (0x4<<17) +#define SETUP_PKT_RECEIVED (0x6<<17) + +/* S5P_OTG_DCTL device control register */ +#define NORMAL_OPERATION (0x1<<0) +#define SOFT_DISCONNECT (0x1<<1) +#define TEST_J_MODE (TEST_J<<4) +#define TEST_K_MODE (TEST_K<<4) +#define TEST_SE0_NAK_MODE (TEST_SE0_NAK<<4) +#define TEST_PACKET_MODE (TEST_PACKET<<4) +#define TEST_FORCE_ENABLE_MODE (TEST_FORCE_ENABLE<<4) +#define TEST_CONTROL_FIELD (0x7<<4) + +/* S5P_OTG_DAINT device all endpoint interrupt register */ +#define INT_IN_EP0 (0x1<<0) +#define INT_IN_EP1 (0x1<<1) +#define INT_IN_EP3 (0x1<<3) +#define INT_OUT_EP0 (0x1<<16) +#define INT_OUT_EP2 (0x1<<18) +#define INT_OUT_EP4 (0x1<<20) + +/* S5P_OTG_DIEPCTL0/S5P_OTG_DOEPCTL0 */ +#define DEPCTL_EPENA (0x1<<31) +#define DEPCTL_EPDIS (0x1<<30) +#define DEPCTL_SNAK (0x1<<27) +#define DEPCTL_CNAK (0x1<<26) +#define DEPCTL_CTRL_TYPE (EP_TYPE_CONTROL<<18) +#define DEPCTL_ISO_TYPE (EP_TYPE_ISOCHRONOUS<<18) +#define DEPCTL_BULK_TYPE (EP_TYPE_BULK<<18) +#define DEPCTL_INTR_TYPE (EP_TYPE_INTERRUPT<<18) +#define DEPCTL_USBACTEP (0x1<<15) + +/*ep0 enable, clear nak, next ep0, max 64byte */ +#define EPEN_CNAK_EP0_64 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(0<<0)) + +/*ep0 enable, clear nak, next ep0, 8byte */ +#define EPEN_CNAK_EP0_8 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(3<<0)) + +/* DIEPCTLn/DOEPCTLn */ +#define BACK2BACK_SETUP_RECEIVED (0x1<<6) +#define INTKN_TXFEMP (0x1<<4) +#define NON_ISO_IN_EP_TIMEOUT (0x1<<3) +#define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3) +#define AHB_ERROR (0x1<<2) +#define TRANSFER_DONE (0x1<<0) + + +/* codes representing languages */ +const u8 string_desc0[] = +{ + 4, STRING_DESCRIPTOR, LANGID_US_L, LANGID_US_H, +}; + +const u8 dnw_string_desc1[] = /* Manufacturer */ +{ + (0x14+2), STRING_DESCRIPTOR, + 'S', 0x0, 'y', 0x0, 's', 0x0, 't', 0x0, 'e', 0x0, + 'm', 0x0, ' ', 0x0, 'M', 0x0, 'C', 0x0, 'U', 0x0, +}; + +const u8 dnw_string_desc2[] = /* Product */ +{ + (0x2a+2), STRING_DESCRIPTOR, + 'S', 0x0, 'E', 0x0, 'C', 0x0, ' ', 0x0, 'S', 0x0, + '3', 0x0, 'C', 0x0, '6', 0x0, '4', 0x0, '0', 0x0, + '0', 0x0, 'X', 0x0, ' ', 0x0, 'T', 0x0, 'e', 0x0, + 's', 0x0, 't', 0x0, ' ', 0x0, 'B', 0x0, '/', 0x0, + 'D', 0x0 +}; + +/* setting the device qualifier descriptor and a string descriptor */ +const u8 qualifier_desc[] = +{ + 0x0a, /* 0 desc size */ + 0x06, /* 1 desc type (DEVICE_QUALIFIER)*/ + 0x00, /* 2 USB release */ + 0x02, /* 3 => 2.00*/ + 0xFF, /* 4 class */ + 0x00, /* 5 subclass */ + 0x00, /* 6 protocol */ + 64, /* 7 max pack size */ + 0x01, /* 8 number of other-speed configuration */ + 0x00, /* 9 reserved */ +}; + +const u8 config_full[] = +{ + 0x09, /* 0 desc size */ + 0x07, /* 1 desc type (other speed)*/ + 0x20, /* 2 Total length of data returned */ + 0x00, /* 3 */ + 0x01, /* 4 Number of interfaces supported by this speed configuration */ + 0x01, /* 5 value to use to select configuration */ + 0x00, /* 6 index of string desc */ + /* 7 same as configuration desc */ + CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED, + 0x19, /* 8 same as configuration desc */ + +}; + +const u8 config_full_total[] = +{ + 0x09, 0x07 ,0x20 ,0x00 ,0x01 ,0x01 ,0x00 ,0xC0 ,0x19, + 0x09 ,0x04 ,0x00 ,0x00 ,0x02 ,0xff ,0x00 ,0x00 ,0x00, + 0x07 ,0x05 ,0x83 ,0x02 ,0x40 ,0x00 ,0x00, + 0x07 ,0x05 ,0x04 ,0x02 ,0x40 ,0x00 ,0x00 +}; + +const u8 config_high[] = +{ + 0x09, /* 0 desc size */ + 0x07, /* 1 desc type (other speed)*/ + 0x20, /* 2 Total length of data returned */ + 0x00, /* 3 */ + 0x01, /* 4 Number of interfaces supported by this speed configuration */ + 0x01, /* 5 value to use to select configuration */ + 0x00, /* 6 index of string desc */ + /* 7 same as configuration desc */ + CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED, + 0x19, /* 8 same as configuration desc */ + +}; + +const u8 config_high_total[] = +{ + 0x09, 0x07 ,0x20 ,0x00 ,0x01 ,0x01 ,0x00 ,0xC0 ,0x19, + 0x09 ,0x04 ,0x00 ,0x00 ,0x02 ,0xff ,0x00 ,0x00 ,0x00, + 0x07 ,0x05 ,0x81 ,0x02 ,0x00 ,0x02 ,0x00, + 0x07 ,0x05 ,0x02 ,0x02 ,0x00 ,0x02 ,0x00 +}; + +/* Descriptor size */ +enum DESCRIPTOR_SIZE +{ + DEVICE_DESC_SIZE = sizeof(device_desc_t), + CONFIG_DESC_SIZE = sizeof(config_desc_t), + INTERFACE_DESC_SIZE = sizeof(intf_desc_t), + ENDPOINT_DESC_SIZE = sizeof(ep_desc_t), + DEVICE_QUALIFIER_SIZE = sizeof(qualifier_desc), + OTHER_SPEED_CFG_SIZE = 9 + +}; + +/*32 <cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>*/ +#define CONFIG_DESC_TOTAL_SIZE \ + (CONFIG_DESC_SIZE+INTERFACE_DESC_SIZE+ENDPOINT_DESC_SIZE*2) +#define TEST_PKT_SIZE 53 + +#ifdef CONFIG_USB_CPUMODE +u8 test_pkt [TEST_PKT_SIZE] = { +#else +u8 test_pkt [TEST_PKT_SIZE] __attribute__((aligned(8))) = { +#endif + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*JKJKJKJK x 9*/ + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, /*JJKKJJKK x 8*/ + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, /*JJJJKKKK x 8*/ + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /*JJJJJJJKKKKKKK x8 - '1'*/ + 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, /*'1' + JJJJJJJK x 8*/ + 0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E /*{JKKKKKKK x 10},JK*/ +}; + +#ifndef CONFIG_USB_CPUMODE +/* BULK XFER SIZE is 256K bytes */ +#define BULK_XFER_SIZE 262144 +u8 usb_ctrl[8] __attribute__((aligned(8))); +u8 ctrl_buf[128] __attribute__((aligned(8))); +u8 tmp_buf[HS_BULK_PKT_SIZE] __attribute__((aligned(8))); +int written_bytes; + +void s3c_usb_transfer_ep0(void); +void s3c_usb_set_outep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize); +#endif +int s3c_usbctl_init(void); +void s3c_usb_set_inep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize); +void s3c_usb_write_in_fifo(u8 *buf, int num); +void s3c_usb_read_out_fifo(u8 *buf, int num); + +#include "fastboot.c" +#include "dnw.c" + +void s3c_usb_init_phy(void) +{ +#if defined(CONFIG_ARCH_EXYNOS5) + writel(0x0, USB_CFG_REG); + writel(0x7454, EXYNOS5_OTG_SYS); + udelay(10); + writel(0x0454, EXYNOS5_OTG_SYS); + udelay(10); +#else /* EXYNOS4 or under */ +#if defined(CONFIG_S5PC110) + writel(0xa0, S5P_OTG_PHYPWR); + writel(0x3, S5P_OTG_PHYCLK); +#elif defined(CONFIG_EXYNOS4X12) || defined(CONFIG_CPU_EXYNOS4415) + writel(0x0, USB_CFG_REG); + writel(0x7f80, S5P_OTG_PHYPWR); + writel(0x5, S5P_OTG_PHYCLK); +#elif defined(CONFIG_S5PC210) + writel(0x1f80, S5P_OTG_PHYPWR); + writel(0x3, S5P_OTG_PHYCLK); +#elif defined(CONFIG_S5P6450) + writel(0xa0, S5P_OTG_PHYPWR); + writel(0x21, S5P_OTG_PHYCLK); +#elif defined(CONFIG_CPU_EXYNOS3250) + writel(0x0, USB_CFG_REG); + writel(0x7f80, S5P_OTG_PHYPWR); + writel(0x215, S5P_OTG_PHYCLK); +#endif + writel(0x1, S5P_OTG_RSTCON); + udelay(10); + writel(0x0, S5P_OTG_RSTCON); + udelay(10); +#endif +} + +/* OTG PHY Power Off */ +void s3c_usb_phy_off(void) { +#if defined(CONFIG_ARCH_EXYNOS5) + writel(0x145F, EXYNOS5_OTG_SYS); +#else + writel(readl(S5P_OTG_PHYPWR)|(0x18), S5P_OTG_PHYPWR); +#endif +#if !defined(CONFIG_S5P6450) + writel(readl(USB_PHY_CONTROL)&~(1<<0), USB_PHY_CONTROL); +#else + writel(readl(OTHERS)|(1<<16), OTHERS); +#endif +} + +void s3c_usb_core_soft_reset(void) +{ + u32 tmp; + + writel(CORE_SOFT_RESET, S5P_OTG_GRSTCTL); + + do + { + tmp = readl(S5P_OTG_GRSTCTL); + }while(!(tmp & AHB_MASTER_IDLE)); + +} + +void s3c_usb_wait_cable_insert(void) +{ + u32 tmp; + int ucFirst = 1; + + do { + udelay(50); + + tmp = readl(S5P_OTG_GOTGCTL); + + if (tmp & (B_SESSION_VALID|A_SESSION_VALID)) { + printf("OTG cable Connected!\n"); + break; + } else if(ucFirst == 1) { + printf("Insert a OTG cable into the connector!\n"); + ucFirst = 0; + } + } while(1); +} + +void s3c_usb_init_core(void) +{ +#ifdef CONFIG_USB_CPUMODE + writel(PTXFE_HALF|NPTXFE_HALF|MODE_SLAVE|BURST_SINGLE|GBL_INT_UNMASK, + S5P_OTG_GAHBCFG); +#else + writel(PTXFE_HALF|NPTXFE_HALF|MODE_DMA|BURST_INCR4|GBL_INT_UNMASK, + S5P_OTG_GAHBCFG); +#endif + + writel( 0<<15 /* PHY Low Power Clock sel */ + |1<<14 /* Non-Periodic TxFIFO Rewind Enable */ + |0x5<<10 /* Turnaround time */ + |0<<9 /* 0:HNP disable, 1:HNP enable */ + |0<<8 /* 0:SRP disable, 1:SRP enable */ + |0<<7 /* ULPI DDR sel */ + |0<<6 /* 0: high speed utmi+, 1: full speed serial */ + |0<<4 /* 0: utmi+, 1:ulpi */ + |1<<3 /* phy i/f 0:8bit, 1:16bit */ + |0x7<<0, /* HS/FS Timeout**/ + S5P_OTG_GUSBCFG ); +} + +void s3c_usb_check_current_mode(u8 *pucMode) +{ + u32 tmp; + + tmp = readl(S5P_OTG_GINTSTS); + *pucMode = tmp & 0x1; +} + +void s3c_usb_set_soft_disconnect(void) +{ + u32 tmp; + + tmp = readl(S5P_OTG_DCTL); + tmp |= SOFT_DISCONNECT; + writel(tmp, S5P_OTG_DCTL); +} + +void s3c_usb_clear_soft_disconnect(void) +{ + u32 tmp; + + tmp = readl(S5P_OTG_DCTL); + tmp &= ~SOFT_DISCONNECT; + writel(tmp, S5P_OTG_DCTL); +} + +void s3c_usb_init_device(void) +{ + writel(1<<18|otg.speed<<0, S5P_OTG_DCFG); /* [][1: full speed(30Mhz) 0:high speed]*/ + +#ifdef CONFIG_USB_CPUMODE + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE| + INT_RESET|INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY, + S5P_OTG_GINTMSK); /*gint unmask */ +#else + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE| + INT_RESET|INT_SUSPEND, + S5P_OTG_GINTMSK); /*gint unmask */ +#endif +} + +int s3c_usbctl_init(void) +{ + u8 ucMode; + + DBG_SETUP0("USB Control Init\n"); +#if defined(CONFIG_EXYNOS4X12) || defined(CONFIG_ARCH_EXYNOS) + writel(readl(USB_PHY_CONTROL)|(1<<0), USB_PHY_CONTROL); /*USB PHY0 Enable */ // c110 +#elif defined(CONFIG_S5PC100) + writel(readl(OTHERS)|~(1<<16), OTHERS); +#elif defined(CONFIG_S5P6450) + writel(readl(OTHERS)&~(1<<16), OTHERS); +#else +#error "* CFG_ERROR : you have to select proper CPU for Android Fastboot" +#endif + + otg.speed = speed; + otg.set_config = 0; + otg.ep0_state = EP0_STATE_INIT; + otg.ep0_substate = 0; + s3c_usb_init_phy(); + s3c_usb_core_soft_reset(); + s3c_usb_wait_cable_insert(); + s3c_usb_init_core(); + s3c_usb_check_current_mode(&ucMode); + is_fastboot = 0; + + if (ucMode == INT_DEV_MODE) { + s3c_usb_set_soft_disconnect(); + udelay(10); + s3c_usb_clear_soft_disconnect(); + s3c_usb_init_device(); + return 0; + } else { + printf("Error : Current Mode is Host\n"); + return 0; + } +} + +int s3c_usbc_activate (void) +{ + /* dont used in usb high speed, but used in common file cmd_usbd.c */ + return 0; +} + +int s3c_usb_stop (void) +{ + /* dont used in usb high speed, but used in common file cmd_usbd.c */ + s3c_usb_core_soft_reset(); + s3c_usb_phy_off(); + return 0; +} + +void s3c_usb_print_pkt(u8 *pt, u8 count) +{ + int i; + printf("[s3c_usb_print_pkt:"); + + for(i=0;i<count;i++) + printf("%x,", pt[i]); + + printf("]\n"); +} + +void s3c_usb_verify_checksum(void) +{ + u8 *cs_start, *cs_end; + u16 dnCS; + u16 checkSum; + + printf("Checksum is being calculated."); + + /* checksum calculation */ + cs_start = (u8*)otg.dn_addr; + cs_end = (u8*)(otg.dn_addr+otg.dn_filesize-10); + checkSum = 0; + while(cs_start < cs_end) { + checkSum += *cs_start++; + if(((u32)cs_start&0xfffff)==0) printf("."); + } + +#if defined(CONFIG_EXYNOS4X12) || defined(CONFIG_ARCH_EXYNOS) + // fixed alignment fault in case when cs_end is odd. + dnCS = (u16)((cs_end[1]<<8) + cs_end[0]); +#elif defined(CONFIG_S5PC100) || defined(CONFIG_S5P6450) + dnCS = *(u16 *)cs_end; +#else +#error "* CFG_ERROR : you have to select proper CPU" +#endif + + if (checkSum == dnCS) + { + printf("\nChecksum O.K.\n"); + } + else + { + printf("\nChecksum Value => MEM:%x DNW:%x\n",checkSum,dnCS); + printf("Checksum failed.\n\n"); + } + +} +#ifndef CONFIG_USB_CPUMODE +void s3c_usb_prepare_setup_pkt(void) +{ + writel(virt_to_phys(ctrl_buf), S5P_OTG_DOEPDMA0); + s3c_usb_set_outep_xfersize(EP_TYPE_CONTROL, 1, 8); + /*ep0 enable, clear nak */ + writel((1u<<31)|(1<<26)|readl(S5P_OTG_DOEPCTL0), S5P_OTG_DOEPCTL0); +} + +void s3c_usb_bulk_outep_setdma(u8* buf, int size) +{ + int pktcnt; + u32 buf_address = (u32)buf; + + if(buf_address & 0x7) { + printf("---------ERROR: DMA Address is not aligned by 8---------\n"); + return; + } + + writel(virt_to_phys(buf), S5P_OTG_DOEPDMA_OUT); + if(size == 0) + pktcnt = 1; + else + pktcnt = (size - 1) / HS_BULK_PKT_SIZE + 1; + + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, pktcnt, size); + /*ep0 enable, clear nak */ + writel((1u<<31)|(1<<26)|readl(S5P_OTG_DOEPCTL_OUT), S5P_OTG_DOEPCTL_OUT); +} + +void s3c_usb_bulk_inep_setdma(u8* buf, int size) +{ + int pktcnt; + u32 buf_address = (u32)buf; + + if(buf_address & 0x7) { + printf("---------ERROR: DMA Address is not aligned by 8---------\n"); + return; + } + + writel(virt_to_phys(buf), S5P_OTG_DIEPDMA_IN); + if(size == 0) + pktcnt = 1; + else + pktcnt = (size - 1) / HS_BULK_PKT_SIZE + 1; + + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt, size); + /*ep0 enable, clear nak */ + writel((1u<<31)|(1<<26)|readl(S5P_OTG_DIEPCTL_IN), S5P_OTG_DIEPCTL_IN); +} + +void s3c_usb_ctrl_inep_setdma(u8* buf, int size) +{ + int pktcnt; + u32 buf_address = (u32)buf; + + if(buf_address & 0x7) { + memcpy(ctrl_buf, buf, size); + buf = ctrl_buf; + } + writel(virt_to_phys(buf), S5P_OTG_DIEPDMA0); + if(size == 0) + pktcnt = 1; + else + pktcnt = (size - 1) / 64 + 1; + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, pktcnt, size); + + /*ep0 enable, clear nak */ + writel((1u<<31)|(1<<26)|readl(S5P_OTG_DIEPCTL0), S5P_OTG_DIEPCTL0); +} + +void s3c_usb_upload_continue(void) +{ + u32 xfer_size, remain_size; + + xfer_size = readl(S5P_OTG_DIEPTSIZ_IN) & 0x7FFF; + otg.up_ptr += (written_bytes - xfer_size); + + remain_size = otg.up_size - ((u32)otg.up_ptr - otg.up_addr); + if (remain_size > 0) { + if(remain_size < BULK_XFER_SIZE) + written_bytes = remain_size; + else + written_bytes = BULK_XFER_SIZE; + + s3c_usb_bulk_inep_setdma(otg.up_ptr, written_bytes); + } else + s3c_receive_done = 1; +} +#endif + +void s3c_usb_set_inep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize) +{ + if(type == EP_TYPE_CONTROL) + { + writel((pktcnt<<19)|(xfersize<<0), S5P_OTG_DIEPTSIZ0); + } + else if(type == EP_TYPE_BULK) + { + writel((1<<29)|(pktcnt<<19)|(xfersize<<0), S5P_OTG_DIEPTSIZ_IN); + } +} + +void s3c_usb_set_outep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize) +{ + if(type == EP_TYPE_CONTROL) + { + writel((1<<29)|(pktcnt<<19)|(xfersize<<0), S5P_OTG_DOEPTSIZ0); + } + else if(type == EP_TYPE_BULK) + { + writel((pktcnt<<19)|(xfersize<<0), S5P_OTG_DOEPTSIZ_OUT); + } +} + +void s3c_usb_write_ep0_fifo(u8 *buf, int num) +{ + int i; + u32 Wr_Data=0; + + DBG_SETUP1("[s3c_usb_write_ep0_fifo:"); + + for(i=0;i<num;i+=4) + { + Wr_Data = ((*(buf+3))<<24)|((*(buf+2))<<16)|((*(buf+1))<<8)|*buf; + DBG_SETUP2(" 0x%08x,", Wr_Data); + writel(Wr_Data, S5P_OTG_EP0_FIFO); + buf += 4; + } + + DBG_SETUP2("]\n"); +} + + +void s3c_usb_write_in_fifo(u8 *buf, int num) +{ + int i; + u32 data=0; + + for(i=0;i<num;i+=4) + { + data=((*(buf+3))<<24)|((*(buf+2))<<16)|((*(buf+1))<<8)|*buf; + writel(data, S5P_OTG_IN_FIFO); + buf += 4; + } +} + +void s3c_usb_read_out_fifo(u8 *buf, int num) +{ + int i; + u32 data; + + for (i=0;i<num;i+=4) + { + data = readl(S5P_OTG_OUT_FIFO); + + buf[i] = (u8)data; + buf[i+1] = (u8)(data>>8); + buf[i+2] = (u8)(data>>16); + buf[i+3] = (u8)(data>>24); + } +} + +void s3c_usb_get_desc(void) +{ + switch (otg.dev_req.wValue_H) { + case DEVICE_DESCRIPTOR: + otg.req_length = (u32)((otg.dev_req.wLength_H << 8) | + otg.dev_req.wLength_L); + DBG_SETUP1("DEVICE_DESCRIPTOR = 0x%x \n",otg.req_length); + otg.ep0_state = EP0_STATE_GD_DEV_0; + break; + + case CONFIGURATION_DESCRIPTOR: + otg.req_length = (u32)((otg.dev_req.wLength_H << 8) | + otg.dev_req.wLength_L); + DBG_SETUP1("CONFIGURATION_DESCRIPTOR = 0x%x \n",otg.req_length); + + /* GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 */ + if (otg.req_length > CONFIG_DESC_SIZE){ + otg.ep0_state = EP0_STATE_GD_CFG_0; + } else + otg.ep0_state = EP0_STATE_GD_CFG_ONLY_0; + break; + + case STRING_DESCRIPTOR : + DBG_SETUP1("STRING_DESCRIPTOR \n"); + + switch(otg.dev_req.wValue_L) { + case 0: + otg.ep0_state = EP0_STATE_GD_STR_I0; + break; + case 1: + otg.ep0_state = EP0_STATE_GD_STR_I1; + break; + case 2: + otg.ep0_state = EP0_STATE_GD_STR_I2; + break; + case 3: + otg.ep0_state = EP0_STATE_GD_STR_I3; + break; + default: + break; + } + break; + + case ENDPOINT_DESCRIPTOR: + DBG_SETUP1("ENDPOINT_DESCRIPTOR \n"); + switch(otg.dev_req.wValue_L&0xf) { + case 0: + otg.ep0_state=EP0_STATE_GD_EP0_ONLY_0; + break; + case 1: + otg.ep0_state=EP0_STATE_GD_EP1_ONLY_0; + break; + default: + break; + } + break; + + case DEVICE_QUALIFIER: + otg.req_length = (u32)((otg.dev_req.wLength_H << 8) | + otg.dev_req.wLength_L); + DBG_SETUP1("DEVICE_QUALIFIER = 0x%x \n",otg.req_length); + otg.ep0_state = EP0_STATE_GD_DEV_QUALIFIER; + break; + + case OTHER_SPEED_CONFIGURATION : + DBG_SETUP1("OTHER_SPEED_CONFIGURATION \n"); + otg.req_length = (u32)((otg.dev_req.wLength_H << 8) | + otg.dev_req.wLength_L); + otg.ep0_state = EP0_STATE_GD_OTHER_SPEED; + break; + + } +} + +void s3c_usb_clear_feature(void) +{ + switch (otg.dev_req.bmRequestType) { + case DEVICE_RECIPIENT: + DBG_SETUP1("DEVICE_RECIPIENT \n"); + if (otg.dev_req.wValue_L == 1) + remode_wakeup = FALSE; + break; + + case ENDPOINT_RECIPIENT: + DBG_SETUP1("ENDPOINT_RECIPIENT \n"); + if (otg.dev_req.wValue_L == 0) { + if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP) + get_status.ep_ctrl= 0; + + /* IN Endpoint */ + if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP) + get_status.ep_in= 0; + + /* OUT Endpoint */ + if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP) + get_status.ep_out= 0; + } + break; + + default: + DBG_SETUP1("\n"); + break; + } + otg.ep0_state = EP0_STATE_INIT; + +} + +void s3c_usb_set_feature(void) +{ + u32 tmp; + + switch (otg.dev_req.bmRequestType) { + case DEVICE_RECIPIENT: + DBG_SETUP1("DEVICE_RECIPIENT \n"); + if (otg.dev_req.wValue_L == 1) + remode_wakeup = TRUE; + break; + + case ENDPOINT_RECIPIENT: + DBG_SETUP1("ENDPOINT_RECIPIENT \n"); + if (otg.dev_req.wValue_L == 0) { + if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP) + get_status.ep_ctrl= 1; + + if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP) + get_status.ep_in= 1; + + if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP) + get_status.ep_out= 1; + } + break; + + default: + DBG_SETUP1("\n"); + break; + } + + switch (otg.dev_req.wValue_L) { + case EP_STALL: + /* TBD: additional processing if required */ + break; + + case TEST_MODE: + if ((0 != otg.dev_req.wIndex_L ) ||(0 != otg.dev_req.bmRequestType)) + break; + + /* Set TEST MODE*/ + tmp = readl(S5P_OTG_DCTL); + tmp = (tmp & ~(TEST_CONTROL_FIELD)) | (TEST_FORCE_ENABLE_MODE); + writel(tmp, S5P_OTG_DCTL); + + switch(otg.dev_req.wIndex_H) { + case TEST_J: + /*Set Test J*/ + tmp = readl(S5P_OTG_DCTL); + tmp = (tmp & ~(TEST_CONTROL_FIELD)) | (TEST_J_MODE); + writel(tmp, S5P_OTG_DCTL); + break; + + case TEST_K: + /*Set Test K*/ + tmp = readl(S5P_OTG_DCTL); + tmp = (tmp & ~(TEST_CONTROL_FIELD)) | (TEST_K_MODE); + writel(tmp, S5P_OTG_DCTL); + break; + + case TEST_SE0_NAK: + /*Set Test SE0NAK*/ + tmp = readl(S5P_OTG_DCTL); + tmp = (tmp & ~(TEST_CONTROL_FIELD)) | (TEST_SE0_NAK_MODE); + writel(tmp, S5P_OTG_DCTL); + break; + + case TEST_PACKET: + DBG_SETUP1 ("Test_packet\n"); +#ifdef CONFIG_USB_CPUMODE + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, TEST_PKT_SIZE); + s3c_usb_write_ep0_fifo(test_pkt, TEST_PKT_SIZE); +#else + s3c_usb_ctrl_inep_setdma(test_pkt, TEST_PKT_SIZE); +#endif + tmp = readl(S5P_OTG_DCTL); + tmp = (tmp & ~(TEST_CONTROL_FIELD)) | (TEST_PACKET_MODE); + writel(tmp, S5P_OTG_DCTL); + DBG_SETUP1 ("S5P_OTG_DCTL=0x%08x\n", tmp); + break; + } + break; + + default: + break; + } + otg.ep0_state = EP0_STATE_INIT; +} + +void s3c_usb_get_status(void) +{ + switch(otg.dev_req.bmRequestType) { + case (0x80): /*device */ + DBG_SETUP1("DEVICE\n"); + get_status.Device=((u8)remode_wakeup<<1)|0x1; /* SelfPowered */ + otg.ep0_state = EP0_STATE_GET_STATUS0; + break; + + case (0x81): /*interface */ + DBG_SETUP1("INTERFACE\n"); + get_status.Interface=0; + otg.ep0_state = EP0_STATE_GET_STATUS1; + break; + + case (0x82): /*endpoint */ + DBG_SETUP1("ENDPOINT\n"); + if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP) + otg.ep0_state = EP0_STATE_GET_STATUS2; + + if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP) + otg.ep0_state = EP0_STATE_GET_STATUS3; + + if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP) + otg.ep0_state = EP0_STATE_GET_STATUS4; + break; + + default: + DBG_SETUP1("\n"); + break; + } +} + +void s3c_usb_ep0_int_hndlr(void) +{ + u16 i; + u32 buf[2]={0x0000, }; + u16 addr; + + DBG_SETUP0("Event EP0\n"); + + if (otg.ep0_state == EP0_STATE_INIT) { + +#ifdef CONFIG_USB_CPUMODE + for(i=0;i<2;i++) + buf[i] = readl(S5P_OTG_EP0_FIFO); + + otg.dev_req.bmRequestType = buf[0]; + otg.dev_req.bRequest = buf[0]>>8; + otg.dev_req.wValue_L = buf[0]>>16; + otg.dev_req.wValue_H = buf[0]>>24; + otg.dev_req.wIndex_L = buf[1]; + otg.dev_req.wIndex_H = buf[1]>>8; + otg.dev_req.wLength_L = buf[1]>>16; + otg.dev_req.wLength_H = buf[1]>>24; +#else + otg.dev_req.bmRequestType = ctrl_buf[0]; + otg.dev_req.bRequest = ctrl_buf[1]; + otg.dev_req.wValue_L = ctrl_buf[2]; + otg.dev_req.wValue_H = ctrl_buf[3]; + otg.dev_req.wIndex_L = ctrl_buf[4]; + otg.dev_req.wIndex_H = ctrl_buf[5]; + otg.dev_req.wLength_L = ctrl_buf[6]; + otg.dev_req.wLength_H = ctrl_buf[7]; +#endif + +#ifdef USB_OTG_DEBUG_SETUP + s3c_usb_print_pkt((u8 *)&otg.dev_req, 8); +#endif + + switch (otg.dev_req.bRequest) { + case STANDARD_SET_ADDRESS: + /* Set Address Update bit */ + addr = (otg.dev_req.wValue_L); + writel(1<<18|addr<<4|otg.speed<<0, S5P_OTG_DCFG); + DBG_SETUP1("S5P_OTG_DCFG : %x, STANDARD_SET_ADDRESS : %d\n", + readl(S5P_OTG_DCFG), addr); + otg.ep0_state = EP0_STATE_INIT; + break; + + case STANDARD_SET_DESCRIPTOR: + DBG_SETUP1("STANDARD_SET_DESCRIPTOR \n"); + break; + + case STANDARD_SET_CONFIGURATION: + DBG_SETUP1("STANDARD_SET_CONFIGURATION \n"); + /* Configuration value in configuration descriptor */ + config_value = otg.dev_req.wValue_L; + otg.set_config = 1; + otg.ep0_state = EP0_STATE_INIT; +#ifndef CONFIG_USB_CPUMODE + /* Set the Dedicated FIFO 1 for Bulk IN EP(1<<22) */ + writel(1<<28|1<<22|2<<18|1<<15|otg.bulkin_max_pktsize<<0,S5P_OTG_DIEPCTL_IN); + writel(1<<28|2<<18|1<<15|otg.bulkout_max_pktsize<<0,S5P_OTG_DOEPCTL_OUT); + s3c_usb_bulk_outep_setdma(tmp_buf, HS_BULK_PKT_SIZE); +#endif + break; + + case STANDARD_GET_CONFIGURATION: + DBG_SETUP1("STANDARD_GET_CONFIGURATION \n"); + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1); + +#ifdef CONFIG_USB_CPUMODE + /*ep0 enable, clear nak, next ep0, 8byte */ + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + writel(config_value, S5P_OTG_EP0_FIFO); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&config_value, 1); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + case STANDARD_GET_DESCRIPTOR: + DBG_SETUP1("STANDARD_GET_DESCRIPTOR :"); + s3c_usb_get_desc(); + break; + + case STANDARD_CLEAR_FEATURE: + DBG_SETUP1("STANDARD_CLEAR_FEATURE :"); + s3c_usb_clear_feature(); + break; + + case STANDARD_SET_FEATURE: + DBG_SETUP1("STANDARD_SET_FEATURE :"); + s3c_usb_set_feature(); + break; + + case STANDARD_GET_STATUS: + DBG_SETUP1("STANDARD_GET_STATUS :"); + s3c_usb_get_status(); + break; + + case STANDARD_GET_INTERFACE: + DBG_SETUP1("STANDARD_GET_INTERFACE \n"); + otg.ep0_state = EP0_STATE_INTERFACE_GET; + break; + + case STANDARD_SET_INTERFACE: + DBG_SETUP1("STANDARD_SET_INTERFACE \n"); + get_intf.AlternateSetting= otg.dev_req.wValue_L; + otg.ep0_state = EP0_STATE_INIT; + break; + + case STANDARD_SYNCH_FRAME: + DBG_SETUP1("STANDARD_SYNCH_FRAME \n"); + otg.ep0_state = EP0_STATE_INIT; + break; + + default: + break; + } + } +#ifdef CONFIG_USB_CPUMODE + + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.ctrl_max_pktsize); + + /*clear nak, next ep0, 64byte */ + writel(((1<<26)|(CONTROL_EP<<11)|(0<<0)), S5P_OTG_DIEPCTL0); + +#else + s3c_usb_transfer_ep0(); +#endif +} + +void s3c_usb_set_otherspeed_conf_desc(u32 length) +{ + /* Standard device descriptor */ + if (length ==9) + { +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 9); + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo(((u8 *)&config_full)+0, 9); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&config_full)+0, 9); +#endif + } + else if(length ==32) + { +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 32); + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo(((u8 *)&config_full_total)+0, 32); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&config_full_total)+0, 32); +#endif + + } + otg.ep0_state = EP0_STATE_INIT; +} + +void s3c_usb_transfer_ep0(void) +{ + const u8 *string_desc1, *string_desc2, *string_desc3; + u32 string_desc1_size, string_desc2_size, string_desc3_size; + + if (is_fastboot +#ifdef CONFIG_DNW_VERSION + && (DNW_v05 != g_dnw_version) +#endif /* CONFIG_DNW_VERSION */ + ) { + string_desc1 = fboot_string_desc1; + string_desc2 = fboot_string_desc2; + string_desc3 = fboot_string_desc3; + + string_desc1_size = sizeof(fboot_string_desc1); + string_desc2_size = sizeof(fboot_string_desc2); + string_desc3_size = sizeof(fboot_string_desc3); + } else { + string_desc1 = dnw_string_desc1; + string_desc2 = dnw_string_desc2; + string_desc3 = dnw_string_desc2; + + string_desc1_size = sizeof(dnw_string_desc1); + string_desc2_size = sizeof(dnw_string_desc2); + string_desc3_size = sizeof(dnw_string_desc2); +#ifdef CONFIG_DNW_VERSION + if ((DNW_v05 <= g_dnw_version)){ + string_desc3 = fboot_string_desc3; + string_desc3_size = sizeof(fboot_string_desc3); + } +#endif /* CONFIG_DNW_VERSION */ + } + + DBG_SETUP0("otg.ep0_state = %d\n", otg.ep0_state); + + switch (otg.ep0_state) { + case EP0_STATE_INIT: +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 0); + + /*ep0 enable, clear nak, next ep0, 8byte */ + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&zlp_buf, 0); +#endif + DBG_SETUP1("EP0_STATE_INIT\n"); + break; + + /* GET_DESCRIPTOR:DEVICE */ + case EP0_STATE_GD_DEV_0: + DBG_SETUP1("EP0_STATE_GD_DEV_0 :"); + + /*ep0 enable, clear nak, next ep0, max 64byte */ +#ifdef CONFIG_USB_CPUMODE + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + if (otg.req_length < DEVICE_DESC_SIZE) { + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.req_length); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.dev))+0, otg.req_length); + } else { + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, DEVICE_DESC_SIZE); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.dev))+0, DEVICE_DESC_SIZE); + } + otg.ep0_state = EP0_STATE_INIT; +#else + if (otg.req_length < DEVICE_DESC_SIZE) { + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.dev))+0, otg.req_length); + } else { + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.dev))+0, DEVICE_DESC_SIZE); + } + otg.ep0_state = EP0_STATE_INIT; +#endif + break; + + /* GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 */ + case EP0_STATE_GD_CFG_0: + DBG_SETUP1("EP0_STATE_GD_CFG_0 :"); +#ifdef CONFIG_USB_CPUMODE + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + if(otg.req_length<CONFIG_DESC_TOTAL_SIZE) + { + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.req_length); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.config))+0, otg.req_length); + } + else + { + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, CONFIG_DESC_TOTAL_SIZE); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.config))+0, CONFIG_DESC_TOTAL_SIZE); + } +#else + if(otg.req_length<CONFIG_DESC_TOTAL_SIZE) + { + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.config))+0, otg.req_length); + } + else + { + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.config))+0, CONFIG_DESC_TOTAL_SIZE); + } +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + case EP0_STATE_GD_OTHER_SPEED: + DBG_SETUP1("EP0_STATE_GD_OTHER_SPEED\n"); + s3c_usb_set_otherspeed_conf_desc(otg.req_length); + break; + + /* GET_DESCRIPTOR:CONFIGURATION ONLY*/ + case EP0_STATE_GD_CFG_ONLY_0: + DBG_SETUP1("EP0_STATE_GD_CFG_ONLY_0:"); + if(otg.req_length<CONFIG_DESC_SIZE) + { +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.req_length); + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.config))+0, otg.req_length); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.config))+0, otg.req_length); +#endif + } + else + { +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, CONFIG_DESC_SIZE); + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.config))+0, + CONFIG_DESC_SIZE); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.config))+0,CONFIG_DESC_SIZE); +#endif + } + otg.ep0_state = EP0_STATE_INIT; + break; + + /* GET_DESCRIPTOR:INTERFACE ONLY */ + + case EP0_STATE_GD_IF_ONLY_0: + DBG_SETUP1("EP0_STATE_GD_IF_ONLY_0 :"); + if(otg.req_length<INTERFACE_DESC_SIZE) + { +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.req_length); + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.intf))+0, otg.req_length); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.intf))+0, otg.req_length); +#endif + } + else + { +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, INTERFACE_DESC_SIZE); + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.intf))+0, INTERFACE_DESC_SIZE); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.intf))+0, INTERFACE_DESC_SIZE); +#endif + } + otg.ep0_state = EP0_STATE_INIT; + break; + + /* GET_DESCRIPTOR:ENDPOINT 1 ONLY */ + case EP0_STATE_GD_EP0_ONLY_0: + DBG_SETUP1("EP0_STATE_GD_EP0_ONLY_0\n"); +#ifdef CONFIG_USB_CPUMODE + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.ep1))+0, ENDPOINT_DESC_SIZE); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.ep1))+0, ENDPOINT_DESC_SIZE); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + /* GET_DESCRIPTOR:ENDPOINT 2 ONLY */ + case EP0_STATE_GD_EP1_ONLY_0: + DBG_SETUP1("EP0_STATE_GD_EP1_ONLY_0\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo(((u8 *)&(otg.desc.ep2))+0, ENDPOINT_DESC_SIZE); +#else + s3c_usb_ctrl_inep_setdma(((u8 *)&(otg.desc.ep2))+0, ENDPOINT_DESC_SIZE); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + /* GET_DESCRIPTOR:STRING */ + case EP0_STATE_GD_STR_I0: + DBG_SETUP1("EP0_STATE_GD_STR_I0\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc0)); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)string_desc0, sizeof(string_desc0)); +#else + s3c_usb_ctrl_inep_setdma((u8 *)string_desc0, sizeof(string_desc0)); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + case EP0_STATE_GD_STR_I1: + DBG_SETUP1("EP0_STATE_GD_STR_I1 %d\n", otg.ep0_substate); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, string_desc1_size); + if ((otg.ep0_substate*otg.ctrl_max_pktsize+otg.ctrl_max_pktsize) + < string_desc1_size) { + + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)string_desc1+(otg.ep0_substate*otg.ctrl_max_pktsize), + otg.ctrl_max_pktsize); + otg.ep0_state = EP0_STATE_GD_STR_I1; + otg.ep0_substate++; + } else { + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)string_desc1+(otg.ep0_substate*otg.ctrl_max_pktsize), + string_desc1_size-(otg.ep0_substate*otg.ctrl_max_pktsize)); + otg.ep0_state = EP0_STATE_INIT; + otg.ep0_substate = 0; + } +#else + s3c_usb_ctrl_inep_setdma((u8 *)string_desc1, string_desc1_size); + otg.ep0_state = EP0_STATE_INIT; +#endif + break; + + case EP0_STATE_GD_STR_I2: +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, string_desc2_size); + if ((otg.ep0_substate*otg.ctrl_max_pktsize+otg.ctrl_max_pktsize) + < string_desc2_size) { + + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)string_desc2+(otg.ep0_substate*otg.ctrl_max_pktsize), + otg.ctrl_max_pktsize); + otg.ep0_state = EP0_STATE_GD_STR_I2; + otg.ep0_substate++; + } else { + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)string_desc2+(otg.ep0_substate*otg.ctrl_max_pktsize), + string_desc2_size-(otg.ep0_substate*otg.ctrl_max_pktsize)); + otg.ep0_state = EP0_STATE_INIT; + otg.ep0_substate = 0; + } + DBG_SETUP1("EP0_STATE_GD_STR_I2 %d", otg.ep0_substate); +#else + s3c_usb_ctrl_inep_setdma((u8 *)string_desc2, string_desc2_size); + otg.ep0_state = EP0_STATE_INIT; +#endif + break; + + case EP0_STATE_GD_STR_I3: +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, string_desc3_size); + if ((otg.ep0_substate*otg.ctrl_max_pktsize+otg.ctrl_max_pktsize) + < string_desc3_size) { + + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)string_desc3+(otg.ep0_substate*otg.ctrl_max_pktsize), + otg.ctrl_max_pktsize); + otg.ep0_state = EP0_STATE_GD_STR_I3; + otg.ep0_substate++; + } else { + writel(EPEN_CNAK_EP0_64, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)string_desc3+(otg.ep0_substate*otg.ctrl_max_pktsize), + string_desc3_size-(otg.ep0_substate*otg.ctrl_max_pktsize)); + otg.ep0_state = EP0_STATE_INIT; + otg.ep0_substate = 0; + } +#else + s3c_usb_ctrl_inep_setdma((u8 *)string_desc3, string_desc3_size); + otg.ep0_state = EP0_STATE_INIT; +#endif + DBG_SETUP1("EP0_STATE_GD_STR_I3 %d", otg.ep0_substate); + break; + + case EP0_STATE_INTERFACE_GET: + DBG_SETUP1("EP0_STATE_INTERFACE_GET\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)&get_intf+0, 1); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&get_intf+0, 1); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + + case EP0_STATE_GET_STATUS0: + DBG_SETUP1("EP0_STATE_GET_STATUS0\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)&get_status+0, 1); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&get_status+0, 1); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + case EP0_STATE_GET_STATUS1: + DBG_SETUP1("EP0_STATE_GET_STATUS1\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)&get_status+1, 1); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&get_status+1, 1); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + case EP0_STATE_GET_STATUS2: + DBG_SETUP1("EP0_STATE_GET_STATUS2\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)&get_status+2, 1); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&get_status+2, 1); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + case EP0_STATE_GET_STATUS3: + DBG_SETUP1("EP0_STATE_GET_STATUS3\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)&get_status+3, 1); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&get_status+3, 1); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + case EP0_STATE_GET_STATUS4: + DBG_SETUP1("EP0_STATE_GET_STATUS4\n"); +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1); + writel(EPEN_CNAK_EP0_8, S5P_OTG_DIEPCTL0); + s3c_usb_write_ep0_fifo((u8 *)&get_status+4, 1); +#else + s3c_usb_ctrl_inep_setdma((u8 *)&get_status+4, 1); +#endif + otg.ep0_state = EP0_STATE_INIT; + break; + + default: + break; + } +} + + +void s3c_usb_int_bulkin(void) +{ + u8* bulkin_buf; + u32 remain_cnt; + + DBG_BULK0("Bulk In Function\n"); + + bulkin_buf = (u8*)otg.up_ptr; + remain_cnt = otg.up_size- ((u32)otg.up_ptr - otg.up_addr); + DBG_BULK1("bulkin_buf = 0x%x,remain_cnt = 0x%x \n", bulkin_buf, remain_cnt); + + if (remain_cnt > otg.bulkin_max_pktsize) { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1, otg.bulkin_max_pktsize); + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkin_max_pktsize<<0, + S5P_OTG_DIEPCTL_IN); + + s3c_usb_write_in_fifo(bulkin_buf, otg.bulkin_max_pktsize); + + otg.up_ptr += otg.bulkin_max_pktsize; + + while(readl(S5P_OTG_DIEPCTL_IN) & (1<<31)); + } else if(remain_cnt > 0) { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1, remain_cnt); + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkin_max_pktsize<<0, + S5P_OTG_DIEPCTL_IN); + + s3c_usb_write_in_fifo(bulkin_buf, remain_cnt); + + otg.up_ptr += remain_cnt; + + while(readl(S5P_OTG_DIEPCTL_IN) & (1<<31)); + } else { /*remain_cnt = 0*/ + writel((DEPCTL_SNAK|DEPCTL_BULK_TYPE), S5P_OTG_DIEPCTL_IN); + } +} + +void s3c_usb_upload_start(void) +{ +#ifdef CONFIG_USB_CPUMODE + u8 tmp_buf[12]; + u32 check; + + s3c_usb_read_out_fifo((u8 *)tmp_buf, 10); +#else + u32 check; +#endif + check = *((u8 *)(tmp_buf+8)) + (*((u8 *)(tmp_buf+9))<<8); + + if (check==0x1) { + otg.up_addr = + *((u8 *)(tmp_buf+0))+ + (*((u8 *)(tmp_buf+1))<<8)+ + (*((u8 *)(tmp_buf+2))<<16)+ + (*((u8 *)(tmp_buf+3))<<24); + + otg.up_size = + *((u8 *)(tmp_buf+4))+ + (*((u8 *)(tmp_buf+5))<<8)+ + (*((u8 *)(tmp_buf+6))<<16)+ + (*((u8 *)(tmp_buf+7))<<24); + + otg.up_ptr=(u8 *)otg.up_addr; + DBG_BULK1("UploadAddress : 0x%x, UploadSize: %d\n", + otg.up_addr, otg.up_size); + +#ifdef CONFIG_USB_CPUMODE + if (otg.op_mode == USB_CPU) { + if (otg.up_size > otg.bulkin_max_pktsize) { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1, + otg.bulkin_max_pktsize); + } else { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1, + otg.up_size); + } + + /*ep1 enable, clear nak, bulk, usb active, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkin_max_pktsize<<0, + S5P_OTG_DIEPCTL_IN); + } else if ((otg.op_mode == USB_DMA) && (otg.up_size > 0)) { + u32 pktcnt, remainder; + + DBG_BULK1("Dma Start for IN PKT \n"); + + writel(MODE_DMA|BURST_INCR4|GBL_INT_UNMASK, + S5P_OTG_GAHBCFG); + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP| INT_ENUMDONE| + INT_RESET|INT_SUSPEND, S5P_OTG_GINTMSK); + + writel((u32)otg.up_ptr, S5P_OTG_DIEPDMA_IN); + + pktcnt = (u32)(otg.up_size/otg.bulkin_max_pktsize); + remainder = (u32)(otg.up_size%otg.bulkin_max_pktsize); + if(remainder != 0) { + pktcnt += 1; + } + + if (pktcnt > 1023) { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1023, + (otg.bulkin_max_pktsize*1023)); + } else { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt, + otg.up_size); + } + + /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */ + writel(1u<<31|1<<26|2<<18|1<<15|BULK_IN_EP<<11| + otg.bulkin_max_pktsize<<0, + S5P_OTG_DIEPCTL_IN); +#else + if (otg.up_size > 0) { + DBG_BULK1("Dma Start for IN PKT \n"); + if(otg.up_size<BULK_XFER_SIZE) + written_bytes = otg.up_size; + else + written_bytes = BULK_XFER_SIZE; + s3c_usb_bulk_inep_setdma(otg.up_ptr, written_bytes); +#endif + } + } + otg.dn_filesize=0; +} + +#ifdef CONFIG_USB_CPUMODE + +void s3c_usb_download_start(u32 fifo_cnt_byte) +{ + u8 tmp_buf[8]; + + s3c_usb_read_out_fifo((u8 *)tmp_buf, 8); + DBG_BULK1("downloadFileSize==0, 1'st BYTE_READ_CNT_REG : %x\n", + fifo_cnt_byte); + + otg.dn_addr=s3c_usbd_dn_addr; + otg.dn_filesize= + *((u8 *)(tmp_buf+4))+ + (*((u8 *)(tmp_buf+5))<<8)+ + (*((u8 *)(tmp_buf+6))<<16)+ + (*((u8 *)(tmp_buf+7))<<24); + + otg.dn_ptr=(u8 *)otg.dn_addr; + DBG_BULK1("downloadAddress : 0x%x, downloadFileSize: %x\n", + otg.dn_addr, otg.dn_filesize); + + /* The first 8-bytes are deleted.*/ + s3c_usb_read_out_fifo((u8 *)otg.dn_ptr, fifo_cnt_byte-8); + otg.dn_ptr += fifo_cnt_byte-8; + + if (otg.op_mode == USB_CPU) { + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, 1, + otg.bulkout_max_pktsize); + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkout_max_pktsize<<0, + S5P_OTG_DOEPCTL_OUT); + } else if (otg.dn_filesize>otg.bulkout_max_pktsize) { + u32 pkt_cnt, remain_cnt; + + DBG_BULK1("downloadFileSize!=0, Dma Start for 2nd OUT PKT \n"); + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE| + INT_RESET|INT_SUSPEND, S5P_OTG_GINTMSK); /*gint unmask */ + writel(MODE_DMA|BURST_INCR4|GBL_INT_UNMASK, + S5P_OTG_GAHBCFG); + writel((u32)otg.dn_ptr, S5P_OTG_DOEPDMA_OUT); + pkt_cnt = (u32)(otg.dn_filesize-otg.bulkout_max_pktsize)/otg.bulkout_max_pktsize; + remain_cnt = (u32)((otg.dn_filesize-otg.bulkout_max_pktsize)%otg.bulkout_max_pktsize); + if(remain_cnt != 0) { + pkt_cnt += 1; + } + + if (pkt_cnt > 1023) { + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, 1023, + (otg.bulkout_max_pktsize*1023)); + } else { + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, pkt_cnt, + (otg.dn_filesize-otg.bulkout_max_pktsize)); + } + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkout_max_pktsize<<0, + S5P_OTG_DOEPCTL_OUT); + } +} + +void s3c_usb_download_continue(u32 fifo_cnt_byte) +{ + if (otg.op_mode == USB_CPU) { + s3c_usb_read_out_fifo((u8 *)otg.dn_ptr, fifo_cnt_byte); + otg.dn_ptr += fifo_cnt_byte; + DBG_BULK1("downloadFileSize!=0, 2nd BYTE_READ_CNT_REG = 0x%x, m_pDownPt = 0x%x\n", + fifo_cnt_byte, otg.dn_ptr); + + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, 1, otg.bulkout_max_pktsize); + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkout_max_pktsize<<0, + S5P_OTG_DOEPCTL_OUT); + + /* USB format : addr(4)+size(4)+data(n)+cs(2) */ + if (((u32)otg.dn_ptr - otg.dn_addr) >= (otg.dn_filesize - 8)) { + printf("Download Done!! Download Address: 0x%x, Download Filesize:0x%x\n", + otg.dn_addr, (otg.dn_filesize-10)); + + s3c_usbd_dn_cnt = otg.dn_filesize-10; + s3c_usbd_dn_addr = otg.dn_addr; + +#ifdef USB_CHECKSUM_EN + s3c_usb_verify_checksum(); +#endif + s3c_receive_done = 1; + } + + }\ +} + +void s3c_usb_int_bulkout(u32 fifo_cnt_byte) +{ + DBG_BULK0("Bulk Out Function : otg.dn_filesize=0x%x\n", otg.dn_filesize); + if (otg.dn_filesize==0) { + if (fifo_cnt_byte == 10) { + s3c_usb_upload_start(); + } else { + s3c_usb_download_start(fifo_cnt_byte); + } + } else { + s3c_usb_download_continue(fifo_cnt_byte); + } +} +#else +void s3c_usb_download_start(void) +{ + otg.dn_addr=s3c_usbd_dn_addr; + otg.dn_filesize= + *((u8 *)(tmp_buf+4))+ + (*((u8 *)(tmp_buf+5))<<8)+ + (*((u8 *)(tmp_buf+6))<<16)+ + (*((u8 *)(tmp_buf+7))<<24); + + otg.dn_ptr=(u8 *)otg.dn_addr; + DBG_BULK1("downloadAddress : 0x%x, downloadFileSize: %x\n", + otg.dn_addr, otg.dn_filesize); + + + memcpy((u8 *)otg.dn_ptr, (u8 *)(tmp_buf+8), HS_BULK_PKT_SIZE - 8); + /* The first 8-bytes are deleted.*/ + otg.dn_ptr += HS_BULK_PKT_SIZE - 8; + + /* USB format : addr(4)+size(4)+data(n)+cs(2) */ + if (otg.dn_filesize>((u32)otg.dn_ptr - otg.dn_addr + 8)) { + s3c_usb_bulk_outep_setdma((u8 *)otg.dn_ptr, BULK_XFER_SIZE); + } + else { +#ifdef USB_CHECKSUM_EN + s3c_usb_verify_checksum(); +#endif + s3c_receive_done = 1; + printf("Download Done!! Download Address: 0x%x, Download Filesize:0x%x\n", + otg.dn_addr, (otg.dn_filesize-10)); + } +} + +void s3c_usb_download_continue(void) +{ + + u32 xfer_size; + + xfer_size = readl(S5P_OTG_DOEPTSIZ_OUT) & 0x7FFF; + otg.dn_ptr += (BULK_XFER_SIZE - xfer_size); + + /* USB format : addr(4)+size(4)+data(n)+cs(2) */ + if (otg.dn_filesize>((u32)otg.dn_ptr - otg.dn_addr + 8)) + s3c_usb_bulk_outep_setdma((u8 *)otg.dn_ptr, BULK_XFER_SIZE); + else { +#ifdef USB_CHECKSUM_EN + s3c_usb_verify_checksum(); +#endif + s3c_receive_done = 1; + printf("Download Done!! Download Address: 0x%x, Download Filesize:0x%x\n", + otg.dn_addr, (otg.dn_filesize-10)); + } +} + +void s3c_usb_int_bulkout(void) +{ + u32 xfer_size; + DBG_BULK0("Bulk Out Function : otg.dn_filesize=0x%x\n", otg.dn_filesize); + + xfer_size = readl(S5P_OTG_DOEPTSIZ_OUT) & 0x7FFF; + if (otg.dn_filesize==0) { + if (xfer_size == 0x1F6) { + s3c_usb_upload_start(); + } else { + s3c_usb_download_start(); + } + } else { + s3c_usb_download_continue(); + } +} +#endif + +void s3c_usb_dma_in_done(void) +{ + s32 remain_cnt; + + DBG_BULK0("DMA IN : Transfer Done\n"); + + otg.up_ptr = (u8 *)readl(S5P_OTG_DIEPDMA_IN); + remain_cnt = otg.up_size- ((u32)otg.up_ptr - otg.up_addr); + + if (remain_cnt>0) { + u32 pktcnt, remainder; + pktcnt = (u32)(remain_cnt/otg.bulkin_max_pktsize); + remainder = (u32)(remain_cnt%otg.bulkin_max_pktsize); + if(remainder != 0) { + pktcnt += 1; + } + DBG_SETUP1("remain_cnt : %d \n", remain_cnt); + if (pktcnt> 1023) { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1023, + (otg.bulkin_max_pktsize*1023)); + } else { + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt, + remain_cnt); + } + + /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */ + writel(1u<<31|1<<26|2<<18|1<<15|BULK_IN_EP<<11|otg.bulkin_max_pktsize<<0, + S5P_OTG_DIEPCTL_IN); + } else + DBG_SETUP1("DMA IN : Transfer Complete\n"); +} + +#ifdef CONFIG_USB_CPUMODE +void s3c_usb_dma_out_done(void) +{ + s32 remain_cnt; + + DBG_BULK1("DMA OUT : Transfer Done\n"); + otg.dn_ptr = (u8 *)readl(S5P_OTG_DOEPDMA_OUT); + + remain_cnt = otg.dn_filesize - ((u32)otg.dn_ptr - otg.dn_addr + 8); + + if (remain_cnt>0) { + u32 pktcnt, remainder; + pktcnt = (u32)(remain_cnt/otg.bulkout_max_pktsize); + remainder = (u32)(remain_cnt%otg.bulkout_max_pktsize); + if(remainder != 0) { + pktcnt += 1; + } + DBG_BULK1("remain_cnt : %d \n", remain_cnt); + if (pktcnt> 1023) { + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, 1023, + (otg.bulkout_max_pktsize*1023)); + } else { + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, pktcnt, + remain_cnt); + } + + /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64*/ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkout_max_pktsize<<0, + S5P_OTG_DOEPCTL_OUT); + } else { + DBG_BULK1("DMA OUT : Transfer Complete\n"); + udelay(500); /*for FPGA ???*/ + } +} +#endif + +void s3c_usb_set_all_outep_nak(void) +{ + u8 i = 0; + u32 tmp; + + for(i=0;i<16;i++) + { + tmp = readl(S5P_OTG_DOEPCTL0+0x20*i); + tmp |= DEPCTL_SNAK; + writel(tmp, S5P_OTG_DOEPCTL0+0x20*i); + } +} + +void s3c_usb_clear_all_outep_nak(void) +{ + u8 i = 0; + u32 tmp; + + for(i=0;i<16;i++) + { + tmp = readl(S5P_OTG_DOEPCTL0+0x20*i); + tmp |= (DEPCTL_EPENA|DEPCTL_CNAK); + writel(tmp, S5P_OTG_DOEPCTL0+0x20*i); + } +} + +void s3c_usb_set_max_pktsize(USB_SPEED speed) +{ + if (speed == USB_HIGH) + { + otg.speed = USB_HIGH; + otg.ctrl_max_pktsize = HS_CTRL_PKT_SIZE; + otg.bulkin_max_pktsize = HS_BULK_PKT_SIZE; + otg.bulkout_max_pktsize = HS_BULK_PKT_SIZE; + } + else + { + otg.speed = USB_FULL; + otg.ctrl_max_pktsize = FS_CTRL_PKT_SIZE; + otg.bulkin_max_pktsize = FS_BULK_PKT_SIZE; + otg.bulkout_max_pktsize = FS_BULK_PKT_SIZE; + } +} + +void s3c_usb_set_endpoint(void) +{ + /* Unmask S5P_OTG_DAINT source */ + writel(0xff, S5P_OTG_DIEPINT0); + writel(0xff, S5P_OTG_DOEPINT0); + writel(0xff, S5P_OTG_DIEPINT_IN); + writel(0xff, S5P_OTG_DOEPINT_OUT); + + /* Init For Ep0*/ +#ifdef CONFIG_USB_CPUMODE + /*MPS:64bytes */ + writel(((1<<26)|(CONTROL_EP<<11)|(0<<0)), S5P_OTG_DIEPCTL0); + /*ep0 enable, clear nak */ + writel((1u<<31)|(1<<26)|(0<<0), S5P_OTG_DOEPCTL0); +#else + if(otg.speed == USB_HIGH) + { + /*MPS:64bytes */ + writel(((1<<26)|(CONTROL_EP<<11)|(0<<0)), S5P_OTG_DIEPCTL0); + s3c_usb_prepare_setup_pkt(); + } + else + { + /*MPS:8bytes */ + writel(((1<<26)|(CONTROL_EP<<11)|(3<<0)), S5P_OTG_DIEPCTL0); + /*ep0 enable, clear nak */ + writel((1u<<31)|(1<<26)|(3<<0), S5P_OTG_DOEPCTL0); + } +#endif +} + +void s3c_usb_set_descriptors(void) +{ + /* Standard device descriptor */ + otg.desc.dev.bLength=DEVICE_DESC_SIZE; /*0x12*/ + otg.desc.dev.bDescriptorType=DEVICE_DESCRIPTOR; + otg.desc.dev.bDeviceClass=0xFF; /* 0x0*/ + otg.desc.dev.bDeviceSubClass=0x0; + otg.desc.dev.bDeviceProtocol=0x0; + otg.desc.dev.bMaxPacketSize0=otg.ctrl_max_pktsize; + otg.desc.dev.idVendorL=0xE8; /*0x45;*/ + otg.desc.dev.idVendorH=0x04; /*0x53;*/ +#ifdef CONFIG_DNW_VERSION + if(g_dnw_version >= DNW_v10) { + otg.desc.dev.idProductL=0x09; + otg.desc.dev.idProductH=0x29; + } + else +#endif /* CONFIG_DNW_VERSION */ + { + otg.desc.dev.idProductL=0x34; /*0x00*/ + otg.desc.dev.idProductH=0x12; /*0x64*/ + } + otg.desc.dev.bcdDeviceL=0x00; + otg.desc.dev.bcdDeviceH=0x01; + otg.desc.dev.iManufacturer=0x1; /* index of string descriptor */ + otg.desc.dev.iProduct=0x2; /* index of string descriptor */ +#ifdef CONFIG_DNW_VERSION + if(g_dnw_version >= DNW_v05) + otg.desc.dev.iSerialNumber=0x3; + else +#endif /* CONFIG_DNW_VERSION */ + otg.desc.dev.iSerialNumber=0x0; + otg.desc.dev.bNumConfigurations=0x1; + if (otg.speed == USB_FULL) { + otg.desc.dev.bcdUSBL=0x10; + otg.desc.dev.bcdUSBH=0x01; /* Ver 1.10*/ + } + else { + otg.desc.dev.bcdUSBL=0x00; + otg.desc.dev.bcdUSBH=0x02; /* Ver 2.0*/ + } + + /* Standard configuration descriptor */ + otg.desc.config.bLength=CONFIG_DESC_SIZE; /* 0x9 bytes */ + otg.desc.config.bDescriptorType=CONFIGURATION_DESCRIPTOR; + otg.desc.config.wTotalLengthL=CONFIG_DESC_TOTAL_SIZE; + otg.desc.config.wTotalLengthH=0; + otg.desc.config.bNumInterfaces=1; +/* dbg descConf.bConfigurationValue=2; // why 2? There's no reason.*/ + otg.desc.config.bConfigurationValue=1; + otg.desc.config.iConfiguration=0; + otg.desc.config.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED; /* bus powered only.*/ + otg.desc.config.maxPower=25; /* draws 50mA current from the USB bus.*/ + + /* Standard interface descriptor */ + otg.desc.intf.bLength=INTERFACE_DESC_SIZE; /* 9*/ + otg.desc.intf.bDescriptorType=INTERFACE_DESCRIPTOR; + otg.desc.intf.bInterfaceNumber=0x0; + otg.desc.intf.bAlternateSetting=0x0; /* ?*/ + otg.desc.intf.bNumEndpoints = 2; /* # of endpoints except EP0*/ + otg.desc.intf.bInterfaceClass=0xff; /* 0x0 ?*/ + otg.desc.intf.bInterfaceSubClass=0x0; + otg.desc.intf.bInterfaceProtocol=0x0; + otg.desc.intf.iInterface=0x0; + + /* Standard endpoint0 descriptor */ + otg.desc.ep1.bLength=ENDPOINT_DESC_SIZE; + otg.desc.ep1.bDescriptorType=ENDPOINT_DESCRIPTOR; + otg.desc.ep1.bEndpointAddress=BULK_IN_EP|EP_ADDR_IN; + otg.desc.ep1.bmAttributes=EP_ATTR_BULK; + otg.desc.ep1.wMaxPacketSizeL=(u8)otg.bulkin_max_pktsize; /* 64*/ + otg.desc.ep1.wMaxPacketSizeH=(u8)(otg.bulkin_max_pktsize>>8); + otg.desc.ep1.bInterval=0x0; /* not used */ + + /* Standard endpoint1 descriptor */ + otg.desc.ep2.bLength=ENDPOINT_DESC_SIZE; + otg.desc.ep2.bDescriptorType=ENDPOINT_DESCRIPTOR; + otg.desc.ep2.bEndpointAddress=BULK_OUT_EP|EP_ADDR_OUT; + otg.desc.ep2.bmAttributes=EP_ATTR_BULK; + otg.desc.ep2.wMaxPacketSizeL=(u8)otg.bulkout_max_pktsize; /* 64*/ + otg.desc.ep2.wMaxPacketSizeH=(u8)(otg.bulkout_max_pktsize>>8); + otg.desc.ep2.bInterval=0x0; /* not used */ +} + +void s3c_usb_check_speed(USB_SPEED *speed) +{ + u32 status; + + status = readl(S5P_OTG_DSTS); /* System status read */ + + *speed = (USB_SPEED)((status&0x6) >>1); +} + +void s3c_usb_clear_dnfile_info(void) +{ + otg.dn_addr = 0; + otg.dn_filesize = 0; + otg.dn_ptr = 0; +} + +void s3c_usb_clear_upfile_info(void) +{ + otg.up_addr= 0; + otg.up_size= 0; + otg.up_ptr = 0; +} + + +int s3c_usb_check_setconf(void) +{ + if (otg.set_config == 0) + return FALSE; + else + return TRUE; +} + +void s3c_usb_set_opmode(USB_OPMODE mode) +{ + otg.op_mode = mode; + +#ifdef CONFIG_USB_CPUMODE + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE| + INT_RESET|INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY, + S5P_OTG_GINTMSK); /*gint unmask */ + + writel(MODE_SLAVE|BURST_SINGLE|GBL_INT_UNMASK, S5P_OTG_GAHBCFG); + + s3c_usb_set_outep_xfersize(EP_TYPE_BULK, 1, otg.bulkout_max_pktsize); + s3c_usb_set_inep_xfersize(EP_TYPE_BULK, 1, 0); + + /*bulk out ep enable, clear nak, bulk, usb active, next ep3, max pkt */ + writel(1u<<31|1<<26|2<<18|1<<15|otg.bulkout_max_pktsize<<0, + S5P_OTG_DOEPCTL_OUT); + + /*bulk in ep enable, clear nak, bulk, usb active, next ep1, max pkt */ + writel(0u<<31|1<<26|2<<18|1<<15|otg.bulkin_max_pktsize<<0, + S5P_OTG_DIEPCTL_IN); +#else + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE| + INT_RESET|INT_SUSPEND, + S5P_OTG_GINTMSK); /*gint unmask */ + + writel(PTXFE_HALF|NPTXFE_HALF|MODE_DMA|BURST_INCR4|GBL_INT_UNMASK, S5P_OTG_GAHBCFG); +#endif +} + +void s3c_usb_reset(void) +{ + s3c_usb_set_all_outep_nak(); + + otg.ep0_state = EP0_STATE_INIT; + writel(((1<<BULK_OUT_EP)|(1<<CONTROL_EP))<<16|((1<<BULK_IN_EP)|(1<<CONTROL_EP)), + S5P_OTG_DAINTMSK); + writel(CTRL_OUT_EP_SETUP_PHASE_DONE|AHB_ERROR|TRANSFER_DONE, + S5P_OTG_DOEPMSK); + writel(INTKN_TXFEMP|NON_ISO_IN_EP_TIMEOUT|AHB_ERROR|TRANSFER_DONE, + S5P_OTG_DIEPMSK); + + /* Rx FIFO Size */ + writel(RX_FIFO_SIZE, S5P_OTG_GRXFSIZ); + + /* Non Periodic Tx FIFO Size */ + writel(NPTX_FIFO_SIZE<<16| NPTX_FIFO_START_ADDR<<0, S5P_OTG_GNPTXFSIZ); +#ifndef CONFIG_USB_CPUMODE + writel(PTX_FIFO_SIZE<<16|(NPTX_FIFO_START_ADDR+NPTX_FIFO_SIZE)<<0, S5P_OTG_DPTXFSIZ1); +#endif + + s3c_usb_clear_all_outep_nak(); + + /*clear device address */ + writel(readl(S5P_OTG_DCFG)&~(0x7f<<4), S5P_OTG_DCFG); + + if(SUSPEND_RESUME_ON) { + writel(readl(S5P_OTG_PCGCCTL)&~(1<<0), S5P_OTG_PCGCCTL); + } +} +int s3c_usb_set_init(void) +{ + u32 status; + + status = readl(S5P_OTG_DSTS); /* System status read */ + + /* Set if Device is High speed or Full speed */ + if (((status&0x6) >>1) == USB_HIGH) { + DBG_SETUP1("High Speed Detection\n"); + s3c_usb_set_max_pktsize(USB_HIGH); + } + else if(((status&0x6) >>1) == USB_FULL) { + DBG_SETUP1("Full Speed Detec tion\n"); + s3c_usb_set_max_pktsize(USB_FULL); + } + else { + printf("**** Error:Neither High_Speed nor Full_Speed\n"); + return FALSE; + } + + s3c_usb_set_endpoint(); + if (is_fastboot +#ifdef CONFIG_DNW_VERSION + && (DNW_v05 != g_dnw_version) +#endif /* CONFIG_DNW_VERSION */ + ) + fboot_usb_set_descriptors(); + else + s3c_usb_set_descriptors(); + s3c_usb_clear_dnfile_info(); + s3c_usb_set_opmode(op_mode); + + return TRUE; +} + +#ifdef CONFIG_USB_CPUMODE +void s3c_usb_pkt_receive(void) +{ + u32 rx_status; + u32 fifo_cnt_byte; + + rx_status = readl(S5P_OTG_GRXSTSP); + DBG_SETUP0("S5P_OTG_GRXSTSP = 0x%x\n", rx_status); + + if ((rx_status & (0xf<<17)) == SETUP_PKT_RECEIVED) { + DBG_SETUP1("SETUP_PKT_RECEIVED\n"); + s3c_usb_ep0_int_hndlr(); + + } else if ((rx_status & (0xf<<17)) == OUT_PKT_RECEIVED) { + fifo_cnt_byte = (rx_status & 0x7ff0)>>4; + DBG_SETUP1("OUT_PKT_RECEIVED\n"); + + if((rx_status & BULK_OUT_EP)&&(fifo_cnt_byte)) { + if (is_fastboot) + fboot_usb_int_bulkout(fifo_cnt_byte); + else + s3c_usb_int_bulkout(fifo_cnt_byte); + if( otg.op_mode == USB_CPU ) + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP| + INT_ENUMDONE|INT_RESET|INT_SUSPEND| + INT_RX_FIFO_NOT_EMPTY, + S5P_OTG_GINTMSK); + return; + } + + } else if ((rx_status & (0xf<<17)) == GLOBAL_OUT_NAK) { + DBG_SETUP1("GLOBAL_OUT_NAK\n"); + + } else if ((rx_status & (0xf<<17)) == OUT_TRNASFER_COMPLETED) { + DBG_SETUP1("OUT_TRNASFER_COMPLETED\n"); + + } else if ((rx_status & (0xf<<17)) == SETUP_TRANSACTION_COMPLETED) { + DBG_SETUP1("SETUP_TRANSACTION_COMPLETED\n"); + + } else { + DBG_SETUP1("Reserved\n"); + } +} +#endif + +void s3c_usb_transfer(void) +{ + u32 ep_int; + u32 check_dma; + u32 ep_int_status; + + ep_int = readl(S5P_OTG_DAINT); + DBG_SETUP0("S5P_OTG_DAINT = 0x%x", ep_int); + + if (ep_int & (1<<CONTROL_EP)) { + ep_int_status = readl(S5P_OTG_DIEPINT0); + DBG_SETUP1("S5P_OTG_DIEPINT0 : %x \n", ep_int_status); + +#ifdef CONFIG_USB_CPUMODE + if (ep_int_status & INTKN_TXFEMP) { + u32 uNTxFifoSpace; + do { + uNTxFifoSpace=readl(S5P_OTG_GNPTXSTS)&0xffff; + }while(uNTxFifoSpace<otg.ctrl_max_pktsize); + + s3c_usb_transfer_ep0(); +#else + if(ep_int_status & TRANSFER_DONE) { + s3c_usb_prepare_setup_pkt(); +#endif + } + + writel(ep_int_status, S5P_OTG_DIEPINT0); /* Interrupt Clear */ + } else if (ep_int & ((1<<CONTROL_EP)<<16)) { + ep_int_status = readl(S5P_OTG_DOEPINT0); + DBG_SETUP1("S5P_OTG_DOEPINT0 : %x \n", ep_int_status); + +#ifdef CONFIG_USB_CPUMODE + s3c_usb_set_outep_xfersize(EP_TYPE_CONTROL, 1, 8); + writel(1u<<31|1<<26, S5P_OTG_DOEPCTL0); /*ep0 enable, clear nak */ + +#else + if(ep_int_status & CTRL_OUT_EP_SETUP_PHASE_DONE) { + s3c_usb_ep0_int_hndlr(); + } + if(ep_int_status & TRANSFER_DONE) { + s3c_usb_prepare_setup_pkt(); + } +#endif + writel(ep_int_status, S5P_OTG_DOEPINT0); /* Interrupt Clear */ + } else if(ep_int & (1<<BULK_IN_EP)) { + ep_int_status = readl(S5P_OTG_DIEPINT_IN); + DBG_BULK1("S5P_OTG_DIEPINT_IN : %x \n", ep_int_status); + writel(ep_int_status, S5P_OTG_DIEPINT_IN); /* Interrupt Clear */ + +#ifdef CONFIG_USB_CPUMODE + if ( (ep_int_status&INTKN_TXFEMP) && otg.op_mode == USB_CPU) { + if (is_fastboot) + fboot_usb_int_bulkin(); +#ifdef CONFIG_DNW_VERSION + else if(DNW_v10 == g_dnw_version) + dnw_usb_handle_ep_in_xfer_complete(); +#endif /* CONFIG_DNW_VERSION */ + else + s3c_usb_int_bulkin(); + } + + check_dma = readl(S5P_OTG_GAHBCFG); + if ((check_dma&MODE_DMA)&&(ep_int_status&TRANSFER_DONE)) + s3c_usb_dma_in_done(); +#else + check_dma = readl(S5P_OTG_GAHBCFG); + if ((check_dma&MODE_DMA)&&(ep_int_status&TRANSFER_DONE)) { + if (is_fastboot) { + u8 is_done; + + fboot_response_flag=0; + is_done = readl(S5P_OTG_DIEPCTL_IN) >> 31; + if (is_fboot_ramdump && !is_done) + fastboot_tx_continue(); + } else + s3c_usb_upload_continue(); + } +#endif + } else if (ep_int & ((1<<BULK_OUT_EP)<<16)) { + ep_int_status = readl(S5P_OTG_DOEPINT_OUT); + DBG_BULK1("S5P_OTG_DOEPINT_OUT : 0x%x\n", ep_int_status); + writel(ep_int_status, S5P_OTG_DOEPINT_OUT); /* Interrupt Clear */ + + check_dma = readl(S5P_OTG_GAHBCFG); + if ((check_dma&MODE_DMA)&&(ep_int_status&TRANSFER_DONE)) { +#ifdef CONFIG_USB_CPUMODE + s3c_usb_dma_out_done(); +#else + if (is_fastboot) + fboot_usb_int_bulkout(); +#ifdef CONFIG_DNW_VERSION + else if(DNW_v10 == g_dnw_version) + dnw_usb_handle_ep_out_xfer_complete(); +#endif /* CONFIG_DNW_VERION */ + else + s3c_usb_int_bulkout(); +#endif + } + } +} + +int s3c_udc_int_hndlr(void) +{ + u32 int_status; + int tmp; + int ret = -1; //ERROR; + + int_status = readl(S5P_OTG_GINTSTS); /* Core Interrupt Register */ + writel(int_status, S5P_OTG_GINTSTS); /* Interrupt Clear */ + DBG_SETUP0("*** USB OTG Interrupt(S5P_OTG_GINTSTS: 0x%08x) ****\n", + int_status); + + if (int_status & INT_RESET) { + DBG_SETUP1("INT_RESET\n"); + writel(INT_RESET, S5P_OTG_GINTSTS); /* Interrupt Clear */ + + s3c_usb_reset(); + ret = 0;//OK; + } + + if (int_status & INT_ENUMDONE) { + DBG_SETUP1("INT_ENUMDONE :"); + writel(INT_ENUMDONE, S5P_OTG_GINTSTS); /* Interrupt Clear */ + + tmp = s3c_usb_set_init(); + ret = 0;//OK; + if (tmp == FALSE) + return ret; + } + + if (int_status & INT_RESUME) { + DBG_SETUP1("INT_RESUME\n"); + writel(INT_RESUME, S5P_OTG_GINTSTS); /* Interrupt Clear */ + + if(SUSPEND_RESUME_ON) { + writel(readl(S5P_OTG_PCGCCTL)&~(1<<0), S5P_OTG_PCGCCTL); + DBG_SETUP1("INT_RESUME\n"); + } + ret = 0;//OK; + } + + if (int_status & INT_SUSPEND) { + DBG_SETUP1("INT_SUSPEND\n"); + writel(INT_SUSPEND, S5P_OTG_GINTSTS); /* Interrupt Clear */ + + if(SUSPEND_RESUME_ON) { + writel(readl(S5P_OTG_PCGCCTL)|(1<<0), S5P_OTG_PCGCCTL); + } + ret = 0;//OK; + } + +#ifdef CONFIG_USB_CPUMODE + if(int_status & INT_RX_FIFO_NOT_EMPTY) { + DBG_SETUP1("INT_RX_FIFO_NOT_EMPTY\n"); + /* Read only register field */ + + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP| + INT_ENUMDONE|INT_RESET|INT_SUSPEND, + S5P_OTG_GINTMSK); + s3c_usb_pkt_receive(); + writel(INT_RESUME|INT_OUT_EP|INT_IN_EP|INT_ENUMDONE| + INT_RESET |INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY, + S5P_OTG_GINTMSK); /*gint unmask */ + ret = 0;//OK; + } +#endif + + if ((int_status & INT_IN_EP) || (int_status & INT_OUT_EP)) { + DBG_SETUP1("INT_IN or OUT_EP\n"); + /* Read only register field */ + + s3c_usb_transfer(); + ret = 0;//OK; + } + return ret; +} + +#endif diff --git a/drivers/usb/gadget/usbd-otg-hs.h b/drivers/usb/gadget/usbd-otg-hs.h new file mode 100644 index 000000000..f8d460eeb --- /dev/null +++ b/drivers/usb/gadget/usbd-otg-hs.h @@ -0,0 +1,306 @@ +/* + * cpu/s5pc1xx/usbd-otg-hs.h + * + * (C) Copyright 2009 + * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com. + * - only support for S5PC100 + * + * 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 __S3C_OTG_HS_H__ +#define __S3C_OTG_HS_H__ + +#include <asm/byteorder.h> +#include <asm/arch/cpu.h> +#include <asm/io.h> + +#define S3C_USBD_DETECT_IRQ() (readl(S5P_OTG_GINTSTS) & \ + (GINTSTS_WkUpInt|GINTSTS_OEPInt|GINTSTS_IEPInt| \ + GINTSTS_EnumDone|GINTSTS_USBRst|GINTSTS_USBSusp|GINTSTS_RXFLvl)) +#define S3C_USBD_CLEAR_IRQ() do { \ + writel(BIT_ALLMSK, (S5P_OTG_GINTSTS)); \ + } while (0) + +#define CONTROL_EP 0 +#define BULK_IN_EP 1 +#define BULK_OUT_EP 2 + +#define FS_CTRL_PKT_SIZE 64 +#define FS_BULK_PKT_SIZE 64 + +#define HS_CTRL_PKT_SIZE 64 +#define HS_BULK_PKT_SIZE 512 + +#define RX_FIFO_SIZE 512 +#define NPTX_FIFO_START_ADDR RX_FIFO_SIZE +#define NPTX_FIFO_SIZE 512 +#define PTX_FIFO_SIZE 512 + +// string descriptor +#define LANGID_US_L (0x09) +#define LANGID_US_H (0x04) + +// Feature Selectors +#define EP_STALL 0 +#define DEVICE_REMOTE_WAKEUP 1 +#define TEST_MODE 2 + +/* Test Mode Selector*/ +#define TEST_J 1 +#define TEST_K 2 +#define TEST_SE0_NAK 3 +#define TEST_PACKET 4 +#define TEST_FORCE_ENABLE 5 + +#define S5P_OTG_DIEPCTL_IN (S5P_OTG_DIEPCTL0 + 0x20*BULK_IN_EP) +#define S5P_OTG_DIEPINT_IN (S5P_OTG_DIEPINT0 + 0x20*BULK_IN_EP) +#define S5P_OTG_DIEPTSIZ_IN (S5P_OTG_DIEPTSIZ0 + 0x20*BULK_IN_EP) +#define S5P_OTG_DIEPDMA_IN (S5P_OTG_DIEPDMA0 + 0x20*BULK_IN_EP) +#define S5P_OTG_DOEPCTL_OUT (S5P_OTG_DOEPCTL0 + 0x20*BULK_OUT_EP) +#define S5P_OTG_DOEPINT_OUT (S5P_OTG_DOEPINT0 + 0x20*BULK_OUT_EP) +#define S5P_OTG_DOEPTSIZ_OUT (S5P_OTG_DOEPTSIZ0 + 0x20*BULK_OUT_EP) +#define S5P_OTG_DOEPDMA_OUT (S5P_OTG_DOEPDMA0 + 0x20*BULK_OUT_EP) +#define S5P_OTG_IN_FIFO (S5P_OTG_EP0_FIFO + 0x1000*BULK_IN_EP) +#define S5P_OTG_OUT_FIFO (S5P_OTG_EP0_FIFO + 0x1000*BULK_OUT_EP) + + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bcdUSBL; + u8 bcdUSBH; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u8 idVendorL; + u8 idVendorH; + u8 idProductL; + u8 idProductH; + u8 bcdDeviceL; + u8 bcdDeviceH; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} __attribute__ ((packed)) device_desc_t; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 wTotalLengthL; + u8 wTotalLengthH; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u8 maxPower; +} __attribute__ ((packed)) config_desc_t; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + u8 iInterface; +} __attribute__ ((packed)) intf_desc_t; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bEndpointAddress; + u8 bmAttributes; + u8 wMaxPacketSizeL; + u8 wMaxPacketSizeH; + u8 bInterval; +} __attribute__ ((packed)) ep_desc_t; + +typedef struct +{ + u8 bmRequestType; + u8 bRequest; + u8 wValue_L; + u8 wValue_H; + u8 wIndex_L; + u8 wIndex_H; + u8 wLength_L; + u8 wLength_H; +} __attribute__ ((packed)) device_req_t; + +typedef struct +{ + device_desc_t dev; + config_desc_t config; + intf_desc_t intf; + ep_desc_t ep1; + ep_desc_t ep2; + ep_desc_t ep3; + ep_desc_t ep4; +} __attribute__ ((packed)) descriptors_t; + +typedef struct +{ + u8 Device; + u8 Interface; + u8 ep_ctrl; + u8 ep_in; + u8 ep_out; +} __attribute__ ((packed)) get_status_t; + +typedef struct +{ + u8 AlternateSetting; +} __attribute__ ((packed)) get_intf_t; + + +typedef enum +{ + USB_CPU, USB_DMA +} USB_OPMODE; + +typedef enum +{ + USB_HIGH, USB_FULL, USB_LOW +} USB_SPEED; + +typedef enum +{ + EP_TYPE_CONTROL, EP_TYPE_ISOCHRONOUS, EP_TYPE_BULK, EP_TYPE_INTERRUPT +} EP_TYPE; + + +typedef struct +{ + descriptors_t desc; + device_req_t dev_req; + + u32 ep0_state; + u32 ep0_substate; + USB_OPMODE op_mode; + USB_SPEED speed; + u32 ctrl_max_pktsize; + u32 bulkin_max_pktsize; + u32 bulkout_max_pktsize; + u32 dn_addr; + u32 dn_filesize; + u32 up_addr; + u32 up_size; + u8* dn_ptr; + u8* up_ptr; + u32 set_config; + u32 req_length; +} __attribute__ ((packed)) otg_dev_t; + +// SPEC1.1 + +// Standard bmRequestType (direction) +enum DEV_REQUEST_DIRECTION +{ + HOST_TO_DEVICE = 0x00, + DEVICE_TO_HOST = 0x80 +}; + +// Standard bmRequestType (Type) +enum DEV_REQUEST_TYPE +{ + STANDARD_TYPE = 0x00, + CLASS_TYPE = 0x20, + VENDOR_TYPE = 0x40, + RESERVED_TYPE = 0x60 +}; + +// Standard bmRequestType (Recipient) +enum DEV_REQUEST_RECIPIENT +{ + DEVICE_RECIPIENT = 0, + INTERFACE_RECIPIENT = 1, + ENDPOINT_RECIPIENT = 2, + OTHER_RECIPIENT = 3 +}; + +// Descriptor types +enum DESCRIPTOR_TYPE +{ + DEVICE_DESCRIPTOR = 1, + CONFIGURATION_DESCRIPTOR = 2, + STRING_DESCRIPTOR = 3, + INTERFACE_DESCRIPTOR = 4, + ENDPOINT_DESCRIPTOR = 5, + DEVICE_QUALIFIER = 6, + OTHER_SPEED_CONFIGURATION = 7, + INTERFACE_POWER = 8, +}; + +// configuration descriptor: bmAttributes +enum CONFIG_ATTRIBUTES +{ + CONF_ATTR_DEFAULT = 0x80, + CONF_ATTR_REMOTE_WAKEUP = 0x20, + CONF_ATTR_SELFPOWERED = 0x40 +}; + +// endpoint descriptor +enum ENDPOINT_ATTRIBUTES +{ + EP_ADDR_IN = 0x80, + EP_ADDR_OUT = 0x00, + + EP_ATTR_CONTROL = 0x0, + EP_ATTR_ISOCHRONOUS = 0x1, + EP_ATTR_BULK = 0x2, + EP_ATTR_INTERRUPT = 0x3 +}; + +// Standard bRequest codes +enum STANDARD_REQUEST_CODE +{ + STANDARD_GET_STATUS = 0, + STANDARD_CLEAR_FEATURE = 1, + STANDARD_RESERVED_1 = 2, + STANDARD_SET_FEATURE = 3, + STANDARD_RESERVED_2 = 4, + STANDARD_SET_ADDRESS = 5, + STANDARD_GET_DESCRIPTOR = 6, + STANDARD_SET_DESCRIPTOR = 7, + STANDARD_GET_CONFIGURATION = 8, + STANDARD_SET_CONFIGURATION = 9, + STANDARD_GET_INTERFACE = 10, + STANDARD_SET_INTERFACE = 11, + STANDARD_SYNCH_FRAME = 12 +}; + +int s3c_usbctl_init(void); +int s3c_usbc_activate (void); +int s3c_usb_stop( void ); +int s3c_udc_int_hndlr(void); + +/* in usbd-otg-hs.c */ +extern unsigned int s3c_usbd_dn_addr; +extern unsigned int s3c_usbd_dn_cnt; +extern int DNW; +extern int s3c_got_header; +extern int s3c_receive_done; + +#endif diff --git a/drivers/usb/gadget/usbd3-ss.c b/drivers/usb/gadget/usbd3-ss.c new file mode 100644 index 000000000..aeb6b7f6d --- /dev/null +++ b/drivers/usb/gadget/usbd3-ss.c @@ -0,0 +1,2639 @@ +/* + * drivers/usb/gadget/usbd3-ss.c + * + * (C) Copyright 2011 + * Yulgon Kim, Samsung Erectronics, yulgon.kim@samsung.com. + * - only support for EXYNOS5210 + * + * 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 <malloc.h> + +#if defined(CONFIG_ARCH_EXYNOS5) +#include <command.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include "usbd3-ss.h" + +#undef USBD3_DBG +#ifdef USBD3_DBG +#define DBG_USBD3(fmt, args...) DBG_USBD3("[%s:%d] " fmt, __FUNCTION__, __LINE__, ##args) +#else +#define DBG_USBD3(fmt, args...) do { } while (0) +#endif + +#define Assert(value) value ? : printf("[%s:%d] Assert(%d) \n", __func__, __LINE__, value) + +#define USBDEVICE3_LINK_BASE (oUsbDev3.m_uLinkBaseRegs) +#define USBDEVICE3_PHYCTRL_BASE (oUsbDev3.m_uPhyBaseRegs) + +// work around for overcurrent issue +// start +#define GPIO_LEFT_BASE 0x14000000 +#define rGPK2CON (GPIO_LEFT_BASE + 0x00E0) +#define rGPK2DAT (GPIO_LEFT_BASE + 0x00E4) +#define rGPK2PUD (GPIO_LEFT_BASE + 0x00E8) +#define rGPK3CON (GPIO_LEFT_BASE + 0x0100) +#define rGPK3DAT (GPIO_LEFT_BASE + 0x0104) +#define rGPK3PUD (GPIO_LEFT_BASE + 0x0108) +// end + +/* codes representing languages */ +const u8 string_desc0[] = +{ + 4, STRING_DESCRIPTOR, LANGID_US_L, LANGID_US_H, +}; + +const u8 dnw_string_desc1[] = /* Manufacturer */ +{ + (0x14+2), STRING_DESCRIPTOR, + 'S', 0x0, 'y', 0x0, 's', 0x0, 't', 0x0, 'e', 0x0, + 'm', 0x0, ' ', 0x0, 'M', 0x0, 'C', 0x0, 'U', 0x0, +}; + +const u8 dnw_string_desc2[] = /* Product */ +{ + (0x2a+2), STRING_DESCRIPTOR, + 'S', 0x0, 'E', 0x0, 'C', 0x0, ' ', 0x0, 'S', 0x0, + '3', 0x0, 'C', 0x0, '6', 0x0, '4', 0x0, '0', 0x0, + '0', 0x0, 'X', 0x0, ' ', 0x0, 'T', 0x0, 'e', 0x0, + 's', 0x0, 't', 0x0, ' ', 0x0, 'B', 0x0, '/', 0x0, + 'D', 0x0 +}; + +/* setting the device qualifier descriptor and a string descriptor */ +const u8 qualifier_desc[] = +{ + 0x0a, /* 0 desc size */ + 0x06, /* 1 desc type (DEVICE_QUALIFIER)*/ + 0x00, /* 2 USB release */ + 0x02, /* 3 => 2.00*/ + 0xFF, /* 4 class */ + 0x00, /* 5 subclass */ + 0x00, /* 6 protocol */ + 64, /* 7 max pack size */ + 0x01, /* 8 number of other-speed configuration */ + 0x00, /* 9 reserved */ +}; + +const u8 config_full[] = +{ + 0x09, /* 0 desc size */ + 0x07, /* 1 desc type (other speed)*/ + 0x20, /* 2 Total length of data returned */ + 0x00, /* 3 */ + 0x01, /* 4 Number of interfaces supported by this speed configuration */ + 0x01, /* 5 value to use to select configuration */ + 0x00, /* 6 index of string desc */ + /* 7 same as configuration desc */ + CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED, + 0x19, /* 8 same as configuration desc */ + +}; + +const u8 config_full_total[] = +{ + 0x09, 0x07 ,0x20 ,0x00 ,0x01 ,0x01 ,0x00 ,0xC0 ,0x19, + 0x09 ,0x04 ,0x00 ,0x00 ,0x02 ,0xff ,0x00 ,0x00 ,0x00, + 0x07 ,0x05 ,0x83 ,0x02 ,0x40 ,0x00 ,0x00, + 0x07 ,0x05 ,0x04 ,0x02 ,0x40 ,0x00 ,0x00 +}; + +const u8 config_high[] = +{ + 0x09, /* 0 desc size */ + 0x07, /* 1 desc type (other speed)*/ + 0x20, /* 2 Total length of data returned */ + 0x00, /* 3 */ + 0x01, /* 4 Number of interfaces supported by this speed configuration */ + 0x01, /* 5 value to use to select configuration */ + 0x00, /* 6 index of string desc */ + /* 7 same as configuration desc */ + CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED, + 0x19, /* 8 same as configuration desc */ + +}; + +const u8 config_high_total[] = +{ + 0x09, 0x07 ,0x20 ,0x00 ,0x01 ,0x01 ,0x00 ,0xC0 ,0x19, + 0x09 ,0x04 ,0x00 ,0x00 ,0x02 ,0xff ,0x00 ,0x00 ,0x00, + 0x07 ,0x05 ,0x81 ,0x02 ,0x00 ,0x02 ,0x00, + 0x07 ,0x05 ,0x02 ,0x02 ,0x00 ,0x02 ,0x00 +}; + +const u8 set_sel[6]; + +/*32 <cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>*/ +#define CONFIG_DESC_TOTAL_SIZE \ + (CONFIG_DESC_SIZE+INTERFACE_DESC_SIZE+ENDPOINT_DESC_SIZE*2) +#define CONFIG_SS_DESC_TOTAL_SIZE \ + (CONFIG_DESC_SIZE+INTERFACE_DESC_SIZE+ENDPOINT_DESC_SIZE*2+ENDPOINT_COMP_DESC_SIZE*2) +#define BOS_DESC_TOTAL_SIZE \ + (BOS_DESC_SIZE+USB20_EXT_CAP_DESC_SIZE+SUPER_CAP_DESC_SIZE+CONTAIN_CAP_DESC_SIZE) +#define TEST_PKT_SIZE 53 + +#define USB_CAP_20_EXT 0x2 +#define USB_CAP_SS 0x3 +#define USB_CAP_CID 0x4 + +#if !defined(CONFIG_ARCH_EXYNOS5) +#define USB_PHY_REF_CLK (DIFF_100MHz) +#else +#define USB_PHY_REF_CLK (EXTREF_24MHz) +#endif + +#if defined(CONFIG_CPU_EXYNOS5250) +#undef CONFIG_PHY_CRPORT +#else +#define CONFIG_PHY_CRPORT +#endif + +u8 test_pkt [TEST_PKT_SIZE] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*JKJKJKJK x 9*/ + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, /*JJKKJJKK x 8*/ + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, /*JJJJKKKK x 8*/ + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /*JJJJJJJKKKKKKK x8 - '1'*/ + 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, /*'1' + JJJJJJJK x 8*/ + 0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E /*{JKKKKKKK x 10},JK*/ +}; + +//===================================================================== +// global varibles used in several functions +USBDEV3 oUsbDev3; +USB_GET_STATUS oStatusGet; +USB_INTERFACE_GET oInterfaceGet; + +u16 g_usConfig; +u16 g_usUploadPktLength=0; +u8 g_bTransferEp0 = 0; + +u8 g_bSuspendResumeDBG_USBD3; + +u8 g_bUsingUsbDownAddr = 0; +u32 g_uUsbDownAddr = 0; + +u32 *g_uUsbDevCtrlInBufferPtr=NULL; +u32 *g_uUsbDevCtrlOutBufferPtr=NULL; +u32 *g_uUsbDevBulkOutTmpBufferPtr=NULL; +u32 *g_uUsbDevBulkOutBufferPtr=NULL; +u8 bCalled_SetEndPoint = 0; + +volatile usbdev3_trb_ptr_t g_pBulkOutTrb0; + +volatile usbdev3_trb_ptr_t g_pBulkOutTrbArray_Base; +volatile usbdev3_trb_ptr_t g_pBulkInTrbArray_Base; + +u8 *g_ucTempDownBuf; +u32 g_uCntOfDescOutComplete = 0; +u32 g_uCntOfBulkOutTrb, g_uCntOfBulkInTrb; +u8 g_bIsBulkOutXferDone = 0; +u8 g_bIsBulkInXferDone = 0; + +//===================================================================== +// For usb download + +unsigned int exynos_usbd_dn_addr = 0; +unsigned int exynos_usbd_dn_cnt = 0; +int is_fastboot = 0; +int DNW; +int exynos_got_header = 0; +int exynos_receive_done = 0; + +extern ulong virt_to_phy_exynos5210(ulong addr); +static u32 exynos_usb_malloc(u32 uSize, u32 uAlign); +static void exynos_usb_free(u32 uAddr); +static void exynos_usb_fill_trb(usbdev3_trb_ptr_t pTrb, u32 uBufAddr, u32 uLen, u32 uTrbCtrl, u32 uHwo); +static int exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum, u32 uTrbAddr, u32 uStrmidSofn, u32 *uTri); + +u32 EXYNOS_USBD_DETECT_IRQ(void) +{ + if (oUsbDev3.m_cable != CONNECTED) + return 0; + + return readl(rGEVNTCOUNT0); +} + +void EXYNOS_USBD_CLEAR_IRQ(void) +{ + do { + ; + } while (0); +} + +#include "fastboot-ss.c" + +void exynoy_usb_phy_on(void) +{ + +#ifdef CONFIG_CPU_EXYNOS5410 + // work around for overcurrent issue + // start + + u32 uReg; + + /* DRD 1 */ + uReg = readl(rGPK2CON); + uReg &= 0x0000FFFF; + writel(uReg|0x11220000, rGPK2CON); + + uReg = readl(rGPK2DAT); + uReg &= 0x0000000F; + writel(uReg|0x00000030, rGPK2DAT); + + uReg = readl(rGPK2PUD); + uReg &= 0x000000FF; + writel(uReg|0x00000000, rGPK2PUD); + + /* DRD 0 */ + uReg = readl(rGPK3CON); + uReg &= 0xFFFF0000; + writel(uReg|0x00001122, rGPK3CON); + + uReg = readl(rGPK3DAT); + uReg &= 0x000000F0; + writel(uReg|0x00000003, rGPK3DAT); + + uReg = readl(rGPK3PUD); + uReg &= 0x0000FF00; + writel(uReg|0x00000000, rGPK3PUD); + // end +#endif + +#if (defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5420)) + writel(0x1, USB_DEVICE_PHY_CONTROL); + writel(0x1, USB_DEVICE1_PHY_CONTROL); +#else + writel(0x1, USB_DEVICE_PHY_CONTROL); +#endif + +#if (defined(CONFIG_CPU_EXYNOS5260) || defined(CONFIG_CPU_EXYNOS5430)) + writel(0x11, USBDEVICE3_PHYCLK_SEL); +#endif +} + +static void exynoy_usb_phy_off(void) +{ + usb3_phy_utmi_t usbdev3_phy_utmi; + + usbdev3_phy_utmi.data = 0x0; + usbdev3_phy_utmi.b.otg_disable = 0x1; + usbdev3_phy_utmi.b.force_sleep = 0x1; + usbdev3_phy_utmi.b.force_suspend = 0x1; + + oUsbDev3.m_uPhyBaseRegs = USBDEVICE3_PHYCTRL_CH0_BASE; + writel(usbdev3_phy_utmi.data, EXYNOS_PHY_UTMI); + writel(0x0, USB_DEVICE_PHY_CONTROL); + +#if (defined(CONFIG_CPU_EXYNOS5410) || defined(CONFIG_CPU_EXYNOS5420)) + oUsbDev3.m_uPhyBaseRegs = USBDEVICE3_PHYCTRL_CH1_BASE; + writel(usbdev3_phy_utmi.data, EXYNOS_PHY_UTMI); + writel(0x0, USB_DEVICE1_PHY_CONTROL); +#endif +} + +static void exynos_usb_init_phy(void) +{ + usb3_phy_utmi_t usbdev3_phy_utmi; + usbdev3_phy_clkpwr_t usbdev3_phy_clkpwr; + u32 eClkFreq = USB_PHY_REF_CLK; + + /* Reset PHY configuration */ + writel(0x00000000, EXYNOS_PHY_REG0); + writel(0x24d466e4, EXYNOS_PHY_PARAM0); //must + writel(0x00000000, EXYNOS_PHY_RESUME); + +#if defined(CONFIG_ARCH_EXYNOS5) + writel(0x08000000, EXYNOS_PHY_LINKSYSTEM); // clear [8] : force_vbusvalid bit, [7] : force_bvalid + writel(0x03fff818, EXYNOS_PHY_PARAM1); //must + writel(0x00000004, EXYNOS_PHY_BATCHG); // PHY CLK Mux. (1<<2) : w_FREECLK, (0<<2) : w_PHYCLK + if (eClkFreq == DIFF_100MHz) + writel(readl(EXYNOS_PHY_PARAM0) | (0x1<<31), EXYNOS_PHY_PARAM0); // use 100MHz clk +#else + writel(0x087fffc0, EXYNOS_PHY_LINKSYSTEM); //must + writel(0x03fff820, EXYNOS_PHY_PARAM1); //must + writel(0x00000000, EXYNOS_PHY_BATCHG); //must + /* Over-current pin is inactive on SMDK5250 EVT0 */ + writel((readl(EXYNOS_PHY_LINK_PORT) & ~(0x3<<4)) | (0x3<<2), EXYNOS_PHY_LINK_PORT); +#endif + usbdev3_phy_utmi.data = 0x0; + usbdev3_phy_utmi.b.otg_disable = 0x1; + + writel(usbdev3_phy_utmi.data, EXYNOS_PHY_UTMI); + + usbdev3_phy_clkpwr.data = 0; + + switch(eClkFreq){ + case DIFF_100MHz: + usbdev3_phy_clkpwr.b.fsel = 0x27; + usbdev3_phy_clkpwr.b.refclksel = 2; // DIFF PAD + usbdev3_phy_clkpwr.b.mpll_multiplier = 0x19; + usbdev3_phy_clkpwr.b.ref_clkdiv2 = 0; + usbdev3_phy_clkpwr.b.ssc_ref_clk_sel = 0x00; + break; + case EXTREF_50MHz: + usbdev3_phy_clkpwr.b.fsel = 0x7; + usbdev3_phy_clkpwr.b.refclksel = 3; // REFCLK_SINGLE + usbdev3_phy_clkpwr.b.mpll_multiplier = 0x32; + usbdev3_phy_clkpwr.b.ref_clkdiv2 = 0; + usbdev3_phy_clkpwr.b.ssc_ref_clk_sel = 0x00; + break; + case EXTREF_20MHz: + usbdev3_phy_clkpwr.b.fsel = 0x4; + usbdev3_phy_clkpwr.b.refclksel = 3; // REFCLK_SINGLE + usbdev3_phy_clkpwr.b.mpll_multiplier = 0x7d; + usbdev3_phy_clkpwr.b.ref_clkdiv2 = 0; + usbdev3_phy_clkpwr.b.ssc_ref_clk_sel = 0x00; + break; + case EXTREF_19_2MHz: + usbdev3_phy_clkpwr.b.fsel = 0x3; + usbdev3_phy_clkpwr.b.refclksel = 3; // REFCLK_SINGLE + usbdev3_phy_clkpwr.b.mpll_multiplier = 0x02; + usbdev3_phy_clkpwr.b.ref_clkdiv2 = 0; + usbdev3_phy_clkpwr.b.ssc_ref_clk_sel = 0x88; + break; + case EXTREF_24MHz: + default: + usbdev3_phy_clkpwr.b.fsel = 0x5; + usbdev3_phy_clkpwr.b.refclksel = 3; // REFCLK_SINGLE + usbdev3_phy_clkpwr.b.mpll_multiplier = 0x68; + usbdev3_phy_clkpwr.b.ref_clkdiv2 = 0; + usbdev3_phy_clkpwr.b.ssc_ref_clk_sel = 0x88; + break; + } + +#if defined(CONFIG_ARCH_EXYNOS5) + usbdev3_phy_clkpwr.b.commononn = 1; // pll blocks are powered in suspend or sleep mode +#else + usbdev3_phy_clkpwr.b.commononn = 0; +#endif + usbdev3_phy_clkpwr.b.portreset = 1; // assert port_reset + usbdev3_phy_clkpwr.b.retenablen = 1; // normal operating mode + usbdev3_phy_clkpwr.b.ref_clkdiv2 = 0; + usbdev3_phy_clkpwr.b.ref_ssp_en = 1; + usbdev3_phy_clkpwr.b.ssc_en = 1; + usbdev3_phy_clkpwr.b.ssc_range = 0; + usbdev3_phy_clkpwr.b.ssc_ref_clk_sel = 0x0; + + writel(usbdev3_phy_clkpwr.data, EXYNOS_PHY_CLKPWR); + usbdev3_phy_clkpwr.b.portreset = 0; + udelay(10); + writel(usbdev3_phy_clkpwr.data, EXYNOS_PHY_CLKPWR); +} + +static void exynos_usb_phy_crport_handshake(usb3_phy_reg0_t *phy_reg0) +{ + usb3_phy_reg1_t phy_reg1; + u32 usec = 100; + u32 tmp; + + writel(phy_reg0->data, EXYNOS_PHY_REG0); + + do { + phy_reg1.data = readl(EXYNOS_PHY_REG1); + if (phy_reg1.b.cr_ack) + break; + } while (usec-- > 0); + + if (!usec) + printf("CRPORT handshake timeout (0x%08x)\n", phy_reg0->data); +} + +static void exynos_phy_crport_ctrl(u16 addr, u16 data) +{ + usb3_phy_reg0_t phy_reg0; + + /* Write Address */ + phy_reg0.data = 0; + phy_reg0.b.cr_data_in = addr; + phy_reg0.b.cr_cap_addr = 1; + exynos_usb_phy_crport_handshake(&phy_reg0); + phy_reg0.b.cr_cap_addr = 0; + exynos_usb_phy_crport_handshake(&phy_reg0); + + /* Write Data */ + phy_reg0.data = 0; + phy_reg0.b.cr_data_in = data; + phy_reg0.b.cr_cap_data = 1; + exynos_usb_phy_crport_handshake(&phy_reg0); + phy_reg0.b.cr_cap_data = 0; + exynos_usb_phy_crport_handshake(&phy_reg0); + + /* Execute write operation */ + phy_reg0.data = 0; + phy_reg0.b.cr_data_in = data; + phy_reg0.b.cr_write = 1; + exynos_usb_phy_crport_handshake(&phy_reg0); + phy_reg0.b.cr_write = 0; + exynos_usb_phy_crport_handshake(&phy_reg0); +} + +static void exynos_usb_crport_config(void) +{ + exynos_phy_crport_ctrl(0x15, 0xA409); + exynos_phy_crport_ctrl(0x12, 0xA000); +} + +static u32 exynos_usb_malloc(u32 uSize, u32 uAlign) +{ + u32 uAddr, uTemp1, uTemp2, uTemp3; + u32 uAddr_aligned; + u32 uAllocHwMem_AlignConstraint = 64; + + // get the GCD(Great Common Divider) + uTemp2 = uAlign; + uTemp3 = uAllocHwMem_AlignConstraint; + while(uTemp3) + { + uTemp1 = uTemp2%uTemp3; + uTemp2 = uTemp3; + uTemp3 = uTemp1; + } + + // get the LCM(Least Common Multiple) + uAlign = uAlign*uAllocHwMem_AlignConstraint/uTemp2; + //TODO : check align + uAddr = (u32)malloc(uSize + uAlign); + uTemp2 = uAddr % uAlign; + + uAddr_aligned = uAddr + (uAlign - uTemp2); + *(u32 *)(uAddr_aligned-4) = uAddr; + + memset((void *)uAddr, 0, uSize); + DBG_USBD3("exynos_usb_malloc:Addr=0x%08x[0x%08x], Size=%d, Align=%d\n\n", uAddr, uAddr_aligned, uSize, uAlign); + + return uAddr_aligned; +} + +static void exynos_usb_free(u32 uAddr) +{ + u32 uFree_addr; + if (uAddr != 0) + { + uFree_addr = *(u32 *)(uAddr - 4); + free((u8 *)uFree_addr); + } + DBG_USBD3("\n\nexynos_usb_free:0x%08x[0x%8x]\n\n", uAddr, uFree_addr); +} + +static void exynos_usb_print_ep0_pkt(u8 *pt, u8 count) +{ + int i; + DBG_USBD3("[DBG:"); + for(i=0;i<count;i++) + DBG_USBD3("%x,", pt[i]); + DBG_USBD3("]\n"); +} + +static void exynos_usb_set_descriptor_tlb(void) +{ + // Standard device descriptor + oUsbDev3.m_oDesc.oDescDevice.bLength=DEVICE_DESC_SIZE; + oUsbDev3.m_oDesc.oDescDevice.bDescriptorType=DEVICE_DESCRIPTOR; + oUsbDev3.m_oDesc.oDescDevice.bDeviceClass=0xFF; + oUsbDev3.m_oDesc.oDescDevice.bDeviceSubClass=0x0; + oUsbDev3.m_oDesc.oDescDevice.bDeviceProtocol=0x0; + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) { + oUsbDev3.m_oDesc.oDescDevice.bMaxPacketSize0=SUPER_SPEED_CONTROL_PKT_EXP_SZ; + } else { + oUsbDev3.m_oDesc.oDescDevice.bMaxPacketSize0=oUsbDev3.m_uControlEPMaxPktSize; + } + oUsbDev3.m_oDesc.oDescDevice.idVendorL=0xE8; + oUsbDev3.m_oDesc.oDescDevice.idVendorH=0x04; + oUsbDev3.m_oDesc.oDescDevice.idProductL=0x34; + oUsbDev3.m_oDesc.oDescDevice.idProductH=0x12; + oUsbDev3.m_oDesc.oDescDevice.bcdDeviceL=0x00; + oUsbDev3.m_oDesc.oDescDevice.bcdDeviceH=0x01; + oUsbDev3.m_oDesc.oDescDevice.iManufacturer=0x1; // index of string descriptor + oUsbDev3.m_oDesc.oDescDevice.iProduct=0x2; // index of string descriptor + oUsbDev3.m_oDesc.oDescDevice.iSerialNumber=0x0; + oUsbDev3.m_oDesc.oDescDevice.bNumConfigurations=0x1; + + // khs. this should be changed, and also other descriptors should be changed + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) { + oUsbDev3.m_oDesc.oDescDevice.bcdUSBL=0x00; + oUsbDev3.m_oDesc.oDescDevice.bcdUSBH=0x03; // Ver 3.0 + } else if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_HIGH) { + oUsbDev3.m_oDesc.oDescDevice.bcdUSBL=0x00; + oUsbDev3.m_oDesc.oDescDevice.bcdUSBH=0x02; // Ver 2.0 + } else if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_FULL) { + oUsbDev3.m_oDesc.oDescDevice.bcdUSBL=0x10; + oUsbDev3.m_oDesc.oDescDevice.bcdUSBH=0x01; // Ver 2.0 + } + + // Standard configuration descriptor + oUsbDev3.m_oDesc.oDescConfig.bLength=CONFIG_DESC_SIZE; // 0x9 bytes + oUsbDev3.m_oDesc.oDescConfig.bDescriptorType=CONFIGURATION_DESCRIPTOR; + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) + oUsbDev3.m_oDesc.oDescConfig.wTotalLengthL=CONFIG_SS_DESC_TOTAL_SIZE; + else + oUsbDev3.m_oDesc.oDescConfig.wTotalLengthL=CONFIG_DESC_TOTAL_SIZE; + oUsbDev3.m_oDesc.oDescConfig.wTotalLengthH=0; + oUsbDev3.m_oDesc.oDescConfig.bNumInterfaces=1; + oUsbDev3.m_oDesc.oDescConfig.bConfigurationValue=1; + oUsbDev3.m_oDesc.oDescConfig.iConfiguration=0; + oUsbDev3.m_oDesc.oDescConfig.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED; // bus powered only. + oUsbDev3.m_oDesc.oDescConfig.maxPower=25; // draws 50mA current from the USB bus. + + // Standard interface descriptor + oUsbDev3.m_oDesc.oDescInterface.bLength=INTERFACE_DESC_SIZE; // 9 + oUsbDev3.m_oDesc.oDescInterface.bDescriptorType=INTERFACE_DESCRIPTOR; + oUsbDev3.m_oDesc.oDescInterface.bInterfaceNumber=0x0; + oUsbDev3.m_oDesc.oDescInterface.bAlternateSetting=0x0; // ? + oUsbDev3.m_oDesc.oDescInterface.bNumEndpoints = 2; // # of endpoints except EP0 + oUsbDev3.m_oDesc.oDescInterface.bInterfaceClass=0xff; // 0x0 ? + oUsbDev3.m_oDesc.oDescInterface.bInterfaceSubClass=0x0; + oUsbDev3.m_oDesc.oDescInterface.bInterfaceProtocol=0x0; + oUsbDev3.m_oDesc.oDescInterface.iInterface=0x0; + + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) { + /* Standard endpoint0 descriptor */ + oUsbDev3.m_oSSDesc.oDescEp0.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescEp0.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oSSDesc.oDescEp0.bEndpointAddress=BULK_IN_EP|EP_ADDR_IN; + oUsbDev3.m_oSSDesc.oDescEp0.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oSSDesc.oDescEp0.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oSSDesc.oDescEp0.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oSSDesc.oDescEp0.bInterval=0x0; /* not used */ + + oUsbDev3.m_oSSDesc.oDescEp0Comp.bLength=6; + oUsbDev3.m_oSSDesc.oDescEp0Comp.bDescriptorType=0x30; + oUsbDev3.m_oSSDesc.oDescEp0Comp.bMaxBurst=15; + oUsbDev3.m_oSSDesc.oDescEp0Comp.bmAttributes=0; + oUsbDev3.m_oSSDesc.oDescEp0Comp.wBytesPerInterval=0; + + /* Standard endpoint1 descriptor */ + oUsbDev3.m_oSSDesc.oDescEp1.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescEp1.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oSSDesc.oDescEp1.bEndpointAddress=BULK_OUT_EP|EP_ADDR_OUT; + oUsbDev3.m_oSSDesc.oDescEp1.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oSSDesc.oDescEp1.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oSSDesc.oDescEp1.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oSSDesc.oDescEp1.bInterval=0x0; /* not used */ + + oUsbDev3.m_oSSDesc.oDescEp1Comp.bLength=6; + oUsbDev3.m_oSSDesc.oDescEp1Comp.bDescriptorType=0x30; + oUsbDev3.m_oSSDesc.oDescEp1Comp.bMaxBurst=15; + oUsbDev3.m_oSSDesc.oDescEp1Comp.bmAttributes=0; + oUsbDev3.m_oSSDesc.oDescEp1Comp.wBytesPerInterval=0; + + // Standard BOS(Binary Object Store) descriptor + oUsbDev3.m_oSSDesc.oDescBos.bLength = BOS_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescBos.bDescriptorType = 0x0F; + oUsbDev3.m_oSSDesc.oDescBos.wTotalLength = BOS_DESC_TOTAL_SIZE; + oUsbDev3.m_oSSDesc.oDescBos.bNumDeviceCaps = 3; + + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bLength = USB20_EXT_CAP_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bDescriptorType = 0x10; + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bDevCapabilityType = USB_CAP_20_EXT; + oUsbDev3.m_oSSDesc.oDescUsb20Ext.bmAttributes = 0x2; + + oUsbDev3.m_oSSDesc.oDescSuperCap.bLength = SUPER_CAP_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescSuperCap.bDescriptorType = 0x10; + oUsbDev3.m_oSSDesc.oDescSuperCap.bDevCapabilityType = USB_CAP_SS; + oUsbDev3.m_oSSDesc.oDescSuperCap.bmAttributes = 0x0; + oUsbDev3.m_oSSDesc.oDescSuperCap.wSpeedsSupported = 0xC; + oUsbDev3.m_oSSDesc.oDescSuperCap.bFunctionalitySupport = 2; + /* TODO: set correct value */ + oUsbDev3.m_oSSDesc.oDescSuperCap.bU1DevExitLat = 0x4; + oUsbDev3.m_oSSDesc.oDescSuperCap.wU2DevExitLat = 0x4; + + oUsbDev3.m_oSSDesc.oDescContainCap.bLength = CONTAIN_CAP_DESC_SIZE; + oUsbDev3.m_oSSDesc.oDescContainCap.bDescriptorType = 0x10; + oUsbDev3.m_oSSDesc.oDescContainCap.bDevCapabilityType = USB_CAP_CID; + oUsbDev3.m_oSSDesc.oDescContainCap.bReserved = 0x0; + memset(oUsbDev3.m_oSSDesc.oDescContainCap.containerID, 0x0, 16); + } + else { + /* Standard endpoint0 descriptor */ + oUsbDev3.m_oDesc.oDescEp0.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oDesc.oDescEp0.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oDesc.oDescEp0.bEndpointAddress=BULK_IN_EP|EP_ADDR_IN; + oUsbDev3.m_oDesc.oDescEp0.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oDesc.oDescEp0.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oDesc.oDescEp0.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oDesc.oDescEp0.bInterval=0x0; /* not used */ + + /* Standard endpoint1 descriptor */ + oUsbDev3.m_oDesc.oDescEp1.bLength=ENDPOINT_DESC_SIZE; + oUsbDev3.m_oDesc.oDescEp1.bDescriptorType=ENDPOINT_DESCRIPTOR; + oUsbDev3.m_oDesc.oDescEp1.bEndpointAddress=BULK_OUT_EP|EP_ADDR_OUT; + oUsbDev3.m_oDesc.oDescEp1.bmAttributes=EP_ATTR_BULK; + oUsbDev3.m_oDesc.oDescEp1.wMaxPacketSizeL=(u8)oUsbDev3.m_uBulkEPMaxPktSize; /* 64*/ + oUsbDev3.m_oDesc.oDescEp1.wMaxPacketSizeH=(u8)(oUsbDev3.m_uBulkEPMaxPktSize>>8); + oUsbDev3.m_oDesc.oDescEp1.bInterval=0x0; /* not used */ + } +} + +static void exynos_usb_softreset_phy(u8 ucSet) +{ + usbdev3_gusb2phycfg_t usbdev3_gusb2phycfg; + usbdev3_gusb3pipectl_t usbdev3_gusb3pipectl; + + usbdev3_gusb2phycfg.data = readl(rGUSB2PHYCFG); + usbdev3_gusb2phycfg.b.phy_soft_reset = ucSet; + writel(usbdev3_gusb2phycfg.data, rGUSB2PHYCFG); + + usbdev3_gusb3pipectl.data = readl(rGUSB3PIPECTL); + usbdev3_gusb3pipectl.b.phy_soft_reset = ucSet; + writel(usbdev3_gusb3pipectl.data, rGUSB3PIPECTL); +} + +static void exynos_usb_softreset_core(void) +{ + usbdev3_dctl_t usbdev3_dctl; + + usbdev3_dctl.data = readl(rDCTL); + usbdev3_dctl.b.core_soft_reset = 1; + //usbdev3_dctl.b.run_stop = 0; + writel(usbdev3_dctl.data, rDCTL); + + do + { + udelay(10); + usbdev3_dctl.data = readl(rDCTL); + } while (usbdev3_dctl.b.core_soft_reset == 1); + + udelay(10); // s/w must wait at least 3 phy clocks(1/60Mz * 3 = 48ns) before accessing the phy domain +} + +static void exynos_usb_enable_eventinterrupt(void) +{ + usbdev3_gevntsiz_t usbdev3_gevntsiz; + + usbdev3_gevntsiz.data = readl(rGEVNTSIZ0); + usbdev3_gevntsiz.b.event_int_mask = 0; + writel(usbdev3_gevntsiz.data, rGEVNTSIZ0); +} + +static void exynos_usb_disable_eventinterrupt(void) +{ + usbdev3_gevntsiz_t usbdev3_gevntsiz; + + usbdev3_gevntsiz.data = readl(rGEVNTSIZ0); + usbdev3_gevntsiz.b.event_int_mask = 1; + writel(usbdev3_gevntsiz.data, rGEVNTSIZ0); +} + +static void exynos_usb_flush_eventbuffer(void) +{ + u32 uEventCount; + + uEventCount = readl(rGEVNTCOUNT0) & 0xffff; + + writel(uEventCount, rGEVNTCOUNT0); +} + +static int exynos_usb_wait_ep_cmd_complete(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum, u32 uSec) +{ + usbdev3_depcmd_t usbdev3_depcmd; + u32 uEpCmdAddr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMD(ucEpNum) : rDOEPCMD(ucEpNum); + + do { + usbdev3_depcmd.data = readl(uEpCmdAddr); + + if (!(usbdev3_depcmd.b.cmd_active)) + { + DBG_USBD3("Complete: D%cEPCMD(%d)=0x%08x\n", + (eEpDir==USBDEV3_EP_DIR_IN)? 'I' : 'O', ucEpNum, usbdev3_depcmd.data); + return 1; + } + + udelay(1); + uSec--; + } while (uSec > 0); + + DBG_USBD3("TimeOver: D%cEPCMD(%d)=0x%08x\n", + (eEpDir==USBDEV3_EP_DIR_IN)? 'I' : 'O', ucEpNum, usbdev3_depcmd.data); + return 0; +} + +static int exynos_usb_set_ep_cfg(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum, u32 uPar0, u32 uPar1) +{ + usbdev3_depcmd_t usbdev3_depcmd; + u32 uEpCmdAddr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMD(ucEpNum) : rDOEPCMD(ucEpNum); + u32 uEpPar0Addr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMDPAR0(ucEpNum) : rDOEPCMDPAR0(ucEpNum); + u32 uEpPar1Addr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMDPAR1(ucEpNum) : rDOEPCMDPAR1(ucEpNum); + + + writel(uPar1, uEpPar1Addr); + writel(uPar0, uEpPar0Addr); + + usbdev3_depcmd.data = 0; + usbdev3_depcmd.b.cmd_type = DEPCMD_CMD_SET_EP_CFG; + usbdev3_depcmd.b.cmd_active = 1; + writel(usbdev3_depcmd.data, uEpCmdAddr); + + if (!exynos_usb_wait_ep_cmd_complete(eEpDir, ucEpNum, CMDCOMPLETEWAIT_UNIT)) + { + return 0; + } + + return 1; +} + +static int exynos_usb_set_ep_xfer_rsrc_cfg(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum, u32 uPar0) +{ + usbdev3_depcmd_t usbdev3_depcmd; + u32 uEpCmdAddr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMD(ucEpNum) : rDOEPCMD(ucEpNum); + u32 uEpPar0Addr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMDPAR0(ucEpNum) : rDOEPCMDPAR0(ucEpNum); + + writel(uPar0, uEpPar0Addr); + + usbdev3_depcmd.data = 0; + usbdev3_depcmd.b.cmd_type = DEPCMD_CMD_SET_EP_XFER_RSRC_CFG; + usbdev3_depcmd.b.cmd_active = 1; + writel(usbdev3_depcmd.data, uEpCmdAddr); + + if (!exynos_usb_wait_ep_cmd_complete(eEpDir, ucEpNum, CMDCOMPLETEWAIT_UNIT)) + { + return 0; + } + + return 1; +} + +static void exynos_usb_enable_ep(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum) +{ + u32 uEpEnaIdx; + + uEpEnaIdx = ucEpNum*2; + + if (eEpDir == USBDEV3_EP_DIR_IN) + { + uEpEnaIdx++; + } + + writel(readl(rDALEPENA) | (1<<uEpEnaIdx), rDALEPENA); +} + +static int exynos_usb_activate_ep0(void) +{ + usbdev3_depcmd_t usbdev3_depcmd; + usbdev3_depcmdpar0_set_ep_cfg_t usbdev3_depcmdpar0_set_ep_cfg; + usbdev3_depcmdpar1_set_ep_cfg_t usbdev3_depcmdpar1_set_ep_cfg; + + // . Start New Configuration + //----------------------- + usbdev3_depcmd.data = 0; + usbdev3_depcmd.b.cmd_type = DEPCMD_CMD_START_NEW_CFG; + usbdev3_depcmd.b.cmd_active = 1; + writel(usbdev3_depcmd.data, rDOEPCMD(0)); + if (!exynos_usb_wait_ep_cmd_complete(USBDEV3_EP_DIR_OUT, 0, CMDCOMPLETEWAIT_UNIT)) + { + return 0; + } + + // . Issue Set Ep Configuraton for EP0-OUT + //------------------------------------ + usbdev3_depcmdpar0_set_ep_cfg.data = 0; + usbdev3_depcmdpar0_set_ep_cfg.b.ep_type = USBDEV3_EP_CTRL; + usbdev3_depcmdpar0_set_ep_cfg.b.mps = oUsbDev3.m_uControlEPMaxPktSize; // should be reconfigured after ConnectDone event + + usbdev3_depcmdpar1_set_ep_cfg.data = 0; + usbdev3_depcmdpar1_set_ep_cfg.b.xfer_cmpl_en = 1; + //usbdev3_depcmdpar1_set_ep_cfg.b.xfer_in_prog_en = 1; + usbdev3_depcmdpar1_set_ep_cfg.b.xfer_nrdy_en = 1; + usbdev3_depcmdpar1_set_ep_cfg.b.ep_dir = USBDEV3_EP_DIR_OUT; + usbdev3_depcmdpar1_set_ep_cfg.b.ep_num = 0; + + if (!exynos_usb_set_ep_cfg(USBDEV3_EP_DIR_OUT, 0, usbdev3_depcmdpar0_set_ep_cfg.data, usbdev3_depcmdpar1_set_ep_cfg.data)) + { + return 0; + } + + // . Issue Set Ep Xfer Resource for EP0-OUT + //------------------------------------ + if (!exynos_usb_set_ep_xfer_rsrc_cfg(USBDEV3_EP_DIR_OUT, 0, 1)) + { + return 0; + } + + // . Issue Set Ep Configuraton for EP0-IN + //------------------------------------ + usbdev3_depcmdpar0_set_ep_cfg.data = 0; + usbdev3_depcmdpar0_set_ep_cfg.b.ep_type = USBDEV3_EP_CTRL; + usbdev3_depcmdpar0_set_ep_cfg.b.mps = oUsbDev3.m_uControlEPMaxPktSize; // should be reconfigured after ConnectDone event + + usbdev3_depcmdpar1_set_ep_cfg.data = 0; + usbdev3_depcmdpar1_set_ep_cfg.b.xfer_cmpl_en = 1; + //usbdev3_depcmdpar1_set_ep_cfg.b.xfer_in_prog_en = 1; + usbdev3_depcmdpar1_set_ep_cfg.b.xfer_nrdy_en = 1; + usbdev3_depcmdpar1_set_ep_cfg.b.ep_dir = USBDEV3_EP_DIR_IN; + usbdev3_depcmdpar1_set_ep_cfg.b.ep_num = 0; + + if (!exynos_usb_set_ep_cfg(USBDEV3_EP_DIR_IN, 0, usbdev3_depcmdpar0_set_ep_cfg.data, usbdev3_depcmdpar1_set_ep_cfg.data)) + { + return 0; + } + + // . Issue Set Ep Xfer Resource for EP0-IN + //------------------------------------ + if (!exynos_usb_set_ep_xfer_rsrc_cfg(USBDEV3_EP_DIR_IN, 0, 1)) + { + return 0; + } + + return 1; +} + +static int exynos_usb_activate_ep(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum) +{ + usbdev3_depcmd_t usbdev3_depcmd; + usbdev3_depcmdpar0_set_ep_cfg_t usbdev3_depcmdpar0_set_ep_cfg; + usbdev3_depcmdpar1_set_ep_cfg_t usbdev3_depcmdpar1_set_ep_cfg; + + + if (oUsbDev3.m_bEPs_Enabled == 0) + { + oUsbDev3.m_bEPs_Enabled = 1; + + // . Start New Configuration + //----------------------- + usbdev3_depcmd.data = 0; + usbdev3_depcmd.b.param = 2; // XferRscIdx = 2 in case of non-EP0, XferRscIdx = 0 in case of EP0 + usbdev3_depcmd.b.cmd_type = DEPCMD_CMD_START_NEW_CFG; + usbdev3_depcmd.b.cmd_active = 1; + writel(usbdev3_depcmd.data, rDOEPCMD(0)); + if (!exynos_usb_wait_ep_cmd_complete(USBDEV3_EP_DIR_OUT, 0, CMDCOMPLETEWAIT_UNIT)) + { + return 0; + } + } + + + // . Issue Set Ep Configuraton + //------------------------------------ + usbdev3_depcmdpar0_set_ep_cfg.data = 0; + usbdev3_depcmdpar0_set_ep_cfg.b.ep_type = USBDEV3_EP_BULK; + usbdev3_depcmdpar0_set_ep_cfg.b.mps = oUsbDev3.m_uBulkEPMaxPktSize; + + if (eEpDir == USBDEV3_EP_DIR_IN) + { + usbdev3_depcmdpar0_set_ep_cfg.b.fifo_num = ucEpNum; + } + + usbdev3_depcmdpar0_set_ep_cfg.b.brst_siz = 0; // khs. should find best value + + + usbdev3_depcmdpar1_set_ep_cfg.data = 0; + usbdev3_depcmdpar1_set_ep_cfg.b.xfer_cmpl_en = 1; + //usbdev3_depcmdpar1_set_ep_cfg.b.xfer_in_prog_en = 1; + //usbdev3_depcmdpar1_set_ep_cfg.b.xfer_nrdy_en = 1; // when using preset transfer, this interrupt can be disabled + usbdev3_depcmdpar1_set_ep_cfg.b.ep_dir = (u32)eEpDir; + usbdev3_depcmdpar1_set_ep_cfg.b.ep_num = ucEpNum; + + if (!exynos_usb_set_ep_cfg(eEpDir, ucEpNum, usbdev3_depcmdpar0_set_ep_cfg.data, usbdev3_depcmdpar1_set_ep_cfg.data)) + { + return 0; + } + + // . Issue Set Ep Xfer Resource + //-------------------------- + if (!exynos_usb_set_ep_xfer_rsrc_cfg(eEpDir, ucEpNum, 1)) + { + return 0; + } + + return 1; +} + +static void exynos_usb_runstop_device(u8 ucSet) +{ + usbdev3_dctl_t usbdev3_dctl; + + usbdev3_dctl.data = readl(rDCTL); + usbdev3_dctl.b.run_stop = ucSet; + writel(usbdev3_dctl.data, rDCTL); +} + +static int exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum, u32 uTrbAddr, u32 uStrmidSofn, u32 *uTri) +{ + usbdev3_depcmd_t usbdev3_depcmd; + u32 uEpCmdAddr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMD(ucEpNum) : rDOEPCMD(ucEpNum); + u32 uEpPar0Addr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMDPAR0(ucEpNum) : rDOEPCMDPAR0(ucEpNum); + u32 uEpPar1Addr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMDPAR1(ucEpNum) : rDOEPCMDPAR1(ucEpNum); + + + writel(virt_to_phys(uTrbAddr), uEpPar1Addr); + writel(0, uEpPar0Addr); + + usbdev3_depcmd.data = 0; + usbdev3_depcmd.b.cmd_type = DEPCMD_CMD_START_XFER; + usbdev3_depcmd.b.cmd_active = 1; + usbdev3_depcmd.b.param = uStrmidSofn; + writel(usbdev3_depcmd.data, uEpCmdAddr); + + if (!exynos_usb_wait_ep_cmd_complete(eEpDir, ucEpNum, CMDCOMPLETEWAIT_UNIT)) + { + return 0; + } + + // . Get the Tranfer Resource Index from the start transfer command + //-------------------------------------------------------- + usbdev3_depcmd.data = readl(uEpCmdAddr); + *uTri = usbdev3_depcmd.b.param & 0x7f; + + return 1; +} + +static void exynos_usb_fill_trb(usbdev3_trb_ptr_t pTrb, u32 uBufAddr, u32 uLen, u32 uTrbCtrl, u32 uHwo) +{ + pTrb->buf_ptr_l = virt_to_phys(uBufAddr); + pTrb->buf_ptr_h = 0; + + pTrb->status.data = 0; + pTrb->status.b.buf_siz = uLen; + + pTrb->control.data = uTrbCtrl & 0xfffffffeU; + + // must do this last => why? + if (uHwo) + { + pTrb->control.b.hwo = 1; + } + +} + +static int exynos_usb_start_ep0_setup_rx(void) +{ + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + + // . Set TRB for Setup + //------------------ + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_SETUP; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 1; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + exynos_usb_fill_trb(oUsbDev3.m_oSetupTrbPtr, (u32)&oUsbDev3.m_oDeviceRequest, + oUsbDev3.m_uControlEPMaxPktSize, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for EP0-OUT + //---------------------------- + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_OUT, 0, (u32)oUsbDev3.m_oSetupTrbPtr, 0, &oUsbDev3.m_uTriOut[0])) + { + return 0; + } + + return 1; +} + +static int exynos_usb_init_core(USBDEV3_SPEED_e eSpeed) +{ + u32 uData; + usbdev3_gsbuscfg0_t usbdev3_gsbuscfg0; + usbdev3_gsbuscfg1_t usbdev3_gsbuscfg1; + usbdev3_gusb2phycfg_t usbdev3_gusb2phycfg; + usbdev3_gusb3pipectl_t usbdev3_gusb3pipectl; + usbdev3_gevntsiz_t usbdev3_gevntsiz; + usbdev3_dcfg_t usbdev3_dcfg; + usbdev3_devten_t usbdev3_devten; + + // . to soft-reset core + //----------------- + exynos_usb_softreset_core(); + // . to crport configuration + //----------------- +#ifdef CONFIG_PHY_CRPORT + exynos_usb_crport_config(); +#endif + // . to configure GSBUSCFG0/1 + // khs. I should find best setting value for our AP system + //---------------------------------------------- + usbdev3_gsbuscfg0.data = 0; + //usbdev3_gsbuscfg0.b.incr_xbrst_ena = 1; + //usbdev3_gsbuscfg0.b.incr_4brst_ena = 1; + //usbdev3_gsbuscfg0.b.incr_8brst_ena = 1; + usbdev3_gsbuscfg0.b.incr_16brst_ena = 1; + writel(usbdev3_gsbuscfg0.data, rGSBUSCFG0); + + usbdev3_gsbuscfg1.data = 0x00000300; // reset value + writel(usbdev3_gsbuscfg1.data, rGSBUSCFG1); + + // . to configure GTXTHRCFG/GRXTHRCFG + //------------------------------------------------ + // skipped because this sfr is only valid in the host mode + + // . to check IP version + //------------------- + uData = readl(rGSNPSID); + DBG_USBD3("IP version is %1x.%03x\n", (uData&0xf000)>>12, (uData&0x0fff)); + + // . to set usb 2.0 phy-related configuration parmeters + //--------------------------------------------- + usbdev3_gusb2phycfg.data = readl(rGUSB2PHYCFG); + usbdev3_gusb2phycfg.b.turnaround_time = 9; + writel(usbdev3_gusb2phycfg.data, rGUSB2PHYCFG); + + // . to set usb 3.0 phy-related configuration parmeters + // (I should find proper setting value) + //--------------------------------------------- + usbdev3_gusb3pipectl.data = 0x00260002; // reset value + // usbdev3_gusb3pipectl.data = 0x00240002; // clear suspend bit + writel(usbdev3_gusb3pipectl.data, rGUSB3PIPECTL); + + // . to set tx fifo sizes + //------------------ + // skipped because of using default setting + + + // . to set rx fifo sizes + //------------------- + // skipped because of using default setting + + + // . to initialize the Event Buffer registers + //------------------------------------- + writel(0, rGEVNTADR_HI0); + oUsbDev3.m_CurrentEventPosition = 0; + writel(virt_to_phys((u32)oUsbDev3.m_pEventBuffer), rGEVNTADR_LO0); + usbdev3_gevntsiz.data = 0; + usbdev3_gevntsiz.b.event_siz = 4*USBDEV3_EVENT_BUFFER_COUNT; + usbdev3_gevntsiz.b.event_int_mask = 0; + writel(usbdev3_gevntsiz.data, rGEVNTSIZ0); + writel(0, rGEVNTCOUNT0); + + // . to set Gloval Control Register + // khs. I should find proper setting value + //-------------------------------- + // writel(rGCTL, 0x30c02000); + + // . to set Device Config. Register + //----------------------------- + usbdev3_dcfg.data = 0; + usbdev3_dcfg.b.dev_speed = (u32) eSpeed; + usbdev3_dcfg.b.dev_addr = 0; + usbdev3_dcfg.b.per_fr_int = 2; // 90% + usbdev3_dcfg.b.intr_num = 0; + usbdev3_dcfg.b.num_rx_buf = 1; // khs. 1(simulation code) or 4(reset value)? +#ifdef USBDEV3_LPM_CAPABLE + usbdev3_dcfg.b.lpm_cap = 1; +#endif + writel(usbdev3_dcfg.data, rDCFG); + + // . to enable Global and Device interrupts + // (I should find proper setting value) + //------------------------------------ + exynos_usb_disable_eventinterrupt(); + exynos_usb_flush_eventbuffer(); + exynos_usb_enable_eventinterrupt(); + + usbdev3_devten.data = 0; + usbdev3_devten.b.disconn_evt_en = 1; + usbdev3_devten.b.usb_reset_en = 1; + usbdev3_devten.b.conn_done_en = 1; + //usbdev3_devten.b.usb_lnk_sts_chng_en = 1; + //usbdev3_devten.b.wake_up_en = 1; + //usbdev3_devten.b.errtic_err_en = 1; + //usbdev3_devten.b.cmd_cmplt_en = 1; + usbdev3_devten.b.evnt_overflow_en = 1; + writel(usbdev3_devten.data, rDEVTEN); + + // . to activate EP0 + //---------------- + if (!exynos_usb_activate_ep0()) + { + DBG_USBD3("Activate Ep0 Fail\n"); + return -1; + } + + // . to start EP0 to receive SETUP packets + //---------------------------------- + if (!exynos_usb_start_ep0_setup_rx()) + { + DBG_USBD3("Start Ep0 Setup Rx Fail\n"); + return -1; + } + + // . to enable EP0-OUT/IN in DALEPENA register + //---------------------------------------- + exynos_usb_enable_ep(USBDEV3_EP_DIR_OUT, 0); + exynos_usb_enable_ep(USBDEV3_EP_DIR_IN, 0); + + // . to set the Run/Stop bit + //---------------------- + + return 0; +} + +static void exynos_usb_handle_disconnect_int(void) +{ + oUsbDev3.m_eUsbDev3State = USBDEV3_STATE_DEFAULT; +} + +static int exynos_usb_end_ep_xfer(USBDEV3_EP_DIR_e eEpDir, u8 ucEpNum, u32 uTri) +{ + usbdev3_depcmd_t usbdev3_depcmd; + u32 uEpCmdAddr = (eEpDir==USBDEV3_EP_DIR_IN)? rDIEPCMD(ucEpNum) : rDOEPCMD(ucEpNum); + + usbdev3_depcmd.data = 0; + usbdev3_depcmd.b.cmd_type = DEPCMD_CMD_END_XFER; + usbdev3_depcmd.b.cmd_active = 1; + //usbdev3_depcmd.b.hipri_forcerm = 1; + usbdev3_depcmd.b.param = uTri; + writel(usbdev3_depcmd.data, uEpCmdAddr); + + if (!exynos_usb_wait_ep_cmd_complete(eEpDir, ucEpNum, (10*CMDCOMPLETEWAIT_UNIT))) // wait time is longer than others' + { + return 0; + } + + return 1; +} + +static void exynos_usb_handle_reset_int(void) +{ + u32 uEpNum; + usbdev3_dcfg_t usbdev3_dcfg; + usbdev3_dsts_t usbdev3_dsts; + usbdev3_dgcmd_t usbdev3_dgcmd; + // . Stop All Transfers except for default control EP0 + //------------------------------------------- + // stop any active xfers on the non-EP0 IN endpoints + for (uEpNum = 1; uEpNum < TOTL_EP_COUNT; uEpNum++) + { + if (oUsbDev3.m_uTriIn[uEpNum]) + { + exynos_usb_end_ep_xfer(USBDEV3_EP_DIR_IN, uEpNum, oUsbDev3.m_uTriIn[uEpNum]); + oUsbDev3.m_uTriIn[uEpNum] = 0; + } + } + + // stop any active xfers on the non-EP0 OUT endpoints + for (uEpNum = 1; uEpNum < TOTL_EP_COUNT; uEpNum++) + { + if (oUsbDev3.m_uTriOut[uEpNum]) + { + exynos_usb_end_ep_xfer(USBDEV3_EP_DIR_OUT, uEpNum, oUsbDev3.m_uTriOut[uEpNum]); + oUsbDev3.m_uTriOut[uEpNum] = 0; + } + } + + // . Flush all FIFOs + //--------------- + usbdev3_dgcmd.data= 0; + usbdev3_dgcmd.b.cmd_type = DGCMD_CMD_ALL_FIFO_FLUSH; + usbdev3_dgcmd.b.cmd_active = 1; + writel(usbdev3_dgcmd.data, rDGCMD); + + // wait until command is completed + do + { + udelay(1); + usbdev3_dgcmd.data = readl(rDGCMD); + }while(usbdev3_dgcmd.b.cmd_active); + + // wait until Rx FIFO becomes empty + do + { + udelay(1); + usbdev3_dsts.data = readl(rDSTS); + }while(!(usbdev3_dsts.b.rx_fifo_empty)); + + // . Issue a DEPCSTALL command for any stalled EP + //-------------------------------------------- + // this routine is necessary??? + + // . Set Device Address to 0 + //----------------------- + usbdev3_dcfg.data = readl(rDCFG); + usbdev3_dcfg.b.dev_addr = 0; + writel(usbdev3_dcfg.data, rDCFG); + + // . Set Device State to Default + //-------------------------- + oUsbDev3.m_eUsbDev3State = USBDEV3_STATE_DEFAULT; +} + +static void exynos_usb_set_maxpktsizes(USBDEV3_SPEED_e eSpeed) +{ + oUsbDev3.m_eSpeed = eSpeed; + + if (eSpeed == USBDEV3_SPEED_SUPER) + { + oUsbDev3.m_uControlEPMaxPktSize = SUPER_SPEED_CONTROL_PKT_SIZE; + oUsbDev3.m_uBulkEPMaxPktSize = SUPER_SPEED_BULK_PKT_SIZE; + } + else if (eSpeed == USBDEV3_SPEED_HIGH) + { + oUsbDev3.m_uControlEPMaxPktSize = HIGH_SPEED_CONTROL_PKT_SIZE; + oUsbDev3.m_uBulkEPMaxPktSize = HIGH_SPEED_BULK_PKT_SIZE; + } + else + { + oUsbDev3.m_uControlEPMaxPktSize = FULL_SPEED_CONTROL_PKT_SIZE; + oUsbDev3.m_uBulkEPMaxPktSize = FULL_SPEED_BULK_PKT_SIZE; + } +} + +static void exynos_usb_get_connected_speed(USBDEV3_SPEED_e *eSpeed) +{ + usbdev3_dsts_t usbdev3_dsts; + + usbdev3_dsts.data = readl(rDSTS); + + *eSpeed = (USBDEV3_SPEED_e)usbdev3_dsts.b.connect_speed; +} + +static void exynos_usb_handle_connect_done_int(void) +{ + USBDEV3_SPEED_e eSpeed; + usbdev3_gusb2phycfg_t usbdev3_gusb2phycfg; + usbdev3_gusb3pipectl_t usbdev3_gusb3pipectl; + + usbdev3_depcmdpar0_set_ep_cfg_t usbdev3_depcmdpar0_set_ep_cfg; + usbdev3_depcmdpar1_set_ep_cfg_t usbdev3_depcmdpar1_set_ep_cfg; + + oUsbDev3.m_uEp0State = EP0_STATE_INIT; + + // . Get the connected speed + //------------------------ + exynos_usb_get_connected_speed(&eSpeed); + + // . Suspend the Inactive PHY + //------------------------- + if (eSpeed == USBDEV3_SPEED_SUPER) + { + usbdev3_gusb2phycfg.data = readl(rGUSB2PHYCFG); + usbdev3_gusb2phycfg.b.suspend_usb2_phy = 1; + writel(usbdev3_gusb2phycfg.data, rGUSB2PHYCFG); + } + else + { + usbdev3_gusb3pipectl.data = readl(rGUSB3PIPECTL); + usbdev3_gusb3pipectl.b.suspend_usb3_ss_phy = 1; + writel(usbdev3_gusb3pipectl.data, rGUSB3PIPECTL); + } + + // . Set Max Packet Size based on enumerated speed + //---------------------------------------------- + switch(eSpeed) { + case USBDEV3_SPEED_SUPER : + exynos_usb_set_maxpktsizes(USBDEV3_SPEED_SUPER); + DBG_USBD3("(Enumerated Speed : Super)\n"); + break; + + case USBDEV3_SPEED_HIGH : + exynos_usb_set_maxpktsizes(USBDEV3_SPEED_HIGH); + DBG_USBD3("(Enumerated Speed : High)\n"); + break; + + case USBDEV3_SPEED_FULL : + exynos_usb_set_maxpktsizes(USBDEV3_SPEED_FULL); + DBG_USBD3("(Enumerated Speed : Full)\n"); + break; + + default : + return; + } + + // . Issue Set Ep Configuraton for EP0-OUT/IN based on the connected speed + //---------------------------------------------------------------- + usbdev3_depcmdpar0_set_ep_cfg.data = 0; + usbdev3_depcmdpar0_set_ep_cfg.b.ep_type = USBDEV3_EP_CTRL; + usbdev3_depcmdpar0_set_ep_cfg.b.mps = oUsbDev3.m_uControlEPMaxPktSize; + usbdev3_depcmdpar0_set_ep_cfg.b.ign_dsnum = 1; // to avoid resetting the sequnece number + + usbdev3_depcmdpar1_set_ep_cfg.data = 0; + usbdev3_depcmdpar1_set_ep_cfg.b.xfer_cmpl_en = 1; + //usbdev3_depcmdpar1_set_ep_cfg.b.xfer_in_prog_en = 1; + usbdev3_depcmdpar1_set_ep_cfg.b.xfer_nrdy_en = 1; + usbdev3_depcmdpar1_set_ep_cfg.b.ep_dir = USBDEV3_EP_DIR_OUT; + usbdev3_depcmdpar1_set_ep_cfg.b.ep_num = 0; + + if (!exynos_usb_set_ep_cfg(USBDEV3_EP_DIR_OUT, 0, usbdev3_depcmdpar0_set_ep_cfg.data, usbdev3_depcmdpar1_set_ep_cfg.data)) + { + return ; + } + + usbdev3_depcmdpar1_set_ep_cfg.b.ep_dir = USBDEV3_EP_DIR_IN; + if (!exynos_usb_set_ep_cfg(USBDEV3_EP_DIR_IN, 0, usbdev3_depcmdpar0_set_ep_cfg.data, usbdev3_depcmdpar1_set_ep_cfg.data)) + { + return ; + } + + // . Prepare Descriptor Table + //------------------------ + if (is_fastboot) + fboot_usb_set_descriptors_tlb(); + else + exynos_usb_set_descriptor_tlb(); +} + +static void exynos_usb_handle_dev_event(usbdev3_devt_t uDevEvent) +{ + switch (uDevEvent.b.evt_type) + { + case DEVT_DISCONN: + DBG_USBD3("Disconnect\n"); + exynos_usb_handle_disconnect_int(); + break; + + case DEVT_USBRESET: + DBG_USBD3("USB Reset\n"); + exynos_usb_handle_reset_int(); + break; + + case DEVT_CONNDONE: + DBG_USBD3("Connect Done\n"); + exynos_usb_handle_connect_done_int(); + break; + + case DEVT_WKUP: + DBG_USBD3("Wakeup\n"); + //USBDEV3_HandleWakeupDetectedInt(); + break; + + case DEVT_ULST_CHNG: + DBG_USBD3("Link Status Change\n"); + //USBDEV3_HandleLinkStatusChange(); + break; + + case DEVT_EOPF: + DBG_USBD3("End of Periodic Frame\n"); + //USBDEV3_HandleEndPeriodicFrameInt(); + break; + + case DEVT_SOF: + DBG_USBD3("Start of Frame\n"); + //USBDEV3_HandleSofInt(); + break; + + case DEVT_ERRATICERR: + DBG_USBD3("Erratic Error\n"); + break; + + case DEVT_CMD_CMPL: + DBG_USBD3("Command Complete\n"); + break; + + case DEVT_OVERFLOW: + DBG_USBD3("Overflow\n"); + break; + + default: + DBG_USBD3("Unknown event!\n"); + } + +} + +static void exynos_usb_handle_ep0_in_xfer_complete(void) +{ + switch (oUsbDev3.m_uEp0State) { + case EP0_STATE_IN_DATA_PHASE: + oUsbDev3.m_uEp0State = EP0_STATE_OUT_WAIT_NRDY; + break; + + case EP0_STATE_IN_STATUS_PHASE: + oUsbDev3.m_uEp0State = EP0_STATE_INIT; + + // . to start EP0 to receive SETUP packets + //---------------------------------- + if (!exynos_usb_start_ep0_setup_rx()) + { + return; + } + break; + + // khs. this routine is abnormal case, and handling for this case is not prepared. + default : + DBG_USBD3("\nError : [EP0-InXferComplete]Not Supported @%d\n", oUsbDev3.m_uEp0State); + break; + } +} + +static void exynos_usb_handle_ep_in_xfer_complete(void) +{ + g_uCntOfDescOutComplete = 0; + + g_bIsBulkInXferDone = 1; + + exynos_usb_free((u32)g_pBulkInTrbArray_Base); + + oUsbDev3.m_pUpPt += oUsbDev3.m_uUploadSize; + DBG_USBD3("DMA IN : Transfer Complete\n"); + if (oUsbDev3.m_uUploadSize > 0) { + exynos_receive_done = 1; + printf("Upload Done!! Upload Address: 0x%x, Upload Filesize:0x%x\n", + oUsbDev3.m_uUploadAddr, (oUsbDev3.m_uUploadSize)); + } + +} + +static int exynos_usb_start_ep0_in_xfer(u32 pBufAddr, u32 uLen) +{ + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + + usbdev3_trb_ctrl.data = 0; + + if (oUsbDev3.m_uEp0State == EP0_STATE_IN_STATUS_PHASE) { + if (oUsbDev3.m_bEp0ThreeStage) + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_STATUS_3; + else + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_STATUS_2; + } else { + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_CTLDATA_1ST; + } + + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 1; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + exynos_usb_fill_trb(oUsbDev3.m_oInTrbPtr, pBufAddr, uLen, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for EP0-IN + //---------------------------- + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_IN, 0, (u32)oUsbDev3.m_oInTrbPtr, 0, &oUsbDev3.m_uTriIn[0])) + { + return 0; + } + + return 1; +} + +static int exynos_usb_start_ep0_out_xfer(u32 pBufAddr, u32 uLen) +{ + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + + usbdev3_trb_ctrl.data = 0; + + if (oUsbDev3.m_uEp0State == EP0_STATE_OUT_STATUS_PHASE) { + if (oUsbDev3.m_bEp0ThreeStage) + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_STATUS_3; + else + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_STATUS_2; + } else { + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_CTLDATA_1ST; + } + + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 1; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + exynos_usb_fill_trb(oUsbDev3.m_oOutTrbPtr, pBufAddr, uLen, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for EP0-OUT + //---------------------------- + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_OUT, 0, (u32)oUsbDev3.m_oOutTrbPtr, 0, &oUsbDev3.m_uTriOut[0])) + { + return 0; + } + + return 1; +} + +static void exynos_usb_setup_in_status_phase(void) +{ + + DBG_USBD3("Setup EP0 IN ZLP\n"); + + oUsbDev3.m_uEp0State = EP0_STATE_IN_STATUS_PHASE; + + exynos_usb_start_ep0_in_xfer(oUsbDev3.m_uStatusBufAddr, 0); +} + +static void exynos_usb_setup_out_status_phase(void) +{ + DBG_USBD3("Setup EP0 OUT ZLP\n"); + + oUsbDev3.m_uEp0State = EP0_STATE_OUT_STATUS_PHASE; + + exynos_usb_start_ep0_out_xfer((u32)&oUsbDev3.m_oDeviceRequest, 0); +} + +static void exynos_usb_handle_ep0_in_xfer_not_ready(void) +{ + switch (oUsbDev3.m_uEp0State) { + case EP0_STATE_IN_WAIT_NRDY: + // . to setup in-status phase + exynos_usb_setup_in_status_phase(); + break; + + // khs. this routine is abnormal case, and handling for this case is not prepared. + default : + DBG_USBD3("\nError : [EP0-InXferNotReady]Not Supported @%d\n", oUsbDev3.m_uEp0State); + break; + } +} + +static void exynos_usb_handle_ep_in_event(usbdev3_depevt_t uEpInEvent) +{ + u32 uEpNum = uEpInEvent.b.ep_num/2; // 1,3,5,7,... + + DBG_USBD3("[EP%d] IN State = 0x%x Type = 0x%x[%x]\n", uEpNum, oUsbDev3.m_uEp0State, uEpInEvent.b.evt_type, uEpInEvent.data); + switch (uEpInEvent.b.evt_type) + { + case DEPEVT_EVT_XFER_CMPL: + DBG_USBD3("[EP%d] IN xfer complete @%d\n", uEpNum, oUsbDev3.m_uEp0State); + if (uEpNum == 0) + exynos_usb_handle_ep0_in_xfer_complete(); + else if (uEpNum == BULK_IN_EP) { + if (is_fastboot) + fboot_usb_handle_ep_in_xfer_complete(); + else + exynos_usb_handle_ep_in_xfer_complete(); + } + else + Assert(0); + break; + + case DEPEVT_EVT_XFER_IN_PROG: + DBG_USBD3("[EP%d] IN xfer in progress @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + case DEPEVT_EVT_XFER_NRDY: + DBG_USBD3("[EP%d] IN xfer not ready @%d\n", uEpNum, oUsbDev3.m_uEp0State); + if (uEpNum == 0) + exynos_usb_handle_ep0_in_xfer_not_ready(); + break; + + case DEPEVT_EVT_FIFOXRUN: + DBG_USBD3("[EP%d] IN FIFO Underrun Error @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + case DEPEVT_EVT_STRM_EVT: + DBG_USBD3("[EP%d] IN Stream Event @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + case DEPEVT_EVT_EPCMD_CMPL: + DBG_USBD3("[EP%d] IN Command Complete @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + default: + DBG_USBD3("Unknown event!\n"); + } +} + +static int exynos_usb_prepare_1st_bulk_out_trb(void) +{ + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + + g_bIsBulkOutXferDone = 0; + g_bIsBulkInXferDone = 0; + + g_pBulkOutTrb0 = (usbdev3_trb_ptr_t)exynos_usb_malloc(sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + if (g_pBulkOutTrb0 == NULL) + { + Assert(0); + } + /* size + 1 is for fastboot */ + g_ucTempDownBuf = (u8 *)exynos_usb_malloc(4096 + 1, USBDEV3_MDWIDTH/8); + + if (g_ucTempDownBuf == NULL) + { + Assert(0); + } + + // . Set TRB for 1st Bulk Out Packet + //----------------------------- + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_NORMAL; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 1; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + exynos_usb_fill_trb(g_pBulkOutTrb0, (u32)g_ucTempDownBuf, oUsbDev3.m_uBulkEPMaxPktSize, usbdev3_trb_ctrl.data, 1); + + // . Issue Start Xfer for 1st Bulk Out Packet + //------------------------------------ + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_OUT, BULK_OUT_EP, (u32)g_pBulkOutTrb0, 0, &oUsbDev3.m_uTriOut[BULK_OUT_EP])) + { + return 0; + } + return 1; +} + +void exynos_usb_handle_setup(void) +{ + const u8 *string_desc1, *string_desc2, *string_desc3; + u32 string_desc1_size, string_desc2_size, string_desc3_size; + usbdev3_dcfg_t usbdev3_dcfg; + u32 uRemoteWakeUp = 0; + + exynos_usb_print_ep0_pkt((u8 *)&oUsbDev3.m_oDeviceRequest, 8); + + // . sort Request type + //------------------- + switch(oUsbDev3.m_oDeviceRequest.bmRequestType & 0x60) { + case STANDARD_TYPE: + break; + + case CLASS_TYPE: + DBG_USBD3("Class Type Request is not supported yet\n"); + return; + + case VENDOR_TYPE: + DBG_USBD3("Vendor Type Request is not supported yet\n"); + return; + + default: + DBG_USBD3("0x%02x Type Request is not supported yet\n", oUsbDev3.m_oDeviceRequest.bmRequestType & 0x60); + return; + } + + // . distinguish host2dev from dev2host + if (oUsbDev3.m_oDeviceRequest.bmRequestType & 0x80) + oUsbDev3.m_uEp0State = EP0_STATE_IN_DATA_PHASE; + else + oUsbDev3.m_uEp0State = EP0_STATE_OUT_DATA_PHASE; + + // . find requestlength and decide whether control xfer is 2 stage or 3 stage + oUsbDev3.m_uDeviceRequestLength = (u32)((oUsbDev3.m_oDeviceRequest.wLength_H << 8) | oUsbDev3.m_oDeviceRequest.wLength_L); + + oUsbDev3.m_bEp0ThreeStage = 1; + + if (oUsbDev3.m_uDeviceRequestLength == 0) + { + oUsbDev3.m_uEp0State = EP0_STATE_IN_WAIT_NRDY; + oUsbDev3.m_bEp0ThreeStage = 0; + } + + + // . handle standard type request + //----------------------------- + switch(oUsbDev3.m_oDeviceRequest.bRequest) { + case STANDARD_SET_ADDRESS: + usbdev3_dcfg.data = readl(rDCFG); + usbdev3_dcfg.b.dev_addr = oUsbDev3.m_oDeviceRequest.wValue_L; + writel(usbdev3_dcfg.data, rDCFG); + + DBG_USBD3("\n MCU >> Set Address : %d \n", usbdev3_dcfg.b.dev_addr); + + oUsbDev3.m_eUsbDev3State = USBDEV3_STATE_ADDRESSED; + break; + + case STANDARD_SET_DESCRIPTOR: + DBG_USBD3("\n MCU >> Set Descriptor \n"); + break; + + case STANDARD_SET_CONFIGURATION: + DBG_USBD3("\n MCU >> Set Configuration \n"); + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) + printf("Super speed enumeration success\n"); + g_usConfig = oUsbDev3.m_oDeviceRequest.wValue_L; // Configuration value in configuration descriptor + oUsbDev3.m_eUsbDev3State = USBDEV3_STATE_CONFIGURED; + + // . to activate endpoints for bulk xfer + exynos_usb_activate_ep(USBDEV3_EP_DIR_IN, BULK_IN_EP); + exynos_usb_activate_ep(USBDEV3_EP_DIR_OUT, BULK_OUT_EP); + + // . to enable endpoints for bulk xfer + exynos_usb_enable_ep(USBDEV3_EP_DIR_IN, BULK_IN_EP); + exynos_usb_enable_ep(USBDEV3_EP_DIR_OUT, BULK_OUT_EP); + + exynos_usb_prepare_1st_bulk_out_trb(); + break; + + case STANDARD_GET_CONFIGURATION: + exynos_usb_start_ep0_in_xfer((u32)&g_usConfig, 1); + break; + + case STANDARD_GET_DESCRIPTOR: + switch (oUsbDev3.m_oDeviceRequest.wValue_H) + { + case DEVICE_DESCRIPTOR: + oUsbDev3.m_uDeviceRequestLength = (u32)((oUsbDev3.m_oDeviceRequest.wLength_H << 8) | + oUsbDev3.m_oDeviceRequest.wLength_L); + DBG_USBD3("\n MCU >> Get Device Descriptor = 0x%x \n",oUsbDev3.m_uDeviceRequestLength); + + if (oUsbDev3.m_uDeviceRequestLength<=DEVICE_DESC_SIZE) + { + exynos_usb_start_ep0_in_xfer(((u32)&(oUsbDev3.m_oDesc.oDescDevice))+0, oUsbDev3.m_uDeviceRequestLength); + } + else + { + exynos_usb_start_ep0_in_xfer(((u32)&(oUsbDev3.m_oDesc.oDescDevice))+0, DEVICE_DESC_SIZE); + } + break; + + case CONFIGURATION_DESCRIPTOR: + oUsbDev3.m_uDeviceRequestLength = (u32)((oUsbDev3.m_oDeviceRequest.wLength_H << 8) | + oUsbDev3.m_oDeviceRequest.wLength_L); + DBG_USBD3("\n MCU >> Get Configuration Descriptor = 0x%x \n",oUsbDev3.m_uDeviceRequestLength); + + if (oUsbDev3.m_uDeviceRequestLength > CONFIG_DESC_SIZE){ + // === GET_DESCRIPTOR:CONFIGURATION+INTERFACE+ENDPOINT0+ENDPOINT1 === + // Windows98 gets these 4 descriptors all together by issuing only a request. + // Windows2000 gets each descriptor seperately. + // oUsbDev3.m_uEpZeroTransferLength = CONFIG_DESC_TOTAL_SIZE; + if(oUsbDev3.m_uDeviceRequestLength<=oUsbDev3.m_oDesc.oDescConfig.wTotalLengthL) + { + exynos_usb_start_ep0_in_xfer(((u32)&(oUsbDev3.m_oDesc.oDescConfig))+0, oUsbDev3.m_uDeviceRequestLength); + } + else + { + exynos_usb_start_ep0_in_xfer(((u32)&(oUsbDev3.m_oDesc.oDescConfig))+0, oUsbDev3.m_oDesc.oDescConfig.wTotalLengthL); + } + } + else // for win2k + { + if(oUsbDev3.m_uDeviceRequestLength<=CONFIG_DESC_SIZE) + { + exynos_usb_start_ep0_in_xfer(((u32)&(oUsbDev3.m_oDesc.oDescConfig))+0, oUsbDev3.m_uDeviceRequestLength); + } + else + { + exynos_usb_start_ep0_in_xfer(((u32)&(oUsbDev3.m_oDesc.oDescConfig))+0, CONFIG_DESC_SIZE); + } + } + break; + + case STRING_DESCRIPTOR : + DBG_USBD3("\n MCU >> Get String Descriptor \n"); + if (is_fastboot) { + string_desc1 = fboot_string_desc1; + string_desc2 = fboot_string_desc2; + string_desc3 = fboot_string_desc3; + + string_desc1_size = sizeof(fboot_string_desc1); + string_desc2_size = sizeof(fboot_string_desc2); + string_desc3_size = sizeof(fboot_string_desc3); + } else { + string_desc1 = dnw_string_desc1; + string_desc2 = dnw_string_desc2; + + string_desc1_size = sizeof(dnw_string_desc1); + string_desc2_size = sizeof(dnw_string_desc2); + } + + switch(oUsbDev3.m_oDeviceRequest.wValue_L) + { + case 0: + exynos_usb_start_ep0_in_xfer((u32)string_desc0, STRING_DESC0_SIZE); + break; + case 1: + exynos_usb_start_ep0_in_xfer((u32)string_desc1, string_desc1_size); + break; + case 2: + exynos_usb_start_ep0_in_xfer((u32)string_desc2, string_desc2_size); + break; + case 3: + exynos_usb_start_ep0_in_xfer((u32)string_desc3, string_desc3_size); + break; + default: + break; + } + break; + + case ENDPOINT_DESCRIPTOR: + DBG_USBD3("\n MCU >> Get Endpoint Descriptor \n"); + switch(oUsbDev3.m_oDeviceRequest.wValue_L&0xf) + { + case 0: + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) + exynos_usb_start_ep0_in_xfer((u32)&(oUsbDev3.m_oSSDesc.oDescEp0), ENDPOINT_DESC_SIZE+ENDPOINT_COMP_DESC_SIZE); + else + exynos_usb_start_ep0_in_xfer((u32)&(oUsbDev3.m_oDesc.oDescEp0), ENDPOINT_DESC_SIZE); + break; + case 1: + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_SUPER) + exynos_usb_start_ep0_in_xfer((u32)&(oUsbDev3.m_oSSDesc.oDescEp1), ENDPOINT_DESC_SIZE+ENDPOINT_COMP_DESC_SIZE); + else + exynos_usb_start_ep0_in_xfer((u32)&(oUsbDev3.m_oDesc.oDescEp1), ENDPOINT_DESC_SIZE); + break; + default: + break; + } + break; + + case DEVICE_QUALIFIER: // only supported in over 2.0 + oUsbDev3.m_uDeviceRequestLength = (u32)((oUsbDev3.m_oDeviceRequest.wLength_H << 8) | + oUsbDev3.m_oDeviceRequest.wLength_L); + DBG_USBD3("\n MCU >> Get Device Qualifier Descriptor = 0x%x \n",oUsbDev3.m_uDeviceRequestLength); + + if(oUsbDev3.m_uDeviceRequestLength<=10) + { + exynos_usb_start_ep0_in_xfer((u32)qualifier_desc, oUsbDev3.m_uDeviceRequestLength); + } + else + { + exynos_usb_start_ep0_in_xfer((u32)qualifier_desc, 10); + } + break; + + case OTHER_SPEED_CONFIGURATION : + DBG_USBD3(("\n MCU >> Get OTHER_SPEED_CONFIGURATION \n")); + oUsbDev3.m_uDeviceRequestLength = (u32)((oUsbDev3.m_oDeviceRequest.wLength_H << 8) | + oUsbDev3.m_oDeviceRequest.wLength_L); + + if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_HIGH) + { + if (oUsbDev3.m_uDeviceRequestLength ==9) + { + exynos_usb_start_ep0_in_xfer((u32)config_high, 9); + } + else if(oUsbDev3.m_uDeviceRequestLength ==32) + { + exynos_usb_start_ep0_in_xfer((u32)config_high_total, 32); + } + } + else if (oUsbDev3.m_eSpeed == USBDEV3_SPEED_FULL) + { + if (oUsbDev3.m_uDeviceRequestLength ==9) + { + exynos_usb_start_ep0_in_xfer((u32)config_full, 9); + } + else if(oUsbDev3.m_uDeviceRequestLength ==32) + { + exynos_usb_start_ep0_in_xfer((u32)config_full_total, 32); + } + } + else // super + { + DBG_USBD3("\n %s(line %d)\n", __FILE__, __LINE__); + DBG_USBD3("Error : Not implemented yet\n"); + } + + break; + case BOS : + if (oUsbDev3.m_uDeviceRequestLength == BOS_DESC_SIZE) + exynos_usb_start_ep0_in_xfer((u32)&oUsbDev3.m_oSSDesc.oDescBos, BOS_DESC_SIZE); + else + exynos_usb_start_ep0_in_xfer((u32)&oUsbDev3.m_oSSDesc.oDescBos, BOS_DESC_TOTAL_SIZE); + break; + } + break; + + case STANDARD_CLEAR_FEATURE: + DBG_USBD3("\n MCU >> Clear Feature \n"); + switch (oUsbDev3.m_oDeviceRequest.bmRequestType) + { + case DEVICE_RECIPIENT: + if (oUsbDev3.m_oDeviceRequest.wValue_L == 1) + uRemoteWakeUp = 0; + break; + + case ENDPOINT_RECIPIENT: + if (oUsbDev3.m_oDeviceRequest.wValue_L == 0) + { + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == CONTROL_EP) + oStatusGet.EndpointCtrl= 0; + + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == BULK_IN_EP) // IN Endpoint + oStatusGet.EndpointIn= 0; + + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == BULK_OUT_EP) // OUT Endpoint + oStatusGet.EndpointOut= 0; + } + break; + + default: + break; + } + break; + + case STANDARD_SET_FEATURE: + DBG_USBD3("\n MCU >> Set Feature \n"); + switch (oUsbDev3.m_oDeviceRequest.bmRequestType) + { + case DEVICE_RECIPIENT: + if (oUsbDev3.m_oDeviceRequest.wValue_L == 1) + uRemoteWakeUp = 1; + break; + + case ENDPOINT_RECIPIENT: + if (oUsbDev3.m_oDeviceRequest.wValue_L == 0) + { + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == CONTROL_EP) + oStatusGet.EndpointCtrl= 1; + + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == BULK_IN_EP) + oStatusGet.EndpointIn= 1; + + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == BULK_OUT_EP) + oStatusGet.EndpointOut= 1; + } + break; + + default: + break; + } + + //======================================================= + + switch (oUsbDev3.m_oDeviceRequest.wValue_L) { + + case EP_STALL: + // TBD: additional processing if required + break; + + + case TEST_MODE: + if ((0 != oUsbDev3.m_oDeviceRequest.wIndex_L ) ||(0 != oUsbDev3.m_oDeviceRequest.bmRequestType)) + { + DBG_USBD3("\n %s(line %d)\n", __FILE__, __LINE__); + DBG_USBD3("Error : Wrong Request Parameter\n"); + break; + } + + switch(oUsbDev3.m_oDeviceRequest.wIndex_H) + { + usbdev3_dctl_t usbdev3_dctl; + + case TEST_J: + //Set Test J + exynos_usb_start_ep0_in_xfer((u32)NULL, 0); + DBG_USBD3 ("Test_J\n"); + usbdev3_dctl.data = readl(rDCTL); + usbdev3_dctl.b.test_ctrl = (u32)DCTL_TEST_J_MODE; + writel(usbdev3_dctl.data, rDCTL); + break; + + case TEST_K: + //Set Test K + exynos_usb_start_ep0_in_xfer((u32)NULL, 0); + DBG_USBD3 ("Test_K\n"); + usbdev3_dctl.data = readl(rDCTL); + usbdev3_dctl.b.test_ctrl = (u32)DCTL_TEST_K_MODE; + writel(usbdev3_dctl.data, rDCTL); + break; + + case TEST_SE0_NAK: + //Set Test SE0_NAK + exynos_usb_start_ep0_in_xfer((u32)NULL, 0); + DBG_USBD3 ("Test_SE0_NAK\n"); + usbdev3_dctl.data = readl(rDCTL); + usbdev3_dctl.b.test_ctrl = (u32)DCTL_TEST_SE0_NAK_MODE; + writel(usbdev3_dctl.data, rDCTL); + break; + + case TEST_PACKET: + //Set Test Packet + exynos_usb_start_ep0_in_xfer((u32)NULL, 0); + + // khs. Is this routine necessary? + //exynos_usb_start_ep0_in_xfer((u32)TestPkt, TEST_PKT_SIZE); + + DBG_USBD3 ("Test_Packet\n"); + usbdev3_dctl.data = readl(rDCTL); + usbdev3_dctl.b.test_ctrl = (u32)DCTL_TEST_PACKET_MODE; + writel(usbdev3_dctl.data, rDCTL); + break; + + case TEST_FORCE_ENABLE: + //Set Test Force Enable + exynos_usb_start_ep0_in_xfer((u32)NULL, 0); + DBG_USBD3 ("Test_Force_Enable\n"); + usbdev3_dctl.data = readl(rDCTL); + usbdev3_dctl.b.test_ctrl = (u32)DCTL_TEST_FORCE_ENABLE; + writel(usbdev3_dctl.data, rDCTL); + break; + } + + break; + + default: + break; + } + //======================================================= + break; + + case STANDARD_GET_STATUS: + switch(oUsbDev3.m_oDeviceRequest.bmRequestType) + { + case (0x80): //device + oStatusGet.Device=((u8)uRemoteWakeUp<<1)|0x1; // SelfPowered + exynos_usb_start_ep0_in_xfer((u32)&oStatusGet.Device, 1); + break; + + case (0x81): //interface + oStatusGet.Interface=0; + exynos_usb_start_ep0_in_xfer((u32)&oStatusGet.Interface, 1); + break; + + case (0x82): //endpoint + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == CONTROL_EP) + exynos_usb_start_ep0_in_xfer((u32)&oStatusGet.EndpointCtrl, 1); + + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == BULK_IN_EP) + exynos_usb_start_ep0_in_xfer((u32)&oStatusGet.EndpointIn, 1); + + if ((oUsbDev3.m_oDeviceRequest.wIndex_L & 0x7f) == BULK_OUT_EP) + exynos_usb_start_ep0_in_xfer((u32)&oStatusGet.EndpointOut, 1); + break; + + default: + break; + } + break; + + case STANDARD_GET_INTERFACE: + exynos_usb_start_ep0_in_xfer((u32)&oInterfaceGet.AlternateSetting, 1); + break; + + case STANDARD_SET_INTERFACE: + oInterfaceGet.AlternateSetting= oUsbDev3.m_oDeviceRequest.wValue_L; + break; + + case STANDARD_SYNCH_FRAME: + break; + + case STANDARD_SET_SEL: + oUsbDev3.m_bReq_Set_sel= 1; + /* For SET_SEL */ + exynos_usb_start_ep0_out_xfer((u32)&set_sel, oUsbDev3.m_uControlEPMaxPktSize); + DBG_USBD3("Standard Req : SET SEL\n"); + break; + + case STANDARD_ISOCH_DELY: + DBG_USBD3("Standard Req : ISOCH Delay\n"); + break; + + default: + DBG_USBD3("\n %s(line %d)\n", __FILE__, __LINE__); + DBG_USBD3("Error : This Request(%d) is not implemented yet\n", oUsbDev3.m_oDeviceRequest.bRequest); + break; + } +} + +static void exynos_usb_handle_ep0_out_xfer_complete(void) +{ + switch (oUsbDev3.m_uEp0State) { + case EP0_STATE_INIT: + exynos_usb_handle_setup(); + break; + + case EP0_STATE_OUT_DATA_PHASE: + oUsbDev3.m_uEp0State = EP0_STATE_IN_WAIT_NRDY; + break; + + case EP0_STATE_OUT_STATUS_PHASE: + oUsbDev3.m_uEp0State = EP0_STATE_INIT; + + // . to start EP0 to receive SETUP packets + //---------------------------------- + if (!exynos_usb_start_ep0_setup_rx()) + { + return; + } + break; + + // khs. this routine is abnormal case, and handling for this case is not prepared. + default : + DBG_USBD3("\nError : [EP0-OutXferComplete]Not Supported @%d\n", oUsbDev3.m_uEp0State); + break; + } + +} + +static void exynos_usb_handle_ep_out_xfer_complete(void) +{ + u16 usRxCnt; + u16 usCheck; + u32 usCapTrbBufSiz; + u32 uLastBufSize; + u32 i=0; + usbdev3_trb_ptr_t pBulkOutTrb; + usbdev3_trb_ptr_t pBulkInTrb; + usbdev3_trb_ctrl_t usbdev3_trb_ctrl; + + if (g_uCntOfDescOutComplete == 0) + { + // Check whether TRB was finished successfully or not + if ((g_pBulkOutTrb0->control.b.hwo != 0)||(g_pBulkOutTrb0->status.b.trb_sts != 0)) + { + Assert(0); + } + + g_uCntOfDescOutComplete++; + + usRxCnt = oUsbDev3.m_uBulkEPMaxPktSize - g_pBulkOutTrb0->status.b.buf_siz; + + exynos_usb_free((u32)g_pBulkOutTrb0); + + if (usRxCnt == 10) //Upload Request + { + usCheck = *((u8 *)(g_ucTempDownBuf+8)) + (*((u8 *)(g_ucTempDownBuf+9))<<8); + + if (usCheck == 0x1) + { + oUsbDev3.m_uUploadAddr = + *((u8 *)(g_ucTempDownBuf+0))+ + (*((u8 *)(g_ucTempDownBuf+1))<<8)+ + (*((u8 *)(g_ucTempDownBuf+2))<<16)+ + (*((u8 *)(g_ucTempDownBuf+3))<<24); + + oUsbDev3.m_uUploadSize = + *((u8 *)(g_ucTempDownBuf+4))+ + (*((u8 *)(g_ucTempDownBuf+5))<<8)+ + (*((u8 *)(g_ucTempDownBuf+6))<<16)+ + (*((u8 *)(g_ucTempDownBuf+7))<<24); + + exynos_usb_free((u32)g_ucTempDownBuf); + + oUsbDev3.m_pUpPt=(u8 *)oUsbDev3.m_uUploadAddr; + + DBG_USBD3("UploadAddress : 0x%x, UploadSize: %d\n", oUsbDev3.m_uUploadAddr, oUsbDev3.m_uUploadSize); + + if (oUsbDev3.m_uUploadSize>0) + { + DBG_USBD3("Dma Start for IN PKT \n"); + + // buffer_size of TRB should be + usCapTrbBufSiz = TRB_BUF_SIZ_LIMIT/oUsbDev3.m_uBulkEPMaxPktSize*oUsbDev3.m_uBulkEPMaxPktSize; + + g_uCntOfBulkInTrb = oUsbDev3.m_uUploadSize/usCapTrbBufSiz; + + if ((oUsbDev3.m_uUploadSize%usCapTrbBufSiz) != 0) + { + g_uCntOfBulkInTrb++; + } + + g_pBulkInTrbArray_Base = (usbdev3_trb_ptr_t)exynos_usb_malloc(g_uCntOfBulkInTrb*sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + + if (g_pBulkInTrbArray_Base == NULL) + { + Assert(0); + } + + pBulkInTrb = g_pBulkInTrbArray_Base; + + + // . fill the Trbs + //------------------ + // (Total Buffer size must be in terms of multiple of Max Packet Size) + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 0; + usbdev3_trb_ctrl.b.chn = 1; + usbdev3_trb_ctrl.b.csp = 0; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_NORMAL; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 0; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + for(i=0;i<(g_uCntOfBulkInTrb-1);i++) + { + exynos_usb_fill_trb(pBulkInTrb, (u32)(oUsbDev3.m_pUpPt+usCapTrbBufSiz*i), usCapTrbBufSiz, usbdev3_trb_ctrl.data, 1); + pBulkInTrb++; + } + + // i = g_uCntOfBulkInTrb-1, last Trb + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.chn = 0; + usbdev3_trb_ctrl.b.ioc = 1; + uLastBufSize = oUsbDev3.m_uUploadSize-usCapTrbBufSiz*i; + exynos_usb_fill_trb(pBulkInTrb, (u32)(oUsbDev3.m_pUpPt+usCapTrbBufSiz*i), uLastBufSize, usbdev3_trb_ctrl.data, 1); + // + //// + + // . Issue Start Xfer for Bulk In Xfer + //---------------------------- + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_IN, BULK_IN_EP, (u32)g_pBulkInTrbArray_Base, 0, &oUsbDev3.m_uTriIn[BULK_IN_EP])) + { + return; + } + } + } + else + { + Assert(0); + } + } + else //Download Request + { + oUsbDev3.m_uDownloadAddress = + *((u8 *)(g_ucTempDownBuf+0))+ + (*((u8 *)(g_ucTempDownBuf+1))<<8)+ + (*((u8 *)(g_ucTempDownBuf+2))<<16)+ + (*((u8 *)(g_ucTempDownBuf+3))<<24); + oUsbDev3.m_uDownloadFileSize = + *((u8 *)(g_ucTempDownBuf+4))+ + (*((u8 *)(g_ucTempDownBuf+5))<<8)+ + (*((u8 *)(g_ucTempDownBuf+6))<<16)+ + (*((u8 *)(g_ucTempDownBuf+7))<<24); + + if (exynos_usbd_dn_addr) + { + oUsbDev3.m_uDownloadAddress = exynos_usbd_dn_addr; // Request usb down Addr + } + + oUsbDev3.m_pDownPt=(u8 *)oUsbDev3.m_uDownloadAddress; + + DBG_USBD3("downloadAddress : 0x%x, downloadFileSize: %d\n", oUsbDev3.m_uDownloadAddress, oUsbDev3.m_uDownloadFileSize); + + memcpy((void *)oUsbDev3.m_pDownPt, (void *)(g_ucTempDownBuf+8), usRxCnt-8); + + exynos_usb_free((u32)g_ucTempDownBuf); + + oUsbDev3.m_pDownPt += usRxCnt-8; + + if (oUsbDev3.m_uDownloadFileSize>usRxCnt) //there are more data to be received + { + + usCapTrbBufSiz = TRB_BUF_SIZ_LIMIT/oUsbDev3.m_uBulkEPMaxPktSize*oUsbDev3.m_uBulkEPMaxPktSize; + + g_uCntOfBulkOutTrb = (oUsbDev3.m_uDownloadFileSize-usRxCnt)/usCapTrbBufSiz; + + if ((oUsbDev3.m_uDownloadFileSize-usRxCnt)%usCapTrbBufSiz != 0) + { + g_uCntOfBulkOutTrb++; + } + + g_pBulkOutTrbArray_Base = (usbdev3_trb_ptr_t)exynos_usb_malloc(g_uCntOfBulkOutTrb*sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + + if (g_pBulkOutTrbArray_Base == NULL) + { + Assert(0); + } + + pBulkOutTrb = (usbdev3_trb_ptr_t)virt_to_phys((u32)g_pBulkOutTrbArray_Base); + + // . fill the Trbs + //------------------ + // (Total Buffer size must be in terms of multiple of Max Packet Size) + usbdev3_trb_ctrl.data = 0; + usbdev3_trb_ctrl.b.lst = 0; + usbdev3_trb_ctrl.b.chn = 1; + usbdev3_trb_ctrl.b.csp = 0; + usbdev3_trb_ctrl.b.trb_ctrl = (u32)TRB_CTRL_NORMAL; + usbdev3_trb_ctrl.b.isp_imi = 1; + usbdev3_trb_ctrl.b.ioc = 0; + usbdev3_trb_ctrl.b.strmid_sofn = 0; + + for(i=0;i<(g_uCntOfBulkOutTrb-1);i++) + { + exynos_usb_fill_trb(pBulkOutTrb, (u32)(oUsbDev3.m_pDownPt+usCapTrbBufSiz*i), usCapTrbBufSiz, usbdev3_trb_ctrl.data, 1); + pBulkOutTrb++; + } + + // i = g_uCntOfBulkOutTrb-1, last Trb + usbdev3_trb_ctrl.b.lst = 1; + usbdev3_trb_ctrl.b.chn = 0; + usbdev3_trb_ctrl.b.ioc = 1; + uLastBufSize = (oUsbDev3.m_uDownloadFileSize-usRxCnt)-usCapTrbBufSiz*i; + uLastBufSize = ((uLastBufSize+oUsbDev3.m_uBulkEPMaxPktSize-1)/oUsbDev3.m_uBulkEPMaxPktSize)*oUsbDev3.m_uBulkEPMaxPktSize; + exynos_usb_fill_trb(pBulkOutTrb, (u32)(oUsbDev3.m_pDownPt+usCapTrbBufSiz*i), uLastBufSize, usbdev3_trb_ctrl.data, 1); + // + //// + + // . Issue Start Xfer for Bulk Out Xfer + //---------------------------- + if (!exynos_usb_start_ep_xfer(USBDEV3_EP_DIR_OUT, BULK_OUT_EP, (u32)g_pBulkOutTrbArray_Base, 0, &oUsbDev3.m_uTriOut[BULK_OUT_EP])) + { + return; + } + } + else //there are no more data + { + g_uCntOfDescOutComplete = 0; + + exynos_receive_done = 1; + + DBG_USBD3("DMA OUT : Transfer Complete\n"); + } + } + } + else + { + g_uCntOfDescOutComplete = 0; + + exynos_receive_done = 1; + + exynos_usb_free((u32)g_pBulkOutTrbArray_Base); + + oUsbDev3.m_pDownPt += (oUsbDev3.m_uDownloadFileSize - 8); + + printf("Download Done!! Download Address: 0x%x, Download Filesize:0x%x\n", + oUsbDev3.m_uDownloadAddress, (oUsbDev3.m_uDownloadFileSize-10)); + } +} + +static void exynos_usb_handle_ep0_out_xfer_not_ready(void) +{ + switch (oUsbDev3.m_uEp0State) { + case EP0_STATE_OUT_WAIT_NRDY: + // . to setup out-status phase + exynos_usb_setup_out_status_phase(); + break; + // khs. this routine is abnormal case, and handling for this case is not prepared. + default : + DBG_USBD3("\nError : [EP0-OutXferNotReady]Not Supported @%d\n", oUsbDev3.m_uEp0State); + break; + } +} + +static void exynos_usb_handle_ep_out_event(usbdev3_depevt_t uEpOutEvent) +{ + u32 uEpNum = uEpOutEvent.b.ep_num/2; // 0,2,4,6,... + + DBG_USBD3("[EP%d] Out State = 0x%x Type = 0x%x[0x%x]\n", uEpNum, oUsbDev3.m_uEp0State, uEpOutEvent.b.evt_type, uEpOutEvent.data); + switch (uEpOutEvent.b.evt_type) + { + case DEPEVT_EVT_XFER_CMPL: + DBG_USBD3("[EP%d] OUT xfer complete @%d\n", uEpNum, oUsbDev3.m_uEp0State); + if (uEpNum == 0) + exynos_usb_handle_ep0_out_xfer_complete(); + else if (uEpNum == BULK_OUT_EP) { + if (is_fastboot) + fboot_usb_handle_ep_out_xfer_complete(); + else + exynos_usb_handle_ep_out_xfer_complete(); + } else + Assert(0); + break; + + case DEPEVT_EVT_XFER_IN_PROG: + DBG_USBD3("[EP%d] OUT xfer in progress @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + case DEPEVT_EVT_XFER_NRDY: + DBG_USBD3("[EP%d] OUT xfer not ready @%d\n", uEpNum, oUsbDev3.m_uEp0State); + if (uEpNum == 0) + exynos_usb_handle_ep0_out_xfer_not_ready(); + else + ;// + break; + + case DEPEVT_EVT_FIFOXRUN: + DBG_USBD3("[EP%d] OUT FIFO Overrun Error @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + case DEPEVT_EVT_STRM_EVT: + DBG_USBD3("[EP%d] OUT Stream Event @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + case DEPEVT_EVT_EPCMD_CMPL: + DBG_USBD3("[EP%d] OUT Command Complete @%d\n", uEpNum, oUsbDev3.m_uEp0State); + break; + + default: + DBG_USBD3("Unknown event!\n"); + } + +} + +static void exynos_usb_handle_event(void) +{ + u16 uEventCount, uLoop=0; + u32 uEventBufferCopied; + + // . Get Event Buffer Count + //---------------------- + uEventCount = readl(rGEVNTCOUNT0); + + uEventCount = uEventCount/4; + + if (uEventCount == 0) + { + return; + } + else + { + DBG_USBD3("## Event Count is %d ##\n", uEventCount); + } + + while((uEventCount--> 0) && (uLoop < USBDEV3_EVENT_BUFFER_COUNT)) + { + if (oUsbDev3.m_CurrentEventPosition == USBDEV3_EVENT_BUFFER_COUNT) + { + oUsbDev3.m_CurrentEventPosition = 0; + } + + uEventBufferCopied = *(oUsbDev3.m_pEventBuffer + oUsbDev3.m_CurrentEventPosition); // to avoid that event buffer is overwritten. + + uLoop++; + oUsbDev3.m_CurrentEventPosition++; + + writel(4, rGEVNTCOUNT0); // update event buffer count + // core update event buffer whenever event occurs + if (uEventBufferCopied == 0) + { + DBG_USBD3("## Null Event!##\n"); + } + else // event buffer contains event information + { + DBG_USBD3("\nLoop%d: Content of %dth Event Buffer is 0x%08x\n", uLoop, oUsbDev3.m_CurrentEventPosition, uEventBufferCopied); + + // Device-Specific Event + if (uEventBufferCopied & 0x1) + { + usbdev3_devt_t usbdev3_devt; + + usbdev3_devt.data = uEventBufferCopied; + + //DBG_USBD3IntR("Device-Specific Event Occurred\n"); + + if (usbdev3_devt.b.dev_specific != 0) + { + DBG_USBD3("Other Core Event\n"); + } + + exynos_usb_handle_dev_event(usbdev3_devt); + } + else // Device Endpoint-Specific Event + { + usbdev3_depevt_t usbdev3_depevt; + u32 uEpNum; + + usbdev3_depevt.data = uEventBufferCopied; + + uEpNum = usbdev3_depevt.b.ep_num; + + if (uEpNum & 1) + { + DBG_USBD3("IN Endpoint%d Event Occurred\n", (uEpNum/2)); + exynos_usb_handle_ep_in_event(usbdev3_depevt); + } + else + { + DBG_USBD3("OUT Endpoint%d Event Occurred\n", (uEpNum/2)); + exynos_usb_handle_ep_out_event(usbdev3_depevt); + } + } + } + } +} + +int exynos_usb_wait_cable_insert(void) +{ + u32 tmp1, tmp2; + char ch; + int ret = -1; +#if (defined(CONFIG_CPU_EXYNOS5250) || defined(CONFIG_CPU_EXYNOS5260) || defined(CONFIG_CPU_EXYNOS5430)) + if(oUsbDev3.m_cable != CONNECTED) { + oUsbDev3.m_cable = CONNECTED; + ret = 0; + } + + oUsbDev3.m_uLinkBaseRegs = USBDEVICE3_LINK_CH0_BASE; + oUsbDev3.m_uPhyBaseRegs = USBDEVICE3_PHYCTRL_CH0_BASE; +#else + oUsbDev3.m_uPhyBaseRegs = USBDEVICE3_PHYCTRL_CH0_BASE; + tmp1 = readl(EXYNOS_PHY_ADP); + oUsbDev3.m_uPhyBaseRegs = USBDEVICE3_PHYCTRL_CH1_BASE; + tmp2 = readl(EXYNOS_PHY_ADP); + oUsbDev3.m_uPhyBaseRegs = 0; + if (tmp1 & 0x8 || tmp2 & 0x8) { + if(oUsbDev3.m_cable != CONNECTED) { + ch = (tmp1 & 0x8) ? 0 : 1; + printf("USB cable Connected![CH-%d]\n", ch); + ret = 0; + oUsbDev3.m_cable = CONNECTED; + if (!ch) { + oUsbDev3.m_uLinkBaseRegs = USBDEVICE3_LINK_CH0_BASE; + oUsbDev3.m_uPhyBaseRegs = USBDEVICE3_PHYCTRL_CH0_BASE; + } else { + oUsbDev3.m_uLinkBaseRegs = USBDEVICE3_LINK_CH1_BASE; + oUsbDev3.m_uPhyBaseRegs = USBDEVICE3_PHYCTRL_CH1_BASE; + } + } + } else { + if(oUsbDev3.m_cable == UNCHECKED) { + printf("Insert a USB cable into the connector!\n"); + oUsbDev3.m_cable = DISCONNECTED; + } else if(oUsbDev3.m_cable == CONNECTED) { + oUsbDev3.m_cable = UNCHECKED; + exynos_usb_runstop_device(0); + is_fastboot = 0; + } + } +#endif + return ret; +} + +int exynos_usbc_activate (void) +{ + exynos_usb_runstop_device(1); + return 0; +} + +int exynos_usb_stop( void ) +{ + if(oUsbDev3.m_cable == CONNECTED) { + udelay(1000); + exynos_usb_runstop_device(0); + } + + exynoy_usb_phy_off(); + oUsbDev3.m_cable = UNCHECKED; + + return 0; +} + +int exynos_udc_int_hndlr(void) +{ + exynos_usb_handle_event(); + return OK; +} + +int exynos_usbctl_init(void) +{ + usbdev3_gusb2phycfg_t usbdev3_gusb2phycfg; + usbdev3_gusb3pipectl_t usbdev3_gusb3pipectl; + usbdev3_gctl_t usbdev3_gctl; + USBDEV3_SPEED_e eSpeed = USBDEV3_SPEED_SUPER; + + // . to initialize variables for usb device + //-------------------------------- + // khs. to be implemented more + oUsbDev3.m_eSpeed = eSpeed; + oUsbDev3.m_eUsbDev3State = USBDEV3_STATE_DEFAULT; + oUsbDev3.m_uEp0State = EP0_STATE_UNCONNECTED; + oUsbDev3.m_uEp0SubState = 0; + oUsbDev3.m_bEPs_Enabled = 0; + oUsbDev3.m_bReq_Set_sel = 0; + switch(eSpeed) + { + case USBDEV3_SPEED_SUPER: + oUsbDev3.m_uControlEPMaxPktSize = SUPER_SPEED_CONTROL_PKT_SIZE; + break; + + case USBDEV3_SPEED_FULL: + oUsbDev3.m_uControlEPMaxPktSize = FULL_SPEED_CONTROL_PKT_SIZE; + break; + + default : + oUsbDev3.m_uControlEPMaxPktSize = HIGH_SPEED_CONTROL_PKT_SIZE; + break; + } + + // . to allocate initial buffers for usb device + //------------------------------------ + oUsbDev3.m_pEventBuffer = (u32 *)exynos_usb_malloc(4*USBDEV3_EVENT_BUFFER_COUNT, USBDEV3_MDWIDTH/8); + oUsbDev3.m_uStatusBufAddr = exynos_usb_malloc(CTRL_BUF_SIZE, USBDEV3_MDWIDTH/8); + oUsbDev3.m_oSetupTrbPtr = (usbdev3_trb_ptr_t)exynos_usb_malloc(sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + oUsbDev3.m_oOutTrbPtr = (usbdev3_trb_ptr_t)exynos_usb_malloc(sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + oUsbDev3.m_oInTrbPtr = (usbdev3_trb_ptr_t)exynos_usb_malloc(sizeof(usbdev3_trb_t), USBDEV3_MDWIDTH/8); + + // khs. ep_init 함수 호출을 통한 ep 별 structure 초기화 수행해야할까....? + + // . to set AP system related to usb device (ex. clock source & gating, phy enable) + //-------------------------------------------------------------------- + // - to enable a bus clock for usb dev controller & phy control block + //TODO: Enable system clock and so on. + /* USBDEV3_HclkUsb3ClkGate(true); */ + /* USBDEV3_Usb3PhyEnable(); // USB PHY Enable */ + exynoy_usb_phy_on(); + + /* EXYNOS5 EVT1 : PHY should be reset before global register configuration + This sequence cover reset sequence on EXYNOS5 EVT0. */ + exynos_usb_softreset_phy(1); + exynos_usb_init_phy(); + exynos_usb_softreset_phy(0); + + usbdev3_gusb2phycfg.data = readl(rGUSB2PHYCFG); + usbdev3_gusb2phycfg.b.suspend_usb2_phy = 0; + usbdev3_gusb2phycfg.b.enable_sleep_n = 0; + writel(usbdev3_gusb2phycfg.data, rGUSB2PHYCFG); + + usbdev3_gusb3pipectl.data = readl(rGUSB3PIPECTL); + usbdev3_gusb3pipectl.b.suspend_usb3_ss_phy = 0; + writel(usbdev3_gusb3pipectl.data, rGUSB3PIPECTL); + + // . to initialize usb device phy + //-------------------------- + usbdev3_gctl.data = readl(rGCTL); + usbdev3_gctl.b.core_soft_reset = 1; // to keep the core in reset state until phy clocks are stable(GCTL의 11번 bit 설명 참조) + /* + * WORKAROUND: DWC3 revisions <1.90a have a bug + * when The device fails to connect at SuperSpeed + * and falls back to high-speed mode which causes + * the device to enter in a Connect/Disconnect loop + */ + usbdev3_gctl.b.u2rst_ecn = 1; + writel(usbdev3_gctl.data, rGCTL); + + usbdev3_gctl.data = readl(rGCTL); + usbdev3_gctl.b.core_soft_reset = 0; // to keep the core out of reset state after phy clocks are stable(GCTL의 11번 bit 설명 참조) + writel(usbdev3_gctl.data, rGCTL); + + usbdev3_gctl.b.pwr_down_scale = ((unsigned int)get_usbdrd_clk()) / 16000; + usbdev3_gctl.b.ram_clk_sel = 0; // 00:bus clock, 01:pipe clock, 10:pipe/2 clock + usbdev3_gctl.b.DisScramble = 0; + writel(usbdev3_gctl.data, rGCTL); + + g_uCntOfDescOutComplete = 0; + is_fastboot = 0; + // . to initialize usb device controller + //------------------------------ + if (exynos_usb_init_core(eSpeed)) + { + DBG_USBD3("Exynos USB3 Core Init Fail\n"); + return 0; + } + + return 0; +} +#endif diff --git a/drivers/usb/gadget/usbd3-ss.h b/drivers/usb/gadget/usbd3-ss.h new file mode 100644 index 000000000..418b9734c --- /dev/null +++ b/drivers/usb/gadget/usbd3-ss.h @@ -0,0 +1,1190 @@ +/* + * drivers/usb/gadget/usbd3-ss.h + * + * (C) Copyright 2011 + * Yulgon Kim, Samsung Erectronics, yulgon.kim@samsung.com. + * - only support for S5PC510 + * + * 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 __EXYNOS_USBD_SS_H__ +#define __EXYNOS_USBD_SS_H__ + +#include <asm/byteorder.h> +#include <asm/arch/cpu.h> +#include <asm/arch/usb.h> +#include <asm/io.h> + +//========================== +// Define +//========================== +#define CONTROL_EP 0 +#define BULK_IN_EP 1 +#define BULK_OUT_EP 2 +#define TOTL_EP_COUNT 16 + +#define USBDEV3_MDWIDTH 64 // master data bus width +#define USBDEV3_DATA_BUF_SIZ 16384 // 16KB + +#define CMDCOMPLETEWAIT_UNIT 1000 + +#define RX_FIFO_SIZE 1024 +#define NPTX_FIFO_START_ADDR RX_FIFO_SIZE +#define NPTX_FIFO_SIZE 256 +#define PTX_FIFO_SIZE 256 + +#define CTRL_BUF_SIZE 128 //512 + +// string descriptor +#define LANGID_US_L (0x09) +#define LANGID_US_H (0x04) + +// Feature Selectors +#define EP_STALL 0 +#define DEVICE_REMOTE_WAKEUP 1 +#define TEST_MODE 2 + +/* Test Mode Selector*/ +#define TEST_J 1 +#define TEST_K 2 +#define TEST_SE0_NAK 3 +#define TEST_PACKET 4 +#define TEST_FORCE_ENABLE 5 + +#define USB_DEVICE 0 +#define USB_HOST 1 +#define USB_OTG 2 + +#define FULL_SPEED_CONTROL_PKT_SIZE 64 +#define FULL_SPEED_BULK_PKT_SIZE 64 + +#define HIGH_SPEED_CONTROL_PKT_SIZE 64 +#define HIGH_SPEED_BULK_PKT_SIZE 512 + +#define SUPER_SPEED_CONTROL_PKT_EXP_SZ 9 // 2^9 = 512 +#define SUPER_SPEED_CONTROL_PKT_SIZE 512 +#define SUPER_SPEED_BULK_PKT_SIZE 1024 + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bcdUSBL; + u8 bcdUSBH; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u8 idVendorL; + u8 idVendorH; + u8 idProductL; + u8 idProductH; + u8 bcdDeviceL; + u8 bcdDeviceH; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} USB_DEVICE_DESCRIPTOR; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 wTotalLengthL; + u8 wTotalLengthH; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u8 maxPower; +} USB_CONFIGURATION_DESCRIPTOR; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + u8 iInterface; +} USB_INTERFACE_DESCRIPTOR; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 bEndpointAddress; + u8 bmAttributes; + u8 wMaxPacketSizeL; + u8 wMaxPacketSizeH; + u8 bInterval; +} USB_ENDPOINT_DESCRIPTOR; + +typedef struct { + u8 bLength; + u8 bDescriptorType; + u8 bMaxBurst; + u8 bmAttributes; + u16 wBytesPerInterval; +} __attribute__ ((packed)) USB_SS_EP_COMP_DESCRIPTOR; + +typedef struct +{ + u8 bLength; + u8 bDescriptorType; + u8 *pString; +} USB_STRING_DESCRIPTOR; + +typedef struct { + __u8 bLength; + __u8 bDescriptorType; + __le16 wTotalLength; + __u8 bNumDeviceCaps; +} __attribute__ ((packed)) USB_BOS_DESCRIPTOR; + +typedef struct { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDevCapabilityType; + __le32 bmAttributes; +} __attribute__ ((packed)) USB20_EXT_CAP_DESCRIPTOR; + +typedef struct { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDevCapabilityType; + __u8 bmAttributes; + __le16 wSpeedsSupported; + __u8 bFunctionalitySupport; + __u8 bU1DevExitLat; + __le16 wU2DevExitLat; +} __attribute__ ((packed)) USB_SUPERSPEED_CAP_DESCRIPTOR; + +typedef struct { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDevCapabilityType; + __u8 bReserved; + __u8 containerID[16]; +} __attribute__ ((packed)) USB_CONTAINER_ID_CAP_DESCRIPTOR; + +typedef struct +{ + USB_DEVICE_DESCRIPTOR oDescDevice; + USB_CONFIGURATION_DESCRIPTOR oDescConfig; + USB_INTERFACE_DESCRIPTOR oDescInterface; + USB_ENDPOINT_DESCRIPTOR oDescEp0; + USB_ENDPOINT_DESCRIPTOR oDescEp1; + USB_ENDPOINT_DESCRIPTOR oDescEp2; + USB_ENDPOINT_DESCRIPTOR oDescEp3; +} __attribute__ ((packed)) USB_DESCRIPTORS; + +typedef struct +{ + USB_DEVICE_DESCRIPTOR oDescDevice; + USB_CONFIGURATION_DESCRIPTOR oDescConfig; + USB_INTERFACE_DESCRIPTOR oDescInterface; + USB_ENDPOINT_DESCRIPTOR oDescEp0; + USB_SS_EP_COMP_DESCRIPTOR oDescEp0Comp; + USB_ENDPOINT_DESCRIPTOR oDescEp1; + USB_SS_EP_COMP_DESCRIPTOR oDescEp1Comp; + USB_ENDPOINT_DESCRIPTOR oDescEp2; + USB_SS_EP_COMP_DESCRIPTOR oDescEp2Comp; + USB_ENDPOINT_DESCRIPTOR oDescEp3; + USB_SS_EP_COMP_DESCRIPTOR oDescEp3Comp; + USB_BOS_DESCRIPTOR oDescBos; + USB20_EXT_CAP_DESCRIPTOR oDescUsb20Ext; + USB_SUPERSPEED_CAP_DESCRIPTOR oDescSuperCap; + USB_CONTAINER_ID_CAP_DESCRIPTOR oDescContainCap; +} __attribute__ ((packed)) USB_SS_DESCRIPTORS; + +typedef struct +{ + u8 bmRequestType; + u8 bRequest; + u8 wValue_L; + u8 wValue_H; + u8 wIndex_L; + u8 wIndex_H; + u8 wLength_L; + u8 wLength_H; +} DEVICE_REQUEST, *DEVICE_REQUEST_PTR; + +//===================================================================== +// definitions related to Standard Device Requests +#define SETUP_DATA_SIZE 8 + +// Standard bmRequestType (direction) +// #define DEVICE_bmREQUEST_TYPE(oDeviceRequest) ((m_poDeviceRequest->bmRequestType) & 0x80) +enum DEV_REQUEST_DIRECTION +{ + HOST_TO_DEVICE = 0x00, + DEVICE_TO_HOST = 0x80 +}; + +// Standard bmRequestType (Type) +// #define DEVICE_bmREQUEST_TYPE(oDeviceRequest) ((m_poDeviceRequest->bmRequestType) & 0x60) +enum DEV_REQUEST_TYPE +{ + STANDARD_TYPE = 0x00, + CLASS_TYPE = 0x20, + VENDOR_TYPE = 0x40, + RESERVED_TYPE = 0x60 +}; + +// Standard bmRequestType (Recipient) +// #define DEVICE_bmREQUEST_RECIPIENT(oDeviceRequest) ((m_poDeviceRequest->bmRequestType) & 0x07) +enum DEV_REQUEST_RECIPIENT +{ + DEVICE_RECIPIENT = 0, + INTERFACE_RECIPIENT = 1, + ENDPOINT_RECIPIENT = 2, + OTHER_RECIPIENT = 3 +}; + +// Standard bRequest codes +enum STANDARD_REQUEST_CODE +{ + STANDARD_GET_STATUS = 0, + STANDARD_CLEAR_FEATURE = 1, + STANDARD_RESERVED_1 = 2, + STANDARD_SET_FEATURE = 3, + STANDARD_RESERVED_2 = 4, + STANDARD_SET_ADDRESS = 5, + STANDARD_GET_DESCRIPTOR = 6, + STANDARD_SET_DESCRIPTOR = 7, + STANDARD_GET_CONFIGURATION = 8, + STANDARD_SET_CONFIGURATION = 9, + STANDARD_GET_INTERFACE = 10, + STANDARD_SET_INTERFACE = 11, + STANDARD_SYNCH_FRAME = 12, + STANDARD_SET_SEL = 48, + STANDARD_ISOCH_DELY = 49, +}; + + +// Descriptor types +enum DESCRIPTOR_TYPE +{ + DEVICE_DESCRIPTOR = 1, + CONFIGURATION_DESCRIPTOR = 2, + STRING_DESCRIPTOR = 3, + INTERFACE_DESCRIPTOR = 4, + ENDPOINT_DESCRIPTOR = 5, + DEVICE_QUALIFIER = 6, + OTHER_SPEED_CONFIGURATION = 7, + INTERFACE_POWER = 8, + BOS = 15, +}; + +// configuration descriptor: bmAttributes +enum CONFIG_ATTRIBUTES +{ + CONF_ATTR_DEFAULT = 0x80, // in Spec 1.0, it was BUSPOWERED bit. + CONF_ATTR_REMOTE_WAKEUP = 0x20, + CONF_ATTR_SELFPOWERED = 0x40 +}; + +// endpoint descriptor +enum ENDPOINT_ATTRIBUTES +{ + EP_ADDR_IN = 0x80, + EP_ADDR_OUT = 0x00, + + EP_ATTR_CONTROL = 0x0, + EP_ATTR_ISOCHRONOUS = 0x1, + EP_ATTR_BULK = 0x2, + EP_ATTR_INTERRUPT = 0x3 +}; + +// Descriptor size +enum DESCRIPTOR_SIZE +{ + DEVICE_DESC_SIZE = 18, + STRING_DESC0_SIZE = 4, + STRING_DESC1_SIZE = 22, + STRING_DESC2_SIZE = 42, + CONFIG_DESC_SIZE = 9, + INTERFACE_DESC_SIZE = 9, + ENDPOINT_DESC_SIZE = 7, + ENDPOINT_COMP_DESC_SIZE = 6, + DEVICE_QUALIFIER_SIZE = 10, + OTHER_SPEED_CFG_SIZE = 9, + BOS_DESC_SIZE = 5, + USB20_EXT_CAP_DESC_SIZE = 7, + SUPER_CAP_DESC_SIZE = 10, + CONTAIN_CAP_DESC_SIZE = 5, +}; + +typedef enum +{ + USB_HIGH, USB_FULL, USB_LOW +}USB_SPEED; + +typedef enum +{ + USBPHY0, + USBPHY1, +}USB_PHY; + +typedef enum { + DIFF_100MHz, + DIFF_24MHz, + DIFF_20MHz, + DIFF_19_2MHz, + + EXTREF_50MHz, + EXTREF_24MHz, + EXTREF_20MHz, + EXTREF_19_2MHz, + EXTREF_12MHz, + EXTREF_10MHz, + EXTREF_9_6MHz, +}USB3_PHY_CLKFREQ; + +typedef enum +{ + UNCHECKED, DISCONNECTED, CONNECTED +}CABLE_STATUS; + +typedef struct +{ + u8 ConfigurationValue; +} __attribute__ ((packed)) USB_CONFIGURATION_SET; + +typedef struct +{ + u8 Device; + u8 Interface; + u8 EndpointCtrl; + u8 EndpointIn; + u8 EndpointOut; +} __attribute__ ((packed)) USB_GET_STATUS; + +typedef struct +{ + u8 AlternateSetting; +} __attribute__ ((packed)) USB_INTERFACE_GET; + +typedef struct Usb_st_REG +{ + u8 name[64]; + u32 uAddr; + u8 uBitLen; + u8 uRWType; + u8 uFlag; //Option Flag(DPDB, DPPB, PPDB PPPB) + u32 uPrivateBitMask; + u32 rValue; +}USBDEV3_REGINFO; + +//================================================================== +// CSR STRUCTURE +// +// PHYUTMI +typedef union +{ + u32 data; // reset value : 0x00000630 + struct { + // bit[0] : force sleep + unsigned force_sleep:1; + // bit[1] : force suspend + unsigned force_suspend:1; + // bit[2] : dmpulldown + unsigned dm_pulldown:1; + // bit[3] : dppulldown + unsigned dp_pulldown:1; + // bit[4] : drvvbus + unsigned drvvbus:1; + // bit[5] : idpullup + unsigned id_pullup:1; + // bit[6] : otg disable + unsigned otg_disable:1; + // bit[8:7] : reserved + unsigned rsvd8_7:2; + // bit[9] : external vbus valid indicator (to phy) + unsigned vbusvld_ext:1; + // bit[10] : external vbus valid select + unsigned vbusvld_extsel:1; + // bit[31:11] : reserved + unsigned rsvd31_11:21; + }b; +} usb3_phy_utmi_t; +// PHYCLKPWR +typedef union +{ + u32 data; // reset value : 0x801bee3b@c520, 0x441b4558@c510 + struct { + // bit[0] : common block power-down control + // (0->in suspend or sleep mode, the HS bias and pll blocks remain powered and continue to draw current, + // 1->in suspend or sleep mode, the HS bias and pll blocks are powered down) + unsigned commononn:1; + // bit[1] : per-port reset (reest the port's USB2.0 transmit and receive logic without disableing the clocks) + unsigned portreset:1; + // bit[3:2] : reference clock select for pll block + // (2'b11:HS pll uses EXTREFCLK as reference, 2'b10:HS pll uses ref_pad_clk{p,m} + unsigned refclksel:2; + // bit[4] : lowered digital suplly indicator (0->normal operating mode, 1->analog blocks are powered-down + unsigned retenablen:1; + // bit[10:5] : frequency select + unsigned fsel:6; + // bit[17:11] : mpll frequency multiplier control + unsigned mpll_multiplier:7; + // bit[18] : input reference clock divider control + unsigned ref_clkdiv2:1; + // bit[19] : reference clock enable for SS function + // enables the reference clock to the prescaler + // this must remain deasserted until the ref. clock is running at the appropriate fre., + // at which point ref_ssp_en can be asserted. + // for lower power states, ref_ssp_en can be deasserted. + unsigned ref_ssp_en:1; + // bit[20] : spread spectrum enable + unsigned ssc_en:1; + // bit[22:21] : spread spectrum clock range + unsigned ssc_range:2; + // bit[30:23] : spread spectrum reference clock shifting + unsigned ssc_ref_clk_sel:8; + // bit[31] : reserved + unsigned rsvd31:1; + }b; +} usbdev3_phy_clkpwr_t; +// PHYREG0 +typedef union +{ + u32 data; + struct { + // bit[0] : CR_CMD_ADDR + unsigned cr_cap_addr:1; + // bit[1] : CR_CMD_DATA + unsigned cr_cap_data:1; + // bit[17:2] : send data to crport + unsigned cr_data_in:16; + // bit[18] : CR_CMD_READ + unsigned cr_read:1; + // bit[19] : CR_CMD_WRITE + unsigned cr_write:1; + // bit[31:20] : reserved + unsigned rsvd31_11:12; + }b; +} usb3_phy_reg0_t; +// PHYREG1 +typedef union +{ + u32 data; + struct { + // bit[0] : receive ack from crport + unsigned cr_ack:1; + // bit[16:1] : receive data from crport + unsigned cr_data_out:16; + // bit[31:17] : reserved + unsigned rsvd31_11:15; + }b; +} usb3_phy_reg1_t; +//----------------------- +// Global Registers (Gxxxx) +//----------------------- +// rGSBUSCFG0 +typedef union +{ + u32 data; // reset value : 0x00000001 + struct { + // bit[0] : undefined length INCR burst type enable + unsigned incr_xbrst_ena:1; + // bit[1] : INCR4 burst type enable + unsigned incr_4brst_ena:1; + // bit[2] : INCR8 burst type enable + unsigned incr_8brst_ena:1; + // bit[3] : INCR16 burst type enable + unsigned incr_16brst_ena:1; + // bit[10:4] : + unsigned rsvd10_4:7; + // bit[11] : data access is big endian + unsigned dat_big_end:1; + // bit[12] : bus store-and-forward mode? + unsigned sbus_store_and_forward:1; + // bit[31:13] + unsigned rsvd31_13:19; + }b; +} usbdev3_gsbuscfg0_t; + +// rGSBUSCFG1 +typedef union +{ + u32 data; // reset value : 0x00000300 + struct { + // bit[7:0] : + unsigned rsvd7_0:8; + // bit[11:8] : axi burst request limit + unsigned breq_limit:4; + // bit[12] : 1k page boundary enable + unsigned en_1kpage:1; + // bit[31:13] + unsigned rsvd31_13:19; + }b; +} usbdev3_gsbuscfg1_t; + +// rGSCTL +typedef union +{ + u32 data; // reset value : 0x30c02000 + struct { + // bit[0] : Disable Clock Gating in LP Mode ( 0:Enable, 1:disable ) + unsigned dis_clk_gating:1; + // bit[1] : HS/FS/LS Module Power Clamp + unsigned HsFsLsPwrClmp:1; + // bit[2] : SS Module Power Clamp + unsigned SsPwrClmp:1; + // bit[3] : Disable Data Scrambling in SS ( 0:enable, 1:disable ) + unsigned DisScramble:1; + // bit[5:4] : Scale Down : for simulation + unsigned ScaleDown:2; + // bit[7:6] : ram clock select (0:bus, 1:pipe, 2:pipe/2, 3:rsvd) + unsigned ram_clk_sel:2; + // bit[8] : debug attach + unsigned debug_attach:1; + // bit[9] : loopback enable + unsigned phy_loopback_en:1; + // bit[10] : local loopback enable + unsigned local_loopback_en:1; + // bit[11] : core soft reset + unsigned core_soft_reset:1; + // bit[13:12] : port cabpbility direction (1:host, 2:device, 3:otg configuration) + unsigned port_capdir:2; + // bit[15:14] : + unsigned frm_scale_down:2; + // bit[16] : + unsigned u2rst_ecn:1; + // bit[18:17] : + unsigned rsvd18_17:2; + // bit[31:19] : power down scale + unsigned pwr_down_scale:13; + }b; +} usbdev3_gctl_t; + +// GSTS +typedef enum +{ + GSTS_CUR_OP_MODE_DEVICE, GSTS_CUR_OP_MODE_HOST, GSTS_CUR_OP_MODE_DRD +} USBDEV3_GSTS_CUR_OP_MODE; +typedef union +{ + u32 data; // reset value : 0x + struct { + // bit[1:0] : current mode of operation + unsigned cur_mod:2; + // bit[31:2] : + unsigned rsvd31_2:30; + }b; +} usbdev3_gsts_t; + +// GUSB2PHYCFG +typedef union +{ + u32 data; // reset value : 0x + struct { + // bit[2:0] : + unsigned timeout_cal:3; + // bit[3] : 0-> 8bit, 1-> 16bit + unsigned phy_if:1; + // bit[5:4] : + unsigned rsvd5_4:2; + // bit[6] : + unsigned suspend_usb2_phy:1; + // bit[7] : + unsigned rsvd7:1; + // bit[8] : + unsigned enable_sleep_n:1; + // bit[9] : + unsigned rsvd9:1; + // bit[13:10] : + unsigned turnaround_time:4; + // bit[30:14] : + unsigned rsvd30_14:17; + // bit[31] : + unsigned phy_soft_reset:1; + }b; +} usbdev3_gusb2phycfg_t; + +// GUSB3PIPECTL +typedef union +{ + u32 data; // reset value : 0x00260002 + struct { + // bit[16:0] : + unsigned rsvd16_0:17; + // bit[17] : suspend USB3.0 SS PHY + unsigned suspend_usb3_ss_phy:1; + // bit[30:18] : + unsigned rsvd31_18:13; + // bit[31] : usb3 phy soft reset + unsigned phy_soft_reset:1; + }b; +} usbdev3_gusb3pipectl_t; + +// GEVNTSIZ +typedef union +{ + u32 data; // reset value : 0x00000000 + struct { + // bit[15:0] : event buffer size in bytes (must be a multiple of 4) + unsigned event_siz:16; + // bit[30:16] : + unsigned rsvd30_16:15; + // bit[31] : event interrupt mask (1 : prevent the interrupt from being generated) + unsigned event_int_mask:1; + }b; +} usbdev3_gevntsiz_t; + + +//----------------------- +// Device Registers (Dxxxx) +//----------------------- +// DCFG +typedef enum +{ + USBDEV3_SPEED_SUPER = 4, + USBDEV3_SPEED_HIGH = 0, + USBDEV3_SPEED_FULL = 1 +}USBDEV3_SPEED_e; +typedef union +{ + u32 data; // reset value : 0x00080804 + struct { + // bit[2:0] : device speed + unsigned dev_speed:3; + // bit[9:3] : device address + unsigned dev_addr:7; + // bit[11:10] : periodic frame interval + unsigned per_fr_int:2; + // bit [16:12] : interrupt number + unsigned intr_num:5; + // bit[21:17] : # of rx buffers + unsigned num_rx_buf:5; + // bit[22] : lpm capable + unsigned lpm_cap:1; + // bit[23] : ignore stream pp ??? + unsigned ignore_stream_pp:1; + // bit[31:24] : + unsigned rsvd31_24:8; + }b; +} usbdev3_dcfg_t; + +typedef enum +{ + DCTL_TEST_MODE_DISABLED = 0, + DCTL_TEST_J_MODE = 1, + DCTL_TEST_K_MODE = 2, + DCTL_TEST_SE0_NAK_MODE = 3, + DCTL_TEST_PACKET_MODE = 4, + DCTL_TEST_FORCE_ENABLE = 5, + DCTL_TEST_CTRL_FIELD = 7 +} USBDEV3_DCTL_TEST_CTRL_e; + +// DCTL +typedef union +{ + u32 data; // reset value : 0x0 + struct { + // bit[0] : + unsigned rsvd0:1; + // bit[4:1] : Test Control + unsigned test_ctrl:4; + // bit[29:5] : + unsigned rsvd29_5:25; + // bit[30] : core soft reset + unsigned core_soft_reset:1; + // bit[31] : run/stop + unsigned run_stop:1; + }b; +} usbdev3_dctl_t; + +// DEVTEN +typedef union +{ + u32 data; // reset value : 0x0 + struct { + // bit[0] : disconnect detected event enable + unsigned disconn_evt_en:1; + // bit[1] : usb reset enable + unsigned usb_reset_en:1; + // bit[2] : connection done enable + unsigned conn_done_en:1; + // bit[3] : usb/link state change event enable + unsigned usb_lnk_sts_chng_en:1; + // bit[4] : resume/remote wakeup detected event enable + unsigned wake_up_en:1; + // bit[5] : + unsigned rsvd5:1; + // bit[6] : end of periodic frame event enable + unsigned eopf_en:1; + // bit[7] : start of (micro)frame enable + unsigned sof_en:1; + // bit[8] : + unsigned rsvd8:1; + // bit[9] : erratic error event enable + unsigned errtic_err_en:1; + // bit[10] : generic command compete event enable + unsigned cmd_cmplt_en:1; + // bit[11] : event buffer overflow event enable + unsigned evnt_overflow_en:1; + // bit[12] : vendor device test LMP received event enable ??? + unsigned vndr_dev_tst_rcved_en:1; + // bit[31:13] : + unsigned rsvd31_13:19; + }b; +} usbdev3_devten_t; + +// DSTS +typedef union +{ + u32 data; // reset value : 0x00020004 + struct { + // bit[2:0] : connected speed(0:hs, 1:fs, 4:ss) + unsigned connect_speed:3; + // bit[16:3] : (u)frame # of the received SOF + unsigned soffn:14; + // bit[17] : RxFIFO Empty + unsigned rx_fifo_empty:1; + // bit[21:18] : USB/Link State + unsigned usb_link_sts:4; + // bit[22] : device controller halted + unsigned dev_ctrl_halted:1; + // bit[23] : core idle + unsigned core_idle:1; + // bit[24] : power up request + unsigned pwr_up_req:1; + // bit[31:25] + unsigned rsvd31_25:7; + }b; +} usbdev3_dsts_t; + +// DGCMD +typedef enum +{ + DGCMD_CMD_XMIT_SET_LINK_FUNC_LMP = 0x1, + DGCMD_CMD_SET_PERIODIC_PARAMS = 0x2, + DGCMD_CMD_XMIT_FUNC_WAKE_DEV_NOTIF = 0x3, + DGCMD_CMD_SELECTED_FIFO_FLUSH = 0x9, + DGCMD_CMD_ALL_FIFO_FLUSH = 0xa, + DGCMD_CMD_SET_EP_NRDY = 0xc, + DGCMD_CMD_RUN_SOC_BUS_LOOPBACK_TEST = 0x10 +}USBDEV3_DGCMD_CMD_e; +typedef union +{ + u32 data; // reset value : 0x0 + struct { + // bit[7:0] : command type + unsigned cmd_type:8; + // bit[8] : command interrupt on complete + unsigned ioc:1; + // bit[9] + unsigned rsvd9:1; + // bit[10] : command active + unsigned cmd_active:1; + // bit[14:11] + unsigned rsvd14_11:4; + // bit[15] : command completion status (0:error, 1:success) + unsigned cmd_sts:1; + // bit[31:16] : + unsigned rsvd31_16:16; + }b; +} usbdev3_dgcmd_t; + +// DEPCMDPAR1 + // This structure represents the bit fields in the Device Endpoint Command + // Parameter 1 Register (DEPCMDPAR1n) for the Set Endpoint Configuration + // (DEPCMD_SET_EP_CFG) command. +typedef enum +{ + USBDEV3_EP_DIR_OUT = 0, + USBDEV3_EP_DIR_IN = 1 +}USBDEV3_EP_DIR_e; +typedef union +{ + u32 data; // reset value : 0x0 + struct { + // bit[4:0] : interrupt number + unsigned intr_num:5; + // bit[7:5] + unsigned rsvd7_5:3; + // bit[8] : transfer complete enable + unsigned xfer_cmpl_en:1; + // bit[9] : xfer in progress enable + unsigned xfer_in_prog_en:1; + // bit[10] : xfer not ready enable + unsigned xfer_nrdy_en:1; + // bit[11] : fifo under/over-run enable + unsigned fifo_xrun_en:1; + // bit[12] + unsigned rsvd12:1; + // bit[13] : stream event enable + unsigned str_evnt_en:1; + // bit[15:14] + unsigned rsvd15_14:2; + // bit[23:16] : b interval -1 + unsigned binterval_m1:8; + // bit[24] : stream capable + unsigned strm_cap:1; + // bit[25] : ep direction(0:out, 1:in) + unsigned ep_dir:1; + // bit[29:26] : ep number + unsigned ep_num:4; + // bit[30] : bulk-base + unsigned bulk_based:1; + // bit[31] : fifo-based + unsigned fifo_based:1; + }b; +} usbdev3_depcmdpar1_set_ep_cfg_t; + +// DEPCMDPAR0 + // This structure represents the bit fields in the Device Endpoint Command + // Parameter 0 Register (DEPCMDPAR0n) for the Set Endpoint Configuration + // (DEPCMD_SET_EP_CFG) command. +typedef enum +{ + USBDEV3_EP_CTRL = 0, + USBDEV3_EP_ISOC = 1, + USBDEV3_EP_BULK = 2, + USBDEV3_EP_INTR = 3 +}USBDEV3_EP_TYPE_e; + +typedef union +{ + u32 data; // reset value : 0x0 + struct { + // bit[0] + unsigned rsvd0:1; + // bit[2:1] : ep type + unsigned ep_type:2; + // bit[13:3] : maximum packet size + unsigned mps:11; + // bit[16:14] + unsigned rsvd16_14:3; + // bit[21:17] : fifo number + unsigned fifo_num:5; + // bit[25:22] : burst size + unsigned brst_siz:4; + // bit[30:26] : data sequence number + unsigned ds_num:5; + // bit[31] : ignor sequence number + unsigned ign_dsnum:1; + }b; +} usbdev3_depcmdpar0_set_ep_cfg_t; + +// DEPCMD +typedef enum +{ + DEPCMD_CMD_RSVD = 0x0, + DEPCMD_CMD_SET_EP_CFG = 0x1, + DEPCMD_CMD_SET_EP_XFER_RSRC_CFG = 0x2, + DEPCMD_CMD_GET_DATA_SEQ_NUM = 0x3, + DEPCMD_CMD_SET_STALL = 0x4, + DEPCMD_CMD_CLR_STALL = 0x5, + DEPCMD_CMD_START_XFER = 0x6, + DEPCMD_CMD_UPDATE_XFER = 0x7, + DEPCMD_CMD_END_XFER = 0x8, + DEPCMD_CMD_START_NEW_CFG = 0x9 +} USBDEV3_DEPCMD_CMD_TYPE_e; +typedef union +{ + u32 data; // reset value : 0x0 + struct { + // bit[3:0] : Command Type + unsigned cmd_type:4; + // bit[7:4] + unsigned rsvd7_4:4; + // bit[8] : command interrupt on complete + unsigned ioc:1; + // bit9] + unsigned rsvd9:1; + // bit[10] : command active + unsigned cmd_active:1; + // bit[11] : high priority(only valid for start transfer command), forceRM(only valid for end transfer command) + unsigned hipri_forcerm:1; + // bit[15:12] : command completion status + unsigned cmd_sts:4; + // bit[31:16] : command parameters(written case), event parameters(read case) + unsigned param:16; + }b; +} usbdev3_depcmd_t; + + +///////////////////////////////////////////////// +// Event Buffer Structures +// + +#define USBDEV3_EVENT_BUFFER_COUNT 128 //256 + +// Event Buffer for Device Endpoint-Specific Events +typedef enum +{ + DEPEVT_EVT_XFER_CMPL = 1, + DEPEVT_EVT_XFER_IN_PROG = 2, + DEPEVT_EVT_XFER_NRDY = 3, + DEPEVT_EVT_FIFOXRUN = 4, + DEPEVT_EVT_STRM_EVT = 6, + DEPEVT_EVT_EPCMD_CMPL = 7, +}USBDEV3_DEPEVT_EVT_e; + +typedef union +{ + u32 data; + struct { + // bit[0] : 0-> ep-specific event + unsigned non_ep_evnt:1; + // bit[5:1] : ep number + unsigned ep_num:5; + // bit[9:6] : event type + unsigned evt_type:4; + // bit[11:10] + unsigned rsvd11_10:2; + // bit[15:12] : event status + unsigned evnt_sts:4; + // bit[31:16] : event parameters + unsigned evnt_param:16; + }b; +}usbdev3_depevt_t; + +// Event Buffer for Device-Specific Events +typedef enum +{ + DEVT_DISCONN = 0, + DEVT_USBRESET = 1, + DEVT_CONNDONE = 2, + DEVT_ULST_CHNG = 3, + DEVT_WKUP = 4, + DEVT_EOPF = 6, + DEVT_SOF = 7, + DEVT_ERRATICERR = 9, + DEVT_CMD_CMPL = 10, + DEVT_OVERFLOW = 11, + DEVT_VNDR_DEV_TST_RCVD = 12, + DEVT_INACT_TIMEOUT_RCVD = 13, +}USBDEV3_DEVT_e; + +typedef union +{ + u32 data; + struct { + // bit[0] : 1-> device-specific event + unsigned non_ep_evnt:1; + // bit[7:1] : 0-> device specific, 1-> OTG, 3-> ULPI Carkit, 4-> I2C + unsigned dev_specific:7; + // bit[11:8] : event type + unsigned evt_type:4; + // bit[15:12] + unsigned rsvd15_12:4; + // bit[23:16] : event information bits + unsigned evt_info:8; + // bit[31:24] + unsigned rsvd31_24:8; + }b; +}usbdev3_devt_t; +// + + +///////////////////////////////////////////////// +// DMA Descriptor Specific Structures +// + +// Limit of bytes in one TRB +#define TRB_BUF_SIZ_LIMIT 16777215 //2^24 - 1 (16MB -1byte) + +// status field of TRB +typedef union +{ + u32 data; + struct + { + // bit[23:0] : buffer size + unsigned buf_siz:24; + // bit[25:24] : packet count minus 1 + unsigned pkt_cnt_m1:2; + // bit[27:26] + unsigned rsvd27_26:2; + // bit[31:28] : TRB status + unsigned trb_sts:4; + }b; +}usbdev3_trb_sts_t; + +typedef enum +{ + TRB_CTRL_NORMAL = 1, // Control-Data-2+ / bulk / Interrupt + TRB_CTRL_SETUP = 2, + TRB_CTRL_STATUS_2 = 3, + TRB_CTRL_STATUS_3 = 4, + TRB_CTRL_CTLDATA_1ST = 5, // 1st TRB of Data stage + TRB_CTRL_ISOC_1ST = 6, // 1st TRB of Service Interval + TRB_CTRL_ISOC = 7, + TRB_CTRL_LINK = 8, // Link TRB +}USBDEV3_TRB_TYPE_e; + +// control field of TRB +typedef union +{ + u32 data; + struct + { + // bit[0] : h/w owner of descriptor + unsigned hwo:1; + // bit[1] : last TRB + unsigned lst:1; + // bit[2] : chain buffers + unsigned chn:1; + // bit[3] : continue on short packet + unsigned csp:1; + // bit[9:4] : TRB control + unsigned trb_ctrl:6; + // bit[10] : interrupt on short packet/ interrupt on missed ISOC + unsigned isp_imi:1; + // bit[11] : interrupt on complete + unsigned ioc:1; + // bit[13:12] + unsigned rsvd13_12:2; + // bit[29:14] : stream ID/ SOF # + unsigned strmid_sofn:16; + // bit[31:30] + unsigned rsvd31_30:2; + }b; +}usbdev3_trb_ctrl_t; + +// TRB structure +typedef struct +{ + u32 buf_ptr_l; // buffer pointer low + u32 buf_ptr_h; // buffer pointer high + usbdev3_trb_sts_t status; + usbdev3_trb_ctrl_t control; +}usbdev3_trb_t, *usbdev3_trb_ptr_t; + + +//------------------------------------------------ +// USBDEV state +typedef enum +{ + USBDEV3_STATE_DEFAULT, + USBDEV3_STATE_ADDRESSED, + USBDEV3_STATE_CONFIGURED, +}USBDEV3_STATE; + +typedef struct +{ + union { + USB_DESCRIPTORS m_oDesc; + USB_SS_DESCRIPTORS m_oSSDesc; + }; + + DEVICE_REQUEST m_oDeviceRequest; + + u32 m_uEp0State; + u32 m_uEp0SubState; + USBDEV3_SPEED_e m_eSpeed; + u32 m_uControlEPMaxPktSize; + u32 m_uBulkEPMaxPktSize; + u32 m_uDownloadAddress; + u32 m_uDownloadFileSize; + u32 m_uUploadAddr; + u32 m_uUploadSize; + u8* m_pDownPt; + u8* m_pUpPt; + USBDEV3_STATE m_eUsbDev3State; + u32 m_uDeviceRequestLength; + u8 m_bEp0ThreeStage; + + u8 m_bEPs_Enabled; + + u32 m_uLinkBaseRegs; + u32 m_uPhyBaseRegs; + u32 *m_pEventBuffer; + u16 m_CurrentEventPosition; + + // Buffer for GET_STATUS & GET_DESCRIPTOR up to 512 bytes in length + u32 m_uStatusBufAddr; + + // SET_SEL request pending info + u8 m_bReq_Set_sel; + + // TRB for Setup Packet + volatile usbdev3_trb_ptr_t m_oSetupTrbPtr; + + // TRB for Data-Out or Status-Out phase + volatile usbdev3_trb_ptr_t m_oOutTrbPtr; + + // TRB for Data-In or Status-In phase + volatile usbdev3_trb_ptr_t m_oInTrbPtr; + + // Transfer Resource Index for Each EP + u32 m_uTriOut[TOTL_EP_COUNT]; + u32 m_uTriIn[TOTL_EP_COUNT]; + + // Stall Status for Each EP + u8 m_bEpOutStalled[TOTL_EP_COUNT]; + u8 m_bEpInStalled[TOTL_EP_COUNT]; + + CABLE_STATUS m_cable; +} USBDEV3; + +// EP0 state +enum EP0_STATE +{ + EP0_STATE_UNCONNECTED = 0xffff, + EP0_STATE_INIT = 0, + EP0_STATE_IN_DATA_PHASE = 1, + EP0_STATE_OUT_DATA_PHASE = 2, + EP0_STATE_IN_WAIT_NRDY = 3, + EP0_STATE_OUT_WAIT_NRDY = 4, + EP0_STATE_IN_STATUS_PHASE = 5, + EP0_STATE_OUT_STATUS_PHASE = 6, + EP0_STATE_STALL = 7 +}; + +//===================================================================================== +// prototypes of API functions +void Isr_UsbDev3(void); +u8 USBDEV3_Init(USBDEV3_SPEED_e eSpeed); +void USBDEV3_DeInit(void); + +u8 USBDEV3_IsUsbDevSetConfiguration(void); + +void USBDEV3_Prepare1stBulkOutTrb(void); + +void USBDEV3_ClearDownFileInfo(void); +void USBDEV3_GetDownFileInfo(u32* uDownAddr, u32* uDownFileSize, u8* bIsFinished); +void USBDEV3_ClearUpFileInfo(void); +void USBDEV3_GetUpFileInfo(u32* uUpAddr, u32* uUpFileSize, u8* bIsFinished); +u8 USBDEV3_VerifyChecksum(void); +void USBDEV3_OpenUsingUsbDownAddr(u32 Addr); +void USBDEV3_CloseUsingUsbDownAddr(void); +u32 USBDEV3_AllocateDataStructure(u32 uSize, u32 uAlign); +void USBDEV3_FreeDataStructure(u32 uAddr); + +int exynos_usbctl_init(void); +int exynos_usbc_activate (void); +int exynos_usb_stop( void ); +int exynos_udc_int_hndlr(void); + +/* in usbd3-ss.c */ +extern unsigned int exynos_usbd_dn_addr; +extern unsigned int exynos_usbd_dn_cnt; +extern int DNW; +extern int exynos_got_header; +extern int exynos_receive_done; + +#endif diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 2f8e2b521..84b77dd91 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -33,6 +33,7 @@ COBJS-$(CONFIG_EXYNOS_FB) += exynos_fb.o exynos_fimd.o COBJS-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \ exynos_mipi_dsi_lowlevel.o COBJS-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o +COBJS-$(CONFIG_SHIRI_LCD) += shiri_mipi_lcd.o COBJS-$(CONFIG_S6E8AX0) += s6e8ax0.o COBJS-$(CONFIG_S6E63D6) += s6e63d6.o COBJS-$(CONFIG_SED156X) += sed156x.o @@ -49,6 +50,8 @@ COBJS-$(CONFIG_VIDEO_SM501) += sm501.o COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o +COBJS-$(CONFIG_USE_LCD) += display.o + COBJS := $(sort $(COBJS-y)) SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/drivers/video/display.c b/drivers/video/display.c new file mode 100644 index 000000000..e06d568eb --- /dev/null +++ b/drivers/video/display.c @@ -0,0 +1,400 @@ +/* + * (C) Copyright 2012 Samsung Electronics Co. Ltd + * + * 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 version 2 as + * published by the Free Software Foundation. + * + */ + +#include <common.h> +#include <asm/io.h> +#include <lcd.h> +#include <asm/arch-exynos/movi_partition.h> + +#ifdef CONFIG_FB_ADDR +#define CFG_LCD_FBUFFER CONFIG_FB_ADDR +#else +#define CFG_LCD_FBUFFER (0x46000000) +#endif +#define LCD_WIDTH 240 +#define LCD_HEIGHT 240 +#define LCD_BGCOLOR 0x1428A0 + +void LCD_Backlight_Off(void); +void LCD_Backlight_On(void); +void LCD_Stop(void); +void LCD_turnoff(void); +void LCD_turnon(void); +#ifdef CONFIG_MACH_SHIRI +static void SWTrigger_for_te(void); +#endif + +// Use Just test purpose to fill dummy pattern in Lcd_read_bootlogo() +#define USE_LCD_TEST_PATTERN (0) +#define USE_RAW_IMAGE (0) + +#define BAT_CHG_BITMAP_WIDTH 260 +#define BAT_CHG_BITMAP_HEIGHT 124 +#define BAT_CHG_BITMAP_LEN (BAT_CHG_BITMAP_WIDTH*BAT_CHG_BITMAP_HEIGHT*4) + +#define LOGO_RESERVED_ADDR (0x47000000) + +unsigned char *boot_logo[4]; // 4frame animation logo set. currently not used. +unsigned char *pboot_logo_data; +unsigned char *pboot_logo_data2; + +unsigned char *charger_logo[4]; +unsigned char *pcharger_logo_data; + +static unsigned int gFgColor = 0xFF; +static unsigned int gLeftColor = LCD_BGCOLOR; + +static int lcd_init(void *lcdbase) +{ + lcd_ctrl_init(lcdbase); + + lcd_enable(); + + return 0; +} + +void LCD_turnon(void) +{ + pmic_turnon_vdd_lcd(); //ldo poower on + + lcd_base = CONFIG_FB_ADDR; + + lcd_init(lcd_base); /* LCD initialization */ +} + +void LCD_Stop(void) +{ + exynos_mipi_dsi_stop(); + + exynos_fimd_lcd_off(); +} + +void LCD_turnoff(void) +{ + pmic_turnoff_vdd_lcd(); +} + +void Display_Turnon(void) +{ + Backlight_Turnoff(); + LCD_turnon(); + printf("Turn on Display\n"); +} + +void Backlight_Turnon(void) +{ + backlight_en(1); +} + +void Backlight_Turnoff(void) +{ + backlight_en(0); +} + +void Display_Turnoff(void) +{ + LCD_Stop(); + Backlight_Turnoff(); + LCD_turnoff(); + + printf("Turn off Display\n"); +} + +void LCD_setfgcolor(unsigned int color) +{ + gFgColor = color; +} + +void LCD_setleftcolor(unsigned int color) +{ + gLeftColor = color; +} + +void LCD_clear_content(void) +{ + memset((void*)CFG_LCD_FBUFFER, 0x00, LCD_WIDTH*LCD_HEIGHT*4); +#ifdef CONFIG_MACH_SHIRI + SWTrigger_for_te(); +#endif +} + +void LCD_setprogress(int percentage) +{ + + u32 i, j; + u32* pBuffer = (u32*)CFG_LCD_FBUFFER; + u32 BAR_WIDTH = 30; + u32 BAR_LENGTH = (LCD_WIDTH/100)*80; + u32 sy = (LCD_HEIGHT-BAR_WIDTH)*2/3; + u32 ey = (LCD_HEIGHT+BAR_WIDTH)*2/3; + u32 sx = (LCD_WIDTH-BAR_LENGTH)/2; + u32 ex = (LCD_WIDTH+BAR_LENGTH)/2; + u32 syy = sy-10; + u32 eyy = ey+10; + u32 sxx = sx-10; + u32 exx = ex+10; + + for(i = sxx; i < exx; i++) + { + for (j = syy; j < eyy; j++) + { + *(pBuffer+(j*LCD_WIDTH+i)) = LCD_BGCOLOR; + } + } + + for (i = sx; i < (ex/100)*percentage; i++) + { + for (j = sy; j < ey; j++) + { + *(pBuffer+(j*LCD_WIDTH+i)) = gFgColor; + } + } + + for (; i < ex; i++) + { + for (j=sy; j < ey; j++) + { + *(pBuffer+(j*LCD_WIDTH+i)) = gLeftColor; + } + } +#ifdef CONFIG_MACH_SHIRI + SWTrigger_for_te(); +#endif +} + +void s5p_lcd_draw_bitmap32(const unsigned char *buf) +{ + unsigned long i, j, sx, sy; + unsigned long* pBuffer = (unsigned long*)CFG_LCD_FBUFFER; + unsigned long* pBitmap = (unsigned long*)buf; + unsigned long iBitmapData; + printf("logobuffer:0x%x\n", buf); + + // at default middle + sx = (LCD_WIDTH-BAT_CHG_BITMAP_WIDTH)>>1; + sy = (LCD_HEIGHT-BAT_CHG_BITMAP_HEIGHT)>>1; + sy -= 20; + + for (i = sy; i < sy+BAT_CHG_BITMAP_HEIGHT; i++) + { + for (j = sx; j < sx+BAT_CHG_BITMAP_WIDTH; j++) + { + iBitmapData = *pBitmap | 0xFF<<24; + *(pBuffer+(i*LCD_WIDTH)+j) = iBitmapData; + pBitmap++; + } + } +#ifdef CONFIG_MACH_SHIRI + SWTrigger_for_te(); +#endif +} + +void s5p_lcd_draw_bitmap16(const unsigned char *buf) +{ + unsigned long i, j, sx, sy; + unsigned long* pBuffer = (unsigned long*)CFG_LCD_FBUFFER; + unsigned long* pBitmap = (unsigned long*)buf; + unsigned long iBitmapData; + printf("logobuffer:0x%x\n", buf); + + sx = (LCD_WIDTH-BAT_CHG_BITMAP_WIDTH)>>1; + sy = (LCD_HEIGHT-BAT_CHG_BITMAP_HEIGHT)>>1; + sy -= 20; + + for (i = sy; i < sy+BAT_CHG_BITMAP_HEIGHT; i++) + { + for (j = sx; j < sx+BAT_CHG_BITMAP_WIDTH*2; j+=2) + { + iBitmapData = 0xFF<<24; + iBitmapData |= ((*pBitmap>>8)&0xF8)<<16; + iBitmapData |= ((*pBitmap>>5)&0x3F)<<10; + iBitmapData |= ((*pBitmap<<3)&0xF8); + + *(pBuffer+(i*LCD_WIDTH)+j) = iBitmapData; + *(pBuffer+(i*LCD_WIDTH)+(j+1)) = iBitmapData; + pBitmap++; + } + } +} + +unsigned int s5p_lcd_search_start_blk(const unsigned char *partition_name) +{ + int i = 0; + for(i = 0; i < 16; i++) + { + if(!strncmp(partition_name, raw_area_control.image[i].description, 16)) + { + printf("found %s partition : startblk=0x%x\n", raw_area_control.image[i].description, raw_area_control.image[i].start_blk); + return raw_area_control.image[i].start_blk; + } + } + printf("cannot find partition %s\n", partition_name); + return 0; +} + +void Lcd_read_charger_logo(void) +{ + char run_cmd[100]; + ulong rfs_size; + uint start_blk, blkcnt; + + rfs_size = (512 * 1024); + + pcharger_logo_data = LOGO_RESERVED_ADDR; + + start_blk = s5p_lcd_search_start_blk("charger"); + blkcnt = rfs_size/512 + ((rfs_size&(512-1)) ? 1 : 0); + printf("%s bootlogo.. %ld, %ld \n", "reading",start_blk, blkcnt); + sprintf(run_cmd,"mmc %s 0 %lx %lx %lx","read",pcharger_logo_data, start_blk, blkcnt); + + run_command(run_cmd,0); + + charger_logo[0] = pcharger_logo_data; + charger_logo[1] = (unsigned char *)(pcharger_logo_data + BAT_CHG_BITMAP_LEN); + charger_logo[2] = (unsigned char *)(pcharger_logo_data + BAT_CHG_BITMAP_LEN*2); + charger_logo[3] = (unsigned char *)(pcharger_logo_data + BAT_CHG_BITMAP_LEN*3); +} + +#define BMP_FILE_TYPE 0x4d42 +typedef struct tag_bmp_file_header +{ // bmfh + unsigned short bfType; + unsigned long bfSize; + unsigned long bfReserved; + unsigned long bfOffBits; + + unsigned long biSize; + long int biWidth; + long int biHeight; + unsigned short biPlanes; + unsigned short biBitCount; + unsigned long biCompression; + unsigned long biSizeImage; + long int biXPelsPerMeter; + long int biYPelsPerMeter; + unsigned long biClrUsed; + unsigned long biClrImportant; +}__attribute__ ((packed)) bmp_info_header; + +bmp_info_header logo_bmp_info_head; + +void s5p_lcd_draw_bootlogo(void) +{ +#if USE_LCD_TEST_PATTERN + int i, j; + unsigned height = LCD_HEIGHT / 3; + printf("height:%d\n",height); + + for (i = 0; i < height; i++){ + for(j = 0; j < LCD_WIDTH; j++){ + *((unsigned int *)(CFG_LCD_FBUFFER + (i * LCD_WIDTH + j) * 4)) = 0x0000ff00; + } + } + printf("i:%d, j:%d\n", i, j); + for (i = height; i < height*2; i++){ + for(j = 0; j < LCD_WIDTH; j++){ + *((unsigned int *)(CFG_LCD_FBUFFER + (i * LCD_WIDTH + j) * 4)) = 0x00ff0000; + } + } + for (i = height*2; i < height*3; i++){ + for(j = 0; j < LCD_WIDTH; j++){ + *((unsigned int *)(CFG_LCD_FBUFFER + (i * LCD_WIDTH + j) * 4)) = 0x000000ff; + } + } +#else +#if USE_RAW_IMAGE +#else + unsigned long i, j, bmp_width, bmp_height, bmp_offset; + unsigned long* pBuffer = (unsigned long*)CFG_LCD_FBUFFER; + unsigned long* pBufferEnd = pBuffer + (LCD_HEIGHT*LCD_WIDTH); + unsigned char* pBitmap; + unsigned long* pBitmapLong = (unsigned long*)pBitmap; + unsigned long iBitmapData; + + memcpy(&logo_bmp_info_head, (const void*)pboot_logo_data, sizeof(bmp_info_header)); + if(BMP_FILE_TYPE!=logo_bmp_info_head.bfType || !logo_bmp_info_head.bfSize) { + printf("Err: Check logo format not match !\n"); + memcpy(CFG_LCD_FBUFFER, pboot_logo_data, LCD_WIDTH * LCD_HEIGHT * 4); + return; + } + + bmp_width = logo_bmp_info_head.biWidth; + bmp_height = logo_bmp_info_head.biHeight; + bmp_offset = logo_bmp_info_head.bfOffBits; + + pBitmap = (unsigned char*)pboot_logo_data + bmp_offset; + + for (i = 0; i < bmp_height; i++) + { + for (j = 0; j < bmp_width; j++) + { + iBitmapData = *pBitmap | *(pBitmap+1)<<8 | *(pBitmap+2)<<16 | 0xFF<<24; + *(pBuffer+(LCD_HEIGHT*LCD_WIDTH)-(i*LCD_WIDTH)+j) = iBitmapData; + pBitmap+=3; + } + } +#endif +#endif +#ifdef CONFIG_MACH_SHIRI + SWTrigger_for_te(); +#endif +} + +void Lcd_read_bootlogo(void) +{ +#if USE_LCD_TEST_PATTERN + // 3 Color bar Pattern for LCD test does not require reading logo +#else + char run_cmd[100]; + uint start_blk, blkcnt; + +#if USE_RAW_IMAGE + pboot_logo_data = CFG_LCD_FBUFFER; +#else + pboot_logo_data = LOGO_RESERVED_ADDR; +#endif + + start_blk = s5p_lcd_search_start_blk("bootlogo"); + blkcnt = LCD_WIDTH*LCD_HEIGHT*4/512; // for RAW + printf("%s bootlogo.. %ld, %ld, %08x %08x\n", "reading",start_blk, blkcnt, pboot_logo_data, pboot_logo_data2); + + + // Reading Logo area does not require emmc Open/Close +#if USE_RAW_IMAGE + sprintf(run_cmd,"mmc read 0 %lx %lx %lx ", CFG_LCD_FBUFFER, start_blk, blkcnt); +#else + sprintf(run_cmd,"movi r z l 0 %lx ", pboot_logo_data); +#endif + run_command(run_cmd,0); +#ifdef CONFIG_SHIRI_LCD +#if USE_RAW_IMAGE +// RGB SWAP (ABGR -> ARGB) + int i, j; + unsigned int tmpB, tmpR, pixel; + + for (i = 0; i < LCD_HEIGHT; i++){ + for(j = 0; j < LCD_WIDTH; j++){ + pixel = *((unsigned int *)(CFG_LCD_FBUFFER + (i * LCD_WIDTH + j) *4 )); + tmpB = pixel & 0x00ff0000; + tmpR = pixel & 0x000000ff; + tmpB = tmpB >> 16; + *((unsigned int *)(CFG_LCD_FBUFFER + (i * LCD_WIDTH + j) *4 )) &= 0xff00ff00; + *((unsigned int *)(CFG_LCD_FBUFFER + (i * LCD_WIDTH + j) *4 )) |= tmpR << 16 | tmpB;; + } + } +#endif +#endif +#endif +#ifdef CONFIG_MACH_SHIRI + SWTrigger_for_te(); +#endif +} diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index 49fdfec76..d34a7e4e0 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -73,7 +73,9 @@ static void draw_logo(void) y = ((panel_height - panel_info.logo_height) >> 1) - 4; addr = panel_info.logo_addr; +#ifdef CONFIG_CMD_BMP bmp_display(addr, x, y); +#endif } static void lcd_panel_on(vidinfo_t *vid) diff --git a/drivers/video/exynos_fimd.c b/drivers/video/exynos_fimd.c index f07568acc..55453eac9 100644 --- a/drivers/video/exynos_fimd.c +++ b/drivers/video/exynos_fimd.c @@ -135,7 +135,7 @@ static void exynos_fimd_set_clock(vidinfo_t *pvid) pvid->vl_vbpd + pvid->vl_row); } else if (pvid->interface_mode == FIMD_CPU_INTERFACE) { pixel_clock = pvid->vl_freq * - pvid->vl_width * pvid->vl_height * + pvid->vl_width * pvid->vl_height * 2 * (pvid->cs_setup + pvid->wr_setup + pvid->wr_act + pvid->wr_hold + 1); } else { @@ -183,11 +183,19 @@ void exynos_set_trigger(void) struct exynos4_fb *fimd_ctrl = (struct exynos4_fb *)samsung_get_base_fimd(); +#ifdef CONFIG_CPU_EXYNOS3250 + cfg = readl(0x11c201a4); +#else cfg = readl(&fimd_ctrl->trigcon); +#endif cfg |= (EXYNOS_I80SOFT_TRIG_EN | EXYNOS_I80START_TRIG); +#ifdef CONFIG_CPU_EXYNOS3250 + writel(cfg, 0x11c201a4); +#else writel(cfg, &fimd_ctrl->trigcon); +#endif } int exynos_is_i80_frame_done(void) @@ -197,7 +205,11 @@ int exynos_is_i80_frame_done(void) struct exynos4_fb *fimd_ctrl = (struct exynos4_fb *)samsung_get_base_fimd(); +#ifdef CONFIG_CPU_EXYNOS3250 + cfg = readl(0x11c201a4); +#else cfg = readl(&fimd_ctrl->trigcon); +#endif /* frame done func is valid only when TRIMODE[0] is set to 1. */ status = (cfg & EXYNOS_I80STATUS_TRIG_DONE) == @@ -317,6 +329,64 @@ void exynos_fimd_lcd_init(vidinfo_t *vid) writel(cfg, &fimd_ctrl->vidtcon2); } + else if(vid->interface_mode == FIMD_CPU_INTERFACE) { + cfg |= EXYNOS_VIDCON0_DSI_ENABLE; + writel(cfg, &fimd_ctrl->vidcon0); + + cfg = readl(&fimd_ctrl->vidcon2); + cfg &= ~(EXYNOS_VIDCON2_WB_MASK | + EXYNOS_VIDCON2_TVFORMATSEL_MASK | + EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK); + cfg |= EXYNOS_VIDCON2_WB_DISABLE; + writel(cfg, &fimd_ctrl->vidcon2); + +//VIDOUT_CON + cfg = readl(0x11c20000); + cfg |= (0x2 << 8); //Indirect I80 interface for LDI0 + writel(cfg, 0x11c20000); + + /* set polarity */ + cfg = 0; + if (!pvid->vl_clkp) + cfg |= EXYNOS_VIDCON1_IVCLK_RISING_EDGE; + if (!pvid->vl_hsp) + cfg |= EXYNOS_VIDCON1_IHSYNC_INVERT; + if (!pvid->vl_vsp) + cfg |= EXYNOS_VIDCON1_IVSYNC_INVERT; + if (!pvid->vl_dp) + cfg |= EXYNOS_VIDCON1_IVDEN_INVERT; + +#ifdef CONFIG_CPU_EXYNOS3250 + writel(0x680, 0x11c20004); +#else + writel(cfg, &fimd_ctrl->vidcon1); +#endif + + /* set timing */ + cfg = EXYNOS_VIDTCON0_VFPD(pvid->vl_vfpd - 1); + cfg |= EXYNOS_VIDTCON0_VBPD(pvid->vl_vbpd - 1); + cfg |= EXYNOS_VIDTCON0_VSPW(pvid->vl_vspw - 1); + writel(cfg, &fimd_ctrl->vidtcon0); + + cfg = EXYNOS_VIDTCON1_HFPD(pvid->vl_hfpd - 1); + cfg |= EXYNOS_VIDTCON1_HBPD(pvid->vl_hbpd - 1); + cfg |= EXYNOS_VIDTCON1_HSPW(pvid->vl_hspw - 1); + + writel(cfg, &fimd_ctrl->vidtcon1); + + /* set lcd size */ + cfg = EXYNOS_VIDTCON2_HOZVAL(pvid->vl_col - 1); + cfg |= EXYNOS_VIDTCON2_LINEVAL(pvid->vl_row - 1); + +#ifdef CONFIG_CPU_EXYNOS3250 + writel(cfg, 0x11c20018); +#else + writel(cfg, &fimd_ctrl->vidtcon2); +#endif + +//I80IFCONA0 LCD_WR_ACT[11:8] I80IFEN[0] + writel(0x00000101, 0x11c201b0); + } /* set display mode */ cfg = readl(&fimd_ctrl->vidcon0); diff --git a/drivers/video/exynos_mipi_dsi.c b/drivers/video/exynos_mipi_dsi.c index aee248c84..dd10135d5 100644 --- a/drivers/video/exynos_mipi_dsi.c +++ b/drivers/video/exynos_mipi_dsi.c @@ -242,6 +242,27 @@ int exynos_mipi_dsi_init(void) return 0; } +void exynos_mipi_dsi_stop(void) +{ + struct mipi_dsim_device *dsim; + + dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL); + if (!dsim) { + debug("failed to allocate dsim object.\n"); + return -EFAULT; + } + + exynos_mipi_dsi_sw_reset(dsim); + exynos_mipi_dsi_enable_hs_clock(dsim, 0); + exynos_mipi_dsi_enable_byte_clock(dsim, 0); + exynos_mipi_dsi_enable_lane(dsim, dsim->data_lane, 0); + exynos_mipi_dsi_enable_pll(dsim, 0); + /* phy_enable(unsigned int dev_index, unsigned int enable) */ + if (dsim_pd->phy_enable) + dsim_pd->phy_enable(0, 0); + +} + void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd) { if (pd == NULL) { diff --git a/drivers/video/shiri_mipi_lcd.c b/drivers/video/shiri_mipi_lcd.c new file mode 100644 index 000000000..eb13efa2f --- /dev/null +++ b/drivers/video/shiri_mipi_lcd.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * + * Author: Jaeyong Lee <jaeyong2.lee@samsung.com> + * + * 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/arch/mipi_dsim.h> + +#include "exynos_mipi_dsi_lowlevel.h" +#include "exynos_mipi_dsi_common.h" +/* MIPI S6D04D2X01 MCS commands */ +enum { + MIPI_MCS_PASSWD1 = 0xF0, + MIPI_MCS_PASSWD2 = 0xF1, + MIPI_MCS_DISPCTL = 0xF2, + MIPI_MCS_MAINPWRSEQ = 0xF3, + MIPI_MCS_PWRCTL = 0xF4, + MIPI_MCS_VCMCTL = 0xF5, + MIPI_MCS_SRCCTL = 0xF6, + MIPI_MCS_IFCTL = 0xF7, + MIPI_MCS_PANELCTL = 0xF8, + MIPI_MCS_IFCLK_CTL = 0xF9, + MIPI_MCS_GAMMACTL = 0xFA, + MIPI_MCS_PASSWD3 = 0xFC, + MIPI_MCS_MTPMVCTL = 0xFE, +}; + +static void shiri_mipi_lcd_sleep_out(struct mipi_dsim_device *dsim_dev) +{ + struct mipi_dsim_master_ops *ops = dsim_dev->master_ops; + + ops->cmd_write(dsim_dev, + MIPI_DSI_DCS_SHORT_WRITE, 0x11, 0x00); +} + +static void shiri_mipi_lcd_sequence_on(struct mipi_dsim_device *dsim_dev) +{ + struct mipi_dsim_master_ops *ops = dsim_dev->master_ops; + + unsigned char MCS_CMD_01[7] = {0xE1, 0xF3, 0x10, 0x1C, 0x17, 0x08, 0x1D}; + unsigned char MCS_CMD_02[18]= {0xF2, 0x00, 0xD7, 0x03, 0x22, 0x23, 0x00, 0x01, 0x01, 0x12, 0x01, 0x08, 0x57, 0x00, 0x00, 0xD7, 0x22, 0x23 }; + unsigned char MCS_CMD_03[15]= {0xF4, 0x0B, 0x00, 0x00, 0x00, 0x21, 0x4F, 0x01, 0x02, 0x2A, 0x7F, 0x03, 0x2A, 0x00, 0x03 }; + unsigned char MCS_CMD_04[11]= {0xF5, 0x00, 0x30, 0x49, 0x00, 0x00, 0x18, 0x00, 0x00, 0x04, 0x04 }; + unsigned char MCS_CMD_05[10]= {0xF6, 0x02, 0x01, 0x06, 0x00, 0x02, 0x04, 0x02, 0x84, 0x06 }; + unsigned char MCS_CMD_06[2] = {0xF7, 0x40 }; + unsigned char MCS_CMD_07[3] = {0xF8, 0x33, 0x00 }; + unsigned char MCS_CMD_08[2] = {0xF9, 0x00 }; + unsigned char MCS_CMD_09[2] = {0x36, 0x08 }; + + unsigned char MCS_CMD_E1[7] = {0xE1, 0xF3, 0x10, 0x1C, 0x17, 0x08, 0x1D }; + unsigned char MCS_CMD_E2[6] = {0xE2, 0xC3, 0x87, 0x39, 0x63, 0xD5 }; + unsigned char MCS_CMD_E3[4] = {0xE3, 0x84, 0x06, 0x52 }; + unsigned char MCS_CMD_E4[4] = {0xE4, 0x43, 0x00, 0x00 }; + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_01, ARRAY_SIZE(MCS_CMD_01)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_02, ARRAY_SIZE(MCS_CMD_02)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_03, ARRAY_SIZE(MCS_CMD_03)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_04, ARRAY_SIZE(MCS_CMD_04)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_05, ARRAY_SIZE(MCS_CMD_05)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, + MCS_CMD_06[0],MCS_CMD_06[1]); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_07, ARRAY_SIZE(MCS_CMD_07)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, + MCS_CMD_08[0],MCS_CMD_08[1]); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_09, ARRAY_SIZE(MCS_CMD_09)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_E1, ARRAY_SIZE(MCS_CMD_E1)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_E2, ARRAY_SIZE(MCS_CMD_E2)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_E3, ARRAY_SIZE(MCS_CMD_E3)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_E4, ARRAY_SIZE(MCS_CMD_E4)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE, + 0x11, 0x00); +} + +static void shiri_mipi_lcd_display_on(struct mipi_dsim_device *dsim_dev) +{ + struct mipi_dsim_master_ops *ops = dsim_dev->master_ops; + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE, + 0x29, 0); +} + +static int shiri_mipi_lcd_suspend(struct mipi_dsim_device *dsim_dev) +{ + unsigned char displayoff[] = {0x28}; + unsigned char sleepin[] = {0x10}; + unsigned char MCS_CMD_F1[3] = {MIPI_MCS_PASSWD2, 0x5A, 0x5A}; + unsigned char MCS_CMD_F1_2[3] = {MIPI_MCS_PASSWD2, 0xA5, 0xA5}; + unsigned char MCS_CMD_F4[15] = {MIPI_MCS_PWRCTL, 0x07, 0x00, 0x00, 0x00, 0x21, 0x4F, 0x01, 0x0E, 0x2A, 0x66, + 0x02, 0x2A, 0x00, 0x02}; + int ret = 0; + struct mipi_dsim_master_ops *ops = dsim_dev->master_ops; + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)displayoff, ARRAY_SIZE(displayoff)); + + mdelay(10); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_F1, ARRAY_SIZE(MCS_CMD_F1)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_F4, ARRAY_SIZE(MCS_CMD_F4)); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)MCS_CMD_F1_2, ARRAY_SIZE(MCS_CMD_F1_2)); + + mdelay(120); + + ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE, + (unsigned int)sleepin, ARRAY_SIZE(sleepin)); + + return 1; +} + +static void shiri_mipi_lcd_panel_init(struct mipi_dsim_device *dsim_dev) +{ + /* power setting */ + shiri_mipi_lcd_sequence_on(dsim_dev); + mdelay(5); +} + +static int shiri_mipi_lcd_panel_set(struct mipi_dsim_device *dsim_dev) +{ + shiri_mipi_lcd_panel_init(dsim_dev); + + return 0; +} + +static void shiri_mipi_lcd_display_enable(struct mipi_dsim_device *dsim_dev) +{ + shiri_mipi_lcd_display_on(dsim_dev); +} + +static struct mipi_dsim_lcd_driver shiri_mipi_lcd_dsim_ddi_driver = { + .name = "shiri_mipi_lcd", + .id = -1, + + .mipi_panel_init = shiri_mipi_lcd_panel_set, + .mipi_display_on = shiri_mipi_lcd_display_enable, +}; + +void shiri_mipi_lcd_init(void) +{ + exynos_mipi_dsi_register_lcd_driver(&shiri_mipi_lcd_dsim_ddi_driver); +} diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c index 182f0acac..b1326cdde 100644 --- a/fs/ext2/ext2fs.c +++ b/fs/ext2/ext2fs.c @@ -917,3 +917,1254 @@ fail: ext2fs_root = NULL; return (0); } + +/* + * Format device by ext2. + */ +struct super_block { + __u8 total_inodes[4]; + __u8 total_blocks[4]; + __u8 reserved_blocks[4]; + __u8 free_blocks[4]; + __u8 free_inodes[4]; + __u8 first_data_block[4]; + __u8 log2_block_size[4]; + __u8 log2_fragment_size[4]; + __u8 blocks_per_group[4]; + __u8 fragments_per_group[4]; + __u8 inodes_per_group[4]; + __u8 mtime[4]; + __u8 wtime[4]; + __u8 mnt_count[2]; + __u8 max_mnt_count[2]; + __u8 magic[2]; + __u8 fs_state[2]; + __u8 error_handling[2]; + __u8 minor_revision_level[2]; + __u8 lastcheck[4]; + __u8 checkinterval[4]; + __u8 creator_os[4]; + __u8 revision_level[4]; + __u8 uid_reserved[2]; + __u8 gid_reserved[2]; + __u8 first_inode[4]; + __u8 inode_size[2]; + __u8 block_group_number[2]; + __u8 feature_compatibility[4]; + __u8 feature_incompat[4]; + __u8 feature_ro_compat[4]; + __u8 unique_id[16]; + __u8 volume_name[16]; + __u8 last_mounted_on[64]; + __u8 compression_info[4]; + __u8 prealloc_blk_cnt; + __u8 prealloc_dir_cnt; + __u8 reserved_gtd_blk[2]; + __u8 journal_uuid[16]; + __u8 journal_inode_num[4]; + __u8 journal_device[4]; + __u8 orphan_inode_list[4]; + __u8 hash_seed[16]; + __u8 hash_version; + __u8 journal_backup_type; + __u8 gtd_size[2]; + __u8 mount_option[4]; + __u8 first_meta_blk[4]; + __u8 mkfs_time[4]; + __u8 journal_blocks[68]; + __u8 blocks_cnt_hi[4]; + __u8 reserved_blk_cnt_hi[4]; + __u8 free_blocks_hi[4]; + __u8 min_extra_isize[2]; + __u8 want_extra_isize[2]; + __u8 flags[4]; + __u8 raid_stride[2]; + __u8 mmp_interval[2]; + __u8 mmp_block[8]; + __u8 raid_stripe_width[4]; +}; + +struct group_desc_table { + __u8 start_blkbit_addr[4]; + __u8 start_indbit_addr[4]; + __u8 start_inode_table[4]; + __u8 free_blk_cnt[2]; + __u8 free_inode_cnt[2]; + __u8 directories_cnt[2]; + __u8 padding[2]; + __u8 reserved[12]; +}; + +struct inode_desc { + __u8 file_mode[2]; + __u8 uid[2]; + __u8 size_byte[4]; + __u8 access_time[4]; + __u8 change_time[4]; + __u8 modify_time[4]; + __u8 deletion_time[4]; + __u8 group_id[2]; + __u8 link_count[2]; + __u8 block_count[4]; + __u8 flags[4]; + __u8 os_description1[4]; + __u8 block_pointers[60]; + __u8 generation_num[4]; + __u8 file_acl[4]; + __u8 directory_acl[4]; + __u8 address_fragmentation[4]; + __u8 os_description2[12]; +}; + +#define mk1(p, x) \ + (p) = (__u8)(x) + +#define mk2(p, x) \ + (p)[0] = (__u8)(x), \ + (p)[1] = (__u8)((x) >> 010) + +#define mk4(p, x) \ + (p)[0] = (__u8)(x), \ + (p)[1] = (__u8)((x) >> 010), \ + (p)[2] = (__u8)((x) >> 020), \ + (p)[3] = (__u8)((x) >> 030) + +#define SEC_PER_BLOCK 8 + +unsigned int get_random_val(unsigned int next) +{ + next = next * 1103515245 + 12345; + return((unsigned)(next/65536) % 65536); +} + +unsigned int default_journal_size(uint32_t block_cnt) +{ + if (block_cnt < 2048) + return -1; + if (block_cnt < 32768) + return (1024); + if (block_cnt < 256 * 1024) + return (4096); + if (block_cnt < 512 * 1024) + return (8192); + if (block_cnt < 1024 * 1024) + return (16384); + return (32768); +} +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) +static unsigned int malloc_align(uint32_t size) +{ + uint8_t *addr; + + addr = malloc(sizeof(__u8) * size + 8); + if (addr == NULL) + return NULL; + + if (((uint32_t)addr % 8) == 0) { + *(uint32_t *)(addr + 4) = (uint32_t)addr; + return (uint32_t)(addr + 8); + } + else { + *(uint32_t *)(addr) = (uint32_t)addr; + return (uint32_t)(addr + 4); + } +} +static void free_align(uint32_t addr) +{ + uint32_t addr_free; + if (addr != NULL) { + addr_free = *(uint32_t *)(addr - 4); + free(addr_free); + } +} +#endif +int ext2fs_format(block_dev_desc_t *dev_desc, int part_no, char set_journaling) +{ + + disk_partition_t info; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, SECTOR_SIZE); +#else + unsigned char buffer[SECTOR_SIZE]; +#endif + + if (!dev_desc->block_read) + return -1; + + /* check if we have a MBR (on floppies we have only a PBR) */ + if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { + printf ("** Can't read from device %d **\n", dev_desc->dev); + return -1; + } + if (buffer[0x1fe] != 0x55 || + buffer[0x1fe + 1] != 0xaa) { + printf("** MBR is broken **\n"); + /* no signature found */ + return -1; + } +#if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) ) + /* First we assume, there is a MBR */ + if (!get_partition_info (dev_desc, part_no, &info)) { + printf ("** Partition%d is not ext2 file-system %d **\n", + part_no, dev_desc->dev); + } +#endif + printf("Partition%d: Start Address(0x%x), Size(0x%x)\n", part_no, info.start, info.size); + + /* Write Super Block */ + int blk_group_num = info.size / 0x40000; /* Block group size : 128MB (512B * 0x40000) */ + if (info.size % 0x40000) + blk_group_num += 1; + + int bgcnt; + uint32_t start_block = 0; + uint8_t *img; /* Super Block Image */ + uint32_t uuid[4]; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + img = malloc_align(COMMON_BLOCK_SIZE); +#else + img = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE); +#endif + if (img == NULL) { + printf("Can't make img buffer~~!!\n"); + return -1; + } + + uint8_t *img2; /* Group Descriptor Table */ + /* + * Current group descriptor table size allows until size of 256GB. + * If you want to format more size than 256GB, + * please change GRP_DESC_TABLE_SIZE below. + */ +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + img2 = malloc_align(GRP_DESC_TABLE_SIZE); +#else + img2 = malloc(sizeof(__u8) * GRP_DESC_TABLE_SIZE); +#endif + if (img2 == NULL) { + printf("Can't make img2 buffer~~!!\n"); + return -1; + } + + uint8_t *reserve_img; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + reserve_img = malloc_align(COMMON_BLOCK_SIZE); +#else + reserve_img = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE); +#endif + if (reserve_img == NULL) { + printf("Can't make reserve_img buffer~~!!\n"); + return -1; + } + + uint8_t *img3; /* Block Bitmap */ +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + img3 = malloc_align(COMMON_BLOCK_SIZE); +#else + img3 = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE); +#endif + if (img3 == NULL) { + printf("Can't make img3 buffer~~!!\n"); + return -1; + } + uint8_t *img4; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + img4 = malloc_align(COMMON_BLOCK_SIZE); +#else + img4 = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE); +#endif + if (img4 == NULL) { + printf("Can't make img4 buffer~~!!\n"); + return -1; + } + +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + uint8_t *zerobuf = malloc_align(COMMON_BLOCK_SIZE * 80); +#else + uint8_t *zerobuf = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE * 80); +#endif + if (zerobuf == NULL) { + printf("Can't make zero buffer~~!!\n"); + return -1; + } + + uint8_t *img5; +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + img5 = malloc_align(COMMON_BLOCK_SIZE / 2); +#else + img5 = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE / 2); +#endif + if (img5 == NULL) { + printf("Can't make img5 buffer~~!!\n"); + return -1; + } + +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + uint8_t *rootdata = malloc_align(COMMON_BLOCK_SIZE); +#else + uint8_t *rootdata = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE); +#endif + if (rootdata == NULL) { + printf("Can't make rootdata buffer~~!!\n"); + return -1; + } + +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + uint8_t *inode_data = malloc_align(INODE_DATA_SIZE); +#else + uint8_t *inode_data = malloc(sizeof(__u8) * INODE_DATA_SIZE); +#endif + if (inode_data == NULL) { + printf("Can't make inodedata buffer~~!!\n"); + return -1; + } + +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + uint8_t *inode_data2 = malloc_align(COMMON_BLOCK_SIZE); +#else + uint8_t *inode_data2 = malloc(sizeof(__u8) * COMMON_BLOCK_SIZE); +#endif + if (inode_data2 == NULL) { + printf("Can't make inodedata2 buffer~~!!\n"); + return -1; + } + + printf("Start ext2format...\n"); + for (bgcnt = 0; bgcnt < blk_group_num; bgcnt++) { + printf("Wirte %d/%dblock-group\n",bgcnt, blk_group_num); + int i = 0; + int rsv_blk_cnt = 0; + struct super_block *sblock; + memset(img, 0x0, sizeof(__u8) * COMMON_BLOCK_SIZE); + if (bgcnt == 0) + sblock = (struct super_block *)(img + 1024); + else + sblock = (struct super_block *)img; + + uint32_t total_blocks = info.size / SEC_PER_BLOCK; /* 4KB block */ + mk4(sblock->total_blocks, total_blocks); /* block count */ + uint32_t total_inodes = (total_blocks / 0x20); + if (total_blocks % 0x20) { + total_inodes += 1; + /* Fix Me... it's just temp code */ + /* Check... 'total_blocks % 0x20'*/ + if (total_blocks > 0x8000 && total_blocks < 0x10000) { + total_inodes += 1; + } + } + total_inodes *= 0x20; + + if (total_blocks > 0x3E800) /* if size > 1GB */ + total_inodes /= 2; + + uint32_t inodes_per_group = ((total_inodes -1) / blk_group_num) + 1; + inodes_per_group = (inodes_per_group / 0x20) + 1; + inodes_per_group *= 0x20; + + if (total_blocks > 0x8000) + mk4(sblock->inodes_per_group, inodes_per_group); /* inode for group */ + else + mk4(sblock->inodes_per_group, total_inodes); /* inode for group */ + + uint32_t reserved_blocks = total_blocks * 5 / 100; + mk4(sblock->reserved_blocks, reserved_blocks); /* reserved block count */ + mk4(sblock->first_data_block, 0); /* frist data block */ + mk4(sblock->log2_block_size, 2); /* log block size */ + mk4(sblock->log2_fragment_size, 2); /* log fragmentation size */ + /* 8(1bit) * 4096(1block:4K) */ + mk4(sblock->blocks_per_group, 0x8000); /* block per group */ + uint32_t blocks_per_group = 0x8000; + mk4(sblock->fragments_per_group, 0x8000); /* fragmentation per group */ + mk4(sblock->mtime, 0); /* mtime */ + mk4(sblock->wtime, 0x33); /* wtime : 0x33 means nothing*/ + mk2(sblock->mnt_count, 0); /* mount count*/ + mk2(sblock->max_mnt_count, 0x20); /* max mount count */ + mk2(sblock->magic, EXT2_MAGIC); /* magic signature */ + mk2(sblock->fs_state, 1); /* state (1:valid, 2:error) */ + mk2(sblock->error_handling, 1); /* errors */ + mk2(sblock->minor_revision_level, 0); /* minor version */ + mk4(sblock->lastcheck, 0); /* last check time */ + mk4(sblock->checkinterval, 0xed4e00); /* check interval */ + mk4(sblock->creator_os, 0); /* creator os */ + mk4(sblock->revision_level, 1); /* major version */ + mk2(sblock->uid_reserved, 0); /* UID that can use reserved blocks */ + mk2(sblock->gid_reserved, 0); /* GID that can use reserved blocks */ + mk4(sblock->first_inode, 0xb); /* first non-reserved inode */ + mk2(sblock->inode_size, 0x80); /* inode structure size */ + mk2(sblock->block_group_number, 0); /* block group num */ + uint32_t feature_compatibility = 0x30; /* default */ + if (set_journaling) { + feature_compatibility += 0x4; /* 0x4 means HAS_JOURNAL */ + } + mk4(sblock->feature_compatibility, feature_compatibility); /* compatible feature */ + mk4(sblock->feature_incompat, 0x2); /* incompatible feature */ + mk4(sblock->feature_ro_compat, 0x3); /* read-only feature */ + if (bgcnt == 0) { + /* Set Unique ID */ + uuid[0] = get_random_val(get_timer(0)); + uuid[0] |= (get_random_val(get_timer(0)) << 16); + uuid[1] = get_random_val(get_timer(0)); + uuid[1] |= (get_random_val(get_timer(0)) << 16); + uuid[2] = get_random_val(get_timer(0)); + uuid[2] |= (get_random_val(get_timer(0)) << 16); + uuid[3] = get_random_val(get_timer(0)); + uuid[3] |= (get_random_val(get_timer(0)) << 16); + } + mk4(sblock->unique_id, uuid[0]); /* UUID filesystem ID */ + mk4(sblock->unique_id + 4, uuid[1]); /* UUID filesystem ID */ + mk4(sblock->unique_id + 8, uuid[2]); /* UUID filesystem ID */ + mk4(sblock->unique_id + 12, uuid[3]); /* UUID filesystem ID */ + mk4(sblock->compression_info, 0); /* algorithm usage bitmap */ + + uint32_t reserved_gdt_blk = total_blocks >> 12; + mk2(sblock->reserved_gtd_blk, reserved_gdt_blk); /* reserved gtd blocks */ + if (set_journaling) { + /* 8th inode is reserved for journaling */ + mk4(sblock->journal_inode_num, 8); + sblock->journal_backup_type = 1; + } + mk2(sblock->hash_seed, get_random_val(get_timer(0))); /* Hash Seed */ + mk2(sblock->hash_seed + 2, get_random_val(get_timer(0))); + mk2(sblock->hash_seed + 4, get_random_val(get_timer(0))); + mk2(sblock->hash_seed + 6, get_random_val(get_timer(0))); + mk2(sblock->hash_seed + 8, get_random_val(get_timer(0))); + mk2(sblock->hash_seed + 10, get_random_val(get_timer(0))); + mk2(sblock->hash_seed + 12, get_random_val(get_timer(0))); + mk2(sblock->hash_seed + 14, get_random_val(get_timer(0))); + sblock->hash_version = 0x2; + mk4(sblock->mkfs_time, 0x33); /* 0x33 means nothing */ + + /* Write Group Descriptor Table */ + struct group_desc_table *desc_table; + memset(img2, 0x0, sizeof(__u8) * GRP_DESC_TABLE_SIZE); + + int offset = 0; + uint32_t free_blk_cnt = 0; + uint32_t free_inode_cnt = 0; + uint32_t free_blocks = 0; + uint32_t free_inodes = 0; + uint32_t start_blkbit_addr = 0; + uint32_t start_indbit_addr = 0; + uint32_t start_indtable_addr = 0; + + uint32_t current_free_blk = 0; + uint32_t reserved_blk_cnt = 0; + uint32_t normal_used_blk = 0; + uint32_t default_used_blk = 0; + uint32_t first_inode_table_addr = 0; + uint32_t current_blkbit_addr = 0; + uint32_t current_indbit_addr = 0; + uint32_t current_indtable_addr= 0; + + char have_rev_gdt = 0; + int remain_blocks = 0; + int jnl_blocks = 0; + int32_t jnldata_start_addr = 0; + /* second group inode table offset */ + int32_t seblk_offset = 0; + + /* write counter for img2 */ + uint32_t w_count = (((blk_group_num - 1) / 128) + 1) * 8; + + /* Starting block address of block bitmap */ + for (i = 0; i < blk_group_num; i++) { + char is_revgdt = 0; + /* 0 group description table need to change for default + * directory. + */ + start_blkbit_addr = i * blocks_per_group; + start_indbit_addr = 1 + i * blocks_per_group; + start_indtable_addr = 2 + i * blocks_per_group; + desc_table = (struct group_desc_table *)(img2 + offset); + + /* last block is not full size */ + if (i == blk_group_num - 1) { + //uint32_t remain_blocks = total_blocks - + // (blocks_per_group * i); + uint32_t remain_blocks = total_blocks % 0x8000; + free_blk_cnt = remain_blocks - 4 - + (inodes_per_group * 128 / COMMON_BLOCK_SIZE) + 2; + free_inode_cnt = inodes_per_group; + } else { + /* + * 0x8000 : total blocks per group + * 4 : super block(1), group descriptor table(1), + * block bitmap(1), inode bitmap(1) + * (inodes_per_group * 128 / 4096) : inode table + * 2 : ?? (block start from 0??) + * reserved block include superblock&gdt + */ + free_blk_cnt = 0x8000 - 4 - (inodes_per_group * 128 / COMMON_BLOCK_SIZE) + 2; + free_inode_cnt = inodes_per_group; + } + + if (i == 0) { + is_revgdt = 1; + reserved_blk_cnt++; + /* For default creation */ + free_blk_cnt -= 6; + if (total_blocks > 0x8000) /* if size > 128MB */ + free_inode_cnt -= 0xb; + else + free_inode_cnt -= 0x2b; + + start_blkbit_addr += reserved_gdt_blk + 2; + start_indbit_addr += reserved_gdt_blk + 2; + start_indtable_addr += reserved_gdt_blk + 2; + free_blk_cnt -= (reserved_gdt_blk + 2); + + first_inode_table_addr = start_indtable_addr; + } + + /* delete journaling block from free blocks */ + if (set_journaling) { + if (i == 0) { + jnl_blocks = default_journal_size(total_blocks); + /* 1024 means number of pointing by 1blcok (4096/4) */ + jnl_blocks += (jnl_blocks / 1024); + if (jnl_blocks >= 4096) { + /* + * 2 blocks are needed to use double + * indirect pointer + */ + jnl_blocks += 2; + } + printf("Reserved blocks for jounaling : %d\n", jnl_blocks); + if (free_blk_cnt >= jnl_blocks) { + free_blk_cnt -= jnl_blocks; + } + else { + remain_blocks = jnl_blocks - + free_blk_cnt; + free_blk_cnt = 0; + } + } else { + + if (remain_blocks > 0) { + free_blk_cnt -= remain_blocks; + remain_blocks = 0; + } + } + } + + /* + * Keep reserved region.??? + * If card is higher than 16GB, below codes must be fixed. + * Please excute mke2fs on linux and check messages + * 'superblock backups stored on blocks:'. + */ + if (i < 10) { + if (i % 2) { + is_revgdt = 1; + reserved_blk_cnt++; + start_blkbit_addr += reserved_gdt_blk + 2; + start_indbit_addr += reserved_gdt_blk + 2; + start_indtable_addr += reserved_gdt_blk + 2; + free_blk_cnt -= (reserved_gdt_blk + 2); + rsv_blk_cnt++; + } + } else if (i > 20 && i < 30) { + if (i == 25 || i == 27) { + is_revgdt = 1; + reserved_blk_cnt++; + start_blkbit_addr += reserved_gdt_blk + 2; + start_indbit_addr += reserved_gdt_blk + 2; + start_indtable_addr += reserved_gdt_blk + 2; + free_blk_cnt -= (reserved_gdt_blk + 2); + rsv_blk_cnt++; + } + } else if (i > 40 && i < 50) { + if (i == 49) { + is_revgdt = 1; + reserved_blk_cnt++; + start_blkbit_addr += reserved_gdt_blk + 2; + start_indbit_addr += reserved_gdt_blk + 2; + start_indtable_addr += reserved_gdt_blk + 2; + free_blk_cnt -= (reserved_gdt_blk + 2); + rsv_blk_cnt++; + } + } + + free_blocks += free_blk_cnt; + free_inodes += free_inode_cnt; + + mk4(desc_table->start_blkbit_addr, start_blkbit_addr); + mk4(desc_table->start_indbit_addr, start_indbit_addr); + mk4(desc_table->start_inode_table, start_indtable_addr); + mk2(desc_table->free_blk_cnt, free_blk_cnt); + + if (i == 1) { + seblk_offset = start_indtable_addr - 0x8000; + } + if (i == bgcnt) { //original code + //if (i == 0) { //first block + //if (i == blk_group_num -1) { // last block + current_free_blk = free_blk_cnt; + current_blkbit_addr = start_blkbit_addr; + current_indbit_addr = start_indbit_addr; + current_indtable_addr = start_indtable_addr; + if (is_revgdt) + have_rev_gdt = 1; + + } + mk2(desc_table->free_inode_cnt, free_inode_cnt); + if (i == 0) + mk2(desc_table->directories_cnt, 2); + else + mk2(desc_table->directories_cnt, 0); + offset += sizeof(struct group_desc_table); + } + + if (set_journaling) { + + /* set journal blocks + * journal data start address = + * next of first inode_table block + * + (size of inode table) + * + 6 (size of root & reserved data region) + */ + if (total_blocks > 0x8000) { /* if size > 128MB */ + jnldata_start_addr = first_inode_table_addr + + (inodes_per_group * 128 / COMMON_BLOCK_SIZE) + 6; + } + else { + jnldata_start_addr = first_inode_table_addr + + (inodes_per_group * 128 / COMMON_BLOCK_SIZE) + 5; + } + + mk4(sblock->journal_blocks, jnldata_start_addr); + mk4(sblock->journal_blocks + 4, jnldata_start_addr + 1); + mk4(sblock->journal_blocks + 8, jnldata_start_addr + 2); + mk4(sblock->journal_blocks + 12, jnldata_start_addr + 3); + mk4(sblock->journal_blocks + 16, jnldata_start_addr + 4); + mk4(sblock->journal_blocks + 20, jnldata_start_addr + 5); + mk4(sblock->journal_blocks + 24, jnldata_start_addr + 6); + mk4(sblock->journal_blocks + 28, jnldata_start_addr + 7); + mk4(sblock->journal_blocks + 32, jnldata_start_addr + 8); + mk4(sblock->journal_blocks + 36, jnldata_start_addr + 9); + mk4(sblock->journal_blocks + 40, jnldata_start_addr + 10); + mk4(sblock->journal_blocks + 44, jnldata_start_addr + 11); + mk4(sblock->journal_blocks + 48, jnldata_start_addr + 12); + + int default_jnl_blocks = default_journal_size(total_blocks); + uint32_t temp_val; + if (default_jnl_blocks == 1024) + temp_val = 0x400000; + else if (default_jnl_blocks == 4096) + temp_val = 0x1000000; + else if (default_jnl_blocks == 8192) + temp_val = 0x2000000; + else if (default_jnl_blocks == 16384) + temp_val = 0x4000000; + else if (default_jnl_blocks == 32768) + temp_val = 0x8000000; + mk4(sblock->journal_blocks + 64, temp_val); + + /* 400 : 0x400(1024) means amount of pointing by 1block + * 4096(1block) / 4 = 1024 + */ + if (default_jnl_blocks != 1024) + mk4(sblock->journal_blocks + 52, jnldata_start_addr + 0x400 + 13); + } + mk4(sblock->free_blocks, free_blocks); /* free block count */ + mk4(sblock->free_inodes, free_inodes); /* free inode count */ + free_inodes += 0x10; + free_inodes &= 0xfffffff0; + mk4(sblock->total_inodes, free_inodes); /* inode count */ + + /* print value */ + /* + printf("Print Super Blocks\n"); + for(i = 0;i < 4096; i++) { + if(img[i] == 0) + printf("00 "); + else + printf("%02x ", img[i]); + + if (!((i+1) % 4)) + printf("| "); + if (!((i+1) % 16)) + printf("\n"); + if (!((i+1) % 512)) + printf("---------------------------------------------------%d\n", i+1); + } + */ + + /* Write super-block to mmc */ + start_block = info.start + (bgcnt * 0x8000 * COMMON_BLOCK_SIZE / 512); + printf("Start write addr : 0x%x\n",start_block); + if (have_rev_gdt) { + if (dev_desc->block_write(dev_desc->dev, start_block, 8, (ulong *)img) != 8) { + printf("Can't write Superblock(%d)~~~!!!\n", bgcnt); + } + } + + /* + printf("\n\nPrint Group Descriptor Table\n"); + for(i = 0;i < 4096; i++) { + if(img2[i] == 0) + printf("00 "); + else + printf("%02x ", img2[i]); + if (!((i+1) % 4)) + printf("| "); + if (!((i+1) % 16)) + printf("\n"); + if (!((i+1) % 512)) + printf("---------------------------------------------------%d\n", i+1); + } + */ + + /* Write Group Descriptor Table */ + if (have_rev_gdt) { + start_block += 8; + if (dev_desc->block_write(dev_desc->dev, start_block, w_count, + (ulong *)img2) != w_count) { + printf("Can't write Descriptor Table(%d)~~~!!!\n", bgcnt); + } + start_block += (w_count - 8); + } + + /* Write reserved region */ + if (bgcnt == 0) { + memset(reserve_img, 0x0, sizeof(__u8) * COMMON_BLOCK_SIZE); + + int rev_cnt; + for (rev_cnt = 2; rev_cnt <= reserved_gdt_blk + + 1; rev_cnt++) { + start_block += 8; + if (rsv_blk_cnt >= 1) + mk4(reserve_img, 0x8000 + rev_cnt); + if (rsv_blk_cnt >= 2) + mk4(reserve_img + 4, 0x18000 + rev_cnt); + if (rsv_blk_cnt >= 3) + mk4(reserve_img + 8, 0x28000 + rev_cnt); + if (rsv_blk_cnt >= 4) + mk4(reserve_img + 12, 0x38000 + rev_cnt); + if (rsv_blk_cnt >= 5) + mk4(reserve_img + 16, 0x48000 + rev_cnt); + if (rsv_blk_cnt >= 6) + mk4(reserve_img + 20, 0xc8000 + rev_cnt); + if (rsv_blk_cnt >= 7) + mk4(reserve_img + 24, 0xd8000 + rev_cnt); + if (rsv_blk_cnt >= 8) + mk4(reserve_img + 28, 0x188000 + rev_cnt); + if (dev_desc->block_write(dev_desc->dev, start_block, 8, + (ulong *)reserve_img) != 8) { + printf("Can't write reserve(%d)~~~!!!\n", bgcnt); + } + } + } + + /* Write Block Bitmap */ + uint8_t *blk_bitmap; + int used_blocks; + int set_full; + int j; + int set_val; + uint32_t bitmap_val; + int empty_blocks; + + + if (bgcnt != blk_group_num - 1) { + memset(img3, 0x00, sizeof(__u8) * COMMON_BLOCK_SIZE); + + used_blocks = 0x8000 - current_free_blk; + set_full = used_blocks / 0x20; + set_val = used_blocks % 0x20; + bitmap_val = 0; + + for (i = 0;i <= set_full;i++) { + blk_bitmap = (uint32_t *)(img3 + (4 * i)); + if(i == set_full) { + for (j = 0;j <= set_val - 1;j++) { + bitmap_val |= 1 << j; + } + mk4(blk_bitmap, bitmap_val); + } else { + mk4(blk_bitmap, 0xffffffff); + } + } + } else { + memset(img3, 0xff, sizeof(__u8) * COMMON_BLOCK_SIZE); + + used_blocks = 0x8000 - (current_free_blk + (0x8000 - + (total_blocks % 0x8000))); + + set_full = used_blocks / 0x20; + set_val = used_blocks % 0x20; + + bitmap_val = 0x0; + //==> write empty blocks + empty_blocks = (current_free_blk + used_blocks) / 32; + int temp = (current_free_blk + used_blocks) % 32; + for (i = 0; i <= empty_blocks; i++) { + blk_bitmap = (uint32_t *)(img3 + (4 * i)); + if (i == empty_blocks ) { + for (j = temp;j < 32; j++) { + bitmap_val |= 1 << j; + } + mk4(blk_bitmap, bitmap_val); + } else { + mk4(blk_bitmap, 0x00); + } + } + + bitmap_val = 0; + for (i = 0;i <= set_full;i++) { + blk_bitmap = (uint32_t *)(img3 + (4 * i)); + if(i == set_full) { + for (j = 0;j <= set_val - 1;j++) { + bitmap_val |= 1 << j; + } + mk4(blk_bitmap, bitmap_val); + } else { + mk4(blk_bitmap, 0xffffffff); + } + } + } + + /* + printf("\n\nPrint Block Bitmap(0x%x)\n",current_free_blk); + for(i = 0;i < 4096; i++) { + if(img3[i] == 0) + printf("00 "); + else + printf("%02x ", img3[i]); + if (!((i+1) % 4)) + printf("| "); + if (!((i+1) % 16)) + printf("\n"); + if (!((i+1) % 512)) + printf("---------------------------------------------------%d\n", i+1); + } + */ + + /* Write block bitmap */ + start_block = (current_blkbit_addr * 8) + info.start; + + if (dev_desc->block_write(dev_desc->dev, start_block, 8, + (ulong *)img3) != 8) { + printf("Can't write Descriptor Table(%d)~~~!!!\n", bgcnt); + } + + /* Write inode bitmap */ + uint8_t *inode_bitmap; + + memset(img4, 0xff, sizeof(__u8) * COMMON_BLOCK_SIZE); + + int empty_inode = inodes_per_group; + int set_empty = empty_inode / 0x20; + + // Fix me~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + if (total_blocks < 0x8000) /* if size < 128MB */ + set_empty -= 1; + + for (i = 0;i < set_empty;i++) { + inode_bitmap = (uint32_t *)(img4 + (4 * i)); + mk4(inode_bitmap, 0); + } + + if (bgcnt == 0) { + inode_bitmap = (uint32_t *)img4; + mk4(inode_bitmap, 0x7ff); + } + + /* + printf("\n\nPrint Inode Bitmap0\n"); + for(i = 0;i < 4096; i++) { + if(img4[i] == 0) + printf("00 "); + else + printf("%02x ", img4[i]); + if (!((i+1) % 4)) + printf("| "); + if (!((i+1) % 16)) + printf("\n"); + if (!((i+1) % 512)) + printf("---------------------------------------------------%d\n", i+1); + } + */ + + /* Write inode bitmap */ + start_block = (current_indbit_addr * 8) + info.start; + if (dev_desc->block_write(dev_desc->dev, start_block, 8, + (ulong *)img4) != 8) { + printf("Can't write inode bitmap(%d)~~~!!!\n", bgcnt); + } + + /* Write Inode Table & data */ + start_block = (current_indtable_addr * 8) + info.start; + //Erase to 0x00 to initialize inode table..... + memset(zerobuf, 0x00, sizeof(__u8) * COMMON_BLOCK_SIZE * 80); + int indt_blknum = (inodes_per_group * 128 / 4096) + 1; + printf("Erase inode table(%d) - 0x%x", bgcnt, start_block); + for (j = 0; j < (indt_blknum /80) + 4; j++) { // 2 means root + a + start_block += j * 8; + if (dev_desc->block_write(dev_desc->dev, + start_block, 640, (ulong *)zerobuf) != 640) { + printf("Can't erase inode table(%d)~~~!!!\n", bgcnt); + } + printf("."); + } + printf("\n"); + + struct inode_desc *inode; + + memset(img5, 0x00, sizeof(__u8) * COMMON_BLOCK_SIZE / 2); + + // 1st inode : bad inode + inode = (struct inode *)img5; + mk4(inode->access_time, 0x33); /* 0x33 means nothing */ + mk4(inode->change_time, 0x33); /* 0x33 means nothing */ + mk4(inode->modify_time, 0x33); /* 0x33 means nothing */ + + // 2nd inode : Root inode + inode = (struct inode *)(img5 + sizeof(struct inode_desc)); + mk2(inode->file_mode, 0x41ed); + mk4(inode->size_byte, 0x1000); + mk4(inode->access_time, 0x33); /* 0x33 means nothing */ + mk4(inode->change_time, 0x33); /* 0x33 means nothing */ + mk4(inode->modify_time, 0x33); /* 0x33 means nothing */ + mk2(inode->link_count, 0x3); + mk2(inode->block_count, 0x8); + /* root data block addr = + * inode_table_addr + inode table size + */ + uint32_t root_data_blk = (inodes_per_group * 128) / COMMON_BLOCK_SIZE; + if (total_blocks > 0x8000) /* if size > 128MB */ + root_data_blk += first_inode_table_addr; + else + root_data_blk += first_inode_table_addr - 1; + + mk4(inode->block_pointers, root_data_blk); + // Write root directory in data region. + if (bgcnt == 0) { + /* root data */ + memset(rootdata, 0x00, sizeof(__u8) * COMMON_BLOCK_SIZE); + mk4(rootdata, 0x2); + mk4(rootdata + 4, 0x201000c); + mk4(rootdata + 8, 0x2e); + mk4(rootdata + 12, 0x2); + mk4(rootdata + 16, 0x202000c); + mk4(rootdata + 20, 0x2e2e); + mk4(rootdata + 24, 0xb); + mk4(rootdata + 28, 0x20a0fe8); + mk4(rootdata + 32, 0x74736f6c); + mk4(rootdata + 36, 0x756f662b); + mk4(rootdata + 40, 0x646e); + if (dev_desc->block_write(dev_desc->dev, + (root_data_blk * 8) + info.start, 8, + (ulong *)rootdata) != 8) { + printf("Can't write rootdata~~~!!!\n"); + } + + /* root + 1 data */ + root_data_blk++; + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + mk4(inode_data, 0xb); + mk4(inode_data + 4, 0x201000c); + mk4(inode_data + 8, 0x2e); + mk4(inode_data + 12, 0x2); + mk4(inode_data + 16, 0x2020ff4); + mk4(inode_data + 20, 0x2e2e); + if (dev_desc->block_write(dev_desc->dev, + (root_data_blk * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write root+1~~~!!!\n"); + } + /* root + 2 data */ + root_data_blk++; + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + mk4(inode_data + 4, 0x1000); + if (dev_desc->block_write(dev_desc->dev, + (root_data_blk * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write root+1~~~!!!\n"); + } + + /* root + 3 data */ + root_data_blk++; + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + mk4(inode_data + 4, 0x1000); + if (dev_desc->block_write(dev_desc->dev, + (root_data_blk * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write root+1~~~!!!\n"); + } + + /* root + 4 data */ + root_data_blk++; + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + mk4(inode_data + 4, 0x1000); + if (dev_desc->block_write(dev_desc->dev, + (root_data_blk * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write root+1~~~!!!\n"); + } + } + + // 3 ~ 6th inode : empty + // 7th inode : reserved_gdt_blocks + inode = (struct inode *)(img5 + sizeof(struct inode_desc) * 6); + mk2(inode->file_mode, 0x8180); + mk4(inode->size_byte, 0x40c000); + mk4(inode->access_time, 0x33); /* 0x33 means nothing */ + mk4(inode->change_time, 0x33); /* 0x33 means nothing */ + mk4(inode->modify_time, 0x33); /* 0x33 means nothing */ + mk2(inode->link_count, 0x1); + uint32_t inode7_cnt; + // 4096 * 512 ==> changing from ext2block to mmc block.... + inode7_cnt = ((reserved_gdt_blk * reserved_blk_cnt) + 1) * COMMON_BLOCK_SIZE / 512; + mk2(inode->block_count, inode7_cnt); + root_data_blk++; + mk4(inode->block_pointers + 52, root_data_blk); + mk4(inode->directory_acl, 1); + + // Write 7th inode data + if (bgcnt == 0) { + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + /* original code + uint32_t temp; + if (reserved_gdt_blk % 2) { + temp = reserved_gdt_blk /= 2; + temp++; + temp *= 2; + } + for(j=0; j< temp; j++) { + if ( j != 0) + mk4(inode_data + (j * 4), j + 1); + } + */ + for(j=0; j< current_blkbit_addr - 1; j++) { + if ( j != 0) + mk4(inode_data + (j * 4), j + 1); + } + if (dev_desc->block_write(dev_desc->dev, + (root_data_blk * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write 7th inode~~~!!!\n"); + } + } + + if (set_journaling) { + // 8th inode : reserved for journaling + inode = (struct inode *)(img5 + sizeof(struct + inode_desc) * 7); + mk2(inode->file_mode, 0x8180); + uint32_t indirect_pointer_addr = 0; + uint32_t d_indirect_pointer_addr = 0; + int default_jnl_blocks = default_journal_size(total_blocks); + uint32_t temp_val; + if (default_jnl_blocks == 1024) + temp_val = 0x400000; + else if (default_jnl_blocks == 4096) + temp_val = 0x1000000; + else if (default_jnl_blocks == 8192) + temp_val = 0x2000000; + else if (default_jnl_blocks == 16384) + temp_val = 0x4000000; + else if (default_jnl_blocks == 32768) + temp_val = 0x8000000; + mk4(inode->size_byte, temp_val); + mk4(inode->change_time, 0x33); + mk4(inode->modify_time, 0x33); + mk2(inode->link_count, 0x1); + // set journaling blocks by 512 per 1block. + int inode_jnl_blocks = jnl_blocks * COMMON_BLOCK_SIZE / 512; + if (total_blocks > 0x8000) /* if size > 128MB */ + mk4(inode->block_count, inode_jnl_blocks); + else + mk4(inode->block_count, inode_jnl_blocks + 8); + + // set journaling block address + mk4(inode->block_pointers, jnldata_start_addr); + mk4(inode->block_pointers + 4, jnldata_start_addr + 1); + mk4(inode->block_pointers + 8, jnldata_start_addr + 2); + mk4(inode->block_pointers + 12, jnldata_start_addr + 3); + mk4(inode->block_pointers + 16, jnldata_start_addr + 4); + mk4(inode->block_pointers + 20, jnldata_start_addr + 5); + mk4(inode->block_pointers + 24, jnldata_start_addr + 6); + mk4(inode->block_pointers + 28, jnldata_start_addr + 7); + mk4(inode->block_pointers + 32, jnldata_start_addr + 8); + mk4(inode->block_pointers + 36, jnldata_start_addr + 9); + mk4(inode->block_pointers + 40, jnldata_start_addr + 10); + mk4(inode->block_pointers + 44, jnldata_start_addr + 11); + indirect_pointer_addr = jnldata_start_addr + 12; + mk4(inode->block_pointers + 48, indirect_pointer_addr); + + /* If journaling data blocks are bigger than 4096, it + * use double indirect pointer (block13) + */ + if (default_jnl_blocks >= 4096) { + /* 400 : 0x400(1024) means amount of pointing by 1block + * 4096(1block) / 4 = 1024 + */ + d_indirect_pointer_addr = jnldata_start_addr + + 0x400 + 13; + mk4(inode->block_pointers + 52, + d_indirect_pointer_addr); + } + // Write 8th inode data + if (bgcnt == 0) { + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + mk4(inode_data, 0x98393bc0); + mk4(inode_data + 4, 0x4000000); + mk4(inode_data + 12, 0x100000); + temp_val >>= 4; + mk4(inode_data + 16, temp_val); + mk4(inode_data + 20, 0x1000000); + mk4(inode_data + 24, 0x1000000); + // set UUID + mk4(inode_data + 48, uuid[0]); + mk4(inode_data + 52, uuid[1]); + mk4(inode_data + 56, uuid[2]); + mk4(inode_data + 60, uuid[3]); + mk4(inode_data + 64, 0x1000000); + + //write data to sd/mmc + if (dev_desc->block_write(dev_desc->dev, + (jnldata_start_addr * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write 8th inode~~~!!!\n"); + } + + // Write indirect pointer value + // 12 means num of default direct pointer + uint32_t remain_blocks = jnl_blocks - 12; + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + for (j = 0; j < 1024; j++) { + mk4(inode_data + (j * 4), + indirect_pointer_addr + 1 + j); + remain_blocks--; + if (remain_blocks == 0) + break; + } + //write data to sd/mmc + if (dev_desc->block_write(dev_desc->dev, + (indirect_pointer_addr * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write 8th inode~~~!!!\n"); + } + + //Write double indirect pointer + if (remain_blocks != 0) { + memset(inode_data, 0x00, sizeof(__u8) * INODE_DATA_SIZE); + int k; + int needed_blocks = remain_blocks / 1024; + // Check me==================> + if (total_blocks > 0x8000) /* if size > 128MB */ + if (remain_blocks % 1024) + needed_blocks += 1; + //<========================== + remain_blocks -= (needed_blocks + 2); + + for (j=0;j < needed_blocks; j++) { + int now_val = + d_indirect_pointer_addr + 1 + (j * 0x400) + j; + mk4(inode_data + (j * 4), now_val); + + memset(inode_data2, 0x00, sizeof(__u8) * COMMON_BLOCK_SIZE); + for (k = 0; k < 1024; k++) { + uint32_t tmp_val = now_val + 1 + k; + if (tmp_val >= 0x8000) { + tmp_val += + seblk_offset + (inodes_per_group * 128 / 4096); + } + mk4(inode_data2 + (k * 4), tmp_val); + remain_blocks--; + if(remain_blocks == 0) + break; + } + //write data to sd/mmc + if (dev_desc->block_write(dev_desc->dev, + (now_val * 8) + info.start, 8, + (ulong*)inode_data2) != 8) { + printf("Can't inodeval~~~!!!\n"); + } + } + //write data to sd/mmc + printf("d_indirect_point:0x%x\n", + (d_indirect_pointer_addr * 8) + info.start); + if (dev_desc->block_write(dev_desc->dev, + (d_indirect_pointer_addr * 8) + info.start, 8, + (ulong*)inode_data) != 8) { + printf("Can't write 8th inode~~~!!!\n"); + } + } + } + } + + // 9 ~ 10th inode : empty + // 11th inode : first inode without reserved + // It point next of root(lost+found) + inode = (struct inode *)(img5 + sizeof(struct inode_desc) * 10); + mk2(inode->file_mode, 0x41c0); + mk4(inode->size_byte, 0x4000); + mk4(inode->access_time, 0x33); /* 0x33 means nothing */ + mk4(inode->change_time, 0x33); /* 0x33 means nothing */ + mk4(inode->modify_time, 0x33); /* 0x33 means nothing */ + mk2(inode->link_count, 0x2); + mk2(inode->block_count, 0x20); + root_data_blk -= 4; + mk4(inode->block_pointers, root_data_blk); + mk4(inode->block_pointers + 4, root_data_blk + 1); + mk4(inode->block_pointers + 8, root_data_blk + 2); + mk4(inode->block_pointers + 12, root_data_blk + 3); + + + /* + printf("\n\nPrint inode table0\n"); + for(i = 0;i < 2048; i++) { + if(img5[i] == 0) + printf("00 "); + else + printf("%02x ", img5[i]); + if (!((i+1) % 4)) + printf("| "); + if (!((i+1) % 16)) + printf("\n"); + if (!((i+1) % 512)) + printf("---------------------------------------------------%d\n", i+1); + } + */ + + if (bgcnt == 0) { + /* Write inode table */ + start_block = (current_indtable_addr * 8) + info.start; + if (dev_desc->block_write(dev_desc->dev, start_block, 4, + (ulong *)img5) != 4) { + printf("Can't write inode table(%d)~~~!!!\n", bgcnt); + } + } + } +#if defined(CONFIG_MMC_64BIT_BUS) || defined(CONFIG_CPU_EXYNOS5410_EVT2) + free_align(img); + free_align(img2); + free_align(reserve_img); + free_align(img3); + free_align(img4); + free_align(zerobuf); + free_align(img5); + free_align(rootdata); + free_align(inode_data); + free_align(inode_data2); +#else + free(img); + free(img2); + free(reserve_img); + free(img3); + free(img4); + free(zerobuf); + free(img5); + free(rootdata); + free(inode_data); + free(inode_data2); +#endif + + return 0; +} diff --git a/fs/fat/fat.c b/fs/fat/fat.c index bc46cc5d2..84bb0ef3d 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -122,6 +122,334 @@ int fat_register_device (block_dev_desc_t * dev_desc, int part_no) return -1; } +/* + * Copy string, padding with spaces. + */ +static void +setstr(u_int8_t *dest, const char *src, size_t len) +{ + while (len--) + *dest++ = *src ? *src++ : ' '; +} + +static int write_pbr(block_dev_desc_t *dev_desc, disk_partition_t *info) +{ + struct bs *bs; + struct bsbpb *bsbpb; + struct bsxbpb *bsxbpb; + struct bsx *bsx; + __u8 *img; + int img_offset = 0; + int reserved_cnt= 0; + int i; + int fat_size = 0; + + img = malloc(sizeof(__u8)*512); + if(img == NULL) { + printf("Can't make img buffer~~!!\n"); + return -1; + } + memset(img, 0x0, sizeof(__u8)*512); + + + /* Erase Reserved Sector(PBR) */ + for (i = 0;i < RESERVED_CNT; i++) { + if (dev_desc->block_write(dev_desc->dev, info->start + i, + 1, (ulong *)img) != 1) { + printf ("Can't erase reserved sector~~~!!!\n"); + return -1; + } + } + + /* Set bs */ + bs = (struct bs *)img; + img_offset += sizeof(struct bs) - 1; + + mk1(bs->jmp[0], 0xeb); + mk1(bs->jmp[1], 0x58); + mk1(bs->jmp[2], 0x90); /* Jump Boot Code */ + setstr(bs->oem, "SAMSUNG", sizeof(bs->oem)); /* OEM Name */ + + uint spc; + /* Set bsbpb */ + bsbpb = (struct bsbpb *)(img + img_offset); + img_offset += sizeof(struct bsbpb) - 2; + + mk2(bsbpb->bps, 512); /* Byte Per Sector */ + + printf("size checking ...\n"); + /* Sector Per Cluster */ + if (info->size < 0x10000) { /* partition size >= 32Mb */ + printf("Can't format less than 32Mb partition!!\n"); + return -1; + } + if (info->size <= 0x20000) { /* under 64M -> 512 bytes */ + printf("Under 64M\n"); + mk1(bsbpb->spc, 1); + spc = 1; + } + else if (info->size <= 0x40000) { /* under 128M -> 1K */ + printf("Under 128M\n"); + mk1(bsbpb->spc, 2); + spc = 2; + } + else if (info->size <= 0x80000) { /* under 256M -> 2K */ + printf("Under 256M\n"); + mk1(bsbpb->spc, 4); + spc = 4; + } + else if (info->size <= 0xFA0000) { /* under 8G -> 4K */ + printf("Under 8G\n"); + mk1(bsbpb->spc, 8); + spc = 8; + } + else if (info->size <= 0x1F40000) { /* under 16G -> 8K */ + printf("Under 16G\n"); + mk1(bsbpb->spc, 16); + spc = 16; + } + else { + printf("16G~\n"); + mk1(bsbpb->spc, 32); + spc = 32; + } + + printf("write FAT info: %d\n",RESERVED_CNT); + mk2(bsbpb->res, RESERVED_CNT); /* Reserved Sector Count */ + mk1(bsbpb->nft, 2); /* Number of FATs */ + mk2(bsbpb->rde, 0); /* Root Directory Entry Count : It's no use in FAT32 */ + mk2(bsbpb->sec, 0); /* Total Sector : It's no use in FAT32 */ + mk1(bsbpb->mid, 0xF8); /* Media */ + mk2(bsbpb->spf, 0); /* FAT Size 16 : It's no use in FAT32 */ + mk2(bsbpb->spt, 0); /* Sector Per Track */ + mk2(bsbpb->hds, 0); /* Number Of Heads */ + mk4(bsbpb->hid, 0); /* Hidden Sector */ + mk4(bsbpb->bsec, info->size); /* Total Sector For FAT32 */ + + /* Set bsxbpb */ + bsxbpb = (struct bsxbpb *)(img + img_offset); + img_offset += sizeof(struct bsxbpb); + + mk4(bsxbpb->bspf, (info->size / (spc * 128))); /* FAT Size 32 */ + fat_size = info->size / (spc * 128); + printf("Fat size : 0x%x\n", info->size / (spc * 128)); + mk2(bsxbpb->xflg, 0); /* Ext Flags */ + mk2(bsxbpb->vers, 0); /* File System Version */ + mk4(bsxbpb->rdcl, 2); /* Root Directory Cluster */ + mk2(bsxbpb->infs, 1); /* File System Information */ + mk2(bsxbpb->bkbs, 0); /* Boot Record Backup Sector */ + + /* Set bsx */ + bsx = (struct bsx *)(img + img_offset); + mk1(bsx->drv, 0); /* Drive Number */ + mk1(bsx->sig, 0x29); /* Boot Signature */ + mk4(bsx->volid, 0x3333); /* Volume ID : 0x3333 means nothing */ + setstr(bsx->label, "NO NAME ", sizeof(bsx->label)); /* Volume Label */ + setstr(bsx->type, "FAT32", sizeof(bsx->type)); /* File System Type */ + + /* Set Magic Number */ + mk2(img + BYTE_PER_SEC - 2, 0xaa55); /* Signature */ + +/* + printf("Print Boot Recode\n"); + for(i = 0;i<512;i++) { + if(img[i] == 0) + printf("00 "); + else + printf("%2x ", img[i]); + if (!((i+1) % 16)) + printf("\n"); + } +*/ + + if (dev_desc->block_write(dev_desc->dev, info->start, + 1, (ulong *)img) != 1) { + printf ("Can't write PBR~~~!!!\n"); + return -1; + } + + return fat_size; +} +static int write_reserved(block_dev_desc_t *dev_desc, disk_partition_t *info) +{ + /* Set Reserved Region */ + __u8 *img; + int i; + img = malloc(sizeof(__u8)*512); + if(img == NULL) { + printf("Can't make img buffer~~(reserved)!!\n"); + return -1; + } + + memset(img, 0x0, sizeof(__u8)*512); + + mk4(img, 0x41615252); /* Lead Signature */ + mk4(img + BYTE_PER_SEC - 28, 0x61417272); /* Struct Signature */ + mk4(img + BYTE_PER_SEC - 24, 0xffffffff); /* Free Cluster Count */ + mk4(img + BYTE_PER_SEC - 20, 0x3); /* Next Free Cluster */ + mk2(img + BYTE_PER_SEC - 2, 0xaa55); /* Trail Signature */ + + /* + printf("Print Reserved Region\n"); + for(i = 0;i<512;i++) { + if(img[i] == 0) + printf("00 "); + else + printf("%2x ", img[i]); + if (!((i+1) % 16)) + printf("\n"); + } + */ + + /* Write Reserved region */ + if (dev_desc->block_write(dev_desc->dev, info->start+1, + 1, (ulong *)img) != 1) { + printf ("Can't write reserved region~~~!!!\n"); + return -1; + } + + return 1; +} +static int write_fat(block_dev_desc_t *dev_desc, disk_partition_t *info, int +fat_size) +{ + __u8 *dummy; + __u8 *img; + int i; + + /* Create buffer for FAT */ + img = malloc(sizeof(__u8)*512); + if(img == NULL) { + printf("Can't make img buffer~~!!\n"); + return -1; + } + memset(img, 0x0, sizeof(__u8) * 512); + + /* Create buffer for erase */ + dummy = malloc(sizeof(__u8) * 8192); + if(dummy == NULL) { + printf("Can't make dummy buffer~~!!\n"); + return -1; + } + memset(dummy, 0x0, sizeof(__u8) * 8192); + + /* Erase FAT Region */ + int erase_block_cnt = (fat_size * 2); + int temp = 0; + printf("Erase FAT region"); + for (i = 0;i < erase_block_cnt + 10; i+=16) { + if (dev_desc->block_write(dev_desc->dev, info->start + + RESERVED_CNT + i, 16, (ulong *)dummy) != 16) { + printf ("Can't erase FAT region~~!!!\n"); + } + if((i % 160) == 0) + printf("."); + + } + printf("\n"); + + mk4(img, 0x0ffffff8); + mk4(img+4, 0x0fffffff); + mk4(img+8, 0x0fffffff); /* Root Directory */ + + /* + printf("Print FAT Region\n"); + for(i = 0;i<512;i++) { + if(img[i] == 0) + printf("00 "); + else + printf("%2x ", img[i]); + if (!((i+1) % 16)) + printf("\n"); + } + */ + /* Write FAT Region */ + if (dev_desc->block_write(dev_desc->dev, info->start + RESERVED_CNT, + 1, (ulong *)img) != 1) { + printf ("Can't write FAT~~~!!!\n"); + return -1; + } + + return 1; +} + +/* + * Make a volume label. + */ + +static void +mklabel(u_int8_t *dest, const char *src) +{ + int c, i; + + for (i = 0; i < 11; i++) { + c = *src ? __toupper(*src++) : ' '; + *dest++ = !i && c == '\xe5' ? 5 : c; + } +} + +/* + * Format device + */ +int +fat_format_device(block_dev_desc_t *dev_desc, int part_no) +{ + unsigned char buffer[SECTOR_SIZE]; + unsigned long part_offset; + int cur_part; + disk_partition_t info; + + if (!dev_desc->block_read) + return -1; + cur_dev = dev_desc; + /* check if we have a MBR (on floppies we have only a PBR) */ + if (dev_desc->block_read (dev_desc->dev, 0, + 1, (ulong *) buffer) != 1) { + printf ("** Can't read from device %d **\n", dev_desc->dev); + return -1; + } + if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || + buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { + printf("** MBR is broken **\n"); + /* no signature found */ + return -1; + } + +#if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) ) + /* First we assume, there is a MBR */ + if (!get_partition_info (dev_desc, part_no, &info)) { + part_offset = info.start; + cur_part = part_no; + } else if (!strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET], "FAT", 3)) { + /* ok, we assume we are on a PBR only */ + cur_part = 1; + part_offset = 0; + } else { + printf ("** Partition %d not valid on device %d **\n", + part_no, dev_desc->dev); + return -1; + } +#endif + + printf("Partition%d: Start Address(0x%x), Size(0x%x)\n", + part_no, info.start, info.size); + + int fat_size; + fat_size = write_pbr(dev_desc, &info); + if(fat_size < 0) + return -1; + if(write_reserved(dev_desc, &info) < 0) + return -1; + if(write_fat(dev_desc, &info, fat_size) < 0) + return -1; + printf("Partition%d format complete.\n", part_no); + + return 0; +} /* * Get the first occurence of a directory delimiter ('/' or '\') in a string. diff --git a/include/configs/espresso3250.h b/include/configs/espresso3250.h new file mode 100644 index 000000000..4137ed6e5 --- /dev/null +++ b/include/configs/espresso3250.h @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * Configuration settings for the SAMSUNG UESPRESSO3250 (EXYNOS3250) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS +#define CONFIG_ARCH_EXYNOS4 +#define CONFIG_CPU_EXYNOS3250 /* which is in a Exynos3250 */ +#define CONFIG_MACH_SMDK3250 + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02025000 +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x3F000) + + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x100000 +#else +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#endif + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x40003800 +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* +* clock setting: +* APLL = 700MHz +* MPLL = 1600MHz +* BPLL = 800MHz +* EPLL = 800MHz +* VPLL = 335MHz +*/ +/* input clock of PLL: SMDK3250 has 24MHz input clock */ +#ifdef CONFIG_SMDK3250_FPGA_DEBUG +#define CONFIG_SYS_FIN_12 +#define CONFIG_SYS_CLK_FREQ 12000000 //FPGA clock source: 12MHz +#else +#define CONFIG_SYS_FIN_24 +#define CONFIG_SYS_CLK_FREQ 24000000 //backup clock in smdk +#endif + +/* Specify the ARM_CLK frequency in MHz */ +#define CONFIG_ARM_CLK 700 +/* MCLK_CDREX */ +#define MCLK_CDREX_400 1 + + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_CMDLINE_EDITING + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#define CONFIG_BAUDRATE 115200 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03040000 +#define DDR_CH0 0x03010000 +#ifndef CONFIG_SMDK3250_FPGA_DEBUG +#define SDR_CH2 0x03010000 +#define DDR_CH2 0x03010000 +#else +#define SDR_CH2 0x03000000 +#define DDR_CH2 0x03000000 +#endif +#define SDR_CH4 0x0 +#define DDR_CH4 0x0 +#endif + + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT + +#define CONFIG_CMD_MOVI +#define CONFIG_CMD_MOVINAND +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE + + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS4_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS4_POWER_BASE + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x41000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc +#undef CONFIG_EFI_PARTITION +#ifdef CONFIG_EFI_PARTITION +#define CONFIG_PRI_GPT_SIZE (34 * 512) +#define CONFIG_SEC_GPT_SIZE (33 * 512) +#define CONFIG_16GEMMC_BLK (30535680) +#endif + +#ifdef CONFIG_CPU_EXYNOS3250 +/* CFG_FASTBOOT_TRANSFER_BUFFER + CFG_FASTBOOT_TRANSFER_BUFFER_SIZE */ +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#endif + + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000028 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 40000000;emmc close 0;" \ + "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 200000;bootz 40008000 41000000" +#endif + +#define CONFIG_RECOVERYCOMMAND_SDMMC \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +#define CONFIG_RECOVERYCOMMAND_USB \ + "fastboot" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "ESPRESSO3250 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_HZ 1000 + + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 8 +#define SDRAM_BANK_SIZE (64UL << 20UL) /* 64 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for ESPRESSO3250" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_ARM 1000 +#define CONFIG_PM_VDD_INT 1000 +#define CONFIG_PM_VDD_G3D 1000 +#define CONFIG_PM_VDD_MIF 1100 +#define CONFIG_PM_VDD_MEM 1200 + +#define CONFIG_PMIC_S5M8767A + +/* Bootloader Recovery */ +#undef CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* Boot configuration */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_EMMC_5_0 BOOT_EMMC_4_4 +#define BOOT_USB 0x100 + +/* Boot device */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02060000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define ISP_ARM_WDTRESET (1 << 25) +#define SYS_WDTRESET (1 << 20) +#define PINRESET (1 << 16) + +#endif /* __CONFIG_H */ diff --git a/include/configs/shiri.h b/include/configs/shiri.h new file mode 100755 index 000000000..a89111dda --- /dev/null +++ b/include/configs/shiri.h @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * Configuration settings for the SAMSUNG UESPRESSO3250 (EXYNOS3250) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS +#define CONFIG_ARCH_EXYNOS4 +#define CONFIG_CPU_EXYNOS3250 /* which is in a Exynos3250 */ +#define CONFIG_MACH_SMDK3250 +#define CONFIG_MACH_SHIRI + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02025000 +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x3F000) + + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x100000 +#else +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#endif + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x40003800 +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* +* clock setting: +* APLL = 700MHz +* MPLL = 1600MHz +* BPLL = 800MHz +* EPLL = 800MHz +* VPLL = 335MHz +*/ +/* input clock of PLL: SMDK3250 has 24MHz input clock */ +#ifdef CONFIG_SMDK3250_FPGA_DEBUG +#define CONFIG_SYS_FIN_12 +#define CONFIG_SYS_CLK_FREQ 12000000 //FPGA clock source: 12MHz +#else +#define CONFIG_SYS_FIN_24 +#define CONFIG_SYS_CLK_FREQ 24000000 //backup clock in smdk +#endif + +/* Specify the ARM_CLK frequency in MHz */ +#define CONFIG_ARM_CLK 700 +/* MCLK_CDREX */ +#define MCLK_CDREX_400 1 + + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_CMDLINE_EDITING + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#define CONFIG_BAUDRATE 115200 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03040000 +#define DDR_CH0 0x03010000 +#ifndef CONFIG_SMDK3250_FPGA_DEBUG +#define SDR_CH2 0x03010000 +#define DDR_CH2 0x03010000 +#else +#define SDR_CH2 0x03000000 +#define DDR_CH2 0x03000000 +#endif +#define SDR_CH4 0x0 +#define DDR_CH4 0x0 +#endif + + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT + +#define CONFIG_CMD_MOVI +#define CONFIG_CMD_MOVINAND +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE +#define CONFIG_EXYNOS_DA +#define CONFIG_DNW + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS4_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS4_POWER_BASE + +/* +* DNW +*/ +#define CONFIG_SPL_EXYNOS_USBD3 +#define CONFIG_DNW_VERSION 0x0a +#define CONFIG_AUTO_STAT_DNW_VERSION 0x05 +/* #undef CONFIG_AUTO_STAT_DNW_VERSION */ +#define CFG_DNW_TRANSFER_BUFFER (0x48000000) +#define CFG_DNW_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +/* #ifdef CONFIG_AUTO_STAT_DNW_VERSION */ +#define CFG_DNW_AUTO_CFG_PARTITION "fdisk -c 0" /* default partition */ +/* #endif */ + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x41000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc +#undef CONFIG_EFI_PARTITION +#ifdef CONFIG_EFI_PARTITION +#define CONFIG_PRI_GPT_SIZE (34 * 512) +#define CONFIG_SEC_GPT_SIZE (33 * 512) +#define CONFIG_16GEMMC_BLK (30535680) +#endif + +#ifdef CONFIG_CPU_EXYNOS3250 +/* CFG_FASTBOOT_TRANSFER_BUFFER + CFG_FASTBOOT_TRANSFER_BUFFER_SIZE */ +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#endif + + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000028 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 40000000;emmc close 0;" \ + "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#else +/*#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 200000;bootz 40008000 41000000"*/ +#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 1000000;bootz 40008000 41000000" /* nermy - for ramdisk */ +#endif + +#define CONFIG_BOOTCOMMAND_VIA_SCRIPT "movi init 1;fatload mmc 1 0x40000000 booting_script;source 0x40000000" + +#define CONFIG_RECOVERYCOMMAND_1st_SDMMC \ + "movi init 1;" \ + "emmc open 1;" \ + "movi r f 0 0x40000000;" \ + "movi r b 0 0x40008000;" \ + "movi r u 0 0x42000000;" \ + "movi r t 0 0x42100000;" \ + "movi w z f 1 0x40000000;" \ + "movi w z b 1 0x40008000;" \ + "movi w z u 1 0x42000000;" \ + "movi w z t 1 0x42100000;" \ + "emmc close 1;" + +#define CONFIG_RECOVERYCOMMAND_SDMMC \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +#define CONFIG_RECOVERYCOMMAND_USB \ + "fastboot" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" +#define CONFIG_FACTORY_RESET_COMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;reset;" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +/* define CONFIG_SYS_PROMPT "ESPRESSO3250 # " by surai */ +#define CONFIG_SYS_PROMPT "SHIRI # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_HZ 1000 + + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 8 +#define SDRAM_BANK_SIZE (64UL << 20UL) /* 64 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +/* #define CONFIG_IDENT_STRING " for ESPRESSO3250" by surai */ +#define CONFIG_IDENT_STRING " for SHIRI" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_ARM 1000 +#define CONFIG_PM_VDD_INT 1000 +#define CONFIG_PM_VDD_G3D 1000 +#define CONFIG_PM_VDD_MIF 1100 +#define CONFIG_PM_VDD_MEM 1200 + +#define CONFIG_PMIC_S5M8767A + +/* Bootloader Recovery */ +#undef CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* Boot configuration */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_EMMC_5_0 BOOT_EMMC_4_4 +#define BOOT_USB 0x100 + +/* Boot device */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ + +#define CONFIG_BOOT_LOGO +#define CONFIG_CHARGER_LOGO + +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02060000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Configurateion of LCD */ +/* #define CONFIG_EXYNOS_FB */ +/* #define CONFIG_USE_LCD */ +/* #define CONFIG_FB_ADDR 0x46000000 */ + +/* #define CONFIG_SHIRI_LCD */ +/* #define CONFIG_EXYNOS_MIPI_DSIM */ +/* #define CONFIG_CMD_LCD */ +/* #define CONFIG_CMD_LCDTEXT */ +/* #define CONFIG_S5P_LCD_INIT */ + +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define ISP_ARM_WDTRESET (1 << 25) +#define SYS_WDTRESET (1 << 20) +#define PINRESET (1 << 16) + +#endif /* __CONFIG_H */ diff --git a/include/configs/smdk4212.h b/include/configs/smdk4212.h new file mode 100644 index 000000000..60088c0f8 --- /dev/null +++ b/include/configs/smdk4212.h @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * Configuration settings for the SAMSUNG SMDK4412 (EXYNOS4412) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG 1 /* in a SAMSUNG core */ +#define CONFIG_S5P 1 /* S5P Family */ +#define CONFIG_ARCH_EXYNOS 1 /* which is in a Exynos Family */ +#define CONFIG_EXYNOS4X12 1 /* which is a EXYNOS4x12 SoC */ +#define CONFIG_EXYNOS4212 1 /* which is a EXYNOS4212 SoC */ +#define CONFIG_SMDKV310 1 /* working with SMDKV310*/ + +#define CONFIG_BL_MONITOR + +#define CONFIG_TRUSTZONE +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x100000 +#ifdef CONFIG_TRUSTZONE +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x2F000) +#endif + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x40003800 +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* APLL : 800MHz */ +/* #define CONFIG_CLK_ARM_800_APLL_800 */ +/* APLL : 1GHz */ +#define CONFIG_CLK_ARM_1000_APLL_1000 +/* APLL : 1.5GHz */ +/* #define CONFIG_CLK_ARM_1500_APLL_1500 */ + +#ifdef CONFIG_EXYNOS4412_EVT2 +/* bus clock: 220Mhz, DMC clock 440Mhz */ +#define CONFIG_CLK_BUS_DMC_220_440 +#else +/* bus clock: 200Mhz, DMC clock 400Mhz */ +#define CONFIG_CLK_BUS_DMC_200_400 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM_VDD_ARM 1.1 +#define CONFIG_PM_VDD_INT 1.1 +#define CONFIG_PM_VDD_G3D 1.1 +#define CONFIG_PM_VDD_MIF 1.1 +#define CONFIG_PM_VDD_LDO14 1.8 + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* Mach Type */ +#define CONFIG_MACH_TYPE MACH_TYPE_SMDK4212 + +/* Keep L2 Cache Disabled */ +#define CONFIG_L2_OFF 1 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Boot configuration */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x8 + +/* Boot device */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x10 +#define EMMC_4_4 0x14 +#define USB 0x40 + +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 + +/* input clock of PLL: SMDKV310 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_CLK_BUS_DMC_200_400 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_CMDLINE_EDITING + +/* Handling Sleep Mode*/ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI 1 +#define CONFIG_SERIAL1 1 /* use SERIAL 1 */ +#define CONFIG_BAUDRATE 115200 +#define EXYNOS4_DEFAULT_UART_OFFSET 0x010000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_SDHCI +#define CONFIG_S5P_MSHC + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_SKIP_MMC_STOP_CMD +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 5 + +#define USE_MMC4 + +#define PHASE_DEVIDER 4 + +#define SDR_CH4 0x00010001 +#define DDR_CH4 0x00010001 +#endif + +/* PWM */ +#define CONFIG_PWM 1 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_NET +#define CONFIG_CMD_FAT +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +/* OHCI : Host 1.0 */ +#define CONFIG_USB_OHCI +#undef CONFIG_USB_CPUMODE + +#define CONFIG_S3C_USBD + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS4_SYSREG_BASE + +/* + * Fast Boot +*/ +/* Fastboot variables */ +#define CONFIG_FASTBOOT + +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x10000000) /* 256MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x40800000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc +#define CFG_FASTBOOT_SDMMCBSP + +/* MMC SPL */ +#define CONFIG_SPL +#define COPY_BL2_FNPTR_ADDR 0x00002488 + +#define CONFIG_BOOTCOMMAND "movi r k 0 40008000; movi r r 0 41000000 100000; bootz 40008000 41000000" + +#define CONFIG_RECOVERYCOMMAND \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "SMDK4212 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size*/ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC2,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x6000000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) + +#define CONFIG_SYS_HZ 1000 + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ +#undef USE_2G_DRAM +#undef USE_512MB_DRAM + +#if defined(USE_512MB_DRAM) +#define MIF_DVFS_LEVEL1 +#endif + +#if defined(USE_2G_DRAM) +#define CONFIG_NR_DRAM_BANKS 8 +#elif defined(USE_512MB_DRAM) +#define CONFIG_NR_DRAM_BANKS 2 +#else +#define CONFIG_NR_DRAM_BANKS 4 +#endif +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#if defined(USE_512MB_DRAM) +#define PHYS_SDRAM_2_SIZE (SDRAM_BANK_SIZE \ + - CONFIG_TRUSTZONE_RESERVED_DRAM) +#else +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#ifdef USE_2G_DRAM +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#else +#define PHYS_SDRAM_4_SIZE (SDRAM_BANK_SIZE \ + - CONFIG_TRUSTZONE_RESERVED_DRAM) +#endif +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE \ + - CONFIG_TRUSTZONE_RESERVED_DRAM) +#endif /* USB_512MB_DRAM */ + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH 1 +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for SMDK4212" + +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +#define CONFIG_CLK_1000_400_200 + +/* MIU (Memory Interleaving Unit) */ +#define CONFIG_MIU_2BIT_INTERLEAVED + +#define CONFIG_ENV_IS_IN_MMC 1 +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#define RESERVE_BLOCK_SIZE (512) +#define BL1_SIZE (16 << 10) /*16 K reserved for BL1*/ +#define CONFIG_ENV_OFFSET (RESERVE_BLOCK_SIZE + BL1_SIZE) +#define CONFIG_DOS_PARTITION 1 +#define CFG_PARTITION_START 0x4000000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE) + +/* U-boot copy size from boot Media to DRAM.*/ +#define COPY_BL2_SIZE 0x80000 +#define BL2_START_OFFSET ((CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)/512) +#define BL2_SIZE_BLOC_COUNT (COPY_BL2_SIZE/512) + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Enable devicetree support */ +#define CONFIG_OF_LIBFDT +#endif /* __CONFIG_H */ diff --git a/include/configs/smdk4412.h b/include/configs/smdk4412.h new file mode 100644 index 000000000..cb9625dd9 --- /dev/null +++ b/include/configs/smdk4412.h @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * Configuration settings for the SAMSUNG SMDK4412 (EXYNOS4412) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG 1 /* in a SAMSUNG core */ +#define CONFIG_S5P 1 /* S5P Family */ +#define CONFIG_ARCH_EXYNOS 1 /* which is in a Exynos Family */ +#define CONFIG_EXYNOS4X12 1 /* which is a EXYNOS4x12 SoC */ +#define CONFIG_EXYNOS4412 1 /* which is a EXYNOS4412 SoC */ +#define CONFIG_SMDKV310 1 /* working with SMDKV310*/ +#undef CONFIG_EXYNOS4412_EVT2 + +#define CONFIG_BL_MONITOR + +#define CONFIG_TRUSTZONE +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x100000 +#ifdef CONFIG_TRUSTZONE +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x2F000) +#endif + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x40003800 +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* APLL : 800MHz */ +/* #define CONFIG_CLK_ARM_800_APLL_800 */ +/* APLL : 1GHz */ +#define CONFIG_CLK_ARM_1000_APLL_1000 +/* APLL : 1.5GHz */ +/* #define CONFIG_CLK_ARM_1500_APLL_1500 */ + +#ifdef CONFIG_EXYNOS4412_EVT2 +/* bus clock: 220Mhz, DMC clock 440Mhz */ +#define CONFIG_CLK_BUS_DMC_220_440 +#else +/* bus clock: 200Mhz, DMC clock 400Mhz */ +#define CONFIG_CLK_BUS_DMC_200_400 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM_VDD_ARM 1.2 +#define CONFIG_PM_VDD_INT 1.1 +#define CONFIG_PM_VDD_G3D 1.1 +#define CONFIG_PM_VDD_MIF 1.1 +#define CONFIG_PM_VDD_LDO14 1.8 + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* Mach Type */ +#define CONFIG_MACH_TYPE MACH_TYPE_SMDK4412 + +/* Keep L2 Cache Disabled */ +#define CONFIG_L2_OFF 1 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Boot configuration */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x8 + +/* Boot device */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x10 +#define EMMC_4_4 0x14 +#define USB 0x40 + +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 + +/* input clock of PLL: SMDKV310 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_CMDLINE_EDITING + +/* Handling Sleep Mode*/ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI 1 +#define CONFIG_SERIAL1 1 /* use SERIAL 1 */ +#define CONFIG_BAUDRATE 115200 +#define EXYNOS4_DEFAULT_UART_OFFSET 0x010000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_MMC_SDMA 1 + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_SKIP_MMC_STOP_CMD +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 5 + +#define USE_MMC4 + +#define PHASE_DEVIDER 4 + +#define SDR_CH4 0x00010001 +#define DDR_CH4 0x00010001 +#endif + +/* PWM */ +#define CONFIG_PWM 1 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_NET +#define CONFIG_CMD_FAT +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +/* OHCI : Host 1.0 */ +#define CONFIG_USB_OHCI +#undef CONFIG_USB_CPUMODE + +#define CONFIG_S3C_USBD + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS4_SYSREG_BASE + +/* + * Fast Boot +*/ +/* Fastboot variables */ +#define CONFIG_FASTBOOT + +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x10000000) /* 256MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x40800000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc +#define CFG_FASTBOOT_SDMMCBSP + +/* MMC SPL */ +#define CONFIG_SPL +#define COPY_BL2_FNPTR_ADDR 0x00002488 + +#define CONFIG_BOOTCOMMAND "movi r k 0 40008000; movi r r 0 41000000 100000; bootz 40008000 41000000" + +#define CONFIG_RECOVERYCOMMAND \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "SMDK4412 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size*/ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC2,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x6000000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) + +#define CONFIG_SYS_HZ 1000 + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ +#undef USE_2G_DRAM + +#ifdef USE_2G_DRAM +#define CONFIG_NR_DRAM_BANKS 8 +#else +#define CONFIG_NR_DRAM_BANKS 4 +#endif +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#ifdef USE_2G_DRAM +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#else +#define PHYS_SDRAM_4_SIZE (SDRAM_BANK_SIZE \ + - CONFIG_TRUSTZONE_RESERVED_DRAM) +#endif +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE \ + - CONFIG_TRUSTZONE_RESERVED_DRAM) +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH 1 +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for SMDK4412" + +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +#define CONFIG_CLK_1000_400_200 + +/* MIU (Memory Interleaving Unit) */ +#define CONFIG_MIU_2BIT_INTERLEAVED + +#define CONFIG_ENV_IS_IN_MMC 1 +#define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#define RESERVE_BLOCK_SIZE (512) +#define BL1_SIZE (16 << 10) /*16 K reserved for BL1*/ +#define CONFIG_ENV_OFFSET (RESERVE_BLOCK_SIZE + BL1_SIZE) +#define CONFIG_DOS_PARTITION 1 +#define CFG_PARTITION_START 0x4000000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE) + +/* U-boot copy size from boot Media to DRAM.*/ +#define COPY_BL2_SIZE 0x80000 +#define BL2_START_OFFSET ((CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)/512) +#define BL2_SIZE_BLOC_COUNT (COPY_BL2_SIZE/512) + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Enable devicetree support */ +#define CONFIG_OF_LIBFDT +#endif /* __CONFIG_H */ diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index d47881bcb..61e67e7d9 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -28,8 +28,10 @@ /* High Level Configuration Options */ #define CONFIG_SAMSUNG /* in a SAMSUNG core */ #define CONFIG_S5P /* S5P Family */ -#define CONFIG_EXYNOS5 /* which is in a Exynos5 Family */ -#define CONFIG_SMDK5250 /* which is in a SMDK5250 */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_CPU_EXYNOS5250 /* which is in a Exynos5250 */ +#define CONFIG_MACH_SMDK5250 /* which is in a SMDK5250 */ #include <asm/arch/cpu.h> /* get chip and board defs */ @@ -37,6 +39,28 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x100000 + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x40003800 +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + /* Keep L2 Cache Disabled */ #define CONFIG_SYS_DCACHE_OFF @@ -49,39 +73,122 @@ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_CMDLINE_TAG #define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG #define CONFIG_CMDLINE_EDITING -/* MACH_TYPE_SMDK5250 macro will be removed once added to mach-types */ -#define MACH_TYPE_SMDK5250 3774 #define CONFIG_MACH_TYPE MACH_TYPE_SMDK5250 +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x2F000) + /* Power Down Modes */ #define S5P_CHECK_SLEEP 0x00000BAD #define S5P_CHECK_DIDLE 0xBAD00000 #define S5P_CHECK_LPA 0xABAD0000 +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + /* Offset for inform registers */ #define INFORM0_OFFSET 0x800 #define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) /* select serial console configuration */ #define CONFIG_SERIAL_MULTI -#define CONFIG_SERIAL1 /* use SERIAL 1 */ +#define CONFIG_SERIAL2 /* use SERIAL 2 */ #define CONFIG_BAUDRATE 115200 #define EXYNOS5_DEFAULT_UART_OFFSET 0x010000 #define TZPC_BASE_OFFSET 0x10000 +/* Memory Type */ +#define CONFIG_LPDDR3 +#undef CONFIG_DDR3 + +/* Power Management is enabled */ +#define CONFIG_PM +/* POP TYPE */ +#define CONFIG_PM_VDD_ARM 1200 +#define CONFIG_PM_VDD_INT 1000 +#define CONFIG_PM_VDD_G3D 1200 +#define CONFIG_PM_VDD_MIF 1100 +#define CONFIG_PM_VDD_MEM 1250 +#define CONFIG_PM_VDDQ_M1_M2 1250 +/* SCP TYPE */ +#if defined(CONFIG_LPDDR3) +/* LPDDR3 */ +#define CONFIG_SCP_PM_VDD_ARM 1200 +#define CONFIG_SCP_PM_VDD_INT 1000 +#define CONFIG_SCP_PM_VDD_G3D 1200 +#define CONFIG_SCP_PM_VDD_MIF 1100 +#define CONFIG_SCP_PM_VDD_MEM 1250 +#define CONFIG_SCP_PM_VDDQ_M1_M2 1250 +#else +/* DDR3L */ +#define CONFIG_SCP_PM_VDD_ARM 1200 +#define CONFIG_SCP_PM_VDD_INT 1000 +#define CONFIG_SCP_PM_VDD_G3D 1200 +#define CONFIG_SCP_PM_VDD_MIF 1100 +#define CONFIG_SCP_PM_VDDQ_M1_M2 1350 +#endif /* CONFIG_LPDDR3 */ + /* SD/MMC configuration */ #define CONFIG_GENERIC_MMC #define CONFIG_MMC #define CONFIG_SDHCI +#define CONFIG_S5P_MSHC #define CONFIG_S5P_SDHCI +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_SKIP_MMC_STOP_CMD +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03030002 +#define DDR_CH0 0x03020001 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x0 +#define DDR_CH4 0x0 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + #define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT /* PWM */ #define CONFIG_PWM @@ -98,21 +205,88 @@ #define CONFIG_CMD_EXT2 #define CONFIG_CMD_FAT #define CONFIG_CMD_NET +#define CONFIG_CMD_BOOTZ #define CONFIG_BOOTDELAY 3 #define CONFIG_ZERO_BOOTDELAY_CHECK /* USB */ -#define CONFIG_CMD_USB -#define CONFIG_USB_EHCI -#define CONFIG_USB_EHCI_EXYNOS -#define CONFIG_USB_STORAGE +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_USB_CPUMODE + +#ifndef CONFIG_EXYNOS_USBD3 +#define CONFIG_S3C_USBD +#endif + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x12000000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000 + +#define EXYNOS_USB_PHY_BASE EXYNOS5_USBPHY_BASE +#define EXYNOS_USB_LINK_BASE EXYNOS5_USBOTG_BASE + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x41000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc /* MMC SPL */ #define CONFIG_SPL #define COPY_BL2_FNPTR_ADDR 0x02020030 -#define CONFIG_BOOTCOMMAND "mmc read 40007000 451 2000; bootm 40007000" +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 40000000;emmc close 0;" \ + "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#endif + +#define CONFIG_BOOTCOMMAND2 \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "movi r k 1 40000000;movi w k 0 40000000;" \ + "movi r r 1 40000000 100000;movi w r 0 40000000 100000;" \ + "fdisk -c 0;" \ + "movi init 0;" \ + "fatformat mmc 0:1;" \ + "mmc read 1 48000000 20000 a0000;" \ + "fastboot flash system 48000000;" \ + "mmc read 1 48000000 c0000 a0000;" \ + "fastboot flash userdata 48000000;" \ + "mmc read 1 48000000 160000 a0000;" \ + "fastboot flash cache 48000000;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" /* Miscellaneous configurable options */ #define CONFIG_SYS_LONGHELP /* undef to save memory */ @@ -153,7 +327,8 @@ #define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) #define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE #define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) -#define PHYS_SDRAM_8_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) #define CONFIG_SYS_MONITOR_BASE 0x00000000 @@ -165,30 +340,21 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_SECURE_BL1_ONLY - -/* Secure FW size configuration */ -#ifdef CONFIG_SECURE_BL1_ONLY -#define CONFIG_SEC_FW_SIZE (8 << 10) /* 8KB */ -#else -#define CONFIG_SEC_FW_SIZE 0 -#endif - -/* Configuration of BL1, BL2, ENV Blocks on mmc */ -#define CONFIG_RES_BLOCK_SIZE (512) -#define CONFIG_BL1_SIZE (16 << 10) /*16 K reserved for BL1*/ -#define CONFIG_BL2_SIZE (512UL << 10UL) /* 512 KB */ +/* Configuration of ENV size on mmc */ #define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> -#define CONFIG_BL1_OFFSET (CONFIG_RES_BLOCK_SIZE + CONFIG_SEC_FW_SIZE) -#define CONFIG_BL2_OFFSET (CONFIG_BL1_OFFSET + CONFIG_BL1_SIZE) -#define CONFIG_ENV_OFFSET (CONFIG_BL2_OFFSET + CONFIG_BL2_SIZE) +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif /* U-boot copy size from boot Media to DRAM.*/ #define BL2_START_OFFSET (CONFIG_BL2_OFFSET/512) #define BL2_SIZE_BLOC_COUNT (CONFIG_BL2_SIZE/512) #define CONFIG_DOS_PARTITION - +#define CFG_PARTITION_START 0x4000000 #define CONFIG_IRAM_STACK 0x02050000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) @@ -201,7 +367,10 @@ #define CONFIG_ENV_SROM_BANK 1 #endif /*CONFIG_CMD_NET*/ -/* Enable devicetree support */ -#define CONFIG_OF_LIBFDT +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) #endif /* __CONFIG_H */ diff --git a/include/configs/smdk5410.h b/include/configs/smdk5410.h new file mode 100644 index 000000000..1f9f481af --- /dev/null +++ b/include/configs/smdk5410.h @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * Configuration settings for the SAMSUNG SMDK5410 (EXYNOS5410) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_ARMV7 +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_SMDK5410 /* which is in a SMDK5410 */ +#define CONFIG_ARCH_EXYNOS +#define CONFIG_ARCH_EXYNOS5 +#define CONFIG_MACH_SMDK5410 +#define CONFIG_CPU_EXYNOS5410 /* which is in a Exynos5410 */ +#define CONFIG_CPU_EXYNOS5410_EVT2 /* which is in a Exynos5410 EVT2 */ +/* +#define CONFIG_MACH_UNIVERSAL5410 +*/ +#undef CONFIG_MACH_ASB5410 + +/* Clock Speed Selection */ +#ifdef CONFIG_MACH_UNIVERSAL5410 +#define CONFIG_CLK_ARM_800 +#define CONFIG_CLK_KFC_600 +#else +#define CONFIG_CLK_ARM_900 +#define CONFIG_CLK_KFC_600 +#endif + +/* Memory type */ +#define CONFIG_LPDDR3 +#define CONFIG_BTS_SUPPORT + +/* MCLK_CDREX */ +#define MCLK_CDREX_800 1 + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +/* +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_DISPLAY_BOARDINFO */ +#define CONFIG_BOARD_LATE_INIT + +/* Bootloader Recovery */ +#if defined(CONFIG_MACH_UNIVERSAL5410) || defined(CONFIG_MACH_ASB5410) +#undef CONFIG_RECOVERY_MODE +#else +#define CONFIG_RECOVERY_MODE +#endif + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x0202D000 + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x200000 +#ifdef CONFIG_TRUSTZONE +#define CONFIG_BOOTLOADER_MONITOR +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x53000) +#endif + +/* input clock of PLL: SMDK5410 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_CMDLINE_EDITING + +/* MACH_TYPE_SMDK5410 macro will be removed once added to mach-types */ +#define CONFIG_MACH_TYPE MACH_TYPE_SMDK5410 + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#ifdef CONFIG_MACH_ASB5410 +#define CONFIG_SERIAL3 /* use SERIAL 3 */ +#else +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#endif +#define CONFIG_BAUDRATE 115200 +#define EXYNOS5_DEFAULT_UART_OFFSET 0x010000 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 + +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03030002 +#define DDR_CH0 0x03020001 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x0 +#define DDR_CH4 0x0 +#endif + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_BL_MONITOR +#ifndef CONFIG_CPU_EXYNOS5410_EVT0 +#define CONFIG_SECURE_TZSW_ONLY +#endif +/* +#define CONFIG_SECURE_BOOT +*/ + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT + +#define CONFIG_CMD_MOVI +#define CONFIG_CMD_MOVINAND +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#define CONFIG_CMD_USB +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_EXYNOS +#define CONFIG_USB_STORAGE + +/* OHCI : Host 1.0 */ +#define CONFIG_USB_OHCI +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_USB_CPUMODE + +#ifdef CONFIG_EXYNOS_USBD3 +#ifdef CONFIG_MACH_UNIVERSAL5410 +#define CONFIG_EXYNOS_USBD3_CH0 +#else +#define CONFIG_EXYNOS_USBD3_CH0 +/*#define CONFIG_EXYNOS_USBD3_CH1*/ +#endif +#else +#undef CONFIG_S3C_USBD +#endif + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x12000000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000 +#define USBDEVICE3_LINK_CH1_BASE 0x12400000 +#define USBDEVICE3_PHYCTRL_CH1_BASE 0x12500000 + +#define EXYNOS_USB_PHY_BASE EXYNOS5_USBPHY_BASE +#define EXYNOS_USB_LINK_BASE EXYNOS5_USBOTG_BASE + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP + +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x41000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc + +#ifdef CONFIG_CPU_EXYNOS5410_EVT2 +/* CFG_FASTBOOT_TRANSFER_BUFFER + CFG_FASTBOOT_TRANSFER_BUFFER_SIZE */ +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#endif + +#ifdef CONFIG_CMD_MOVINAND +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +#endif + +/* MMC SPL */ +#define CONFIG_SPL + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 40000000;emmc close 0;" \ + "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#endif + +#ifdef CONFIG_RAMDUMP_MODE +#define CONFIG_BOOTCOMMAND_RAMDUMP "ramdump" +#endif + +#define CONFIG_BOOTARGS "" + +#define CONFIG_BOOTCOMMAND2 \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + /* + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "movi r k 1 40000000;movi w k 0 40000000;" \ + "movi r r 1 40000000 100000;movi w r 0 40000000 100000;" \ + "fdisk -c 0;" \ + "movi init 0;" \ + "fatformat mmc 0:1;" \ + "mmc read 1 48000000 20000 a0000;" \ + "fastboot flash system 48000000;" \ + "mmc read 1 48000000 c0000 a0000;" \ + "fastboot flash userdata 48000000;" \ + "mmc read 1 48000000 160000 a0000;" \ + "fastboot flash cache 48000000;" \ + "reset" + */ + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "SMDK5410 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) + +#define CONFIG_SYS_HZ 1000 + +#define CONFIG_RD_LVL + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 8 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) + + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for SMDK5410" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM +#ifdef CONFIG_MACH_UNIVERSAL5410 +#define CONFIG_PM_VDD_ARM 1.0750 +#define CONFIG_PM_VDD_KFC 1.0500 +#define CONFIG_PM_VDD_INT 1.1875 +#define CONFIG_PM_VDD_G3D 1.00 +#define CONFIG_PM_VDD_MIF 1.0625 +#else +#define CONFIG_PM_VDD_ARM 1.20 +#define CONFIG_PM_VDD_KFC 1.20 +#define CONFIG_PM_VDD_INT 1.05 +#define CONFIG_PM_VDD_G3D 1.20 +#define CONFIG_PM_VDD_MIF 1.05 +#endif + +/* Boot configuration */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* Boot device */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ + +#include <asm/arch/movi_partition.h> + +/* U-boot copy size from boot Media to DRAM.*/ +#define BL2_START_OFFSET (CONFIG_BL2_OFFSET/512) +#define BL2_SIZE_BLOC_COUNT (CONFIG_BL2_SIZE/512) +#define CONFIG_DOS_PARTITION +#define CFG_PARTITION_START 0x4000000 + +#define CONFIG_IRAM_STACK 0x02074000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_NET_MULTI +#endif /*CONFIG_CMD_NET*/ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Enable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +#endif /* __CONFIG_H */ diff --git a/include/configs/smdk5412.h b/include/configs/smdk5412.h new file mode 100644 index 000000000..d802c3e4b --- /dev/null +++ b/include/configs/smdk5412.h @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * Configuration settings for the SAMSUNG SMDK5412 (EXYNOS5412) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_CPU_EXYNOS5412 /* which is in a Exynos5412 */ +#define CONFIG_MACH_SMDK5412 /* which is in a SMDK5412 */ +/* +#define CONFIG_MACH_UNIVERSAL5412 +*/ + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x600000 +#else +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#define CONFIG_TZPC +#undef CONFIG_SMC_CMD +#endif + +/* Reserved memory for U-Boot */ +#define CONFIG_UBOOT_RESERVED_DRAM 0x80000 /* Reserved 512Kbyte */ +#define CONFIG_UBOOT_ATAG_RESERVED_DRAM 0x380000 /* Reserved 512Kbyte */ + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x20003800 +#define CONFIG_SECURE_KERNEL_BASE 0x20008000 +#define CONFIG_SECURE_KERNEL_SIZE PART_SIZE_KERNEL +#define CONFIG_SECURE_ROOTFS_BASE 0x21000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_ARM 1.00 +#define CONFIG_PM_VDD_KFC 1.00 +#define CONFIG_PM_VDD_INT 1.00 +#define CONFIG_PM_VDD_G3D 1.00 +#define CONFIG_PM_VDD_MIF 1.00 + +/* Bootloader Recovery */ +#define CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x20000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02026000 + +/* input clock of PLL: SMDK5412 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_MACH_TYPE MACH_TYPE_SMDK5412 + +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x53000) + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#define CONFIG_BAUDRATE 115200 +#define EXYNOS5_DEFAULT_UART_OFFSET 0x010000 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI +#define CONFIG_MMC_64BIT_BUS + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03030002 +#define DDR_CH0 0x03020001 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x0 +#define DDR_CH4 0x0 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#define CONFIG_CMD_USB +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_EXYNOS +#define CONFIG_USB_STORAGE + +/* OHCI : Host 1.0 */ +#define CONFIG_USB_OHCI +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_USB_CPUMODE + +#ifdef CONFIG_EXYNOS_USBD3 +#define CONFIG_EXYNOS_USBD3_CH0 +/*#define CONFIG_EXYNOS_USBD3_CH1*/ +#else +#undef CONFIG_S3C_USBD +#endif + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x12000000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000 +#define USBDEVICE3_LINK_CH1_BASE 0x12400000 +#define USBDEVICE3_PHYCTRL_CH1_BASE 0x12500000 + +#define EXYNOS_USB_PHY_BASE EXYNOS5_USBPHY_BASE +#define EXYNOS_USB_LINK_BASE EXYNOS5_USBOTG_BASE + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x28000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x20008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x21000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc +#ifdef CONFIG_MMC_64BIT_BUS +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#endif + +/* MMC SPL */ +#define CONFIG_SPL +#define IROM_FNPTR_BASE 0x02020030 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000004 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 20000000;emmc close 0;" \ + "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#endif + +#ifdef CONFIG_RAMDUMP_MODE +#define CONFIG_BOOTCOMMAND_RAMDUMP "fastboot" +#endif + +#define CONFIG_RECOVERYCOMMAND \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 20008000;" \ + "movi read rootfs 0 21000000 100000;" \ + "bootz 20008000 21000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "SMDK5412 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) + +#define CONFIG_SYS_HZ 1000 + +#define CONFIG_RD_LVL + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 12 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_9 (CONFIG_SYS_SDRAM_BASE + (8 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_9_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_10 (CONFIG_SYS_SDRAM_BASE + (9 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_10_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_11 (CONFIG_SYS_SDRAM_BASE + (10 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_11_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_12 (CONFIG_SYS_SDRAM_BASE + (11 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_12_SIZE (SDRAM_BANK_SIZE - \ + (CONFIG_TRUSTZONE_RESERVED_DRAM + \ + CONFIG_UBOOT_RESERVED_DRAM)) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for SMDK5412" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* U-boot copy size from boot Media to DRAM.*/ +#define CONFIG_DOS_PARTITION +#define CFG_PARTITION_START 0x4000000 +#define CONFIG_IRAM_STACK 0x02074000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_NET_MULTI +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +#endif /* __CONFIG_H */ diff --git a/include/configs/universal3250.h b/include/configs/universal3250.h new file mode 100644 index 000000000..33e977e68 --- /dev/null +++ b/include/configs/universal3250.h @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * Configuration settings for the SAMSUNG UNIVERSAL3250 (EXYNOS3250) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS +#define CONFIG_ARCH_EXYNOS4 +#define CONFIG_CPU_EXYNOS3250 /* which is in a Exynos3250 */ +#define CONFIG_MACH_SMDK3250 + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02025000 +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x3F000) + + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x100000 +#else +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#endif + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x40003800 +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* +* clock setting: +* APLL = 700MHz +* MPLL = 1600MHz +* BPLL = 800MHz +* EPLL = 800MHz +* VPLL = 335MHz +*/ +/* input clock of PLL: SMDK3250 has 24MHz input clock */ +#ifdef CONFIG_SMDK3250_FPGA_DEBUG +#define CONFIG_SYS_FIN_12 +#define CONFIG_SYS_CLK_FREQ 12000000 //FPGA clock source: 12MHz +#else +#define CONFIG_SYS_FIN_24 +#define CONFIG_SYS_CLK_FREQ 24000000 //backup clock in smdk +#endif + +/* MCLK_CDREX */ +#define MCLK_CDREX_400 1 + + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_CMDLINE_EDITING + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL1 /* use SERIAL 1 */ +#define CONFIG_BAUDRATE 115200 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03040000 +#define DDR_CH0 0x03010000 +#ifndef CONFIG_SMDK3250_FPGA_DEBUG +#define SDR_CH2 0x03010000 +#define DDR_CH2 0x03010000 +#else +#define SDR_CH2 0x03000000 +#define DDR_CH2 0x03000000 +#endif +#define SDR_CH4 0x0 +#define DDR_CH4 0x0 +#endif + + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT + +#define CONFIG_CMD_MOVI +#define CONFIG_CMD_MOVINAND +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE + + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS4_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS4_POWER_BASE + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x41000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc +#undef CONFIG_EFI_PARTITION +#ifdef CONFIG_EFI_PARTITION +#define CONFIG_PRI_GPT_SIZE (34 * 512) +#define CONFIG_SEC_GPT_SIZE (33 * 512) +#define CONFIG_16GEMMC_BLK (30535680) +#endif + +#ifdef CONFIG_CPU_EXYNOS3250 +/* CFG_FASTBOOT_TRANSFER_BUFFER + CFG_FASTBOOT_TRANSFER_BUFFER_SIZE */ +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#endif + + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000028 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 40000000;emmc close 0;" \ + "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 200000;bootz 40008000 41000000" +#endif + +#define CONFIG_RECOVERYCOMMAND_SDMMC \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +#define CONFIG_RECOVERYCOMMAND_USB \ + "fastboot" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "UNIVERSAL3250 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_HZ 1000 + + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 8 +#define SDRAM_BANK_SIZE (64UL << 20UL) /* 64 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for UNIVERSAL3250" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_ARM 1000 +#define CONFIG_PM_VDD_INT 1000 +#define CONFIG_PM_VDD_G3D 1000 +#define CONFIG_PM_VDD_MIF 1100 +#define CONFIG_PM_VDD_MEM 1200 + +#define CONFIG_PMIC_S5M8767A + +/* Bootloader Recovery */ +#define CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* Boot configuration */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_EMMC_5_0 BOOT_EMMC_4_4 +#define BOOT_USB 0x100 + +/* Boot device */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02060000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define ISP_ARM_WDTRESET (1 << 25) +#define SYS_WDTRESET (1 << 20) +#define PINRESET (1 << 16) + +#endif /* __CONFIG_H */ diff --git a/include/configs/universal5260.h b/include/configs/universal5260.h new file mode 100644 index 000000000..df753fb88 --- /dev/null +++ b/include/configs/universal5260.h @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * Configuration settings for the SAMSUNG SMDK4270 (EXYNOS4270) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_CPU_EXYNOS5260 /* which is in a Exynos5260 */ +#define CONFIG_MACH_UNIVERSAL5260 /* which is in a UNIVERSAL5260 */ +#define CONFIG_MACH_UNIVERSAL5260_REV1 /* which is in a UNIVERSAL5260_REV0.1 */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_DISPLAY_CHIPID + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x600000 +#else +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#endif + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x20003800 +#define CONFIG_SECURE_KERNEL_BASE 0x20008000 +#define CONFIG_SECURE_KERNEL_SIZE PART_SIZE_KERNEL +#define CONFIG_SECURE_ROOTFS_BASE 0x21000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_EGL 1000 +#define CONFIG_PM_VDD_KFC 1000 +#define CONFIG_PM_VDD_MIF 1000 +#define CONFIG_PM_VDD_INT 1025 +#define CONFIG_PM_VDD_G3D 1000 + +/* Bootloader Recovery */ +#define CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x20000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02026000 + +/* input clock of PLL: SMDK5260 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_MACH_TYPE MACH_TYPE_XYREF5260 + +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x53000) + +/* BL1 version information */ +#define CONFIG_BL1_VERSION_INFORM (CONFIG_PHY_IRAM_NS_BASE + 0x810) + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#if defined(CONFIG_MACH_UNIVERSAL5260_REV1) +#define CONFIG_SERIAL1 /* use SERIAL 1 */ +#else +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#endif +#define CONFIG_BAUDRATE 115200 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03020001 +#define DDR_CH0 0x03030002 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x00010001 +#define DDR_CH4 0x00010001 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT + +/* CHIP ID */ +#define CHIPID0_OFFSET 0x14 +#define CHIPID1_OFFSET 0x18 + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_NET +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5260_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5260_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x12000000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000 + +#define CLK_MUX_SEL_FSYS1_OFFSET 0x0204 +#define CLK_MUX_STATE_FSYS1_OFFSET 0x0404 +#define USBDEVICE3_PHYCLK_SEL (EXYNOS5260_CMU_FSYS_BASE+CLK_MUX_SEL_FSYS1_OFFSET) +#define USBDEVICE3_PHYCLK_STATE (EXYNOS5260_CMU_FSYS_BASE+CLK_MUX_STATE_FSYS1_OFFSET) + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot multiple access */ +#define CFG_FASTBOOT_MULTI_ACESS +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x28000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x20008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x21000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000028 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 20000000;emmc close 0;" \ + "movi read kernel 0 20008000;movi read rootfs 0 22000000 100000;bootz 20008000 22000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 20008000;movi read rootfs 0 22000000 100000;bootz 20008000 22000000" +#endif + +#define CONFIG_RECOVERYCOMMAND_SDMMC \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +#define CONFIG_RECOVERYCOMMAND_USB \ + "fastboot" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 20008000;" \ + "movi read rootfs 0 22000000 100000;" \ + "bootz 20008000 22000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "UNIVERSAL5260 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_HZ 1000 + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 8 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for UNIVERSAL5260" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02074000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define A5IS_WDTRESET (1 << 27) +#define CORTEXA7_WDTRESET (1 << 24) +#define CORTEXA15_WDTRESET (1 << 23) +#define PINRESET (1 << 16) +#define CORTEXA7_WRESET3 (1 << 7) +#define CORTEXA7_WRESET2 (1 << 6) +#define CORTEXA7_WRESET1 (1 << 5) +#define CORTEXA7_WRESET0 (1 << 4) +#define CORTEXA15_WRESET1 (1 << 1) +#define CORTEXA15_WRESET0 (1 << 0) + +#endif /* __CONFIG_H */ diff --git a/include/configs/universal5412.h b/include/configs/universal5412.h new file mode 100644 index 000000000..948ffa604 --- /dev/null +++ b/include/configs/universal5412.h @@ -0,0 +1,385 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * Configuration settings for the SAMSUNG SMDK5412 (EXYNOS5412) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_CPU_EXYNOS5412 /* which is in a Exynos5412 */ +#define CONFIG_MACH_SMDK5412 /* which is in a SMDK5412 */ +#define CONFIG_MACH_UNIVERSAL5412 + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x600000 +#else +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#define CONFIG_TZPC +#undef CONFIG_SMC_CMD +#endif + +/* Reserved memory for U-Boot */ +#define CONFIG_UBOOT_RESERVED_DRAM 0x80000 /* Reserved 512Kbyte */ +#define CONFIG_UBOOT_ATAG_RESERVED_DRAM 0x380000 /* Reserved 512Kbyte */ + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x20003800 +#define CONFIG_SECURE_KERNEL_BASE 0x20008000 +#define CONFIG_SECURE_KERNEL_SIZE PART_SIZE_KERNEL +#define CONFIG_SECURE_ROOTFS_BASE 0x21000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_ARM 1.00 +#define CONFIG_PM_VDD_KFC 1.00 +#define CONFIG_PM_VDD_INT 1.00 +#define CONFIG_PM_VDD_G3D 1.00 +#define CONFIG_PM_VDD_MIF 1.00 + +/* Bootloader Recovery */ +#define CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x20000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02026000 + +/* input clock of PLL: SMDK5412 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_MACH_TYPE MACH_TYPE_SMDK5412 + +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x53000) + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#define CONFIG_BAUDRATE 115200 +#define EXYNOS5_DEFAULT_UART_OFFSET 0x010000 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI +#define CONFIG_MMC_64BIT_BUS + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03030002 +#define DDR_CH0 0x03020001 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x0 +#define DDR_CH4 0x0 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#define CONFIG_CMD_USB +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_EXYNOS +#define CONFIG_USB_STORAGE + +/* OHCI : Host 1.0 */ +#define CONFIG_USB_OHCI +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_USB_CPUMODE + +#ifdef CONFIG_EXYNOS_USBD3 +#define CONFIG_EXYNOS_USBD3_CH0 +/*#define CONFIG_EXYNOS_USBD3_CH1*/ +#else +#undef CONFIG_S3C_USBD +#endif + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x12000000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000 +#define USBDEVICE3_LINK_CH1_BASE 0x12400000 +#define USBDEVICE3_PHYCTRL_CH1_BASE 0x12500000 + +#define EXYNOS_USB_PHY_BASE EXYNOS5_USBPHY_BASE +#define EXYNOS_USB_LINK_BASE EXYNOS5_USBOTG_BASE + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x28000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x20008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x21000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc +#ifdef CONFIG_MMC_64BIT_BUS +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#endif + +/* MMC SPL */ +#define CONFIG_SPL +#define IROM_FNPTR_BASE 0x02020030 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000004 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 20000000;emmc close 0;" \ + "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#endif + +#ifdef CONFIG_RAMDUMP_MODE +#define CONFIG_BOOTCOMMAND_RAMDUMP "fastboot" +#endif + +#define CONFIG_RECOVERYCOMMAND \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 20008000;" \ + "movi read rootfs 0 21000000 100000;" \ + "bootz 20008000 21000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "SMDK5412 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) + +#define CONFIG_SYS_HZ 1000 + +#define CONFIG_RD_LVL + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 12 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_9 (CONFIG_SYS_SDRAM_BASE + (8 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_9_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_10 (CONFIG_SYS_SDRAM_BASE + (9 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_10_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_11 (CONFIG_SYS_SDRAM_BASE + (10 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_11_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_12 (CONFIG_SYS_SDRAM_BASE + (11 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_12_SIZE (SDRAM_BANK_SIZE - \ + (CONFIG_TRUSTZONE_RESERVED_DRAM + \ + CONFIG_UBOOT_RESERVED_DRAM)) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for SMDK5412" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* U-boot copy size from boot Media to DRAM.*/ +#define CONFIG_DOS_PARTITION +#define CFG_PARTITION_START 0x4000000 +#define CONFIG_IRAM_STACK 0x02074000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_NET_MULTI +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +#endif /* __CONFIG_H */ diff --git a/include/configs/universal5430.h b/include/configs/universal5430.h new file mode 100644 index 000000000..44d5e15ff --- /dev/null +++ b/include/configs/universal5430.h @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * Configuration settings for the SAMSUNG UNIVERSAL5430 (EXYNOS5430) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_CPU_EXYNOS5430 /* which is in a Exynos5430 */ +#define CONFIG_MACH_XYREF5430 /* which is in a XYREF5430 */ +#define CONFIG_MACH_UNIVERSAL5430 /* which is in a UNIVERSAL5430 */ + +#define CONFIG_GPIO_DAT_MASK /* opertation to mask dat register */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_DISPLAY_CHIPID + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x600000 +#else +#define CONFIG_TZPC +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#endif + +/* Reserved memory for U-Boot */ +#define CONFIG_UBOOT_RESERVED_DRAM 0x80000 /* Reserved 512Kbyte */ +#define CONFIG_UBOOT_ATAG_RESERVED_DRAM 0x380000 /* Reserved 512Kbyte */ + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x20003800 +#define CONFIG_SECURE_KERNEL_BASE 0x20008000 +#define CONFIG_SECURE_KERNEL_SIZE PART_SIZE_KERNEL +#define CONFIG_SECURE_ROOTFS_BASE 0x21000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_MIF 1025 +#define CONFIG_PM_VDD_EGL 900 +#define CONFIG_PM_VDD_KFC 950 +#define CONFIG_PM_VDD_INT 1050 +#define CONFIG_PM_VDD_G3D 875 + + +/* Bootloader Recovery */ +#define CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x20000000 +#if defined(CONFIG_TRUSTZONE_ENABLE) +#define CONFIG_SYS_TEXT_BASE 0x9F980000 +#else +#define CONFIG_SYS_TEXT_BASE 0x9FF80000 +#endif +#define CONFIG_SPL_TEXT_BASE 0x02026000 + +/* input clock of PLL: SMDK5430 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_MACH_TYPE MACH_TYPE_XYREF5430 + +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x5F000) + +/* BL1 version information */ +#define CONFIG_BL1_VERSION_INFORM (CONFIG_PHY_IRAM_NS_BASE + 0x810) + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL1 /* use SERIAL 1 */ +#define CONFIG_BAUDRATE 115200 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI +#define CONFIG_MMC_64BIT_BUS + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03020001 +#define DDR_CH0 0x03030002 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x00010001 +#define DDR_CH4 0x00010001 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT +#define CONFIG_PREP_BOARDCONFIG_FOR_KERNEL + +/* CHIP ID */ +#define CHIPID0_OFFSET 0x14 +#define CHIPID1_OFFSET 0x18 + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_NET +#define CONFIG_CMD_BOOTZ + +/* FAT filesystem */ +#define CONFIG_FAT_WRITE + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5430_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5430_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x15400000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x15500000 + +#define CLK_MUX_SEL_FSYS2_OFFSET 0x0208 +#define CLK_MUX_STATE_FSYS2_OFFSET 0x0408 +#define USBDEVICE3_PHYCLK_SEL (EXYNOS5430_CMU_FSYS_BASE+CLK_MUX_SEL_FSYS2_OFFSET) +#define USBDEVICE3_PHYCLK_STATE (EXYNOS5430_CMU_FSYS_BASE+CLK_MUX_STATE_FSYS2_OFFSET) + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot multiple access */ +#define CFG_FASTBOOT_MULTI_ACESS +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x28000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x20008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x21000000) +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000028 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 +#define EMMC_ENDBOOTOP_OFFSET 0x00000018 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 20000000;emmc close 0;" \ + "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#endif + +#define CONFIG_RECOVERYCOMMAND \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 20008000;" \ + "movi read rootfs 0 21000000 100000;" \ + "bootz 20008000 21000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "UNIVERSAL5430 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_HZ 1000 + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 12 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8_END_SIZE (SDRAM_BANK_SIZE - \ + (CONFIG_TRUSTZONE_RESERVED_DRAM + \ + CONFIG_UBOOT_RESERVED_DRAM)) +#define PHYS_SDRAM_9 (CONFIG_SYS_SDRAM_BASE + (8 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_9_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_10 (CONFIG_SYS_SDRAM_BASE + (9 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_10_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_11 (CONFIG_SYS_SDRAM_BASE + (10 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_11_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_12 (CONFIG_SYS_SDRAM_BASE + (11 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_12_SIZE (SDRAM_BANK_SIZE - \ + (CONFIG_TRUSTZONE_RESERVED_DRAM + \ + CONFIG_UBOOT_RESERVED_DRAM)) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for UNIVERSAL5430" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02080000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x100000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* secondary boot information */ +#define CONFIG_SECOND_BOOT_INFORM_SIZE (0x4) +#define CONFIG_SECOND_BOOT_INFORM_BASE (CONFIG_PHY_IRAM_NS_BASE + \ + nscode_end - nscode_base) + +/* image inforamtion base address for SMC */ +#define CONFIG_SMC_IMAGE_INFORM_BASE (CONFIG_PHY_IRAM_NS_BASE + \ + nscode_end - nscode_base + \ + CONFIG_SECOND_BOOT_INFORM_SIZE) +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define A5IS_WDTRESET (1 << 27) +#define CORTEXA7_WDTRESET (1 << 24) +#define CORTEXA15_WDTRESET (1 << 23) +#define PINRESET (1 << 16) +#define CORTEXA7_WRESET3 (1 << 7) +#define CORTEXA7_WRESET2 (1 << 6) +#define CORTEXA7_WRESET1 (1 << 5) +#define CORTEXA7_WRESET0 (1 << 4) +#define CORTEXA15_WRESET1 (1 << 1) +#define CORTEXA15_WRESET0 (1 << 0) + +#endif /* __CONFIG_H */ diff --git a/include/configs/xyref4415.h b/include/configs/xyref4415.h new file mode 100644 index 000000000..9842501dd --- /dev/null +++ b/include/configs/xyref4415.h @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * + * Configuration settings for the SAMSUNG XYREF4415 (EXYNOS4415) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS4 /* which is in a Exynos4 Family */ +#define CONFIG_CPU_EXYNOS4415 /* which is in a Exynos4415 */ +#define CONFIG_MACH_XYREF4415 /* which is in a XYREF4415 */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +/* Configuration of SDRAM size */ +#undef CONFIG_SDRAM_SIZE_1536MB + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x400000 +#endif + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x40003800 +#define CONFIG_SECURE_KERNEL_BASE 0x40008000 +#define CONFIG_SECURE_KERNEL_SIZE 0x400000 +#define CONFIG_SECURE_ROOTFS_BASE 0x41000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02026000 + +/* input clock of PLL: XYREF4415 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_MACH_TYPE MACH_TYPE_XYREF4415 + +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x4F000) + +/* bootloader system information */ +#define CONFIG_BL_SYS_INFO_BASE (CONFIG_PHY_IRAM_NS_BASE + 0x800) + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL3 /* use SERIAL 3 */ +#define CONFIG_BAUDRATE 115200 +#define EXYNOS4_DEFAULT_UART_OFFSET 0x010000 + +#define TZPC_BASE_OFFSET 0x10000 + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_MIF 1100 +#define CONFIG_PM_VDD_ARM 1000 +#define CONFIG_PM_VDD_INT 1000 +#define CONFIG_PM_VDD_G3D 1100 + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03020001 +#define DDR_CH0 0x03030002 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x00010001 +#define DDR_CH4 0x00010001 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_NET +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS4_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS4_POWER_BASE + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x41000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000040 +#define SDMMC_DEV_OFFSET 0x00000010 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 40000000;emmc close 0;" \ + "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootz 40008000 41000000" +#endif + +#define CONFIG_RECOVERYCOMMAND \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 40008000;" \ + "movi read rootfs 0 41000000 100000;" \ + "bootz 40008000 41000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "XYREF4415 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x3E00000) + +#define CONFIG_SYS_HZ 1000 + +#define CONFIG_RD_LVL + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#if defined(CONFIG_SDRAM_SIZE_1536MB) +#define CONFIG_NR_DRAM_BANKS 6 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) +#else +#define CONFIG_NR_DRAM_BANKS 4 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) +#endif + +#define CONFIG_SYS_SDRAM_SIZE (CONFIG_NR_DRAM_BANKS * SDRAM_BANK_SIZE) +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for XYREF4415" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02080000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Configurateion of LCD */ +#ifdef CONFIG_EXYNOS_FB +#define CONFIG_SAMSUNG_LOGO +#define CONFIG_FB_EXYNOS_FIMD_V8 +#define CONFIG_BMP_32BPP +#define CONFIG_FB_ADDR 0x50000000 +#define CONFIG_S6E8AA0 +#define CONFIG_EXYNOS_MIPI_DSIM + +#define CONFIG_VIDEO_BMP_GZIP +#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((588 * 120 * 4) + (1 << 12)) +#endif + +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define CP_WDTRESET (1 << 27) +#define ISP_ARM_WDTRESET (1 << 25) +#define SYS_WDTRESET (1 << 20) +#define PINRESET (1 << 16) + +#endif /* __CONFIG_H */ diff --git a/include/configs/xyref5260.h b/include/configs/xyref5260.h new file mode 100644 index 000000000..bc53dd1ae --- /dev/null +++ b/include/configs/xyref5260.h @@ -0,0 +1,386 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * Configuration settings for the SAMSUNG SMDK4270 (EXYNOS4270) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_CPU_EXYNOS5260 /* which is in a Exynos5260 */ +#define CONFIG_MACH_XYREF5260 /* which is in a XYREF5260 */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_DISPLAY_CHIPID + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x600000 +#else +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#endif + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x20003800 +#define CONFIG_SECURE_KERNEL_BASE 0x20008000 +#define CONFIG_SECURE_KERNEL_SIZE PART_SIZE_KERNEL +#define CONFIG_SECURE_ROOTFS_BASE 0x21000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_EGL 1000 +#define CONFIG_PM_VDD_KFC 1000 +#define CONFIG_PM_VDD_MIF 1000 +#define CONFIG_PM_VDD_INT 1025 +#define CONFIG_PM_VDD_G3D 1000 + +/* Bootloader Recovery */ +#define CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x20000000 +#define CONFIG_SYS_TEXT_BASE 0x43E00000 +#define CONFIG_SPL_TEXT_BASE 0x02026000 + +/* input clock of PLL: SMDK5260 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_MACH_TYPE MACH_TYPE_XYREF5260 + +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x53000) + +/* BL1 version information */ +#define CONFIG_BL1_VERSION_INFORM (CONFIG_PHY_IRAM_NS_BASE + 0x810) + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#define CONFIG_BAUDRATE 115200 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03020001 +#define DDR_CH0 0x03030002 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x00010001 +#define DDR_CH4 0x00010001 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT + +/* CHIP ID */ +#define CHIPID0_OFFSET 0x14 +#define CHIPID1_OFFSET 0x18 + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_NET +#define CONFIG_CMD_BOOTZ + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5260_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5260_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x12000000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x12100000 + +#define CLK_MUX_SEL_FSYS1_OFFSET 0x0204 +#define CLK_MUX_STATE_FSYS1_OFFSET 0x0404 +#define USBDEVICE3_PHYCLK_SEL (EXYNOS5260_CMU_FSYS_BASE+CLK_MUX_SEL_FSYS1_OFFSET) +#define USBDEVICE3_PHYCLK_STATE (EXYNOS5260_CMU_FSYS_BASE+CLK_MUX_STATE_FSYS1_OFFSET) + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot multiple access */ +#define CFG_FASTBOOT_MULTI_ACESS +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x28000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x20008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x21000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000028 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 20000000;emmc close 0;" \ + "movi read kernel 0 20008000;movi read rootfs 0 22000000 100000;bootz 20008000 22000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 20008000;movi read rootfs 0 22000000 100000;bootz 20008000 22000000" +#endif + +#define CONFIG_RECOVERYCOMMAND_SDMMC \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +#define CONFIG_RECOVERYCOMMAND_USB \ + "fastboot" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 20008000;" \ + "movi read rootfs 0 22000000 100000;" \ + "bootz 20008000 22000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "XYREF5260 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_HZ 1000 + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 8 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE (SDRAM_BANK_SIZE - \ + CONFIG_TRUSTZONE_RESERVED_DRAM) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for XYREF5260" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02074000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_SMC911X +#define CONFIG_SMC911X_BASE 0x5000000 +#define CONFIG_SMC911X_16_BIT +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* Base address for secondary boot information */ +#define CONFIG_SECONDARY_BOOT_INFORM_BASE (CONFIG_SYS_TEXT_BASE - 0x8) + +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define A5IS_WDTRESET (1 << 27) +#define CORTEXA7_WDTRESET (1 << 24) +#define CORTEXA15_WDTRESET (1 << 23) +#define PINRESET (1 << 16) +#define CORTEXA7_WRESET3 (1 << 7) +#define CORTEXA7_WRESET2 (1 << 6) +#define CORTEXA7_WRESET1 (1 << 5) +#define CORTEXA7_WRESET0 (1 << 4) +#define CORTEXA15_WRESET1 (1 << 1) +#define CORTEXA15_WRESET0 (1 << 0) + +#endif /* __CONFIG_H */ diff --git a/include/configs/xyref5430.h b/include/configs/xyref5430.h new file mode 100644 index 000000000..23981c701 --- /dev/null +++ b/include/configs/xyref5430.h @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * Configuration settings for the SAMSUNG XYREF5430 (EXYNOS5430) board. + * + * 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 __CONFIG_H +#define __CONFIG_H + +/* High Level Configuration Options */ +#define CONFIG_SAMSUNG /* in a SAMSUNG core */ +#define CONFIG_S5P /* S5P Family */ +#define CONFIG_ARCH_EXYNOS /* which is in a Exynos Family */ +#define CONFIG_ARCH_EXYNOS5 /* which is in a Exynos5 Family */ +#define CONFIG_CPU_EXYNOS5430 /* which is in a Exynos5430 */ +#define CONFIG_MACH_XYREF5430 /* which is in a XYREF5430 */ + +#define CONFIG_GPIO_DAT_MASK /* opertation to mask dat register */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_DISPLAY_CHIPID + +/* TRUSTZONE */ +#define CONFIG_TRUSTZONE_ENABLE +#ifdef CONFIG_TRUSTZONE_ENABLE +#undef CONFIG_TZPC +#define CONFIG_SMC_CMD +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x600000 +#else +#define CONFIG_TZPC +#define CONFIG_TRUSTZONE_RESERVED_DRAM 0x0 +#endif + +/* Reserved memory for U-Boot */ +#define CONFIG_UBOOT_RESERVED_DRAM 0x80000 /* Reserved 512Kbyte */ +#define CONFIG_UBOOT_ATAG_RESERVED_DRAM 0x380000 /* Reserved 512Kbyte */ + +/* Configuration of bl1 partition size */ +#define CONFIG_BL_MONITOR + +/* Configuration of secure boot */ +#undef CONFIG_UBOOT_SECURE_BOOT +#undef CONFIG_TZSW_SECURE_BOOT +#undef CONFIG_SECURE_BOOT + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_UBOOT_SECURE_BOOT +#define CONFIG_TZSW_SECURE_BOOT +#define CONFIG_SECURE_ROOTFS +#define CONFIG_SECURE_CONTEXT_BASE 0x20003800 +#define CONFIG_SECURE_KERNEL_BASE 0x20008000 +#define CONFIG_SECURE_KERNEL_SIZE PART_SIZE_KERNEL +#define CONFIG_SECURE_ROOTFS_BASE 0x21000000 +#define CONFIG_SECURE_ROOTFS_SIZE 0x100000 +#endif + +/* Power Management is enabled */ +#define CONFIG_PM +#define CONFIG_PM_VDD_MIF 1025 +#define CONFIG_PM_VDD_EGL 900 +#define CONFIG_PM_VDD_KFC 950 +#define CONFIG_PM_VDD_INT 1050 +#define CONFIG_PM_VDD_G3D 875 + +/* Bootloader Recovery */ +#define CONFIG_RECOVERY_MODE + +/* RAMDUMP MODE */ +#define CONFIG_RAMDUMP_MODE 0xD + +/* Keep L2 Cache Disabled */ +#define CONFIG_SYS_DCACHE_OFF + +#define CONFIG_SYS_SDRAM_BASE 0x20000000 +#if defined(CONFIG_TRUSTZONE_ENABLE) +#define CONFIG_SYS_TEXT_BASE 0x9F980000 +#else +#define CONFIG_SYS_TEXT_BASE 0x9FF80000 +#endif +#define CONFIG_SPL_TEXT_BASE 0x02026000 + +/* input clock of PLL: SMDK5430 has 24MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 24000000 + +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_CMDLINE_TAG +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG +#define CONFIG_CMDLINE_EDITING + +#define CONFIG_MACH_TYPE MACH_TYPE_XYREF5430 + +/* iRAM information */ +#define CONFIG_PHY_IRAM_BASE (0x02020000) +#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x5F000) + +/* BL1 version information */ +#define CONFIG_BL1_VERSION_INFORM (CONFIG_PHY_IRAM_NS_BASE + 0x810) + +/* Power Down Modes */ +#define S5P_CHECK_SLEEP 0x00000BAD +#define S5P_CHECK_DIDLE 0xBAD00000 +#define S5P_CHECK_LPA 0xABAD0000 + +/* Offset for OM status registers */ +#define OM_STATUS_OFFSET 0x0 + +/* Offset for inform registers */ +#define INFORM0_OFFSET 0x800 +#define INFORM1_OFFSET 0x804 +#define INFORM2_OFFSET 0x808 +#define INFORM3_OFFSET 0x80C + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20)) + +/* select serial console configuration */ +#define CONFIG_SERIAL_MULTI +#define CONFIG_SERIAL2 /* use SERIAL 2 */ +#define CONFIG_BAUDRATE 115200 + +#define TZPC_BASE_OFFSET 0x10000 + +/* SD/MMC configuration */ +#define CONFIG_GENERIC_MMC +#define CONFIG_MMC +#define CONFIG_SDHCI +#define CONFIG_S5P_MSHC +#define CONFIG_S5P_SDHCI +#define CONFIG_MMC_64BIT_BUS + +#if defined(CONFIG_S5P_MSHC) +#define CONFIG_MMC_SMU_INIT +#define CONFIG_MMC_EARLY_INIT +#define MMC_MAX_CHANNEL 4 +#define USE_MMC0 +#define USE_MMC2 + +#define PHASE_DEVIDER 4 + +#define SDR_CH0 0x03020001 +#define DDR_CH0 0x03030002 + +#define SDR_CH2 0x03020001 +#define DDR_CH2 0x03030002 + +#define SDR_CH4 0x00010001 +#define DDR_CH4 0x00010001 +#endif + +/* + * Boot configuration + */ +#define BOOT_ONENAND 0x1 +#define BOOT_NAND 0x40000 +#define BOOT_MMCSD 0x3 +#define BOOT_NOR 0x4 +#define BOOT_SEC_DEV 0x5 +#define BOOT_EMMC 0x6 +#define BOOT_EMMC_4_4 0x7 +#define BOOT_USB 0x100 + +/* + * Boot device + */ +#define SDMMC_CH2 0x0 +#define SDMMC_CH0 0x4 +#define EMMC 0x14 +#define SATA 0x18 +#define SPI_SF 0x28 +#define SFMC 0x34 +#define USB 0x40 + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT +#define CONFIG_PREP_BOARDCONFIG_FOR_KERNEL + +/* CHIP ID */ +#define CHIPID0_OFFSET 0x14 +#define CHIPID1_OFFSET 0x18 + +/* PWM */ +#define CONFIG_PWM + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +/* Command definition*/ +#include <config_cmd_default.h> + +#define CONFIG_CMD_PING +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MMC +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_NET +#define CONFIG_CMD_BOOTZ + +/* FAT filesystem */ +#define CONFIG_FAT_WRITE + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* USB */ +#undef CONFIG_CMD_USB +/* EHCI : 2.0 Host */ +#undef CONFIG_USB_EHCI +#undef CONFIG_USB_EHCI_EXYNOS +#undef CONFIG_USB_STORAGE + +#define CONFIG_EXYNOS_USBD3 +#undef CONFIG_S3C_USBD +#undef CONFIG_USB_CPUMODE + +#define USBD_DOWN_ADDR 0x40000000 +#define EXYNOS_SYSREG_BASE EXYNOS5430_SYSREG_BASE +#define EXYNOS_POWER_BASE EXYNOS5430_POWER_BASE + +/* + * USBD 3.0 SFR + */ +#define USBDEVICE3_LINK_CH0_BASE 0x15400000 +#define USBDEVICE3_PHYCTRL_CH0_BASE 0x15500000 + +#define CLK_MUX_SEL_FSYS2_OFFSET 0x0208 +#define CLK_MUX_STATE_FSYS2_OFFSET 0x0408 +#define USBDEVICE3_PHYCLK_SEL (EXYNOS5430_CMU_FSYS_BASE+CLK_MUX_SEL_FSYS2_OFFSET) +#define USBDEVICE3_PHYCLK_STATE (EXYNOS5430_CMU_FSYS_BASE+CLK_MUX_STATE_FSYS2_OFFSET) + +/* + * FASTBOOT + */ +#define CONFIG_FASTBOOT +#define CFG_FASTBOOT_SDMMCBSP +/* Fastboot multiple access */ +#define CFG_FASTBOOT_MULTI_ACESS +/* Fastboot variables */ +#define CFG_FASTBOOT_TRANSFER_BUFFER (0x28000000) +#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x30000000) /* 768MB */ +#define CFG_FASTBOOT_ADDR_KERNEL (0x20008000) +#define CFG_FASTBOOT_ADDR_RAMDISK (0x21000000) +#define CFG_FASTBOOT_MMC_BUFFER (0x78000000) +#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device +#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc + +/* MMC SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_15KB +#define IROM_FNPTR_BASE 0x020200A0 +#define SECCOND_BOOT_INFORM_OFFSET 0x00000028 +#define SDMMC_DEV_OFFSET 0x00000000 +#define EMMC_DEV_OFFSET 0x00000014 +#define EMMC_ENDBOOTOP_OFFSET 0x00000018 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_BOOTCOMMAND "emmc open 0;movi r z f 0 20000000;emmc close 0;" \ + "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#else +#define CONFIG_BOOTCOMMAND "movi read kernel 0 20008000;movi read rootfs 0 21000000 100000;bootz 20008000 21000000" +#endif + +#define CONFIG_RECOVERYCOMMAND \ + "emmc partition 0 10 0;" \ + "mmc erase user 0 1072 1;" \ + "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \ + "movi r b 1 40000000;emmc open 0;movi w z b 0 40000000;emmc close 0;" \ + "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \ + "movi r t 1 40000000;emmc open 0;movi w z t 0 40000000;emmc close 0;" \ + "reset" + +/* Configuration for factory reset mode */ +#define CONFIG_FACTORY_RESET_MODE 0xf +#define CONFIG_FACTORY_RESET_BOOTCOMMAND \ + "ext3format mmc 0:3;ext3format mmc 0:4;" \ + "movi read kernel 0 20008000;" \ + "movi read rootfs 0 21000000 100000;" \ + "bootz 20008000 21000000" + +/* Miscellaneous configurable options */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT "XYREF5430 # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_DEFAULT_CONSOLE "console=ttySAC1,115200n8\0" +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5E00000) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_HZ 1000 + +/* Stack sizes */ +#define CONFIG_STACKSIZE (256 << 10) /* 256KB */ + +#define CONFIG_NR_DRAM_BANKS 12 +#define SDRAM_BANK_SIZE (256UL << 20UL) /* 256 MB */ +#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE +#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) +#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_8_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_8_END_SIZE (SDRAM_BANK_SIZE - \ + (CONFIG_TRUSTZONE_RESERVED_DRAM + \ + CONFIG_UBOOT_RESERVED_DRAM)) +#define PHYS_SDRAM_9 (CONFIG_SYS_SDRAM_BASE + (8 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_9_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_10 (CONFIG_SYS_SDRAM_BASE + (9 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_10_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_11 (CONFIG_SYS_SDRAM_BASE + (10 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_11_SIZE SDRAM_BANK_SIZE +#define PHYS_SDRAM_12 (CONFIG_SYS_SDRAM_BASE + (11 * SDRAM_BANK_SIZE)) +#define PHYS_SDRAM_12_SIZE (SDRAM_BANK_SIZE - \ + (CONFIG_TRUSTZONE_RESERVED_DRAM + \ + CONFIG_UBOOT_RESERVED_DRAM)) + +#define CONFIG_SYS_MONITOR_BASE 0x00000000 + +/* FLASH and environment organization */ +#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_IDENT_STRING " for XYREF5430" + +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 0 + +/* Configuration of ENV size on mmc */ +#define CONFIG_ENV_SIZE (16 << 10) /* 16 KB */ +#include <asm/arch/movi_partition.h> + +/* Configuration of ROOTFS_ATAGS */ +#define CONFIG_ROOTFS_ATAGS +#ifdef CONFIG_ROOTFS_ATAGS +#define CONFIG_EXTRA_ENV_SETTINGS "rootfslen= 100000" +#endif + +/* Configuration for Partition */ +#define CONFIG_DOS_PARTITION +#define CONFIG_NVDATA_PARTITION +#define CFG_PARTITION_START 0x6400000 +#define CONFIG_IRAM_STACK 0x02080000 + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x100000) + +/* Ethernet Controllor Driver */ +#ifdef CONFIG_CMD_NET +#define CONFIG_ENV_SROM_BANK 1 +#endif /*CONFIG_CMD_NET*/ + +/* Disable devicetree support */ +/* #define CONFIG_OF_LIBFDT */ + +/* secondary boot information */ +#define CONFIG_SECOND_BOOT_INFORM_SIZE (0x4) +#define CONFIG_SECOND_BOOT_INFORM_BASE (CONFIG_PHY_IRAM_NS_BASE + \ + nscode_end - nscode_base) + +/* image inforamtion base address for SMC */ +#define CONFIG_SMC_IMAGE_INFORM_BASE (CONFIG_PHY_IRAM_NS_BASE + \ + nscode_end - nscode_base + \ + CONFIG_SECOND_BOOT_INFORM_SIZE) +/* Offset for pmu reset status */ +#define RST_STAT_OFFSET 0x404 + +/* RST_STAT */ +#define SWRESET (1 << 29) +#define WRESET (1 << 28) +#define A5IS_WDTRESET (1 << 27) +#define CORTEXA7_WDTRESET (1 << 24) +#define CORTEXA15_WDTRESET (1 << 23) +#define PINRESET (1 << 16) +#define CORTEXA7_WRESET3 (1 << 7) +#define CORTEXA7_WRESET2 (1 << 6) +#define CORTEXA7_WRESET1 (1 << 5) +#define CORTEXA7_WRESET0 (1 << 4) +#define CORTEXA15_WRESET1 (1 << 1) +#define CORTEXA15_WRESET0 (1 << 0) + +#endif /* __CONFIG_H */ diff --git a/include/decompress_ext4.h b/include/decompress_ext4.h new file mode 100644 index 000000000..ddc5732a3 --- /dev/null +++ b/include/decompress_ext4.h @@ -0,0 +1,44 @@ +/* copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * 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. +*/ + +typedef struct _ext4_file_header { + unsigned int magic; + unsigned short major; + unsigned short minor; + unsigned short file_header_size; + unsigned short chunk_header_size; + unsigned int block_size; + unsigned int total_blocks; + unsigned int total_chunks; + unsigned int crc32; +}ext4_file_header; + + +typedef struct _ext4_chunk_header { + unsigned short type; + unsigned short reserved; + unsigned int chunk_size; + unsigned int total_size; +}ext4_chunk_header; + +#define EXT4_FILE_HEADER_MAGIC 0xED26FF3A +#define EXT4_FILE_HEADER_MAJOR 0x0001 +#define EXT4_FILE_HEADER_MINOR 0x0000 +#define EXT4_FILE_BLOCK_SIZE 0x1000 + +#define EXT4_FILE_HEADER_SIZE (sizeof(struct _ext4_file_header)) +#define EXT4_CHUNK_HEADER_SIZE (sizeof(struct _ext4_chunk_header)) + + +#define EXT4_CHUNK_TYPE_RAW 0xCAC1 +#define EXT4_CHUNK_TYPE_FILL 0xCAC2 +#define EXT4_CHUNK_TYPE_NONE 0xCAC3 + +int write_compressed_ext4(char* img_base, unsigned int sector_base); +int check_compress_ext4(char *img_base, unsigned long long parti_size); + diff --git a/include/dnw.h b/include/dnw.h new file mode 100644 index 000000000..12341e476 --- /dev/null +++ b/include/dnw.h @@ -0,0 +1,144 @@ +#ifndef DNW_H +#define DNW_H + +#include <common.h> +#include <command.h> + +#include <asm/byteorder.h> +//#include <asm/arch/hardware.h> +#include <asm/arch/cpu.h> +#include <asm/io.h> + +#ifdef CONFIG_DNW +#define DNW_RESPONSE_PACKET_SIZE 64 +enum{ + DNW_DETATCH = 0, + DNW_DNLOAD, + DNW_UPLOAD, + DNW_GETSTATUS, + DNW_CLRSTATUS, + DNW_GETSTATE, + DNW_ABORT, + DNW_DEVINFO, + DNW_STORE, + DNW_REBOOT, + DNW_CMD_END, +}; + +enum{ + DNW_OK =0, + DNW_DISCONNECT, + DNW_INACTIVE, + ERR_TARGET, + ERR_FILE, + ERR_WRITE, + ERR_ERASE, + ERR_VERIFY, + ERR_ADDRESS, + ERR_USB, + ERR_UNKNOWN, +}; + +enum{ + DNW_v01 = 1, + DNW_v02 = 2, + DNW_v05 = 5, + DNW_v10 = 10, +}; + +struct dnw_devinfo{ + char chip_info[4]; + char dnw_version; + char reserved[3]; +}__attribute__ ((packed)); + +struct dnw_subcmd_dnload +{ + char sub_cmd; + char reserved[3]; + u32 start_address; + u32 tot_size; + u32 packet_size; +} __attribute__ ((packed)); + +struct dnw_subcmd_store +{ + u64 start_address; + u64 tot_size; + u32 attribute; +// u32 reserved; + +/* u32 start_address; + u32 tot_size; + u32 packet_size; + u32 reserved; */ +} __attribute__ ((packed)); + +struct dnw_cmd +{ + unsigned char cmd; + unsigned char reserved[3]; +// u32 length; +// temp void* data; +} __attribute__ ((packed)); + +struct dnw_response +{ + unsigned char cmd; + unsigned char cmd_status; + unsigned char reserved[2]; + u32 length; + unsigned char data[DNW_RESPONSE_PACKET_SIZE-8]; +} __attribute__ ((packed)); + +/* state */ +typedef enum +{ + dnwNOTINIT=0, + dnwIDLE = 2, + dnwDOWNLOADSYNC, + dnwDNBUSY, + dnwERROR, +}USBDNW_STATE; + +//static unsigned int download_size; +//static unsigned int download_bytes; +//static unsigned int download_bytes_unpadded; +///static unsigned int download_error; + +struct dnw_dnload_ram_type{ + u64 start_address; + u64 tot_size; + u64 packet_size; + u64 transfed_size; + u64 remained_size; + u64 downloaded_bytes; + u64 dnload_error; + unsigned char * transfer_buffer; + u64 transfer_buffer_size; +}; + +struct dnw_dnload_str_type{ + u32 start_address; + unsigned int tot_size; +}; + + +typedef struct{ + USBDNW_STATE state; + struct dnw_cmd cmd; + struct dnw_dnload_ram_type dnload; + struct dnw_dnload_str_type dn_stor; +}USBDNW; + + +extern int dnw_init(void); +extern void dnw_shutdown(void); +extern int dnw_poll(void); +extern void dnw_usb_handle_ep_in_xfer_complete(void); +extern int dnw_usb_handle_ep_out_xfer_complete(void); +#else + +#endif /* CONFIG_DNW */ + +#endif /* DNW_H */ diff --git a/include/ext2fs.h b/include/ext2fs.h index 163a9bbc0..60bea71bd 100644 --- a/include/ext2fs.h +++ b/include/ext2fs.h @@ -29,6 +29,29 @@ #define SECTOR_SIZE 0x200 #define SECTOR_BITS 9 +#define COMMON_BLOCK_SIZE 4096 + +/* + * Current group descriptor table size allows until size of 256GB. + * If you want to format more size than 256GB, + * please change GRP_DESC_TABLE_SIZE below. + * + * Unit for size : MB + */ +#define BLOCK_GROUP_SIZE (128) /* 128MB */ + +#define STORAGE_SIZE_16G (1024 * 16) +#define STORAGE_SIZE_32G (1024 * 32) +#define STORAGE_SIZE_64G (1024 * 64) +#define STORAGE_SIZE_128G (1024 * 128) +#define STORAGE_SIZE_256G (1024 * 256) + +#define GRP_DESC_SIZE 32 /* 32Byte */ +#define GRP_DESC_TABLE_SIZE \ + ((STORAGE_SIZE_256G / BLOCK_GROUP_SIZE) * GRP_DESC_SIZE) + +#define INODE_DATA_SIZE GRP_DESC_TABLE_SIZE + /* Error codes */ typedef enum { diff --git a/include/fastboot.h b/include/fastboot.h new file mode 100644 index 000000000..4bca7bc30 --- /dev/null +++ b/include/fastboot.h @@ -0,0 +1,349 @@ + +/* + * (C) Copyright 2008 - 2009 + * Windriver, <www.windriver.com> + * Tom Rix <Tom.Rix@windriver.com> + * + * 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 + * + * The logical naming of flash comes from the Android project + * Thse structures and functions that look like fastboot_flash_* + * They come from bootloader/legacy/include/boot/flash.h + * + * The boot_img_hdr structure and associated magic numbers also + * come from the Android project. They are from + * system/core/mkbootimg/bootimg.h + * + * Here are their copyrights + * + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef FASTBOOT_H +#define FASTBOOT_H + +#include <common.h> +#include <command.h> + +#include <asm/byteorder.h> +//#include <asm/arch/hardware.h> +#include <asm/arch/cpu.h> +#include <asm/io.h> + +/* This is the interface file between the common cmd_fastboot.c and + the board specific support. + + To use this interface, define CONFIG_FASTBOOT in your board config file. + An example is include/configs/omap3430labrador.h + ... + #define CONFIG_FASTBOOT 1 / * Using fastboot interface * / + ... + + An example of the board specific spupport for omap3 is found at + cpu/omap3/fastboot.c + +*/ + +/* From fastboot client.. */ +#define FASTBOOT_INTERFACE_CLASS 0xff +#define FASTBOOT_INTERFACE_SUB_CLASS 0x42 +#define FASTBOOT_INTERFACE_PROTOCOL 0x03 + +#define FASTBOOT_VERSION "0.4" + +/* The fastboot client uses a value of 2048 for the + page size of it boot.img file format. + Reset this in your board config file as needed. */ +#ifndef CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE +#define CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE 2048 +#endif + +struct cmd_fastboot_interface +{ + /* This function is called when a buffer has been + recieved from the client app. + The buffer is a supplied by the board layer and must be unmodified. + The buffer_size is how much data is passed in. + Returns 0 on success + Returns 1 on failure + + Set by cmd_fastboot */ + int (*rx_handler)(const unsigned char *buffer, + unsigned int buffer_size); + + /* This function is called when an exception has + occurred in the device code and the state + off fastboot needs to be reset + + Set by cmd_fastboot */ + void (*reset_handler)(void); + + /* A getvar string for the product name + It can have a maximum of 60 characters + + Set by board */ + char *product_name; + + /* A getvar string for the serial number + It can have a maximum of 60 characters + + Set by board */ + char *serial_no; + + /* Nand block size + Supports the write option WRITE_NEXT_GOOD_BLOCK + + Set by board */ + unsigned int nand_block_size; + + /* Transfer buffer, for handling flash updates + Should be multiple of the nand_block_size + Care should be take so it does not overrun bootloader memory + Controlled by the configure variable CFG_FASTBOOT_TRANSFER_BUFFER + + Set by board */ + unsigned char *transfer_buffer; + + /* How big is the transfer buffer + Controlled by the configure variable + CFG_FASTBOOT_TRANSFER_BUFFER_SIZE + + Set by board */ + unsigned int transfer_buffer_size; + +}; + +/* Android-style flash naming */ +typedef struct fastboot_ptentry fastboot_ptentry; + +/* flash partitions are defined in terms of blocks +** (flash erase units) +*/ +struct fastboot_ptentry +{ + /* The logical name for this partition, null terminated */ + char name[16]; + /* The start wrt the nand part, must be multiple of nand block size */ + unsigned long long start; + /* The length of the partition, must be multiple of nand block size */ + unsigned long long length; + /* Controls the details of how operations are done on the partition + See the FASTBOOT_PTENTRY_FLAGS_*'s defined below */ + unsigned int flags; +}; + +/* Lower byte shows if the read/write/erase operation in + repeated. The base address is incremented. + Either 0 or 1 is ok for a default */ + +#define FASTBOOT_PTENTRY_FLAGS_REPEAT(n) (n & 0x0f) +#define FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK 0x0000000F + +/* Writes happen a block at a time. + If the write fails, go to next block + NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK 0x00000010 + +/* Find a contiguous block big enough for a the whole file + NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK 0x00000020 + +/* Sets the ECC to hardware before writing + HW and SW ECC should not both be set. */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC 0x00000040 + +/* Sets the ECC to software before writing + HW and SW ECC should not both be set. */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC 0x00000080 + +/* Write the file with write.i */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_I 0x00000100 + +/* Write the file with write.yaffs */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS 0x00000200 + +/* Write the file as a series of variable/value pairs + using the setenv and saveenv commands */ +#define FASTBOOT_PTENTRY_FLAGS_WRITE_ENV 0x00000400 + +/* Use mmc command to read/write this partition */ +#define FASTBOOT_PTENTRY_FLAGS_USE_MMC_CMD 0x00010000 + +/* Use movi command to read/write this partition */ +#define FASTBOOT_PTENTRY_FLAGS_USE_MOVI_CMD 0x00020000 + +/* Status values */ +#define FASTBOOT_OK 0 +#define FASTBOOT_ERROR -1 +#define FASTBOOT_DISCONNECT 1 +#define FASTBOOT_INACTIVE 2 + +/* Magic string to enable fastboot during preboot */ +#define FASTBOOT_REBOOT_MAGIC "REBOOT-FASTBOOT" +#define FASTBOOT_REBOOT_MAGIC_SIZE 15 + +/* Android bootimage file format */ +#define FASTBOOT_BOOT_MAGIC "ANDROID!" +#define FASTBOOT_BOOT_MAGIC_SIZE 8 +#define FASTBOOT_BOOT_NAME_SIZE 16 +#define FASTBOOT_BOOT_ARGS_SIZE 512 + +/* Input of fastboot_tx_status */ +#define FASTBOOT_TX_ASYNC 0 +#define FASTBOOT_TX_SYNC 1 + +struct fastboot_boot_img_hdr { + unsigned char magic[FASTBOOT_BOOT_MAGIC_SIZE]; + + unsigned kernel_size; /* size in bytes */ + unsigned kernel_addr; /* physical load addr */ + + unsigned ramdisk_size; /* size in bytes */ + unsigned ramdisk_addr; /* physical load addr */ + + unsigned second_size; /* size in bytes */ + unsigned second_addr; /* physical load addr */ + + unsigned tags_addr; /* physical addr for kernel tags */ + unsigned page_size; /* flash page size we assume */ + unsigned unused[2]; /* future expansion: should be 0 */ + + unsigned char name[FASTBOOT_BOOT_NAME_SIZE]; /* asciiz product name */ + + unsigned char cmdline[FASTBOOT_BOOT_ARGS_SIZE]; + + unsigned id[8]; /* timestamp / checksum / sha1 / etc */ +}; + +#if defined(CONFIG_FASTBOOT) +/* A board specific test if u-boot should go into the fastboot command + ahead of the bootcmd + Returns 0 to continue with normal u-boot flow + Returns 1 to execute fastboot */ +extern int fastboot_preboot(void); + +/* Initizes the board specific fastboot + Returns 0 on success + Returns 1 on failure */ +extern int fastboot_init(struct cmd_fastboot_interface *interface); + +/* Cleans up the board specific fastboot */ +extern void fastboot_shutdown(void); + +/* + * Handles board specific usb protocol exchanges + * Returns 0 on success + * Returns 1 on disconnects, break out of loop + * Returns 2 if no USB activity detected + * Returns -1 on failure, unhandled usb requests and other error conditions +*/ +extern int fastboot_poll(void); + +/* Is this high speed (2.0) or full speed (1.1) ? + Returns 0 on full speed + Returns 1 on high speed */ +extern int fastboot_is_highspeed(void); + +/* Return the size of the fifo */ +extern int fastboot_fifo_size(void); + +/* Send a status reply to the client app + buffer does not have to be null terminated. + buffer_size must be not be larger than what is returned by + fastboot_fifo_size + Returns 0 on success + Returns 1 on failure */ +extern int fastboot_tx_status(const char *buffer, unsigned int buffer_size, const u32 need_sync_flag); + +/* A board specific variable handler. + The size of the buffers is governed by the fastboot spec. + rx_buffer is at most 57 bytes + tx_buffer is at most 60 bytes + Returns 0 on success + Returns 1 on failure */ +extern int fastboot_getvar(const char *rx_buffer, char *tx_buffer); + +/* The Android-style flash handling */ + +/* tools to populate and query the partition table */ +extern void fastboot_flash_add_ptn(fastboot_ptentry *ptn); +extern fastboot_ptentry *fastboot_flash_find_ptn(const char *name); +extern fastboot_ptentry *fastboot_flash_get_ptn(unsigned n); +extern unsigned int fastboot_flash_get_ptn_count(void); +extern void fastboot_flash_dump_ptn(void); + +extern int fastboot_flash_init(void); +extern int fastboot_flash_erase(fastboot_ptentry *ptn); +extern int fastboot_flash_read_ext(fastboot_ptentry *ptn, + unsigned extra_per_page, unsigned offset, + void *data, unsigned bytes); +#define fastboot_flash_read(ptn, offset, data, bytes) \ + flash_read_ext(ptn, 0, offset, data, bytes) +extern int fastboot_flash_write(fastboot_ptentry *ptn, unsigned extra_per_page, + const void *data, unsigned bytes); + + +#else + +/* Stubs for when CONFIG_FASTBOOT is not defined */ +#define fastboot_preboot() 0 +#define fastboot_init(a) 1 +#define fastboot_shutdown() +#define fastboot_poll() 1 +#define fastboot_is_highspeed() 0 +#define fastboot_fifo_size() 0 +#define fastboot_tx_status(a, b, c) 1 +#define fastboot_getvar(a,b) 1 + +#define fastboot_flash_add_ptn(a) +#define fastboot_flash_find_ptn(a) NULL +#define fastboot_flash_get_ptn(a) NULL +#define fastboot_flash_get_ptn_count() 0 +#define fastboot_flash_dump_ptn() +#define fastboot_flash_init() +#define fastboot_flash_erase(a) 1 +#define fastboot_flash_read_ext(a, b, c, d, e) 0 +#define fastboot_flash_read(a, b, c, d, e) 0 +#define fastboot_flash_write(a, b, c, d) 0 + +#endif /* CONFIG_FASTBOOT */ +#endif /* FASTBOOT_H */ + diff --git a/include/fat.h b/include/fat.h index f1b4a0d97..57f233de4 100644 --- a/include/fat.h +++ b/include/fat.h @@ -46,6 +46,13 @@ #define FAT16BUFSIZE (FATBUFSIZE/2) #define FAT32BUFSIZE (FATBUFSIZE/4) +#define SECTOR_SIZE 512 +#define BYTE_PER_SEC 512 +#define RESERVED_CNT 32 +#define DOS_PART_TBL_OFFSET 0x1be +#define DOS_PART_MAGIC_OFFSET 0x1fe +#define DOS_FS_TYPE_OFFSET 0x36 +#define DOS_FS32_TYPE_OFFSET 0x52 /* Filesystem identifiers */ #define FAT12_SIGN "FAT12 " @@ -107,6 +114,88 @@ #define CHECK_CLUST(x, fatsize) ((x) <= 1 || \ (x) >= ((fatsize) != 32 ? 0xfff0 : 0xffffff0)) +#define mk1(p, x) \ + (p) = (__u8)(x) + +#define mk2(p, x) \ + (p)[0] = (__u8)(x), \ + (p)[1] = (__u8)((x) >> 010) + +#define mk4(p, x) \ + (p)[0] = (__u8)(x), \ + (p)[1] = (__u8)((x) >> 010), \ + (p)[2] = (__u8)((x) >> 020), \ + (p)[3] = (__u8)((x) >> 030) + +struct bs { + __u8 jmp[3]; /* bootstrap entry point */ + __u8 oem[9]; /* OEM name and version */ +}; + +struct bsbpb { + __u8 bps[2]; /* bytes per sector */ + __u8 spc; /* sectors per cluster */ + __u8 res[2]; /* reserved sectors */ + __u8 nft; /* number of FATs */ + __u8 rde[2]; /* root directory entries */ + __u8 sec[2]; /* total sectors */ + __u8 mid; /* media descriptor */ + __u8 spf[2]; /* sectors per FAT */ + __u8 spt[2]; /* sectors per track */ + __u8 hds[2]; /* drive heads */ + __u8 hid[4]; /* hidden sectors */ + __u8 bsec[6]; /* big total sectors */ +}; + +/* For FAT32 */ +struct bsxbpb { + __u8 bspf[4]; /* big sectors per FAT */ + __u8 xflg[2]; /* FAT control flags */ + __u8 vers[2]; /* file system version */ + __u8 rdcl[4]; /* root directory start cluster */ + __u8 infs[2]; /* file system info sector */ + __u8 bkbs[2]; /* backup boot sector */ + __u8 rsvd[12]; /* reserved */ +}; + +struct bsx { + __u8 drv; /* drive number */ + __u8 rsvd; /* reserved */ + __u8 sig; /* extended boot signature */ + __u8 volid[4]; /* volume ID number */ + __u8 label[11]; /* volume label */ + __u8 type[8]; /* file system type */ +}; + +struct de { + __u8 namext[11]; /* name and extension */ + __u8 attr; /* attributes */ + __u8 rsvd[10]; /* reserved */ + __u8 time[2]; /* creation time */ + __u8 date[2]; /* creation date */ + __u8 clus[2]; /* starting cluster */ + __u8 size[4]; /* size */ +}; + +struct bpb { + __u32 bps; /* bytes per sector */ + __u32 spc; /* sectors per cluster */ + __u32 res; /* reserved sectors */ + __u32 nft; /* number of FATs */ + __u32 rde; /* root directory entries */ + __u32 sec; /* total sectors */ + __u32 mid; /* media descriptor */ + __u32 spf; /* sectors per FAT */ + __u32 spt; /* sectors per track */ + __u32 hds; /* drive heads */ + __u32 hid; /* hidden sectors */ + __u32 bsec; /* big total sectors */ + __u32 bspf; /* big sectors per FAT */ + __u32 rdcl; /* root directory start cluster */ + __u32 infs; /* file system info sector */ + __u32 bkbs; /* backup boot sector */ +}; + typedef struct boot_sector { __u8 ignored[3]; /* Bootstrap code */ char system_id[8]; /* Name of fs */ diff --git a/include/mmc.h b/include/mmc.h index 230598654..67c678869 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -44,8 +44,9 @@ #define MMC_MODE_HS_52MHz 0x010 #define MMC_MODE_4BIT 0x100 #define MMC_MODE_8BIT 0x200 -#define MMC_MODE_SPI 0x400 +#define MMC_MODE_DDR 0x400 #define MMC_MODE_HC 0x800 +#define MMC_MODE_SPI 0x1000 #define MMC_MODE_MASK_WIDTH_BITS (MMC_MODE_4BIT | MMC_MODE_8BIT) #define MMC_MODE_WIDTH_BITS_SHIFT 8 @@ -101,13 +102,16 @@ #define SD_HIGHSPEED_SUPPORTED 0x00020000 #define MMC_HS_TIMING 0x00000100 -#define MMC_HS_52MHZ 0x2 +#define MMC_HS_52MHZ (1 << 1) +#define MMC_HS_52MHZ_1_8V_3V_IO (1 << 2) +#define MMC_HS_52MHZ_1_2V_IO (1 << 3) #define OCR_BUSY 0x80000000 #define OCR_HCS 0x40000000 #define OCR_VOLTAGE_MASK 0x007FFF80 #define OCR_ACCESS_MODE 0x60000000 +#define NORMAL_ERASE 0x00000000 #define SECURE_ERASE 0x80000000 #define MMC_STATUS_MASK (~0x0206BF7F) @@ -151,6 +155,7 @@ * EXT_CSD fields */ #define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ +#define EXT_CSD_SANITIZE_START 165 /* W */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ #define EXT_CSD_PART_CONF 179 /* R/W */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ @@ -159,17 +164,25 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ +#define EXT_CSD_BOOT_SIZE_MULTI 226 /* RO */ +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */ /* * EXT_CSD field definitions */ +#define EXT_CSD_SEC_ER_EN (1 << 0) +#define EXT_CSD_SEC_BD_BLK_EN (1 << 2) +#define EXT_CSD_SEC_GB_CL_EN (1 << 4) +#define EXT_CSD_SEC_SANITIZE (1 << 6) /* v4.5 only */ #define EXT_CSD_CMD_SET_NORMAL (1 << 0) #define EXT_CSD_CMD_SET_SECURE (1 << 1) #define EXT_CSD_CMD_SET_CPSECURE (1 << 2) -#define EXT_CSD_CARD_TYPE_26 (1 << 0) /* Card can run at 26MHz */ -#define EXT_CSD_CARD_TYPE_52 (1 << 1) /* Card can run at 52MHz */ +#define EXT_CSD_CARD_TYPE_26 (1 << 0)/* Card can run at 26MHz */ +#define EXT_CSD_CARD_TYPE_52 (1 << 1)/* Card can run at 52MHz */ +#define EXT_CSD_CARD_TYPE_52_DDR_18_30 (1 << 2)/* Card can run at 52MHz DDR 1.8V or 3V */ +#define EXT_CSD_CARD_TYPE_52_DDR_12 (1 << 3)/* Card can run at 52MHz DDR 1.2V */ #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ @@ -237,6 +250,7 @@ struct mmc { uint f_max; int high_capacity; uint bus_width; + uint ddr; uint clock; uint card_caps; uint host_caps; @@ -245,12 +259,14 @@ struct mmc { uint csd[4]; uint cid[4]; ushort rca; + uint boot_size_multi; char part_config; char part_num; uint tran_speed; uint read_bl_len; uint write_bl_len; uint erase_grp_size; + uint sec_feature_support; u64 capacity; block_dev_desc_t block_dev; int (*send_cmd)(struct mmc *mmc, diff --git a/sd_fuse/Makefile b/sd_fuse/Makefile new file mode 100644 index 000000000..6d58e59f4 --- /dev/null +++ b/sd_fuse/Makefile @@ -0,0 +1,46 @@ +.SUFFIXES : .c .o + +CC = gcc +ASM = +LINK = +LIBCC = ar +RM = rm + +#---------------------------------------------------------------------------------------------- +INCPATH = +LIBPATH = +OBJPATH = . +OUTPATH = . +SOURCEPATH = . + +LDFLAGS = -L$(LIBPATH) +#LFLAGS = -lm +ASFLAGS = +ARFLAGS = -ruv +CFLAGS = -o + +LIBS = + +#--------------------------------------------------------------------------------------- +SOURCES = $(OBJECTS:.o=.c) + +all: + $(CC) $(CFLAGS) mkbl2 exynos-mkbl2.c + $(CC) $(CFLAGS) sd_fdisk sd_fdisk.c + +#--------------------------------------------------------------------------------------- +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +dep: + gccmakedep $(SOURCES) + +#--------------------------------------------------------------------------------------- +clean: + $(RM) -rf sd_fdisk + $(RM) -rf mkbl2 + +new: + $(MAKE) clean + $(MAKE) + diff --git a/sd_fuse/exynos-mkbl2.c b/sd_fuse/exynos-mkbl2.c new file mode 100644 index 000000000..351e8f6dc --- /dev/null +++ b/sd_fuse/exynos-mkbl2.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * 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. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int main (int argc, char *argv[]) +{ + FILE *fp; + unsigned char src; + char *Buf, *a; + int BufLen; + int nbytes, fileLen; + unsigned int checksum = 0; + int i; + + if (argc != 4) + { + printf("Usage: mkbl1 <source file> <destination file> <size> \n"); + return -1; + } + + BufLen = atoi(argv[3]); + Buf = (char *)malloc(BufLen); + memset(Buf, 0x00, BufLen); + + fp = fopen(argv[1], "rb"); + if( fp == NULL) + { + printf("source file open error\n"); + free(Buf); + return -1; + } + + fseek(fp, 0L, SEEK_END); + fileLen = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + if ( BufLen > fileLen ) + { + printf("Usage: unsupported size\n"); + free(Buf); + fclose(fp); + return -1; + } + + nbytes = fread(Buf, 1, BufLen, fp); + + if ( nbytes != BufLen ) + { + printf("source file read error\n"); + free(Buf); + fclose(fp); + return -1; + } + + fclose(fp); + + for(i = 0;i < (14 * 1024) - 4;i++) + { + checksum += (unsigned char)(Buf[i]); + } + *(unsigned int*)(Buf+i) = checksum; + + fp = fopen(argv[2], "wb"); + if (fp == NULL) + { + printf("destination file open error\n"); + free(Buf); + return -1; + } + + a = Buf; + nbytes = fwrite( a, 1, BufLen, fp); + + if ( nbytes != BufLen ) + { + printf("destination file write error\n"); + free(Buf); + fclose(fp); + return -1; + } + + free(Buf); + fclose(fp); + + return 0; +} diff --git a/sd_fuse/sd_fdisk.c b/sd_fuse/sd_fdisk.c new file mode 100644 index 000000000..5971b34d7 --- /dev/null +++ b/sd_fuse/sd_fdisk.c @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define BLOCK_SIZE 512 +#define BLOCK_END 0xFFFFFFFF +#define _10MB (10*1024*1024) +#define _100MB (100*1024*1024) +#define _8_4GB (1023*254*63) + +#define CHS_MODE 0 +#define LBA_MODE !(CHS_MODE) + +typedef struct +{ + int C_start; + int H_start; + int S_start; + + int C_end; + int H_end; + int S_end; + + int available_block; + int unit; + int total_block_count; + int addr_mode; // LBA_MODE or CHS_MODE +} SDInfo; + +typedef struct +{ + unsigned char bootable; + unsigned char partitionId; + + int C_start; + int H_start; + int S_start; + + int C_end; + int H_end; + int S_end; + + int block_start; + int block_count; + int block_end; +} PartitionInfo; + +///////////////////////////////////////////////////////////////// +int calc_unit(int length, SDInfo sdInfo) +{ + if (sdInfo.addr_mode == CHS_MODE) + return ( (length / BLOCK_SIZE / sdInfo.unit + 1 ) * sdInfo.unit); + + else + return ( (length / BLOCK_SIZE) ); +} + +///////////////////////////////////////////////////////////////// +void encode_chs(int C, int H, int S, unsigned char *result) +{ + *result++ = (unsigned char) H; + *result++ = (unsigned char) ( S + ((C & 0x00000300) >> 2) ); + *result = (unsigned char) (C & 0x000000FF); +} + +///////////////////////////////////////////////////////////////// +void encode_partitionInfo(PartitionInfo partInfo, unsigned char *result) +{ + *result++ = partInfo.bootable; + + encode_chs(partInfo.C_start, partInfo.H_start, partInfo.S_start, result); + result +=3; + + *result++ = partInfo.partitionId; + + encode_chs(partInfo.C_end, partInfo.H_end, partInfo.S_end, result); + result += 3; + + *((int *)result) = partInfo.block_start; + result += 4; + + *((int *)result) = partInfo.block_count; +} + +///////////////////////////////////////////////////////////////// +void get_SDInfo(int block_count, SDInfo *sdInfo) +{ + int C, H, S; + + int C_max = 1023, H_max = 255, S_max = 63; + int H_start = 1, S_start = 1; + int diff_min = 0, diff = 0; + + if(block_count >= _8_4GB) + sdInfo->addr_mode = LBA_MODE; + else + sdInfo->addr_mode = CHS_MODE; + + if (sdInfo->addr_mode == CHS_MODE) + { + diff_min = C_max; + + for (H = H_start; H <= H_max; H++) + for (S = S_start; S <= S_max; S++) + { + C = block_count / (H * S); + + if ( (C <= C_max) ) + { + diff = C_max - C; + if (diff <= diff_min) + { + diff_min = diff; + sdInfo->C_end = C; + sdInfo->H_end = H; + sdInfo->S_end = S; + } + } + } + } + else + { + sdInfo->C_end = 1023; + sdInfo->H_end = 254; + sdInfo->S_end = 63; + } + + sdInfo->C_start = 0; + sdInfo->H_start = 1; + sdInfo->S_start = 1; + + sdInfo->total_block_count = block_count; + sdInfo->available_block = sdInfo->C_end * sdInfo->H_end * sdInfo->S_end; + sdInfo->unit = sdInfo->H_end * sdInfo->S_end; +} + +///////////////////////////////////////////////////////////////// +void make_partitionInfo(int LBA_start, int count, SDInfo sdInfo, PartitionInfo *partInfo) +{ + int temp = 0; + int _10MB_unit; + + partInfo->block_start = LBA_start; + + if (sdInfo.addr_mode == CHS_MODE) + { + partInfo->C_start = partInfo->block_start / (sdInfo.H_end * sdInfo.S_end); + temp = partInfo->block_start % (sdInfo.H_end * sdInfo.S_end); + partInfo->H_start = temp / sdInfo.S_end; + partInfo->S_start = temp % sdInfo.S_end + 1; + + if (count == BLOCK_END) + { + _10MB_unit = calc_unit(_10MB, sdInfo); + partInfo->block_end = sdInfo.C_end * sdInfo.H_end * sdInfo.S_end - _10MB_unit - 1; + partInfo->block_count = partInfo->block_end - partInfo->block_start + 1; + + partInfo->C_end = partInfo->block_end / sdInfo.unit; + partInfo->H_end = sdInfo.H_end - 1; + partInfo->S_end = sdInfo.S_end; + } + else + { + partInfo->block_count = count; + + partInfo->block_end = partInfo->block_start + count - 1; + partInfo->C_end = partInfo->block_end / sdInfo.unit; + + temp = partInfo->block_end % sdInfo.unit; + partInfo->H_end = temp / sdInfo.S_end; + partInfo->S_end = temp % sdInfo.S_end + 1; + } + } + else + { + partInfo->C_start = 0; + partInfo->H_start = 1; + partInfo->S_start = 1; + + partInfo->C_end = 1023; + partInfo->H_end = 254; + partInfo->S_end = 63; + + if (count == BLOCK_END) + { + _10MB_unit = calc_unit(_10MB, sdInfo); + partInfo->block_end = sdInfo.total_block_count - _10MB_unit - 1; + partInfo->block_count = partInfo->block_end - partInfo->block_start + 1; + + } + else + { + partInfo->block_count = count; + partInfo->block_end = partInfo->block_start + count - 1; + } + } +} + +///////////////////////////////////////////////////////////////// +int get_sd_block_count(char *devicefile) +{ + FILE *fp; + char buf[128]; + + int block_count = 0; + int nbytes = 0; + + char *t = "/sys/block/"; + char sd_size_file[64]; + + strcpy(sd_size_file, t); + strcat(sd_size_file, &devicefile[5]); + strcat(sd_size_file, "/size"); + + fp = fopen(sd_size_file, "rb"); + nbytes = fread(buf, 1, 128, fp); + fclose(fp); + + block_count = atoi(buf); + + return block_count; +} + + +///////////////////////////////////////////////////////////////// +int main(int argc, char *argv[]) +{ + FILE *fp; + + int total_block_count; + int block_start = 0, block_offset = 0; + + SDInfo sdInfo; + PartitionInfo partInfo[4]; + + unsigned char mbr[512]; + + if (argc != 2) + { + printf("Usage: sd_fdisk <device_file>\n"); + return -1; + } +/////////////////////////////////////////////////////////// + memset((unsigned char *)&sdInfo, 0x00, sizeof(SDInfo)); + +/////////////////////////////////////////////////////////// + total_block_count = get_sd_block_count(argv[1]); + get_SDInfo(total_block_count, &sdInfo); +/* +/////////////////////////////////////////////////////////// +// ݵ Unit Ѵ. + block_start = calc_unit(_10MB, sdInfo); + block_offset = calc_unit(_100MB, sdInfo); + +/////////////////////////////////////////////////////////// + partInfo[0].bootable = 0x00; + partInfo[0].partitionId = 0x83; + + make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[0]); + +/////////////////////////////////////////////////////////// + block_start += block_offset; + + partInfo[1].bootable = 0x00; + partInfo[1].partitionId = 0x83; + + make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[1]); + +/////////////////////////////////////////////////////////// + block_start += block_offset; + partInfo[2].bootable = 0x00; + partInfo[2].partitionId = 0x83; + + make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[2]); +*/ +/////////////////////////////////////////////////////////// +// block_start += block_offset; + block_start = calc_unit(_10MB, sdInfo); + + block_offset += BLOCK_END; + partInfo[3].bootable = 0x00; + partInfo[3].partitionId = 0x0C; + + make_partitionInfo(block_start, BLOCK_END, sdInfo, &partInfo[3]); + +/////////////////////////////////////////////////////////// + memset(mbr, 0x00, sizeof(mbr)); + mbr[510] = 0x55; mbr[511] = 0xAA; + +// encode_partitionInfo(partInfo[0], &mbr[0x1CE]); +// encode_partitionInfo(partInfo[1], &mbr[0x1DE]); +// encode_partitionInfo(partInfo[2], &mbr[0x1EE]); + encode_partitionInfo(partInfo[3], &mbr[0x1BE]); + + fp = fopen("sd_mbr.dat", "wb"); + fwrite(mbr, 1, sizeof(mbr), fp); + fclose(fp); + + return 0; +} + diff --git a/sd_fuse/sd_fusing.sh b/sd_fuse/sd_fusing.sh new file mode 100644 index 000000000..cc176f34f --- /dev/null +++ b/sd_fuse/sd_fusing.sh @@ -0,0 +1,115 @@ +# +# Copyright (C) 2010 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# 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. +# +#################################### +reader_type1="/dev/sdb" +reader_type2="/dev/mmcblk0" + +c210_bl1="c210N.nbl1.bin" +v310_bl1="v310N.nbl1.bin" + +if [ -z $1 ] +then + echo "usage: ./sd_fusing.sh <SD Reader's device file>" + exit 0 +fi + +if [ $1 = $reader_type1 ] +then + partition1="$11" + partition2="$12" + partition3="$13" + partition4="$14" + +elif [ $1 = $reader_type2 ] +then + partition1="$1p1" + partition2="$1p2" + partition3="$1p3" + partition4="$1p4" + +else + echo "Unsupported SD reader" + exit 0 +fi + +if [ -b $1 ] +then + echo "$1 reader is identified." +else + echo "$1 is NOT identified." + exit 0 +fi + +#################################### +# make partition +echo "make sd card partition" +echo "./sd_fdisk $1" +./sd_fdisk $1 +dd iflag=dsync oflag=dsync if=sd_mbr.dat of=$1 +rm sd_mbr.dat + +#################################### +# format +umount $partition1 2> /dev/null +umount $partition2 2> /dev/null +umount $partition3 2> /dev/null +umount $partition4 2> /dev/null + +echo "mkfs.vfat -F 32 $partition1" +mkfs.vfat -F 32 $partition1 + +#echo "mkfs.ext2 $partition2" +#mkfs.ext2 $partition2 + +#echo "mkfs.ext2 $partition3" +#mkfs.ext2 $partition3 + +#echo "mkfs.ext2 $partition4" +#mkfs.ext2 $partition4 + +#################################### +# mount +#umount /media/sd 2> /dev/null +#mkdir -p /media/sd +#echo "mount -t vfat $partition1 /media/sd" +#mount -t vfat $partition1 /media/sd + +#################################### +#<BL1 fusing> + +if [ $2 = $c210_bl1 ] +then + signed_bl1_position=1 + bl2_position=17 + uboot_position=49 +elif [ $2 = $v310_bl1 ] +then + signed_bl1_position=1 + bl2_position=17 + uboot_position=49 +else + echo "Unknown BL1" + exit 0 +fi + +echo "BL1 fusing" +dd iflag=dsync oflag=dsync if=../$2 of=$1 seek=$signed_bl1_position + +#################################### +#<u-boot fusing> +echo "u-boot fusing" +./mkbl2 ../u-boot.bin ../bl2 16384 +dd iflag=dsync oflag=dsync if=../bl2 of=$1 seek=$bl2_position #count=28 +dd iflag=dsync oflag=dsync if=../u-boot.bin of=$1 seek=$uboot_position +rm ../bl2 + +#################################### +#<Message Display> +echo "U-boot image is fused successfully." +echo "Eject SD card and insert it again." diff --git a/sd_fuse/smdk4x12/sd_fusing.sh b/sd_fuse/smdk4x12/sd_fusing.sh new file mode 100644 index 000000000..3afd42841 --- /dev/null +++ b/sd_fuse/smdk4x12/sd_fusing.sh @@ -0,0 +1,52 @@ +# +# Copyright (C) 2011 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# 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. +# +#################################### + +if [ -z $1 ] +then + echo "usage: ./sd_fusing.sh <SD Reader's device file>" + exit 0 +fi + +if [ -b $1 ] +then + echo "$1 reader is identified." +else + echo "$1 is NOT identified." + exit 0 +fi + +#################################### +# fusing images + +signed_bl1_position=1 +bl2_position=31 +uboot_position=63 +tzsw_position=719 + +#<BL1 fusing> +echo "BL1 fusing" +dd iflag=dsync oflag=dsync if=./E4x12_N.bl1.bin of=$1 seek=$signed_bl1_position + +#<BL2 fusing> +echo "BL2 fusing" +dd iflag=dsync oflag=dsync if=$2 of=$1 seek=$bl2_position + +#<u-boot fusing> +echo "u-boot fusing" +dd iflag=dsync oflag=dsync if=./u-boot.bin of=$1 seek=$uboot_position + +#<TrustZone S/W fusing> +echo "TrustZone S/W fusing" +dd iflag=dsync oflag=dsync if=./E4x12_tzsw.bin of=$1 seek=$tzsw_position + +#################################### +#<Message Display> +echo "U-boot image is fused successfully." +echo "Eject SD card and insert it again." diff --git a/sd_fuse/smdk5250/sd_fusing.sh b/sd_fuse/smdk5250/sd_fusing.sh new file mode 100644 index 000000000..425f8247e --- /dev/null +++ b/sd_fuse/smdk5250/sd_fusing.sh @@ -0,0 +1,52 @@ +# +# Copyright (C) 2011 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# 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. +# +#################################### + +if [ -z $1 ] +then + echo "usage: ./sd_fusing.sh <SD Reader's device file>" + exit 0 +fi + +if [ -b $1 ] +then + echo "$1 reader is identified." +else + echo "$1 is NOT identified." + exit 0 +fi + +#################################### +# fusing images + +signed_bl1_position=1 +bl2_position=31 +uboot_position=63 +tzsw_position=719 + +#<BL1 fusing> +echo "BL1 fusing" +dd iflag=dsync oflag=dsync if=./E5250_N.bl1.bin of=$1 seek=$signed_bl1_position + +#<BL2 fusing> +echo "BL2 fusing" +dd iflag=dsync oflag=dsync if=$2 of=$1 seek=$bl2_position + +#<u-boot fusing> +echo "u-boot fusing" +dd iflag=dsync oflag=dsync if=./u-boot.bin of=$1 seek=$uboot_position + +#<TrustZone S/W fusing> +echo "TrustZone S/W fusing" +dd iflag=dsync oflag=dsync if=./E5250_tzsw.bin of=$1 seek=$tzsw_position + +#################################### +#<Message Display> +echo "U-boot image is fused successfully." +echo "Eject SD card and insert it again." diff --git a/sd_fuse/smdk5410/sd_fusing.sh b/sd_fuse/smdk5410/sd_fusing.sh new file mode 100644 index 000000000..540f35d4d --- /dev/null +++ b/sd_fuse/smdk5410/sd_fusing.sh @@ -0,0 +1,52 @@ +# +# Copyright (C) 2013 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# 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. +# +#################################### + +if [ -z $1 ] +then + echo "usage: ./sd_fusing.sh <SD Reader's device file>" + exit 0 +fi + +if [ -b $1 ] +then + echo "$1 reader is identified." +else + echo "$1 is NOT identified." + exit 0 +fi + +#################################### +# fusing images + +signed_bl1_position=1 +bl2_position=31 +uboot_position=63 +tzsw_position=719 + +#<BL1 fusing> +echo "BL1 fusing" +dd iflag=dsync oflag=dsync if=./E5410_S.bl1.bin of=$1 seek=$signed_bl1_position + +#<BL2 fusing> +echo "BL2 fusing" +dd iflag=dsync oflag=dsync if=./E5410_bl2.bin of=$1 seek=$bl2_position + +#<u-boot fusing> +echo "u-boot fusing" +dd iflag=dsync oflag=dsync if=./u-boot.bin of=$1 seek=$uboot_position + +#<TrustZone S/W fusing> +echo "TrustZone S/W fusing" +dd iflag=dsync oflag=dsync if=./E5410_tzsw.bin of=$1 seek=$tzsw_position + +#################################### +#<Message Display> +echo "U-boot image is fused successfully." +echo "Eject SD card and insert it again." diff --git a/sd_fuse/xyref5430/sd_fusing.sh b/sd_fuse/xyref5430/sd_fusing.sh new file mode 100644 index 000000000..287011d7a --- /dev/null +++ b/sd_fuse/xyref5430/sd_fusing.sh @@ -0,0 +1,52 @@ +# +# Copyright (C) 2013 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# 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. +# +#################################### + +if [ -z $1 ] +then + echo "usage: ./sd_fusing.sh <SD Reader's device file>" + exit 0 +fi + +if [ -b $1 ] +then + echo "$1 reader is identified." +else + echo "$1 is NOT identified." + exit 0 +fi + +#################################### +# fusing images + +signed_bl1_position=1 +bl2_position=31 +uboot_position=63 +tzsw_position=719 + +#<BL1 fusing> +echo "BL1 fusing" +dd iflag=dsync oflag=dsync if=./E5430.N.bl1.bin of=$1 seek=$signed_bl1_position + +#<BL2 fusing> +echo "BL2 fusing" +dd iflag=dsync oflag=dsync if=./E5430.N.bl2.bin of=$1 seek=$bl2_position + +#<u-boot fusing> +echo "u-boot fusing" +dd iflag=dsync oflag=dsync if=./u-boot.bin of=$1 seek=$uboot_position + +#<TrustZone S/W fusing> +echo "TrustZone S/W fusing" +dd iflag=dsync oflag=dsync if=./E5430.N.tzsw.bin of=$1 seek=$tzsw_position + +#################################### +#<Message Display> +echo "U-boot image is fused successfully." +echo "Eject SD card and insert it again." diff --git a/spl/Makefile b/spl/Makefile index ea7d4750f..411dcc113 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -117,10 +117,16 @@ endif all: $(ALL-y) ifdef CONFIG_SAMSUNG +ifdef CONFIG_SPL_15KB +$(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin + $(OBJTREE)/tools/mk$(BOARD)spl15kb \ + $(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.bin +else $(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin $(OBJTREE)/tools/mk$(BOARD)spl \ $(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.bin endif +endif $(obj)u-boot-spl.bin: $(obj)u-boot-spl $(OBJCOPY) $(OBJCFLAGS) -O binary $< $@ @@ -129,7 +135,7 @@ GEN_UBOOT = \ UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) | \ sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\ cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $$UNDEF_SYM $(__START) \ - --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ + --start-group $(__LIBS) --end-group $(PLATFORM_SPL_LIBS) \ -Map u-boot-spl.map -o u-boot-spl $(obj)u-boot-spl: depend $(START) $(LIBS) $(obj)u-boot-spl.lds diff --git a/tools/.gitignore b/tools/.gitignore index 3557a75b9..0c8b28544 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -16,3 +16,4 @@ /env/fw_printenv /gdb/gdbcont /gdb/gdbsend +/mkespresso3250spl15kb diff --git a/tools/Makefile b/tools/Makefile index a7d1e18fe..3f7139cd9 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -68,7 +68,15 @@ BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX) BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX) BIN_FILES-y += mkenvimage$(SFX) BIN_FILES-y += mkimage$(SFX) -BIN_FILES-$(CONFIG_SMDK5250) += mksmdk5250spl$(SFX) +BIN_FILES-$(CONFIG_MACH_SMDK5250) += mksmdk5250spl$(SFX) +BIN_FILES-$(CONFIG_MACH_SMDK5412) += mksmdk5412spl$(SFX) +BIN_FILES-$(CONFIG_SMDK5410) += mksmdk5410spl$(SFX) +BIN_FILES-$(CONFIG_EXYNOS4412) += mksmdk4x12spl$(SFX) +BIN_FILES-$(CONFIG_EXYNOS4212) += mksmdk4x12spl$(SFX) +BIN_FILES-$(CONFIG_CPU_EXYNOS3250) += mkespresso3250spl15kb$(SFX) +BIN_FILES-$(CONFIG_CPU_EXYNOS4415) += mkxyref4415spl15kb$(SFX) +BIN_FILES-$(CONFIG_CPU_EXYNOS5260) += mkxyref5260spl15kb$(SFX) +BIN_FILES-$(CONFIG_CPU_EXYNOS5430) += mkxyref5430spl15kb$(SFX) BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX) BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX) BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX) @@ -96,7 +104,15 @@ NOPED_OBJ_FILES-y += imximage.o NOPED_OBJ_FILES-y += omapimage.o NOPED_OBJ_FILES-y += mkenvimage.o NOPED_OBJ_FILES-y += mkimage.o -OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o +OBJ_FILES-$(CONFIG_MACH_SMDK5250) += mkexynosspl.o +OBJ_FILES-$(CONFIG_MACH_SMDK5412) += mkexynosspl.o +OBJ_FILES-$(CONFIG_SMDK5410) += mkexynosspl.o +OBJ_FILES-$(CONFIG_EXYNOS4412) += mkexynosspl.o +OBJ_FILES-$(CONFIG_EXYNOS4212) += mkexynosspl.o +OBJ_FILES-$(CONFIG_CPU_EXYNOS3250) += mkexynosspl15kb.o +OBJ_FILES-$(CONFIG_CPU_EXYNOS4415) += mkexynosspl15kb.o +OBJ_FILES-$(CONFIG_CPU_EXYNOS5260) += mkexynosspl15kb.o +OBJ_FILES-$(CONFIG_CPU_EXYNOS5430) += mkexynosspl15kb.o OBJ_FILES-$(CONFIG_MX28) += mxsboot.o OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o NOPED_OBJ_FILES-y += os_support.o @@ -222,6 +238,10 @@ $(obj)mk$(BOARD)spl$(SFX): $(obj)mkexynosspl.o $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTSTRIP) $@ +$(obj)mk$(BOARD)spl15kb$(SFX): $(obj)mkexynosspl15kb.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ + $(obj)mpc86x_clk$(SFX): $(obj)mpc86x_clk.o $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTSTRIP) $@ diff --git a/tools/mkexynosspl15kb.c b/tools/mkexynosspl15kb.c new file mode 100644 index 000000000..5fea7e63f --- /dev/null +++ b/tools/mkexynosspl15kb.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/stat.h> +#include <compiler.h> + +#define CHECKSUM_OFFSET (15*1024-4) +#define BUFSIZE (15*1024) +#define FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP \ + | S_IWGRP | S_IROTH | S_IWOTH) +/* +* Requirement: +* IROM code reads first 14K bytes from boot device. +* It then calculates the checksum of 14K-4 bytes and compare with data at +* 14K-4 offset. +* +* This function takes two filenames: +* IN "u-boot-spl.bin" and +* OUT "$(BOARD)-spl.bin as filenames. +* It reads the "u-boot-spl.bin" in 16K buffer. +* It calculates checksum of 14K-4 Bytes and stores at 14K-4 offset in buffer. +* It writes the buffer to "$(BOARD)-spl.bin" file. +*/ + +int main(int argc, char **argv) +{ + unsigned char buffer[BUFSIZE]; + int i, ifd, ofd; + uint32_t checksum = 0; + off_t len; + ssize_t count; + struct stat stat; + + if (argc != 3) { + fprintf(stderr, "Usage: %s <infile> <outfile>\n", argv[0]); + exit(EXIT_FAILURE); + } + + ifd = open(argv[1], O_RDONLY); + if (ifd < 0) { + fprintf(stderr, "%s: Can't open %s: %s\n", + argv[0], argv[1], strerror(errno)); + exit(EXIT_FAILURE); + } + + ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM); + if (ifd < 0) { + fprintf(stderr, "%s: Can't open %s: %s\n", + argv[0], argv[2], strerror(errno)); + close(ifd); + exit(EXIT_FAILURE); + } + + if (fstat(ifd, &stat)) { + fprintf(stderr, "%s: Unable to get size of %s: %s\n", + argv[0], argv[1], strerror(errno)); + close(ifd); + close(ofd); + exit(EXIT_FAILURE); + } + + len = stat.st_size; + + count = (len < CHECKSUM_OFFSET) ? len : CHECKSUM_OFFSET; + + if (read(ifd, buffer, count) != count) { + fprintf(stderr, "%s: Can't read %s: %s\n", + argv[0], argv[1], strerror(errno)); + + close(ifd); + close(ofd); + + exit(EXIT_FAILURE); + } + + for (i = 0, checksum = 0; i < CHECKSUM_OFFSET; i++) + checksum += buffer[i]; + + checksum = cpu_to_le32(checksum); + + memcpy(&buffer[CHECKSUM_OFFSET], &checksum, sizeof(checksum)); + + if (write(ofd, buffer, BUFSIZE) != BUFSIZE) { + fprintf(stderr, "%s: Can't write %s: %s\n", + argv[0], argv[2], strerror(errno)); + + close(ifd); + close(ofd); + + exit(EXIT_FAILURE); + } + + close(ifd); + close(ofd); + + return EXIT_SUCCESS; +} |