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 /board | |
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>
Diffstat (limited to 'board')
95 files changed, 31511 insertions, 681 deletions
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] 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 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); +} |