[U-Boot] [PATCH 00/10 V4] EXYNOS5: Support for Exynos5250 Rev 1.0

This patch set adds support for Exynos5250 Rev 1.0. Exynos5250 Rev 1.0 supports DDR3 Memory configuration and support for LPDDR2 is removed. Exynos5250 Rev 1.0 supports DWMMC controller and does not support SDHCI controller. After DWMMC driver is added to Mainline support for generic S5P MMC driver will be removed.
Due to Support of SDHCI controller currently still there for EXYNOS5 you can see the following error on boot.
mmc_reset: timeout error mmc_change_clock: timeout error mmc_send_cmd: waiting for status update MMC init failed
Changes in V2: - Included Paramateric structure with in #ifndef __ASSEMBLY__. Chnages in V3: - Incorporated the review comments. - Added support for BPLL. - Corrected the gpio pinmux settings. Changes in V4: - Corrected a warning message
Rajeshwari Shinde (10): ARCH: SPL: Add parametric board initializer SMDK5250: SPL: Define parametric board initializer SMDK5250: Add smdk5250-uboot-spl.lds EXYNOS5: CLOCK: define additional clock registers for Exynos5250 Rev 1.0 EXYNOS5: CLOCK: Add clock support for Exynos5250 Rev 1.0 Exynos5: DDR3: Add DDR3 memory setup for Exynos5250 Rev 1.0 EXYNOS5: CLOCK: Modify MPLL clock out for Exynos5250 Rev 1.0 EXYNOS5: CLOCK: Add BPLL support EXYNOS5 : Modify pinnumx settings as per Exynos5250 Rev 1.0 SMDK5250: Enable UART and MMC for Exynos5250 Rev 1.0
arch/arm/cpu/armv7/exynos/clock.c | 28 +- arch/arm/cpu/armv7/exynos/pinmux.c | 22 +- arch/arm/include/asm/arch-exynos/clk.h | 1 + arch/arm/include/asm/arch-exynos/clock.h | 237 +++++---- arch/arm/include/asm/arch-exynos/dmc.h | 65 +++ arch/arm/include/asm/arch-exynos/gpio.h | 7 +- arch/arm/include/asm/arch-exynos/spl.h | 97 ++++ board/samsung/smdk5250/Makefile | 3 +- board/samsung/smdk5250/clock_init.c | 714 +++++++++++++++++++---- board/samsung/smdk5250/clock_init.h | 149 +++++ board/samsung/smdk5250/dmc_common.c | 199 +++++++ board/samsung/smdk5250/dmc_init.c | 462 --------------- board/samsung/smdk5250/dmc_init_ddr3.c | 228 ++++++++ board/samsung/smdk5250/setup.h | 762 +++++++++++++++---------- board/samsung/smdk5250/smdk5250-uboot-spl.lds | 66 +++ board/samsung/smdk5250/smdk5250.c | 6 +- board/samsung/smdk5250/smdk5250_spl.c | 68 +++ include/configs/smdk5250.h | 7 +- 18 files changed, 2099 insertions(+), 1022 deletions(-) create mode 100644 arch/arm/include/asm/arch-exynos/spl.h create mode 100644 board/samsung/smdk5250/clock_init.h create mode 100644 board/samsung/smdk5250/dmc_common.c delete mode 100644 board/samsung/smdk5250/dmc_init.c create mode 100644 board/samsung/smdk5250/dmc_init_ddr3.c create mode 100644 board/samsung/smdk5250/smdk5250-uboot-spl.lds create mode 100644 board/samsung/smdk5250/smdk5250_spl.c

Add a structure for table-driven configuration mechanism such that no recompilation is needed to update the configuration parameters, rather than hard-coding board initialization parameters.
Signed-off-by: Che-Liang Chiou clchiou@chromium.org Signed-off-by: Abhilash Kesavan a.kesavan@samsung.com Signed-off-by: Tom Wai-Hong Tam waihong@chromium.org Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - Included Paramateric structure with in #ifndef __ASSEMBLY__. Changes in V3: - None Changes in V4: - None arch/arm/include/asm/arch-exynos/spl.h | 97 ++++++++++++++++++++++++++++++++ 1 files changed, 97 insertions(+), 0 deletions(-) create mode 100644 arch/arm/include/asm/arch-exynos/spl.h
diff --git a/arch/arm/include/asm/arch-exynos/spl.h b/arch/arm/include/asm/arch-exynos/spl.h new file mode 100644 index 0000000..306b41d --- /dev/null +++ b/arch/arm/include/asm/arch-exynos/spl.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * 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 __ASM_ARCH_EXYNOS_SPL_H__ +#define __ASM_ARCH_EXYNOS_SPL_H__ + +#include <asm/arch-exynos/dmc.h> + +enum boot_mode { + /* + * Assign the OM pin values for respective boot modes. + * Exynos4 does not support spi boot and the mmc boot OM + * pin values are the same across Exynos4 and Exynos5. + */ + BOOT_MODE_MMC = 4, + BOOT_MODE_SERIAL = 20, + /* Boot based on Operating Mode pin settings */ + BOOT_MODE_OM = 32, + BOOT_MODE_USB, /* Boot using USB download */ +}; + +#ifndef __ASSEMBLY__ +/* Parameters of early board initialization in SPL */ +struct spl_machine_param { + /* Add fields as and when required */ + u32 signature; + u32 version; /* Version number */ + u32 size; /* Size of block */ + /** + * Parameters we expect, in order, terminated with \0. Each parameter + * is a single character representing one 32-bit word in this + * structure. + * + * Valid characters in this string are: + * + * Code Name + * v mem_iv_size + * m mem_type + * u uboot_size + * b boot_source + * f frequency_mhz (memory frequency in MHz) + * a ARM clock frequency in MHz + * s serial base address + * i i2c base address for early access (meant for PMIC) + * r board rev GPIO numbers used to read board revision + * (lower halfword=bit 0, upper=bit 1) + * M Memory Manufacturer name + * \0 termination + */ + char params[12]; /* Length must be word-aligned */ + u32 mem_iv_size; /* Memory channel interleaving size */ + enum ddr_mode mem_type; /* Type of on-board memory */ + /* + * U-boot size - The iROM mmc copy function used by the SPL takes a + * block count paramter to describe the u-boot size unlike the spi + * boot copy function which just uses the u-boot size directly. Align + * the u-boot size to block size (512 bytes) when populating the SPL + * table only for mmc boot. + */ + u32 uboot_size; + enum boot_mode boot_source; /* Boot device */ + enum mem_manuf mem_manuf; /* Memory Manufacturer */ + unsigned frequency_mhz; /* Frequency of memory in MHz */ + unsigned arm_freq_mhz; /* ARM Frequency in MHz */ + u32 serial_base; /* Serial base address */ + u32 i2c_base; /* i2c base address */ +} __attribute__((__packed__)); +#endif + +/** + * Validate signature and return a pointer to the parameter table. If the + * signature is invalid, call panic() and never return. + * + * @return pointer to the parameter table if signature matched or never return. + */ +struct spl_machine_param *spl_get_machine_params(void); + +#endif /* __ASM_ARCH_EXYNOS_SPL_H__ */

Define table-driven configuration mechanism for SMDK5250 rather than hard-coding board initialization parameters.
Signed-off-by: Che-Liang Chiou clchiou@chromium.org Signed-off-by: Abhilash Kesavan a.kesavan@samsung.com Signed-off-by: Tom Wai-Hong Tam waihong@chromium.org Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None Changes in V3: - None Changes in V4: - None board/samsung/smdk5250/Makefile | 1 + board/samsung/smdk5250/smdk5250_spl.c | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 0 deletions(-) create mode 100644 board/samsung/smdk5250/smdk5250_spl.c
diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 226db1f..3675fad 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -29,6 +29,7 @@ SOBJS := lowlevel_init.o COBJS := clock_init.o COBJS += dmc_init.o COBJS += tzpc_init.o +COBJS += smdk5250_spl.o
ifndef CONFIG_SPL_BUILD COBJS += smdk5250.o diff --git a/board/samsung/smdk5250/smdk5250_spl.c b/board/samsung/smdk5250/smdk5250_spl.c new file mode 100644 index 0000000..1d453ca --- /dev/null +++ b/board/samsung/smdk5250/smdk5250_spl.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * 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/arch/cpu.h> +#include <asm/arch/spl.h> +#include <asm/arch/clk.h> + +#define SIGNATURE 0xdeadbeef + +/* Parameters of early board initialization in SPL */ +static struct spl_machine_param machine_param + __attribute__((section(".machine_param"))) = { + .signature = SIGNATURE, + .version = 1, + .params = "vmubfasirM", + .size = sizeof(machine_param), + + .mem_iv_size = 0x1f, + .mem_type = DDR_MODE_DDR3, + + /* + * Set uboot_size to 0x100000 bytes. + * + * This is an overly conservative value chosen to accommodate all + * possible U-Boot image. You are advised to set this value to a + * smaller realistic size via scripts that modifies the .machine_param + * section of output U-Boot image. + */ + .uboot_size = 0x100000, + + .boot_source = BOOT_MODE_OM, + .frequency_mhz = 800, + .arm_freq_mhz = 1700, + .serial_base = 0x12c30000, + .i2c_base = 0x12c60000, + .mem_manuf = MEM_MANUF_SAMSUNG, +}; + +struct spl_machine_param *spl_get_machine_params(void) +{ + if (machine_param.signature != SIGNATURE) { + /* Will hang if SIGNATURE dont match */ + while (1) + ; + } + + return &machine_param; +}

Default spl/u-boot-spl.lds created by spl/Makefile resolves the spl text load addr to 0x0. As 0x0 belongs to iROM addr so Global variables can not be used.
Adding specific smdk5250-uboot-spl.lds makes possible to use Global Variables in spl.
Signed-off-by: Alim Akhtar alim.akhtar@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None Changes in V3: - None Changes in V4: - None board/samsung/smdk5250/smdk5250-uboot-spl.lds | 66 +++++++++++++++++++++++++ include/configs/smdk5250.h | 5 ++ 2 files changed, 71 insertions(+), 0 deletions(-) create mode 100644 board/samsung/smdk5250/smdk5250-uboot-spl.lds
diff --git a/board/samsung/smdk5250/smdk5250-uboot-spl.lds b/board/samsung/smdk5250/smdk5250-uboot-spl.lds new file mode 100644 index 0000000..d78dd77 --- /dev/null +++ b/board/samsung/smdk5250/smdk5250-uboot-spl.lds @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de + * + * Copyright (C) 2012 Samsung Electronics + * + * Based on arch/arm/cpu/armv7/omap-common/u-boot-spl.lds + * + * 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 + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE, \ + LENGTH = CONFIG_SPL_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) + +SECTIONS +{ + .text : + { + __start = .; + arch/arm/cpu/armv7/start.o (.text) + *(.text*) + } >.sram + . = ALIGN(4); + + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + . = ALIGN(4); + + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + . = ALIGN(4); + + /* Align .machine_param on 256 byte boundary for easier searching */ + .machine_param ALIGN(0x100) : { *(.machine_param) } >.sram + . = ALIGN(4); + + __image_copy_end = .; + _end = .; + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end__ = .; + } >.sram +} diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 9659f9e..405abd5 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -105,6 +105,11 @@ #define CONFIG_SPL #define COPY_BL2_FNPTR_ADDR 0x02020030
+/* specific .lds file */ +#define CONFIG_SPL_LDSCRIPT "board/samsung/smdk5250/smdk5250-uboot-spl.lds" +#define CONFIG_SPL_TEXT_BASE 0x02023400 +#define CONFIG_SPL_MAX_SIZE (14 * 1024) + #define CONFIG_BOOTCOMMAND "mmc read 40007000 451 2000; bootm 40007000"
/* Miscellaneous configurable options */

Define additional registers for clock control in Exynos5250 Rev 1.0
Signed-off-by: Hatim Ali hatim.rv@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None Changes in V3: - Modified Clocks as per Exynos5250 Rev 1.0. Changes in V4: - None arch/arm/include/asm/arch-exynos/clock.h | 234 ++++++++++++++++-------------- 1 files changed, 126 insertions(+), 108 deletions(-)
diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h index 50da958..90271f1 100644 --- a/arch/arm/include/asm/arch-exynos/clock.h +++ b/arch/arm/include/asm/arch-exynos/clock.h @@ -273,8 +273,7 @@ struct exynos5_clock { unsigned int clkout_cmu_cpu_div_stat; unsigned char res8[0x5f8]; unsigned int armclk_stopctrl; - unsigned int atclk_stopctrl; - unsigned char res9[0x8]; + unsigned char res9[0x0c]; unsigned int parityfail_status; unsigned int parityfail_clear; unsigned char res10[0x8]; @@ -323,259 +322,278 @@ struct exynos5_clock { unsigned char res19[0xf8]; unsigned int div_core0; unsigned int div_core1; - unsigned char res20[0xf8]; + unsigned int div_sysrgt; + unsigned char res20[0xf4]; unsigned int div_stat_core0; unsigned int div_stat_core1; - unsigned char res21[0x2f8]; + unsigned int div_stat_sysrgt; + unsigned char res21[0x2f4]; unsigned int gate_ip_core; - unsigned char res22[0xfc]; + unsigned int gate_ip_sysrgt; + unsigned char res22[0x8]; + unsigned int c2c_monitor; + unsigned char res23[0xec]; unsigned int clkout_cmu_core; unsigned int clkout_cmu_core_div_stat; - unsigned char res23[0x5f8]; + unsigned char res24[0x5f8]; unsigned int dcgidx_map0; unsigned int dcgidx_map1; unsigned int dcgidx_map2; - unsigned char res24[0x14]; + unsigned char res25[0x14]; unsigned int dcgperf_map0; unsigned int dcgperf_map1; - unsigned char res25[0x18]; + unsigned char res26[0x18]; unsigned int dvcidx_map; - unsigned char res26[0x1c]; + unsigned char res27[0x1c]; unsigned int freq_cpu; unsigned int freq_dpm; - unsigned char res27[0x18]; + unsigned char res28[0x18]; unsigned int dvsemclk_en; unsigned int maxperf; - unsigned char res28[0x3478]; + unsigned char res29[0xf78]; + unsigned int c2c_config; + unsigned char res30[0x24fc]; unsigned int div_acp; - unsigned char res29[0xfc]; + unsigned char res31[0xfc]; unsigned int div_stat_acp; - unsigned char res30[0x1fc]; + unsigned char res32[0x1fc]; unsigned int gate_ip_acp; - unsigned char res31[0x1fc]; + unsigned char res33[0xfc]; + unsigned int div_syslft; + unsigned char res34[0xc]; + unsigned int div_stat_syslft; + unsigned char res35[0x1c]; + unsigned int gate_ip_syslft; + unsigned char res36[0xcc]; unsigned int clkout_cmu_acp; unsigned int clkout_cmu_acp_div_stat; - unsigned char res32[0x38f8]; + unsigned char res37[0x8]; + unsigned int ufmc_config; + unsigned char res38[0x38ec]; unsigned int div_isp0; unsigned int div_isp1; unsigned int div_isp2; - unsigned char res33[0xf4]; + unsigned char res39[0xf4]; unsigned int div_stat_isp0; unsigned int div_stat_isp1; unsigned int div_stat_isp2; - unsigned char res34[0x3f4]; + unsigned char res40[0x3f4]; unsigned int gate_ip_isp0; unsigned int gate_ip_isp1; - unsigned char res35[0xf8]; + unsigned char res41[0xf8]; unsigned int gate_sclk_isp; - unsigned char res36[0xc]; + unsigned char res42[0xc]; unsigned int mcuisp_pwr_ctrl; - unsigned char res37[0xec]; + unsigned char res43[0xec]; unsigned int clkout_cmu_isp; unsigned int clkout_cmu_isp_div_stat; - unsigned char res38[0x3618]; + unsigned char res44[0x3618]; unsigned int cpll_lock; - unsigned char res39[0xc]; + unsigned char res45[0xc]; unsigned int epll_lock; - unsigned char res40[0xc]; + unsigned char res46[0xc]; unsigned int vpll_lock; - unsigned char res41[0xdc]; + unsigned char res47[0xc]; + unsigned int gpll_lock; + unsigned char res48[0xcc]; unsigned int cpll_con0; unsigned int cpll_con1; - unsigned char res42[0x8]; + unsigned char res49[0x8]; unsigned int epll_con0; unsigned int epll_con1; unsigned int epll_con2; - unsigned char res43[0x4]; + unsigned char res50[0x4]; unsigned int vpll_con0; unsigned int vpll_con1; unsigned int vpll_con2; - unsigned char res44[0xc4]; + unsigned char res51[0x4]; + unsigned int gpll_con0; + unsigned int gpll_con1; + unsigned char res52[0xb8]; unsigned int src_top0; unsigned int src_top1; unsigned int src_top2; unsigned int src_top3; unsigned int src_gscl; - unsigned int src_disp0_0; - unsigned int src_disp0_1; + unsigned char res53[0x8]; unsigned int src_disp1_0; - unsigned int src_disp1_1; - unsigned char res46[0xc]; + unsigned char res54[0x10]; unsigned int src_mau; unsigned int src_fsys; - unsigned char res47[0x8]; + unsigned int src_gen; + unsigned char res55[0x4]; unsigned int src_peric0; unsigned int src_peric1; - unsigned char res48[0x18]; + unsigned char res56[0x18]; unsigned int sclk_src_isp; - unsigned char res49[0x9c]; + unsigned char res57[0x9c]; unsigned int src_mask_top; - unsigned char res50[0xc]; + unsigned char res58[0xc]; unsigned int src_mask_gscl; - unsigned int src_mask_disp0_0; - unsigned int src_mask_disp0_1; + unsigned char res59[0x8]; unsigned int src_mask_disp1_0; - unsigned int src_mask_disp1_1; - unsigned int src_mask_maudio; - unsigned char res52[0x8]; + unsigned char res60[0x4]; + unsigned int src_mask_mau; + unsigned char res61[0x8]; unsigned int src_mask_fsys; - unsigned char res53[0xc]; + unsigned int src_mask_gen; + unsigned char res62[0x8]; unsigned int src_mask_peric0; unsigned int src_mask_peric1; - unsigned char res54[0x18]; + unsigned char res63[0x18]; unsigned int src_mask_isp; - unsigned char res55[0x9c]; + unsigned char res67[0x9c]; unsigned int mux_stat_top0; unsigned int mux_stat_top1; unsigned int mux_stat_top2; unsigned int mux_stat_top3; - unsigned char res56[0xf0]; + unsigned char res68[0xf0]; unsigned int div_top0; unsigned int div_top1; - unsigned char res57[0x8]; + unsigned char res69[0x8]; unsigned int div_gscl; - unsigned int div_disp0_0; - unsigned int div_disp0_1; + unsigned char res70[0x8]; unsigned int div_disp1_0; - unsigned int div_disp1_1; - unsigned char res59[0x8]; + unsigned char res71[0xc]; unsigned int div_gen; - unsigned char res60[0x4]; + unsigned char res72[0x4]; unsigned int div_mau; unsigned int div_fsys0; unsigned int div_fsys1; unsigned int div_fsys2; - unsigned int div_fsys3; + unsigned char res73[0x4]; unsigned int div_peric0; unsigned int div_peric1; unsigned int div_peric2; unsigned int div_peric3; unsigned int div_peric4; unsigned int div_peric5; - unsigned char res61[0x10]; + unsigned char res74[0x10]; unsigned int sclk_div_isp; - unsigned char res62[0xc]; + unsigned char res75[0xc]; unsigned int div2_ratio0; unsigned int div2_ratio1; - unsigned char res63[0x8]; + unsigned char res76[0x8]; unsigned int div4_ratio; - unsigned char res64[0x6c]; + unsigned char res77[0x6c]; unsigned int div_stat_top0; unsigned int div_stat_top1; - unsigned char res65[0x8]; + unsigned char res78[0x8]; unsigned int div_stat_gscl; - unsigned int div_stat_disp0_0; - unsigned int div_stat_disp0_1; + unsigned char res79[0x8]; unsigned int div_stat_disp1_0; - unsigned int div_stat_disp1_1; - unsigned char res67[0x8]; + unsigned char res80[0xc]; unsigned int div_stat_gen; - unsigned char res68[0x4]; - unsigned int div_stat_maudio; + unsigned char res81[0x4]; + unsigned int div_stat_mau; unsigned int div_stat_fsys0; unsigned int div_stat_fsys1; unsigned int div_stat_fsys2; - unsigned int div_stat_fsys3; + unsigned char res82[0x4]; unsigned int div_stat_peric0; unsigned int div_stat_peric1; unsigned int div_stat_peric2; unsigned int div_stat_peric3; unsigned int div_stat_peric4; unsigned int div_stat_peric5; - unsigned char res69[0x10]; + unsigned char res83[0x10]; unsigned int sclk_div_stat_isp; - unsigned char res70[0xc]; + unsigned char res84[0xc]; unsigned int div2_stat0; unsigned int div2_stat1; - unsigned char res71[0x8]; + unsigned char res85[0x8]; unsigned int div4_stat; - unsigned char res72[0x180]; - unsigned int gate_top_sclk_disp0; + unsigned char res86[0x184]; unsigned int gate_top_sclk_disp1; unsigned int gate_top_sclk_gen; - unsigned char res74[0xc]; + unsigned char res87[0xc]; unsigned int gate_top_sclk_mau; unsigned int gate_top_sclk_fsys; - unsigned char res75[0xc]; + unsigned char res88[0xc]; unsigned int gate_top_sclk_peric; - unsigned char res76[0x1c]; + unsigned char res89[0x1c]; unsigned int gate_top_sclk_isp; - unsigned char res77[0xac]; + unsigned char res90[0xac]; unsigned int gate_ip_gscl; - unsigned int gate_ip_disp0; + unsigned char res91[0x4]; unsigned int gate_ip_disp1; unsigned int gate_ip_mfc; unsigned int gate_ip_g3d; unsigned int gate_ip_gen; - unsigned char res79[0xc]; + unsigned char res92[0xc]; unsigned int gate_ip_fsys; - unsigned char res80[0x4]; - unsigned int gate_ip_gps; + unsigned char res93[0x8]; unsigned int gate_ip_peric; - unsigned char res81[0xc]; + unsigned char res94[0xc]; unsigned int gate_ip_peris; - unsigned char res82[0x1c]; + unsigned char res95[0x1c]; unsigned int gate_block; - unsigned char res83[0x7c]; + unsigned char res96[0x1c]; + unsigned int mcuiop_pwr_ctrl; + unsigned char res97[0x5c]; unsigned int clkout_cmu_top; unsigned int clkout_cmu_top_div_stat; - unsigned char res84[0x37f8]; + unsigned char res98[0x37f8]; unsigned int src_lex; - unsigned char res85[0x2fc]; + unsigned char res99[0x1fc]; + unsigned int mux_stat_lex; + unsigned char res100[0xfc]; unsigned int div_lex; - unsigned char res86[0xfc]; + unsigned char res101[0xfc]; unsigned int div_stat_lex; - unsigned char res87[0x1fc]; + unsigned char res102[0x1fc]; unsigned int gate_ip_lex; - unsigned char res88[0x1fc]; + unsigned char res103[0x1fc]; unsigned int clkout_cmu_lex; unsigned int clkout_cmu_lex_div_stat; - unsigned char res89[0x3af8]; + unsigned char res104[0x3af8]; unsigned int div_r0x; - unsigned char res90[0xfc]; + unsigned char res105[0xfc]; unsigned int div_stat_r0x; - unsigned char res91[0x1fc]; + unsigned char res106[0x1fc]; unsigned int gate_ip_r0x; - unsigned char res92[0x1fc]; + unsigned char res107[0x1fc]; unsigned int clkout_cmu_r0x; unsigned int clkout_cmu_r0x_div_stat; - unsigned char res94[0x3af8]; + unsigned char res108[0x3af8]; unsigned int div_r1x; - unsigned char res95[0xfc]; + unsigned char res109[0xfc]; unsigned int div_stat_r1x; - unsigned char res96[0x1fc]; + unsigned char res110[0x1fc]; unsigned int gate_ip_r1x; - unsigned char res97[0x1fc]; + unsigned char res111[0x1fc]; unsigned int clkout_cmu_r1x; unsigned int clkout_cmu_r1x_div_stat; - unsigned char res98[0x3608]; + unsigned char res112[0x3608]; unsigned int bpll_lock; - unsigned char res99[0xfc]; + unsigned char res113[0xfc]; unsigned int bpll_con0; unsigned int bpll_con1; - unsigned char res100[0xe8]; + unsigned char res114[0xe8]; unsigned int src_cdrex; - unsigned char res101[0x1fc]; + unsigned char res115[0x1fc]; unsigned int mux_stat_cdrex; - unsigned char res102[0xfc]; + unsigned char res116[0xfc]; unsigned int div_cdrex; - unsigned int div_cdrex2; - unsigned char res103[0xf8]; + unsigned char res117[0xfc]; unsigned int div_stat_cdrex; - unsigned char res104[0x2fc]; + unsigned char res118[0x2fc]; unsigned int gate_ip_cdrex; - unsigned char res105[0xc]; - unsigned int c2c_monitor; - unsigned int dmc_pwr_ctrl; - unsigned char res106[0x4]; + unsigned char res119[0x10]; + unsigned int dmc_freq_ctrl; + unsigned char res120[0x4]; unsigned int drex2_pause; - unsigned char res107[0xe0]; + unsigned char res121[0xe0]; unsigned int clkout_cmu_cdrex; unsigned int clkout_cmu_cdrex_div_stat; - unsigned char res108[0x8]; + unsigned char res122[0x8]; unsigned int lpddr3phy_ctrl; - unsigned char res109[0xf5f8]; + unsigned int lpddr3phy_con0; + unsigned int lpddr3phy_con1; + unsigned int lpddr3phy_con2; + unsigned int lpddr3phy_con3; + unsigned int pll_div2_sel; + unsigned char res123[0xf5d8]; }; #endif - #endif

2012/6/29 Rajeshwari Shinde rajeshwari.s@samsung.com:
Define additional registers for clock control in Exynos5250 Rev 1.0
Signed-off-by: Hatim Ali hatim.rv@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V2: - None Changes in V3: - Modified Clocks as per Exynos5250 Rev 1.0. Changes in V4: - None arch/arm/include/asm/arch-exynos/clock.h | 234 ++++++++++++++++-------------- 1 files changed, 126 insertions(+), 108 deletions(-)
Acked-by: Joonyoung Shim jy0922.shim@samsung.com

Add new clock values for Exynos5250 Rev 1.0
Signed-off-by: Hatim Ali hatim.rv@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None Changes in V3: - Set Peric3 clock for PWM Ratio. Changes in V4: - None board/samsung/smdk5250/clock_init.c | 714 +++++++++++++++++++++++++++++------ board/samsung/smdk5250/clock_init.h | 149 ++++++++ board/samsung/smdk5250/setup.h | 715 ++++++++++++++++++++--------------- 3 files changed, 1138 insertions(+), 440 deletions(-) create mode 100644 board/samsung/smdk5250/clock_init.h
diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c index 305842d..c009ae5 100644 --- a/board/samsung/smdk5250/clock_init.c +++ b/board/samsung/smdk5250/clock_init.c @@ -22,181 +22,645 @@ * MA 02111-1307 USA */
+#include <common.h> #include <config.h> -#include <version.h> #include <asm/io.h> +#include <asm/arch/clk.h> #include <asm/arch/clock.h> -#include <asm/arch/cpu.h> -#include <asm/arch/gpio.h> +#include <asm/arch/spl.h> + +#include "clock_init.h" #include "setup.h"
-void system_clock_init() +DECLARE_GLOBAL_DATA_PTR; + +struct arm_clk_ratios arm_clk_ratios[] = { + { + .arm_freq_mhz = 600, + + .apll_mdiv = 0xc8, + .apll_pdiv = 0x4, + .apll_sdiv = 0x1, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x2, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x1, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 800, + + .apll_mdiv = 0x64, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x3, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x2, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1000, + + .apll_mdiv = 0x7d, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x4, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x2, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1200, + + .apll_mdiv = 0x96, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x5, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x3, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1400, + + .apll_mdiv = 0xaf, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x6, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x3, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1700, + + .apll_mdiv = 0x1a9, + .apll_pdiv = 0x6, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x6, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x3, + .arm_ratio = 0x0, + } +}; +struct mem_timings mem_timings[] = { + { + .mem_manuf = MEM_MANUF_ELPIDA, + .mem_type = DDR_MODE_DDR3, + .frequency_mhz = 800, + .mpll_mdiv = 0xc8, + .mpll_pdiv = 0x3, + .mpll_sdiv = 0x0, + .cpll_mdiv = 0xde, + .cpll_pdiv = 0x4, + .cpll_sdiv = 0x2, + .gpll_mdiv = 0x215, + .gpll_pdiv = 0xc, + .gpll_sdiv = 0x1, + .epll_mdiv = 0x60, + .epll_pdiv = 0x3, + .epll_sdiv = 0x3, + .vpll_mdiv = 0x96, + .vpll_pdiv = 0x3, + .vpll_sdiv = 0x2, + + .bpll_mdiv = 0x64, + .bpll_pdiv = 0x3, + .bpll_sdiv = 0x0, + .pclk_cdrex_ratio = 0x5, + .direct_cmd_msr = { + 0x00020018, 0x00030000, 0x00010042, 0x00000d70 + }, + .timing_ref = 0x000000bb, + .timing_row = 0x8c36650e, + .timing_data = 0x3630580b, + .timing_power = 0x41000a44, + .phy0_dqs = 0x08080808, + .phy1_dqs = 0x08080808, + .phy0_dq = 0x08080808, + .phy1_dq = 0x08080808, + .phy0_tFS = 0x4, + .phy1_tFS = 0x4, + .phy0_pulld_dqs = 0xf, + .phy1_pulld_dqs = 0xf, + + .lpddr3_ctrl_phy_reset = 0x1, + .ctrl_start_point = 0x10, + .ctrl_inc = 0x10, + .ctrl_start = 0x1, + .ctrl_dll_on = 0x1, + .ctrl_ref = 0x8, + + .ctrl_force = 0x1a, + .ctrl_rdlat = 0x0b, + .ctrl_bstlen = 0x08, + + .fp_resync = 0x8, + .iv_size = 0x7, + .dfi_init_start = 1, + .aref_en = 1, + + .rd_fetch = 0x3, + + .zq_mode_dds = 0x7, + .zq_mode_term = 0x1, + .zq_mode_noterm = 0, + + /* + * Dynamic Clock: Always Running + * Memory Burst length: 8 + * Number of chips: 1 + * Memory Bus width: 32 bit + * Memory Type: DDR3 + * Additional Latancy for PLL: 0 Cycle + */ + .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE | + DMC_MEMCONTROL_DPWRDN_DISABLE | + DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE | + DMC_MEMCONTROL_TP_DISABLE | + DMC_MEMCONTROL_DSREF_ENABLE | + DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) | + DMC_MEMCONTROL_MEM_TYPE_DDR3 | + DMC_MEMCONTROL_MEM_WIDTH_32BIT | + DMC_MEMCONTROL_NUM_CHIP_1 | + DMC_MEMCONTROL_BL_8 | + DMC_MEMCONTROL_PZQ_DISABLE | + DMC_MEMCONTROL_MRR_BYTE_7_0, + .memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED | + DMC_MEMCONFIGx_CHIP_COL_10 | + DMC_MEMCONFIGx_CHIP_ROW_15 | + DMC_MEMCONFIGx_CHIP_BANK_8, + .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40), + .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80), + .prechconfig_tp_cnt = 0xff, + .dpwrdn_cyc = 0xff, + .dsref_cyc = 0xffff, + .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE | + DMC_CONCONTROL_TIMEOUT_LEVEL0 | + DMC_CONCONTROL_RD_FETCH_DISABLE | + DMC_CONCONTROL_EMPTY_DISABLE | + DMC_CONCONTROL_AREF_EN_DISABLE | + DMC_CONCONTROL_IO_PD_CON_DISABLE, + .dmc_channels = 2, + .chips_per_channel = 2, + .chips_to_configure = 1, + .send_zq_init = 1, + .impedance = IMP_OUTPUT_DRV_30_OHM, + .gate_leveling_enable = 0, + }, { + .mem_manuf = MEM_MANUF_SAMSUNG, + .mem_type = DDR_MODE_DDR3, + .frequency_mhz = 800, + .mpll_mdiv = 0xc8, + .mpll_pdiv = 0x3, + .mpll_sdiv = 0x0, + .cpll_mdiv = 0xde, + .cpll_pdiv = 0x4, + .cpll_sdiv = 0x2, + .gpll_mdiv = 0x215, + .gpll_pdiv = 0xc, + .gpll_sdiv = 0x1, + .epll_mdiv = 0x60, + .epll_pdiv = 0x3, + .epll_sdiv = 0x3, + .vpll_mdiv = 0x96, + .vpll_pdiv = 0x3, + .vpll_sdiv = 0x2, + + .bpll_mdiv = 0x64, + .bpll_pdiv = 0x3, + .bpll_sdiv = 0x0, + .pclk_cdrex_ratio = 0x5, + .direct_cmd_msr = { + 0x00020018, 0x00030000, 0x00010000, 0x00000d70 + }, + .timing_ref = 0x000000bb, + .timing_row = 0x8c36650e, + .timing_data = 0x3630580b, + .timing_power = 0x41000a44, + .phy0_dqs = 0x08080808, + .phy1_dqs = 0x08080808, + .phy0_dq = 0x08080808, + .phy1_dq = 0x08080808, + .phy0_tFS = 0x8, + .phy1_tFS = 0x8, + .phy0_pulld_dqs = 0xf, + .phy1_pulld_dqs = 0xf, + + .lpddr3_ctrl_phy_reset = 0x1, + .ctrl_start_point = 0x10, + .ctrl_inc = 0x10, + .ctrl_start = 0x1, + .ctrl_dll_on = 0x1, + .ctrl_ref = 0x8, + + .ctrl_force = 0x1a, + .ctrl_rdlat = 0x0b, + .ctrl_bstlen = 0x08, + + .fp_resync = 0x8, + .iv_size = 0x7, + .dfi_init_start = 1, + .aref_en = 1, + + .rd_fetch = 0x3, + + .zq_mode_dds = 0x5, + .zq_mode_term = 0x1, + .zq_mode_noterm = 1, + + /* + * Dynamic Clock: Always Running + * Memory Burst length: 8 + * Number of chips: 1 + * Memory Bus width: 32 bit + * Memory Type: DDR3 + * Additional Latancy for PLL: 0 Cycle + */ + .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE | + DMC_MEMCONTROL_DPWRDN_DISABLE | + DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE | + DMC_MEMCONTROL_TP_DISABLE | + DMC_MEMCONTROL_DSREF_ENABLE | + DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) | + DMC_MEMCONTROL_MEM_TYPE_DDR3 | + DMC_MEMCONTROL_MEM_WIDTH_32BIT | + DMC_MEMCONTROL_NUM_CHIP_1 | + DMC_MEMCONTROL_BL_8 | + DMC_MEMCONTROL_PZQ_DISABLE | + DMC_MEMCONTROL_MRR_BYTE_7_0, + .memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED | + DMC_MEMCONFIGx_CHIP_COL_10 | + DMC_MEMCONFIGx_CHIP_ROW_15 | + DMC_MEMCONFIGx_CHIP_BANK_8, + .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40), + .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80), + .prechconfig_tp_cnt = 0xff, + .dpwrdn_cyc = 0xff, + .dsref_cyc = 0xffff, + .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE | + DMC_CONCONTROL_TIMEOUT_LEVEL0 | + DMC_CONCONTROL_RD_FETCH_DISABLE | + DMC_CONCONTROL_EMPTY_DISABLE | + DMC_CONCONTROL_AREF_EN_DISABLE | + DMC_CONCONTROL_IO_PD_CON_DISABLE, + .dmc_channels = 2, + .chips_per_channel = 2, + .chips_to_configure = 1, + .send_zq_init = 1, + .impedance = IMP_OUTPUT_DRV_40_OHM, + .gate_leveling_enable = 1, + } +}; + +/** + * Get the required memory type and speed (SPL version). + * + * In SPL we have no device tree, so we use the machine parameters + * + * @param mem_type Returns memory type + * @param frequency_mhz Returns memory speed in MHz + * @param arm_freq Returns ARM clock speed in MHz + * @param mem_manuf Return Memory Manufacturer name + * @return 0 if all ok + */ +static int clock_get_mem_selection(enum ddr_mode *mem_type, + unsigned *frequency_mhz, unsigned *arm_freq, + enum mem_manuf *mem_manuf) { - struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + struct spl_machine_param *params;
- /* - * MUX_APLL_SEL[0]: FINPLL = 0 - * MUX_CPU_SEL[6]: MOUTAPLL = 0 - * MUX_HPM_SEL[20]: MOUTAPLL = 0 - */ - writel(0x0, &clk->src_cpu); + params = spl_get_machine_params(); + *mem_type = params->mem_type; + *frequency_mhz = params->frequency_mhz; + *arm_freq = params->arm_freq_mhz; + *mem_manuf = params->mem_manuf;
- /* MUX_MPLL_SEL[8]: FINPLL = 0 */ - writel(0x0, &clk->src_core1); + return 0; +}
- /* - * VPLLSRC_SEL[0]: FINPLL = 0 - * MUX_{CPLL[8]}|{EPLL[12]}|{VPLL[16]}_SEL: FINPLL = 0 - */ - writel(0x0, &clk->src_top2); +/* Get the ratios for setting ARM clock */ +struct arm_clk_ratios *get_arm_ratios(void) +{ + struct arm_clk_ratios *arm_ratio; + enum ddr_mode mem_type; + enum mem_manuf mem_manuf; + unsigned frequency_mhz, arm_freq; + int i; + + if (clock_get_mem_selection(&mem_type, &frequency_mhz, + &arm_freq, &mem_manuf)) + ; + for (i = 0, arm_ratio = arm_clk_ratios; i < ARRAY_SIZE(arm_clk_ratios); + i++, arm_ratio++) { + if (arm_ratio->arm_freq_mhz == arm_freq) + return arm_ratio; + } + + /* will hang if failed to find clock ratio */ + while (1) + ; + + return NULL; +}
- /* MUX_BPLL_SEL[0]: FINPLL = 0 */ - writel(0x0, &clk->src_cdrex); +struct mem_timings *clock_get_mem_timings(void) +{ + struct mem_timings *mem; + enum ddr_mode mem_type; + enum mem_manuf mem_manuf; + unsigned frequency_mhz, arm_freq; + int i; + + if (!clock_get_mem_selection(&mem_type, &frequency_mhz, + &arm_freq, &mem_manuf)) { + for (i = 0, mem = mem_timings; i < ARRAY_SIZE(mem_timings); + i++, mem++) { + if (mem->mem_type == mem_type && + mem->frequency_mhz == frequency_mhz && + mem->mem_manuf == mem_manuf) + return mem; + } + } + + /* will hang if failed to find memory timings */ + while (1) + ; + + return NULL; +}
- /* MUX_ACLK_* Clock Selection */ - writel(CLK_SRC_TOP0_VAL, &clk->src_top0); +void system_clock_init() +{ + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + struct mem_timings *mem; + struct arm_clk_ratios *arm_clk_ratio; + u32 val, tmp; + + mem = clock_get_mem_timings(); + arm_clk_ratio = get_arm_ratios(); + + clrbits_le32(&clk->src_cpu, MUX_APLL_SEL_MASK); + do { + val = readl(&clk->mux_stat_cpu); + } while ((val | MUX_APLL_SEL_MASK) != val); + + clrbits_le32(&clk->src_core1, MUX_MPLL_SEL_MASK); + do { + val = readl(&clk->mux_stat_core1); + } while ((val | MUX_MPLL_SEL_MASK) != val); + + clrbits_le32(&clk->src_core1, MUX_CPLL_SEL_MASK); + clrbits_le32(&clk->src_core1, MUX_EPLL_SEL_MASK); + clrbits_le32(&clk->src_core1, MUX_VPLL_SEL_MASK); + clrbits_le32(&clk->src_core1, MUX_GPLL_SEL_MASK); + tmp = MUX_CPLL_SEL_MASK | MUX_EPLL_SEL_MASK | MUX_VPLL_SEL_MASK + | MUX_GPLL_SEL_MASK; + do { + val = readl(&clk->mux_stat_top2); + } while ((val | tmp) != val); + + clrbits_le32(&clk->src_cdrex, MUX_BPLL_SEL_MASK); + do { + val = readl(&clk->mux_stat_cdrex); + } while ((val | MUX_BPLL_SEL_MASK) != val);
- /* MUX_ACLK_* Clock Selection */ - writel(CLK_SRC_TOP1_VAL, &clk->src_top1); + /* PLL locktime */ + writel(APLL_LOCK_VAL, &clk->apll_lock);
- /* MUX_ACLK_* Clock Selection */ - writel(CLK_SRC_TOP3_VAL, &clk->src_top3); + writel(MPLL_LOCK_VAL, &clk->mpll_lock);
- /* MUX_PWI_SEL[19:16]: SCLKMPLL = 6 */ - writel(CLK_SRC_CORE0_VAL, &clk->src_core0); + writel(BPLL_LOCK_VAL, &clk->bpll_lock);
- /* MUX_ATCLK_LEX[0]: ACLK_200 = 0 */ - writel(CLK_SRC_LEX_VAL, &clk->src_lex); + writel(CPLL_LOCK_VAL, &clk->cpll_lock);
- /* UART [0-5]: SCLKMPLL = 6 */ - writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); + writel(GPLL_LOCK_VAL, &clk->gpll_lock);
- /* Set Clock Ratios */ - writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0); + writel(EPLL_LOCK_VAL, &clk->epll_lock); + + writel(VPLL_LOCK_VAL, &clk->vpll_lock); + + writel(CLK_REG_DISABLE, &clk->pll_div2_sel); + + writel(MUX_HPM_SEL_MASK, &clk->src_cpu); + do { + val = readl(&clk->mux_stat_cpu); + } while ((val | HPM_SEL_SCLK_MPLL) != val); + + val = arm_clk_ratio->arm2_ratio << 28 + | arm_clk_ratio->apll_ratio << 24 + | arm_clk_ratio->pclk_dbg_ratio << 20 + | arm_clk_ratio->atb_ratio << 16 + | arm_clk_ratio->periph_ratio << 12 + | arm_clk_ratio->acp_ratio << 8 + | arm_clk_ratio->cpud_ratio << 4 + | arm_clk_ratio->arm_ratio; + writel(val, &clk->div_cpu0); + do { + val = readl(&clk->div_stat_cpu0); + } while (0 != val);
- /* Set COPY and HPM Ratio */ writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); + do { + val = readl(&clk->div_stat_cpu1); + } while (0 != val);
- /* CORED_RATIO, COREP_RATIO */ - writel(CLK_DIV_CORE0_VAL, &clk->div_core0); + /* Set APLL */ + writel(APLL_CON1_VAL, &clk->apll_con1); + val = set_pll(arm_clk_ratio->apll_mdiv, arm_clk_ratio->apll_pdiv, + arm_clk_ratio->apll_sdiv); + writel(val, &clk->apll_con0); + while (readl(&clk->apll_con0) & APLL_CON0_LOCKED) + ;
- /* PWI_RATIO[11:8], DVSEM_RATIO[22:16], DPM_RATIO[24:20] */ - writel(CLK_DIV_CORE1_VAL, &clk->div_core1); + /* Set MPLL */ + writel(MPLL_CON1_VAL, &clk->mpll_con1); + val = set_pll(mem->mpll_mdiv, mem->mpll_pdiv, mem->mpll_sdiv); + writel(val, &clk->mpll_con0); + while (readl(&clk->mpll_con0) & MPLL_CON0_LOCKED) + ;
- /* ACLK_*_RATIO */ - writel(CLK_DIV_TOP0_VAL, &clk->div_top0); + /* Set BPLL */ + writel(BPLL_CON1_VAL, &clk->bpll_con1); + val = set_pll(mem->bpll_mdiv, mem->bpll_pdiv, mem->bpll_sdiv); + writel(val, &clk->bpll_con0); + while (readl(&clk->bpll_con0) & BPLL_CON0_LOCKED) + ;
- /* ACLK_*_RATIO */ - writel(CLK_DIV_TOP1_VAL, &clk->div_top1); + /* Set CPLL */ + writel(CPLL_CON1_VAL, &clk->cpll_con1); + val = set_pll(mem->cpll_mdiv, mem->cpll_pdiv, mem->cpll_sdiv); + writel(val, &clk->cpll_con0); + while (readl(&clk->cpll_con0) & CPLL_CON0_LOCKED) + ; + + /* Set GPLL */ + writel(GPLL_CON1_VAL, &clk->gpll_con1); + val = set_pll(mem->gpll_mdiv, mem->gpll_pdiv, mem->gpll_sdiv); + writel(val, &clk->gpll_con0); + while (readl(&clk->gpll_con0) & GPLL_CON0_LOCKED) + ;
- /* CDREX Ratio */ - writel(CLK_DIV_CDREX_INIT_VAL, &clk->div_cdrex); + /* Set EPLL */ + writel(EPLL_CON2_VAL, &clk->epll_con2); + writel(EPLL_CON1_VAL, &clk->epll_con1); + val = set_pll(mem->epll_mdiv, mem->epll_pdiv, mem->epll_sdiv); + writel(val, &clk->epll_con0); + while (readl(&clk->epll_con0) & EPLL_CON0_LOCKED) + ;
- /* MCLK_EFPHY_RATIO[3:0] */ - writel(CLK_DIV_CDREX2_VAL, &clk->div_cdrex2); + /* Set VPLL */ + writel(VPLL_CON2_VAL, &clk->vpll_con2); + writel(VPLL_CON1_VAL, &clk->vpll_con1); + val = set_pll(mem->vpll_mdiv, mem->vpll_pdiv, mem->vpll_sdiv); + writel(val, &clk->vpll_con0); + while (readl(&clk->vpll_con0) & VPLL_CON0_LOCKED) + ;
- /* {PCLK[4:6]|ATCLK[10:8]}_RATIO */ - writel(CLK_DIV_LEX_VAL, &clk->div_lex); + writel(CLK_SRC_CORE0_VAL, &clk->src_core0); + writel(CLK_DIV_CORE0_VAL, &clk->div_core0); + while (readl(&clk->div_stat_core0) != 0) + ;
- /* PCLK_R0X_RATIO[3:0] */ - writel(CLK_DIV_R0X_VAL, &clk->div_r0x); + writel(CLK_DIV_CORE1_VAL, &clk->div_core1); + while (readl(&clk->div_stat_core1) != 0) + ;
- /* PCLK_R1X_RATIO[3:0] */ - writel(CLK_DIV_R1X_VAL, &clk->div_r1x); + writel(CLK_DIV_SYSRGT_VAL, &clk->div_sysrgt); + while (readl(&clk->div_stat_sysrgt) != 0) + ;
- /* SATA[24]: SCLKMPLL=0, MMC[0-4]: SCLKMPLL = 6 */ - writel(CLK_SRC_FSYS_VAL, &clk->src_fsys); + writel(CLK_DIV_ACP_VAL, &clk->div_acp); + while (readl(&clk->div_stat_acp) != 0) + ;
- /* UART[0-4] */ - writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0); + writel(CLK_DIV_SYSLFT_VAL, &clk->div_syslft); + while (readl(&clk->div_stat_syslft) != 0) + ;
- /* PWM_RATIO[3:0] */ - writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3); + writel(CLK_SRC_TOP0_VAL, &clk->src_top0); + writel(CLK_SRC_TOP1_VAL, &clk->src_top1); + writel(TOP2_VAL, &clk->src_top2); + writel(CLK_SRC_TOP3_VAL, &clk->src_top3);
- /* SATA_RATIO, USB_DRD_RATIO */ - writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); + writel(CLK_DIV_TOP0_VAL, &clk->div_top0); + while (readl(&clk->div_stat_top0)) + ;
- /* MMC[0-1] */ - writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1); + writel(CLK_DIV_TOP1_VAL, &clk->div_top1); + while (readl(&clk->div_stat_top1)) + ;
- /* MMC[2-3] */ - writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2); + writel(CLK_SRC_LEX_VAL, &clk->src_lex); + while (1) { + val = readl(&clk->mux_stat_lex); + if (val == (val | 1)) + break; + }
- /* MMC[4] */ - writel(CLK_DIV_FSYS3_VAL, &clk->div_fsys3); + writel(CLK_DIV_LEX_VAL, &clk->div_lex); + while (readl(&clk->div_stat_lex)) + ;
- /* ACLK|PLCK_ACP_RATIO */ - writel(CLK_DIV_ACP_VAL, &clk->div_acp); + writel(CLK_DIV_R0X_VAL, &clk->div_r0x); + while (readl(&clk->div_stat_r0x)) + ;
- /* ISPDIV0_RATIO, ISPDIV1_RATIO */ - writel(CLK_DIV_ISP0_VAL, &clk->div_isp0); + writel(CLK_DIV_R0X_VAL, &clk->div_r0x); + while (readl(&clk->div_stat_r0x)) + ;
- /* MCUISPDIV0_RATIO, MCUISPDIV1_RATIO */ - writel(CLK_DIV_ISP1_VAL, &clk->div_isp1); + writel(CLK_DIV_R1X_VAL, &clk->div_r1x); + while (readl(&clk->div_stat_r1x)) + ;
- /* MPWMDIV_RATIO */ - writel(CLK_DIV_ISP2_VAL, &clk->div_isp2); + writel(CLK_REG_DISABLE, &clk->src_cdrex);
- /* PLL locktime */ - writel(APLL_LOCK_VAL, &clk->apll_lock); + writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex); + while (readl(&clk->div_stat_cdrex)) + ;
- writel(MPLL_LOCK_VAL, &clk->mpll_lock); + val = readl(&clk->src_cpu); + val |= CLK_SRC_CPU_VAL; + writel(val, &clk->src_cpu);
- writel(BPLL_LOCK_VAL, &clk->bpll_lock); + val = readl(&clk->src_top2); + val |= CLK_SRC_TOP2_VAL; + writel(val, &clk->src_top2);
- writel(CPLL_LOCK_VAL, &clk->cpll_lock); + val = readl(&clk->src_core1); + val |= CLK_SRC_CORE1_VAL; + writel(val, &clk->src_core1);
- writel(EPLL_LOCK_VAL, &clk->epll_lock); + writel(CLK_SRC_FSYS0_VAL, &clk->src_fsys); + writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); + while (readl(&clk->div_stat_fsys0)) + ; + + writel(CLK_REG_DISABLE, &clk->clkout_cmu_cpu); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_core); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_acp); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_top); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_lex); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_r0x); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_r1x); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_cdrex);
- writel(VPLL_LOCK_VAL, &clk->vpll_lock); + writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); + writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0);
- sdelay(0x10000); + writel(CLK_SRC_PERIC1_VAL, &clk->src_peric1); + writel(CLK_DIV_PERIC1_VAL, &clk->div_peric1); + writel(CLK_DIV_PERIC2_VAL, &clk->div_peric2); + writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3);
- /* Set APLL */ - writel(APLL_CON1_VAL, &clk->apll_con1); - writel(APLL_CON0_VAL, &clk->apll_con0); - sdelay(0x30000); + writel(SCLK_SRC_ISP_VAL, &clk->sclk_src_isp); + writel(SCLK_DIV_ISP_VAL, &clk->sclk_div_isp); + writel(CLK_DIV_ISP0_VAL, &clk->div_isp0); + writel(CLK_DIV_ISP1_VAL, &clk->div_isp1); + writel(CLK_DIV_ISP2_VAL, &clk->div_isp2);
- /* Set MPLL */ - writel(MPLL_CON1_VAL, &clk->mpll_con1); - writel(MPLL_CON0_VAL, &clk->mpll_con0); - sdelay(0x30000); - writel(BPLL_CON1_VAL, &clk->bpll_con1); - writel(BPLL_CON0_VAL, &clk->bpll_con0); - sdelay(0x30000); + /* FIMD1 SRC CLK SELECTION */ + writel(CLK_SRC_DISP1_0_VAL, &clk->src_disp1_0);
- /* Set CPLL */ - writel(CPLL_CON1_VAL, &clk->cpll_con1); - writel(CPLL_CON0_VAL, &clk->cpll_con0); - sdelay(0x30000); + val = MMC2_PRE_RATIO_VAL << MMC2_PRE_RATIO_OFFSET + | MMC2_RATIO_VAL << MMC2_RATIO_OFFSET + | MMC3_PRE_RATIO_VAL << MMC3_PRE_RATIO_OFFSET + | MMC3_RATIO_VAL << MMC3_RATIO_OFFSET; + writel(val, &clk->div_fsys2); +}
- /* Set EPLL */ - writel(EPLL_CON2_VAL, &clk->epll_con2); - writel(EPLL_CON1_VAL, &clk->epll_con1); - writel(EPLL_CON0_VAL, &clk->epll_con0); - sdelay(0x30000); +void clock_init_dp_clock(void) +{ + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
- /* Set VPLL */ - writel(VPLL_CON2_VAL, &clk->vpll_con2); - writel(VPLL_CON1_VAL, &clk->vpll_con1); - writel(VPLL_CON0_VAL, &clk->vpll_con0); - sdelay(0x30000); + /* DP clock enable */ + setbits_le32(&clk->gate_ip_disp1, CLK_GATE_DP1_ALLOW);
- /* 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_MPLL_SEL[8]: MOUTMPLLFOUT = 1 */ - writel(CLK_SRC_CORE1_VAL, &clk->src_core1); - - /* MUX_BPLL_SEL[0]: FOUTBPLL = 1*/ - writel(CLK_SRC_CDREX_INIT_VAL, &clk->src_cdrex); - - /* - * 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); + /* We run DP at 267 Mhz */ + setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1); } diff --git a/board/samsung/smdk5250/clock_init.h b/board/samsung/smdk5250/clock_init.h new file mode 100644 index 0000000..f751bcb --- /dev/null +++ b/board/samsung/smdk5250/clock_init.h @@ -0,0 +1,149 @@ +/* + * Clock initialization routines + * + * Copyright (c) 2011 The Chromium OS Authors. + * + * 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 __EXYNOS_CLOCK_INIT_H +#define __EXYNOS_CLOCK_INIT_H + +enum { + MEM_TIMINGS_MSR_COUNT = 4, +}; + +/* These are the ratio's for configuring ARM clock */ +struct arm_clk_ratios { + unsigned arm_freq_mhz; /* Frequency of ARM core in MHz */ + + unsigned apll_mdiv; + unsigned apll_pdiv; + unsigned apll_sdiv; + + unsigned arm2_ratio; + unsigned apll_ratio; + unsigned pclk_dbg_ratio; + unsigned atb_ratio; + unsigned periph_ratio; + unsigned acp_ratio; + unsigned cpud_ratio; + unsigned arm_ratio; +}; + +/* These are the memory timings for a particular memory type and speed */ +struct mem_timings { + enum mem_manuf mem_manuf; /* Memory manufacturer */ + enum ddr_mode mem_type; /* Memory type */ + unsigned frequency_mhz; /* Frequency of memory in MHz */ + + /* Here follow the timing parameters for the selected memory */ + unsigned apll_mdiv; + unsigned apll_pdiv; + unsigned apll_sdiv; + unsigned mpll_mdiv; + unsigned mpll_pdiv; + unsigned mpll_sdiv; + unsigned cpll_mdiv; + unsigned cpll_pdiv; + unsigned cpll_sdiv; + unsigned gpll_mdiv; + unsigned gpll_pdiv; + unsigned gpll_sdiv; + unsigned epll_mdiv; + unsigned epll_pdiv; + unsigned epll_sdiv; + unsigned vpll_mdiv; + unsigned vpll_pdiv; + unsigned vpll_sdiv; + unsigned bpll_mdiv; + unsigned bpll_pdiv; + unsigned bpll_sdiv; + unsigned pclk_cdrex_ratio; + unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT]; + + unsigned timing_ref; + unsigned timing_row; + unsigned timing_data; + unsigned timing_power; + + /* DQS, DQ, DEBUG offsets */ + unsigned phy0_dqs; + unsigned phy1_dqs; + unsigned phy0_dq; + unsigned phy1_dq; + unsigned phy0_tFS; + unsigned phy1_tFS; + unsigned phy0_pulld_dqs; + unsigned phy1_pulld_dqs; + + unsigned lpddr3_ctrl_phy_reset; + unsigned ctrl_start_point; + unsigned ctrl_inc; + unsigned ctrl_start; + unsigned ctrl_dll_on; + unsigned ctrl_ref; + + unsigned ctrl_force; + unsigned ctrl_rdlat; + unsigned ctrl_bstlen; + + unsigned fp_resync; + unsigned iv_size; + unsigned dfi_init_start; + unsigned aref_en; + + unsigned rd_fetch; + + unsigned zq_mode_dds; + unsigned zq_mode_term; + unsigned zq_mode_noterm; /* 1 to allow termination disable */ + + unsigned memcontrol; + unsigned memconfig; + + unsigned membaseconfig0; + unsigned membaseconfig1; + unsigned prechconfig_tp_cnt; + unsigned dpwrdn_cyc; + unsigned dsref_cyc; + unsigned concontrol; + /* Channel and Chip Selection */ + uint8_t dmc_channels; /* number of memory channels */ + uint8_t chips_per_channel; /* number of chips per channel */ + uint8_t chips_to_configure; /* number of chips to configure */ + uint8_t send_zq_init; /* 1 to send this command */ + unsigned impedance; /* drive strength impedeance */ + uint8_t gate_leveling_enable; /* check gate leveling is enabled */ +}; + +/** + * Get the correct memory timings for our selected memory type and speed. + * + * This function can be called from SPL or the main U-Boot. + * + * @return pointer to the memory timings that we should use + */ +struct mem_timings *clock_get_mem_timings(void); + +/* + * Initialize clock for the device + */ +void system_clock_init(void); +#endif diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h index 1276fd3..bae0faf 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -1,5 +1,5 @@ /* - * Machine Specific Values for SMDK5250 board based on S5PC520 + * Machine Specific Values for SMDK5250 board based on EXYNOS5 * * Copyright (C) 2012 Samsung Electronics * @@ -26,12 +26,6 @@ #define _SMDK5250_SETUP_H
#include <config.h> -#include <version.h> -#include <asm/arch/cpu.h> - -/* GPIO Offsets for UART: GPIO Contol Register */ -#define EXYNOS5_GPIO_A0_CON_OFFSET 0x0 -#define EXYNOS5_GPIO_A1_CON_OFFSET 0x20
/* TZPC : Register Offsets */ #define TZPC0_BASE 0x10100000 @@ -45,295 +39,423 @@ #define TZPC8_BASE 0x10180000 #define TZPC9_BASE 0x10190000
-/* CLK_SRC_CPU */ -/* 0 = MOUTAPLL, 1 = SCLKMPLL */ -#define MUX_HPM_SEL 0 -#define MUX_CPU_SEL 0 -#define MUX_APLL_SEL 1 -#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL << 20) \ - | (MUX_CPU_SEL << 16) \ - | (MUX_APLL_SEL)) - -/* CLK_DIV_CPU0 */ -#define ARM2_RATIO 0x0 -#define APLL_RATIO 0x1 -#define PCLK_DBG_RATIO 0x1 -#define ATB_RATIO 0x4 -#define PERIPH_RATIO 0x7 -#define ACP_RATIO 0x7 -#define CPUD_RATIO 0x2 -#define ARM_RATIO 0x0 -#define CLK_DIV_CPU0_VAL ((ARM2_RATIO << 28) \ - | (APLL_RATIO << 24) \ - | (PCLK_DBG_RATIO << 20) \ - | (ATB_RATIO << 16) \ - | (PERIPH_RATIO << 12) \ - | (ACP_RATIO << 8) \ - | (CPUD_RATIO << 4) \ - | (ARM_RATIO)) - -/* CLK_DIV_CPU1 */ -#define HPM_RATIO 0x4 -#define COPY_RATIO 0x0 -#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) \ - | (COPY_RATIO)) - -#define APLL_MDIV 0x7D -#define APLL_PDIV 0x3 -#define APLL_SDIV 0x0 - -#define MPLL_MDIV 0x64 -#define MPLL_PDIV 0x3 -#define MPLL_SDIV 0x0 - -#define CPLL_MDIV 0x96 -#define CPLL_PDIV 0x4 -#define CPLL_SDIV 0x0 - -/* APLL_CON1 */ +/* APLL_CON1 */ #define APLL_CON1_VAL (0x00203800)
-/* MPLL_CON1 */ -#define MPLL_CON1_VAL (0x00203800) +/* MPLL_CON1 */ +#define MPLL_CON1_VAL (0x00203800)
-/* CPLL_CON1 */ +/* CPLL_CON1 */ #define CPLL_CON1_VAL (0x00203800)
-#define EPLL_MDIV 0x60 -#define EPLL_PDIV 0x3 -#define EPLL_SDIV 0x3 +/* GPLL_CON1 */ +#define GPLL_CON1_VAL (0x00203800)
+/* EPLL_CON1, CON2 */ #define EPLL_CON1_VAL 0x00000000 #define EPLL_CON2_VAL 0x00000080
-#define VPLL_MDIV 0x96 -#define VPLL_PDIV 0x3 -#define VPLL_SDIV 0x2 - +/* VPLL_CON1, CON2 */ #define VPLL_CON1_VAL 0x00000000 #define VPLL_CON2_VAL 0x00000080
-#define BPLL_MDIV 0x215 -#define BPLL_PDIV 0xC -#define BPLL_SDIV 0x1 - +/* BPLL_CON1 */ #define BPLL_CON1_VAL 0x00203800
/* 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 CPLL_CON0_VAL set_pll(CPLL_MDIV, CPLL_PDIV, CPLL_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_CPU */ +/* 0 = MOUTAPLL, 1 = SCLKMPLL */ +#define MUX_HPM_SEL 0 +#define MUX_CPU_SEL 0 +#define MUX_APLL_SEL 1 + +#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL << 20) \ + | (MUX_CPU_SEL << 16) \ + | (MUX_APLL_SEL)) + +/* MEMCONTROL register bit fields */ +#define DMC_MEMCONTROL_CLK_STOP_DISABLE (0 << 0) +#define DMC_MEMCONTROL_DPWRDN_DISABLE (0 << 1) +#define DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE (0 << 2) +#define DMC_MEMCONTROL_TP_DISABLE (0 << 4) +#define DMC_MEMCONTROL_DSREF_DISABLE (0 << 5) +#define DMC_MEMCONTROL_DSREF_ENABLE (1 << 5) +#define DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(x) (x << 6) + +#define DMC_MEMCONTROL_MEM_TYPE_LPDDR3 (7 << 8) +#define DMC_MEMCONTROL_MEM_TYPE_DDR3 (6 << 8) +#define DMC_MEMCONTROL_MEM_TYPE_LPDDR2 (5 << 8) + +#define DMC_MEMCONTROL_MEM_WIDTH_32BIT (2 << 12) + +#define DMC_MEMCONTROL_NUM_CHIP_1 (0 << 16) +#define DMC_MEMCONTROL_NUM_CHIP_2 (1 << 16) + +#define DMC_MEMCONTROL_BL_8 (3 << 20) +#define DMC_MEMCONTROL_BL_4 (2 << 20) + +#define DMC_MEMCONTROL_PZQ_DISABLE (0 << 24) + +#define DMC_MEMCONTROL_MRR_BYTE_7_0 (0 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_15_8 (1 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_23_16 (2 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_31_24 (3 << 25) + +/* MEMCONFIG0 register bit fields */ +#define DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED (1 << 12) +#define DMC_MEMCONFIGx_CHIP_COL_10 (3 << 8) +#define DMC_MEMCONFIGx_CHIP_ROW_14 (2 << 4) +#define DMC_MEMCONFIGx_CHIP_ROW_15 (3 << 4) +#define DMC_MEMCONFIGx_CHIP_BANK_8 (3 << 0) + +#define DMC_MEMBASECONFIGx_CHIP_BASE(x) (x << 16) +#define DMC_MEMBASECONFIGx_CHIP_MASK(x) (x << 0) +#define DMC_MEMBASECONFIG_VAL(x) ( \ + DMC_MEMBASECONFIGx_CHIP_BASE(x) | \ + DMC_MEMBASECONFIGx_CHIP_MASK(0x780) \ +) + +#define DMC_MEMBASECONFIG0_VAL DMC_MEMBASECONFIG_VAL(0x40) +#define DMC_MEMBASECONFIG1_VAL DMC_MEMBASECONFIG_VAL(0x80) + +#define DMC_PRECHCONFIG_VAL 0xFF000000 +#define DMC_PWRDNCONFIG_VAL 0xFFFF00FF + +#define DMC_CONCONTROL_RESET_VAL 0x0FFF0000 +#define DFI_INIT_START (1 << 28) +#define EMPTY (1 << 8) +#define AREF_EN (1 << 5) + +#define DFI_INIT_COMPLETE_CHO (1 << 2) +#define DFI_INIT_COMPLETE_CH1 (1 << 3) + +#define RDLVL_COMPLETE_CHO (1 << 14) +#define RDLVL_COMPLETE_CH1 (1 << 15) + +#define CLK_STOP_EN (1 << 0) +#define DPWRDN_EN (1 << 1) +#define DSREF_EN (1 << 5) + +/* COJCONTROL register bit fields */ +#define DMC_CONCONTROL_IO_PD_CON_DISABLE (0 << 3) +#define DMC_CONCONTROL_AREF_EN_DISABLE (0 << 5) +#define DMC_CONCONTROL_EMPTY_DISABLE (0 << 8) +#define DMC_CONCONTROL_EMPTY_ENABLE (1 << 8) +#define DMC_CONCONTROL_RD_FETCH_DISABLE (0x0 << 12) +#define DMC_CONCONTROL_TIMEOUT_LEVEL0 (0xFFF << 16) +#define DMC_CONCONTROL_DFI_INIT_START_DISABLE (0 << 28) + +/* CLK_DIV_CPU0_VAL */ +#define CLK_DIV_CPU0_VAL ((ARM2_RATIO << 28) \ + | (APLL_RATIO << 24) \ + | (PCLK_DBG_RATIO << 20) \ + | (ATB_RATIO << 16) \ + | (PERIPH_RATIO << 12) \ + | (ACP_RATIO << 8) \ + | (CPUD_RATIO << 4) \ + | (ARM_RATIO)) + + +/* CLK_FSYS */ +#define CLK_SRC_FSYS0_VAL 0x66666 +#define CLK_DIV_FSYS0_VAL 0x0BB00000 + +/* CLK_DIV_CPU1 */ +#define HPM_RATIO 0x2 +#define COPY_RATIO 0x0 + +/* CLK_DIV_CPU1 = 0x00000003 */ +#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) \ + | (COPY_RATIO))
/* CLK_SRC_CORE0 */ -#define CLK_SRC_CORE0_VAL 0x00060000 +#define CLK_SRC_CORE0_VAL 0x00000000
/* CLK_SRC_CORE1 */ -#define CLK_SRC_CORE1_VAL 0x100 +#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 +#define CLK_DIV_CORE1_VAL 0x07070700 + +/* CLK_DIV_SYSRGT */ +#define CLK_DIV_SYSRGT_VAL 0x00000111 + +/* CLK_DIV_ACP */ +#define CLK_DIV_ACP_VAL 0x12 + +/* CLK_DIV_SYSLFT */ +#define CLK_DIV_SYSLFT_VAL 0x00000311
/* 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_CDREX2_RATIO 0x0 +#define ACLK_EFCON_RATIO 0x1 +#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 << 24) \ + | (C2C_CLK_400_RATIO << 6) \ + | (PCLK_CDREX_RATIO << 4) \ + | (ACLK_CDREX_RATIO))
-/* CLK_DIV_ACP */ -#define CLK_DIV_ACP_VAL 0x12 - -/* CLK_SRC_TOP0 */ -#define MUX_ACLK_300_GSCL_SEL 0x1 -#define MUX_ACLK_300_GSCL_MID_SEL 0x0 -#define MUX_ACLK_400_SEL 0x0 -#define MUX_ACLK_333_SEL 0x0 -#define MUX_ACLK_300_DISP1_SEL 0x1 -#define MUX_ACLK_300_DISP1_MID_SEL 0x0 -#define MUX_ACLK_200_SEL 0x0 -#define MUX_ACLK_166_SEL 0x0 -#define CLK_SRC_TOP0_VAL ((MUX_ACLK_300_GSCL_SEL << 25) \ - | (MUX_ACLK_300_GSCL_MID_SEL << 24) \ - | (MUX_ACLK_400_SEL << 20) \ - | (MUX_ACLK_333_SEL << 16) \ - | (MUX_ACLK_300_DISP1_SEL << 15) \ +/* CLK_SRC_TOP0 */ +#define MUX_ACLK_300_GSCL_SEL 0x0 +#define MUX_ACLK_300_GSCL_MID_SEL 0x0 +#define MUX_ACLK_400_G3D_MID_SEL 0x0 +#define MUX_ACLK_333_SEL 0x0 +#define MUX_ACLK_300_DISP1_SEL 0x0 +#define MUX_ACLK_300_DISP1_MID_SEL 0x0 +#define MUX_ACLK_200_SEL 0x0 +#define MUX_ACLK_166_SEL 0x0 +#define CLK_SRC_TOP0_VAL ((MUX_ACLK_300_GSCL_SEL << 25) \ + | (MUX_ACLK_300_GSCL_MID_SEL << 24) \ + | (MUX_ACLK_400_G3D_MID_SEL << 20) \ + | (MUX_ACLK_333_SEL << 16) \ + | (MUX_ACLK_300_DISP1_SEL << 15) \ | (MUX_ACLK_300_DISP1_MID_SEL << 14) \ - | (MUX_ACLK_200_SEL << 12) \ + | (MUX_ACLK_200_SEL << 12) \ | (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)) +/* CLK_SRC_TOP1 */ +#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 0x0 +#define MUX_ACLK_300_DISP1_MID1_SEL 0x0 +#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 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 0x2 +#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 0x5 +#define ACLK_166_RATIO 0x1 #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 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)) - -/* APLL_LOCK */ -#define APLL_LOCK_VAL (0x3E8) -/* MPLL_LOCK */ -#define MPLL_LOCK_VAL (0x2F1) -/* CPLL_LOCK */ -#define CPLL_LOCK_VAL (0x3E8) -/* EPLL_LOCK */ -#define EPLL_LOCK_VAL (0x2321) -/* VPLL_LOCK */ -#define VPLL_LOCK_VAL (0x2321) -/* BPLL_LOCK */ -#define BPLL_LOCK_VAL (0x3E8) +/* 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 0x2 + +#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 (0x546) +/* MPLL_LOCK */ +#define MPLL_LOCK_VAL (0x546) +/* CPLL_LOCK */ +#define CPLL_LOCK_VAL (0x546) +/* GPLL_LOCK */ +#define GPLL_LOCK_VAL (0x546) +/* EPLL_LOCK */ +#define EPLL_LOCK_VAL (0x3A98) +/* VPLL_LOCK */ +#define VPLL_LOCK_VAL (0x3A98) +/* BPLL_LOCK */ +#define BPLL_LOCK_VAL (0x546) + +#define MUX_APLL_SEL_MASK (1 << 0) +#define MUX_MPLL_SEL_MASK (1 << 8) +#define MPLL_SEL_MOUT_MPLLFOUT (2 << 8) +#define MUX_CPLL_SEL_MASK (1 << 8) +#define MUX_EPLL_SEL_MASK (1 << 12) +#define MUX_VPLL_SEL_MASK (1 << 16) +#define MUX_GPLL_SEL_MASK (1 << 28) +#define MUX_BPLL_SEL_MASK (1 << 0) +#define MUX_HPM_SEL_MASK (1 << 20) +#define HPM_SEL_SCLK_MPLL (1 << 21) +#define APLL_CON0_LOCKED (1 << 29) +#define MPLL_CON0_LOCKED (1 << 29) +#define BPLL_CON0_LOCKED (1 << 29) +#define CPLL_CON0_LOCKED (1 << 29) +#define EPLL_CON0_LOCKED (1 << 29) +#define GPLL_CON0_LOCKED (1 << 29) +#define VPLL_CON0_LOCKED (1 << 29) +#define CLK_REG_DISABLE 0x0 +#define TOP2_VAL 0x0110000
/* CLK_SRC_PERIC0 */ +#define PWM_SEL 0 +#define UART3_SEL 6 +#define UART2_SEL 6 +#define UART1_SEL 6 +#define UART0_SEL 6 +/* SRC_CLOCK = SCLK_MPLL */ +#define CLK_SRC_PERIC0_VAL ((PWM_SEL << 24) \ + | (UART3_SEL << 12) \ + | (UART2_SEL << 8) \ + | (UART1_SEL << 4) \ + | (UART0_SEL)) + +/* CLK_SRC_PERIC1 */ /* 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) \ - | (UART0_SEL << 0)) - -#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 - -/* 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) \ - | (UART2_RATIO << 8) \ - | (UART1_RATIO << 4) \ - | (UART0_RATIO << 0)) +#define SPI0_SEL 6 +#define SPI1_SEL 6 +#define SPI2_SEL 6 +#define CLK_SRC_PERIC1_VAL ((SPI2_SEL << 24) \ + | (SPI1_SEL << 20) \ + | (SPI0_SEL << 16)) + +/* SCLK_SRC_ISP - set SPI0/1 to 6 = SCLK_MPLL_USER */ +#define SPI0_ISP_SEL 6 +#define SPI1_ISP_SEL 6 +#define SCLK_SRC_ISP_VAL (SPI1_ISP_SEL << 4) \ + | (SPI0_ISP_SEL << 0) + +/* SCLK_DIV_ISP - set SPI0/1 to 0xf = divide by 16 */ +#define SPI0_ISP_RATIO 0xf +#define SPI1_ISP_RATIO 0xf +#define SCLK_DIV_ISP_VAL (SPI1_ISP_RATIO << 12) \ + | (SPI0_ISP_RATIO << 0) + +/* CLK_DIV_PERIL0 */ +#define UART5_RATIO 7 +#define UART4_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)) +/* CLK_DIV_PERIC1 */ +#define SPI1_RATIO 0x7 +#define SPI0_RATIO 0xf +#define SPI1_SUB_RATIO 0x0 +#define SPI0_SUB_RATIO 0x0 +#define CLK_DIV_PERIC1_VAL ((SPI1_SUB_RATIO << 24) \ + | ((SPI1_RATIO << 16) \ + | (SPI0_SUB_RATIO << 8) \ + | (SPI0_RATIO << 0))) + +/* CLK_DIV_PERIC2 */ +#define SPI2_RATIO 0xf +#define SPI2_SUB_RATIO 0x0 +#define CLK_DIV_PERIC2_VAL ((SPI2_SUB_RATIO << 8) \ + | (SPI2_RATIO << 0))
/* CLK_DIV_PERIC3 */ #define PWM_RATIO 8 #define CLK_DIV_PERIC3_VAL (PWM_RATIO << 0)
+/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO_MASK 0xf +#define MMC2_RATIO_VAL 0x3 +#define MMC2_RATIO_OFFSET 0 + +#define MMC2_PRE_RATIO_MASK 0xff +#define MMC2_PRE_RATIO_VAL 0x9 +#define MMC2_PRE_RATIO_OFFSET 8 + +#define MMC3_RATIO_MASK 0xf +#define MMC3_RATIO_VAL 0x1 +#define MMC3_RATIO_OFFSET 16 + +#define MMC3_PRE_RATIO_MASK 0xff +#define MMC3_PRE_RATIO_VAL 0x0 +#define MMC3_PRE_RATIO_OFFSET 24 + /* CLK_SRC_LEX */ -#define CLK_SRC_LEX_VAL 0x0 +#define CLK_SRC_LEX_VAL 0x0
/* CLK_DIV_LEX */ -#define CLK_DIV_LEX_VAL 0x10 +#define CLK_DIV_LEX_VAL 0x10
/* CLK_DIV_R0X */ -#define CLK_DIV_R0X_VAL 0x10 +#define CLK_DIV_R0X_VAL 0x10
/* CLK_DIV_L0X */ -#define CLK_DIV_R1X_VAL 0x10 +#define CLK_DIV_R1X_VAL 0x10
-/* SCLK_SRC_ISP */ -#define SCLK_SRC_ISP_VAL 0x600 /* CLK_DIV_ISP0 */ -#define CLK_DIV_ISP0_VAL 0x31 +#define CLK_DIV_ISP0_VAL 0x31
/* CLK_DIV_ISP1 */ -#define CLK_DIV_ISP1_VAL 0x0 +#define CLK_DIV_ISP1_VAL 0x0
/* CLK_DIV_ISP2 */ -#define CLK_DIV_ISP2_VAL 0x1 +#define CLK_DIV_ISP2_VAL 0x1
-#define MPLL_DEC (MPLL_MDIV * MPLL_MDIV / (MPLL_PDIV * 2^(MPLL_SDIV-1))) +/* CLK_SRC_DISP1_0 */ +#define CLK_SRC_DISP1_0_VAL 0x6 + +/* + * DIV_DISP1_0 + * For DP, divisor should be 2 + */ +#define CLK_DIV_DISP1_0_FIMD1 (2 << 0) + +/* CLK_GATE_IP_DISP1 */ +#define CLK_GATE_DP1_ALLOW (1 << 4)
/* * TZPC Register Value : @@ -347,103 +469,66 @@ */ #define DECPROTXSET 0xFF
-/* DMC Init */ -#define SET 1 -#define RESET 0 -/* (Memory Interleaving Size = 1 << IV_SIZE) */ -#define CONFIG_IV_SIZE 0x07 +#define DDR3PHY_CTRL_PHY_RESET (1 << 0) +#define DDR3PHY_CTRL_PHY_RESET_OFF (0 << 0) + +#define PHY_CON0_RESET_VAL 0x17020a40 +#define P0_CMD_EN (1 << 14) +#define BYTE_RDLVL_EN (1 << 13) +#define CTRL_SHGATE (1 << 8) + +#define PHY_CON1_RESET_VAL 0x09210100 +#define CTRL_GATEDURADJ_MASK (0xf << 20)
-#define PHY_RESET_VAL (0 << 0) +#define PHY_CON2_RESET_VAL 0x00010004 +#define INIT_DESKEW_EN (1 << 6) +#define RDLVL_GATE_EN (1 << 24)
/*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) +#define ZQ_DONE (1 << 0) + +#define CTRL_RDLVL_GATE_ENABLE 1 +#define CTRL_RDLVL_GATE_DISABLE 1 + +/* Direct Command */ +#define DIRECT_CMD_NOP 0x07000000 +#define DIRECT_CMD_PALL 0x01000000 +#define DIRECT_CMD_ZQINIT 0x0a000000 +#define DIRECT_CMD_CHANNEL_SHIFT 28 +#define DIRECT_CMD_CHIP_SHIFT 20 + +/* DMC PHY Control0 register */ +#define PHY_CONTROL0_RESET_VAL 0x0 +#define MEM_TERM_EN (1 << 31) /* Termination enable for memory */ +#define PHY_TERM_EN (1 << 30) /* Termination enable for PHY */ +#define DMC_CTRL_SHGATE (1 << 29) /* Duration of DQS gating signal */ +#define FP_RSYNC (1 << 3) /* Force DLL resyncronization */ + +/* Driver strength for CK, CKE, CS & CA */ +#define IMP_OUTPUT_DRV_40_OHM 0x5 +#define IMP_OUTPUT_DRV_30_OHM 0x7 +#define CA_CK_DRVR_DS_OFFSET 9 +#define CA_CKE_DRVR_DS_OFFSET 6 +#define CA_CS_DRVR_DS_OFFSET 3 +#define CA_ADR_DRVR_DS_OFFSET 0 + +#define PHY_CON42_CTRL_BSTLEN_SHIFT 8 +#define PHY_CON42_CTRL_RDLAT_SHIFT 0 + +struct mem_timings; + +/* Errors that we can encourter in low-level setup */ +enum { + SETUP_ERR_OK, + SETUP_ERR_RDLV_COMPLETE_TIMEOUT = -1, + SETUP_ERR_ZQ_CALIBRATION_FAILURE = -2, +};
-/* 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);

The patch adds the memory initialization sequence of DDR3.
Signed-off-by: Hatim Ali hatim.rv@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None Changes in V3: - None Changes in V4: - None arch/arm/include/asm/arch-exynos/dmc.h | 65 +++++ board/samsung/smdk5250/Makefile | 2 +- board/samsung/smdk5250/dmc_common.c | 199 ++++++++++++++ board/samsung/smdk5250/dmc_init.c | 462 -------------------------------- board/samsung/smdk5250/dmc_init_ddr3.c | 228 ++++++++++++++++ board/samsung/smdk5250/setup.h | 59 ++++- 6 files changed, 551 insertions(+), 464 deletions(-) create mode 100644 board/samsung/smdk5250/dmc_common.c delete mode 100644 board/samsung/smdk5250/dmc_init.c create mode 100644 board/samsung/smdk5250/dmc_init_ddr3.c
diff --git a/arch/arm/include/asm/arch-exynos/dmc.h b/arch/arm/include/asm/arch-exynos/dmc.h index bd52d16..f65c676 100644 --- a/arch/arm/include/asm/arch-exynos/dmc.h +++ b/arch/arm/include/asm/arch-exynos/dmc.h @@ -251,5 +251,70 @@ struct exynos5_phy_control { unsigned int phy_con41; unsigned int phy_con42; }; + +enum ddr_mode { + DDR_MODE_DDR2, + DDR_MODE_DDR3, + DDR_MODE_LPDDR2, + DDR_MODE_LPDDR3, + + DDR_MODE_COUNT, +}; + +enum mem_manuf { + MEM_MANUF_AUTODETECT, + MEM_MANUF_ELPIDA, + MEM_MANUF_SAMSUNG, + + MEM_MANUF_COUNT, +}; + +/* CONCONTROL register fields */ +#define CONCONTROL_DFI_INIT_START_SHIFT 28 +#define CONCONTROL_RD_FETCH_SHIFT 12 +#define CONCONTROL_RD_FETCH_MASK (0x7 << CONCONTROL_RD_FETCH_SHIFT) +#define CONCONTROL_AREF_EN_SHIFT 5 + +/* PRECHCONFIG register field */ +#define PRECHCONFIG_TP_CNT_SHIFT 24 + +/* PWRDNCONFIG register field */ +#define PWRDNCONFIG_DPWRDN_CYC_SHIFT 0 +#define PWRDNCONFIG_DSREF_CYC_SHIFT 16 + +/* PHY_CON0 register fields */ +#define PHY_CON0_T_WRRDCMD_SHIFT 17 +#define PHY_CON0_T_WRRDCMD_MASK (0x7 << PHY_CON0_T_WRRDCMD_SHIFT) +#define PHY_CON0_CTRL_DDR_MODE_SHIFT 11 + +/* PHY_CON1 register fields */ +#define PHY_CON1_RDLVL_RDDATA_ADJ_SHIFT 0 + +/* PHY_CON12 register fields */ +#define PHY_CON12_CTRL_START_POINT_SHIFT 24 +#define PHY_CON12_CTRL_INC_SHIFT 16 +#define PHY_CON12_CTRL_FORCE_SHIFT 8 +#define PHY_CON12_CTRL_START_SHIFT 6 +#define PHY_CON12_CTRL_START_MASK (1 << PHY_CON12_CTRL_START_SHIFT) +#define PHY_CON12_CTRL_DLL_ON_SHIFT 5 +#define PHY_CON12_CTRL_DLL_ON_MASK (1 << PHY_CON12_CTRL_DLL_ON_SHIFT) +#define PHY_CON12_CTRL_REF_SHIFT 1 + +/* PHY_CON16 register fields */ +#define PHY_CON16_ZQ_MODE_DDS_SHIFT 24 +#define PHY_CON16_ZQ_MODE_DDS_MASK (0x7 << PHY_CON16_ZQ_MODE_DDS_SHIFT) + +#define PHY_CON16_ZQ_MODE_TERM_SHIFT 21 +#define PHY_CON16_ZQ_MODE_TERM_MASK (0x7 << PHY_CON16_ZQ_MODE_TERM_SHIFT) + +#define PHY_CON16_ZQ_MODE_NOTERM_MASK (1 << 19) + +/* PHY_CON42 register fields */ +#define PHY_CON42_CTRL_BSTLEN_SHIFT 8 +#define PHY_CON42_CTRL_BSTLEN_MASK (0xff << PHY_CON42_CTRL_BSTLEN_SHIFT) + +#define PHY_CON42_CTRL_RDLAT_SHIFT 0 +#define PHY_CON42_CTRL_RDLAT_MASK (0x1f << PHY_CON42_CTRL_RDLAT_SHIFT) + #endif #endif diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 3675fad..1474fa8 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(BOARD).o SOBJS := lowlevel_init.o
COBJS := clock_init.o -COBJS += dmc_init.o +COBJS += dmc_common.o dmc_init_ddr3.o COBJS += tzpc_init.o COBJS += smdk5250_spl.o
diff --git a/board/samsung/smdk5250/dmc_common.c b/board/samsung/smdk5250/dmc_common.c new file mode 100644 index 0000000..109602a --- /dev/null +++ b/board/samsung/smdk5250/dmc_common.c @@ -0,0 +1,199 @@ +/* + * Mem setup common file for different types of DDR present on SMDK5250 boards. + * + * 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/arch/spl.h> + +#include "clock_init.h" +#include "setup.h" + +#define ZQ_INIT_TIMEOUT 10000 + +int dmc_config_zq(struct mem_timings *mem, + struct exynos5_phy_control *phy0_ctrl, + struct exynos5_phy_control *phy1_ctrl) +{ + unsigned long val = 0; + int i; + + /* + * ZQ Calibration: + * Select Driver Strength, + * long calibration for manual calibration + */ + val = PHY_CON16_RESET_VAL; + val |= mem->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT; + val |= mem->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT; + val |= ZQ_CLK_DIV_EN; + writel(val, &phy0_ctrl->phy_con16); + writel(val, &phy1_ctrl->phy_con16); + + /* Disable termination */ + if (mem->zq_mode_noterm) + val |= PHY_CON16_ZQ_MODE_NOTERM_MASK; + 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); + + /* ZQ_MANUAL_START: Disable */ + val &= ~ZQ_MANUAL_STR; + + /* + * Since we are manaully calibrating the ZQ values, + * we are looping for the ZQ_init to complete. + */ + i = ZQ_INIT_TIMEOUT; + while ((readl(&phy0_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { + sdelay(100); + i--; + } + if (!i) + return -1; + writel(val, &phy0_ctrl->phy_con16); + + i = ZQ_INIT_TIMEOUT; + while ((readl(&phy1_ctrl->phy_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { + sdelay(100); + i--; + } + if (!i) + return -1; + writel(val, &phy1_ctrl->phy_con16); + + return 0; +} + +void update_reset_dll(struct exynos5_dmc *dmc, enum ddr_mode mode) +{ + unsigned long val; + + if (mode == DDR_MODE_DDR3) { + val = MEM_TERM_EN | PHY_TERM_EN | DMC_CTRL_SHGATE; + writel(val, &dmc->phycontrol0); + } + + /* 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); +} + +void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc) +{ + int channel, chip; + + for (channel = 0; channel < mem->dmc_channels; channel++) { + unsigned long mask; + + mask = channel << DIRECT_CMD_CHANNEL_SHIFT; + for (chip = 0; chip < mem->chips_to_configure; chip++) { + int i; + + mask |= chip << DIRECT_CMD_CHIP_SHIFT; + + /* Sending NOP command */ + writel(DIRECT_CMD_NOP | mask, &dmc->directcmd); + + /* + * TODO(alim.akhtar@samsung.com): Do we need these + * delays? This one and the next were not there for + * DDR3. + */ + sdelay(0x10000); + + /* Sending EMRS/MRS commands */ + for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) { + writel(mem->direct_cmd_msr[i] | mask, + &dmc->directcmd); + sdelay(0x10000); + } + + if (mem->send_zq_init) { + /* Sending ZQINIT command */ + writel(DIRECT_CMD_ZQINIT | mask, + &dmc->directcmd); + + sdelay(10000); + } + } + } +} + +void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc) +{ + int channel, chip; + + for (channel = 0; channel < mem->dmc_channels; channel++) { + unsigned long mask; + + mask = channel << DIRECT_CMD_CHANNEL_SHIFT; + for (chip = 0; chip < mem->chips_per_channel; chip++) { + mask |= chip << DIRECT_CMD_CHIP_SHIFT; + + /* PALL (all banks precharge) CMD */ + writel(DIRECT_CMD_PALL | mask, &dmc->directcmd); + sdelay(0x10000); + } + } +} + +void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc) +{ + writel(mem->memconfig, &dmc->memconfig0); + writel(mem->memconfig, &dmc->memconfig1); + writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0); + writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1); +} + +void mem_ctrl_init() +{ + struct spl_machine_param *param = spl_get_machine_params(); + struct mem_timings *mem; + int ret; + + mem = clock_get_mem_timings(); + + /* If there are any other memory variant, add their init call below */ + if (param->mem_type == DDR_MODE_DDR3) { + ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size); + if (ret) { + /* will hang if failed to init memory control */ + while (1) + ; + } + } else { + /* will hang if unknow memory type */ + while (1) + ; + } +} diff --git a/board/samsung/smdk5250/dmc_init.c b/board/samsung/smdk5250/dmc_init.c deleted file mode 100644 index 7881074..0000000 --- a/board/samsung/smdk5250/dmc_init.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Memory setup for SMDK5250 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 <config.h> -#include <asm/io.h> -#include <asm/arch/dmc.h> -#include <asm/arch/clock.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) -{ - struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; - - writel(PHY_RESET_VAL, &clk->lpddr3phy_ctrl); - sdelay(0x10000); -} - -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 - */ - 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); - - /* ZQ_MANUAL_START: Disable */ - val &= ~ZQ_MANUAL_STR; - writel(val, &phy0_ctrl->phy_con16); - writel(val, &phy1_ctrl->phy_con16); -} - -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); -} - -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); - } - } -} - -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); - } - } -} - -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); - - 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) -{ - 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); -} - -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); -} - -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); -} - -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); -} - -#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; - - /* Disable CTRL_DLL_ON and set ctrl_force */ - config_ctrl_dll_on(RESET, 0x2D, phy0_ctrl, phy1_ctrl); - - /* - * 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); - - /* Enable Data Eye Training */ - val = readl(&dmc->rdlvl_config); - val |= CTRL_RDLVL_DATA_EN; - writel(val, &dmc->rdlvl_config); - sdelay(0x10000); - - /* Disable Data Eye Training */ - val = readl(&dmc->rdlvl_config); - val &= ~CTRL_RDLVL_DATA_EN; - writel(val, &dmc->rdlvl_config); - - /* 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); - - /* Enable CTRL_DLL_ON */ - config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl); - - update_reset_dll(dmc); - sdelay(0x10000); - - /* 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); -} -#endif - -static void config_memory(struct exynos5_dmc *dmc) -{ - /* - * 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); - - /* - * 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); - - /* - * Chip0: AXI - * AXI Base Address: 0x40000000 - * AXI Base Address Mask: 0x780 - */ - writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0); - - /* - * Chip1: AXI - * AXI Base Address: 0x80000000 - * AXI Base Address Mask: 0x780 - */ - writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1); -} - -void mem_ctrl_init() -{ - struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; - struct exynos5_dmc *dmc; - unsigned long val; - - 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); - - /* 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); - - /* 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); - - /* Init SEC SDRAM PHY */ - sec_sdram_phy_init(dmc); - sdelay(0x10000); - - update_reset_dll(dmc); - - /* - * 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 - */ - writel(DMC_MEMCONTROL_VAL, &dmc->memcontrol); - - config_memory(dmc); - - /* Precharge Configuration */ - writel(DMC_PRECHCONFIG_VAL, &dmc->prechconfig); - - /* Power Down mode Configuration */ - writel(DMC_PWRDNCONFIG_VAL, &dmc->pwrdnconfig); - - /* Periodic Refrese Interval */ - writel(DMC_TIMINGREF_VAL, &dmc->timingref); - - /* - * TimingRow, TimingData, TimingPower Setting: - * Values as per Memory AC Parameters - */ - writel(DMC_TIMINGROW_VAL, &dmc->timingrow); - - writel(DMC_TIMINGDATA_VAL, &dmc->timingdata); - - writel(DMC_TIMINGPOWER_VAL, &dmc->timingpower); - - /* Memory Channel Inteleaving Size: 128 Bytes */ - writel(CONFIG_IV_SIZE, &dmc->ivcontrol); - - /* Set DQS, DQ and DEBUG offsets */ - config_offsets(SET, phy0_ctrl, phy1_ctrl); - - /* Disable CTRL_DLL_ON and set ctrl_force */ - config_ctrl_dll_on(RESET, 0x7F, phy0_ctrl, phy1_ctrl); - sdelay(0x10000); - - update_reset_dll(dmc); - - /* Config MRS(Mode Register Settingg) */ - config_mrs(dmc); - - config_cdrex(); - - /* Reset DQS DQ and DEBUG offsets */ - config_offsets(RESET, phy0_ctrl, phy1_ctrl); - - /* Enable CTRL_DLL_ON */ - config_ctrl_dll_on(SET, 0x0, phy0_ctrl, phy1_ctrl); - - /* Stop DLL Locking */ - config_ctrl_start(RESET, phy0_ctrl, phy1_ctrl); - sdelay(0x10000); - - /* Start DLL Locking */ - config_ctrl_start(SET, phy0_ctrl, phy1_ctrl); - sdelay(0x10000); - - update_reset_dll(dmc); - -#if defined(CONFIG_RD_LVL) - config_rdlvl(dmc, phy0_ctrl, phy1_ctrl); -#endif - config_prech(dmc); - - /* - * Dynamic Clock: Stops During Idle Period - * Dynamic Power Down: Enable - * Dynamic Self refresh: Enable - */ - 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); -} diff --git a/board/samsung/smdk5250/dmc_init_ddr3.c b/board/samsung/smdk5250/dmc_init_ddr3.c new file mode 100644 index 0000000..e050790 --- /dev/null +++ b/board/samsung/smdk5250/dmc_init_ddr3.c @@ -0,0 +1,228 @@ +/* + * DDR3 mem setup file for SMDK5250 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 <config.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dmc.h> +#include "setup.h" +#include "clock_init.h" + +#define RDLVL_COMPLETE_TIMEOUT 10000 + +static void reset_phy_ctrl(void) +{ + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE; + + writel(DDR3PHY_CTRL_PHY_RESET_OFF, &clk->lpddr3phy_ctrl); + writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl); +} + +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size) +{ + unsigned int val; + struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; + struct exynos5_dmc *dmc; + int i; + + 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_ctrl(); + + /* Set Impedance Output Driver */ + val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) | + (mem->impedance << CA_CKE_DRVR_DS_OFFSET) | + (mem->impedance << CA_CS_DRVR_DS_OFFSET) | + (mem->impedance << CA_ADR_DRVR_DS_OFFSET); + writel(val, &phy0_ctrl->phy_con39); + writel(val, &phy1_ctrl->phy_con39); + + /* Set Read Latency and Burst Length for PHY0 and PHY1 */ + val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) | + (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT); + writel(val, &phy0_ctrl->phy_con42); + writel(val, &phy1_ctrl->phy_con42); + + /* ZQ Calibration */ + if (dmc_config_zq(mem, phy0_ctrl, phy1_ctrl)) + return SETUP_ERR_ZQ_CALIBRATION_FAILURE; + + /* DQ Signal */ + writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14); + writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14); + + writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) + | (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT), + &dmc->concontrol); + + update_reset_dll(dmc, DDR_MODE_DDR3); + + /* DQS Signal */ + writel(mem->phy0_dqs, &phy0_ctrl->phy_con4); + writel(mem->phy1_dqs, &phy1_ctrl->phy_con4); + + writel(mem->phy0_dq, &phy0_ctrl->phy_con6); + writel(mem->phy1_dq, &phy1_ctrl->phy_con6); + + writel(mem->phy0_tFS, &phy0_ctrl->phy_con10); + writel(mem->phy1_tFS, &phy1_ctrl->phy_con10); + + val = (mem->ctrl_start_point << PHY_CON12_CTRL_START_POINT_SHIFT) | + (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | + (mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) | + (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); + writel(val, &phy0_ctrl->phy_con12); + writel(val, &phy1_ctrl->phy_con12); + + /* Start DLL locking */ + writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT), + &phy0_ctrl->phy_con12); + writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT), + &phy1_ctrl->phy_con12); + + update_reset_dll(dmc, DDR_MODE_DDR3); + + writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT), + &dmc->concontrol); + + /* Memory Channel Inteleaving Size */ + writel(mem->iv_size, &dmc->ivcontrol); + + writel(mem->memconfig, &dmc->memconfig0); + writel(mem->memconfig, &dmc->memconfig1); + writel(mem->membaseconfig0, &dmc->membaseconfig0); + writel(mem->membaseconfig1, &dmc->membaseconfig1); + + /* Precharge Configuration */ + writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT, + &dmc->prechconfig); + + /* Power Down mode Configuration */ + writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT | + mem->dsref_cyc << PWRDNCONFIG_DSREF_CYC_SHIFT, + &dmc->pwrdnconfig); + + /* TimingRow, TimingData, TimingPower and Timingaref + * values as per Memory AC parameters + */ + writel(mem->timing_ref, &dmc->timingref); + writel(mem->timing_row, &dmc->timingrow); + writel(mem->timing_data, &dmc->timingdata); + writel(mem->timing_power, &dmc->timingpower); + + /* Send PALL command */ + dmc_config_prech(mem, dmc); + + /* Send NOP, MRS and ZQINIT commands */ + dmc_config_mrs(mem, dmc); + + if (mem->gate_leveling_enable) { + val = PHY_CON0_RESET_VAL; + val |= P0_CMD_EN; + writel(val, &phy0_ctrl->phy_con0); + writel(val, &phy1_ctrl->phy_con0); + + val = PHY_CON2_RESET_VAL; + val |= INIT_DESKEW_EN; + writel(val, &phy0_ctrl->phy_con2); + writel(val, &phy1_ctrl->phy_con2); + + val = PHY_CON0_RESET_VAL; + val |= P0_CMD_EN; + val |= BYTE_RDLVL_EN; + writel(val, &phy0_ctrl->phy_con0); + writel(val, &phy1_ctrl->phy_con0); + + val = (mem->ctrl_start_point << + PHY_CON12_CTRL_START_POINT_SHIFT) | + (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | + (mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) | + (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) | + (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); + writel(val, &phy0_ctrl->phy_con12); + writel(val, &phy1_ctrl->phy_con12); + + val = PHY_CON2_RESET_VAL; + val |= INIT_DESKEW_EN; + val |= RDLVL_GATE_EN; + writel(val, &phy0_ctrl->phy_con2); + writel(val, &phy1_ctrl->phy_con2); + + val = PHY_CON0_RESET_VAL; + val |= P0_CMD_EN; + val |= BYTE_RDLVL_EN; + val |= CTRL_SHGATE; + writel(val, &phy0_ctrl->phy_con0); + writel(val, &phy1_ctrl->phy_con0); + + val = PHY_CON1_RESET_VAL; + val &= ~(CTRL_GATEDURADJ_MASK); + writel(val, &phy0_ctrl->phy_con1); + writel(val, &phy1_ctrl->phy_con1); + + writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config); + i = RDLVL_COMPLETE_TIMEOUT; + while ((readl(&dmc->phystatus) & + (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) != + (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) { + /* + * TODO(waihong): Comment on how long this take to + * timeout + */ + sdelay(100); + i--; + } + if (!i) + return SETUP_ERR_RDLV_COMPLETE_TIMEOUT; + writel(CTRL_RDLVL_GATE_DISABLE, &dmc->rdlvl_config); + + writel(0, &phy0_ctrl->phy_con14); + writel(0, &phy1_ctrl->phy_con14); + + val = (mem->ctrl_start_point << + PHY_CON12_CTRL_START_POINT_SHIFT) | + (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | + (mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) | + (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) | + (mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) | + (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); + writel(val, &phy0_ctrl->phy_con12); + writel(val, &phy1_ctrl->phy_con12); + + update_reset_dll(dmc, DDR_MODE_DDR3); + } + + /* Send PALL command */ + dmc_config_prech(mem, dmc); + + writel(mem->memcontrol, &dmc->memcontrol); + + /* Set DMC Concontrol and enable auto-refresh counter */ + writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) + | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol); + return 0; +} diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h index bae0faf..3abfa7d 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -529,8 +529,65 @@ enum { };
+/* + * Memory variant specific initialization code + * + * @param mem Memory timings for this memory type. + * @param mem_iv_size Memory interleaving size is a configurable parameter + * which the DMC uses to decide how to split a memory + * chunk into smaller chunks to support concurrent + * accesses; may vary across boards. + * @return 0 if ok, SETUP_ERR_... if there is a problem + */ +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size); + +/* + * Configure ZQ I/O interface + * + * @param mem Memory timings for this memory type. + * @param phy0_ctrl Pointer to struct containing PHY0 control reg + * @param phy1_ctrl Pointer to struct containing PHY1 control reg + * @return 0 if ok, -1 on error + */ +int dmc_config_zq(struct mem_timings *mem, + struct exynos5_phy_control *phy0_ctrl, + struct exynos5_phy_control *phy1_ctrl); + +/* + * Send NOP and MRS/EMRS Direct commands + * + * @param mem Memory timings for this memory type. + * @param dmc Pointer to struct of DMC registers + */ +void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc); + +/* + * Send PALL Direct commands + * + * @param mem Memory timings for this memory type. + * @param dmc Pointer to struct of DMC registers + */ +void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc); + +/* + * Configure the memconfig and membaseconfig registers + * + * @param mem Memory timings for this memory type. + * @param exynos5_dmc Pointer to struct of DMC registers + */ +void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc); + +/* + * Reset the DLL. This function is common between DDR3 and LPDDR2. + * However, the reset value is different. So we are passing a flag + * ddr_mode to distinguish between LPDDR2 and DDR3. + * + * @param exynos5_dmc Pointer to struct of DMC registers + * @param ddr_mode Type of DDR memory + */ +void update_reset_dll(struct exynos5_dmc *, enum ddr_mode); + void mem_ctrl_init(void); void system_clock_init(void); void tzpc_init(void); - #endif

MPLL clock-out of Exynos5250 Rev 1.0 is always at 1.6GHz. Adjust the divisor value to get 800MHz as needed by devices like UART etc
Signed-off-by: Hatim Ali hatim.rv@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None Changes in V3: - Incorported review comments from Minkyu Kang. Changes in V4: - None arch/arm/cpu/armv7/exynos/clock.c | 12 +++++++++++- arch/arm/include/asm/arch-exynos/clock.h | 3 +++ 2 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 330bd75..dbd5f11 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -98,7 +98,7 @@ static unsigned long exynos5_get_pll_clk(int pllreg) struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); unsigned long r, m, p, s, k = 0, mask, fout; - unsigned int freq; + unsigned int freq, pll_div2_sel, mpll_fout_sel;
switch (pllreg) { case APLL: @@ -155,6 +155,16 @@ static unsigned long exynos5_get_pll_clk(int pllreg) fout = m * (freq / (p * (1 << (s - 1)))); }
+ /* According to the user manual, in EVT1 MPLL always gives + * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/ + if (pllreg == MPLL) { + pll_div2_sel = readl(&clk->pll_div2_sel); + mpll_fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT) + & MPLL_FOUT_SEL_MASK; + if (mpll_fout_sel == 0) + fout /= 2; + } + return fout; }
diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h index 90271f1..bf41c19 100644 --- a/arch/arm/include/asm/arch-exynos/clock.h +++ b/arch/arm/include/asm/arch-exynos/clock.h @@ -596,4 +596,7 @@ struct exynos5_clock { unsigned char res123[0xf5d8]; }; #endif + +#define MPLL_FOUT_SEL_SHIFT 4 +#define MPLL_FOUT_SEL_MASK 0x1 #endif

2012/6/29 Rajeshwari Shinde rajeshwari.s@samsung.com:
MPLL clock-out of Exynos5250 Rev 1.0 is always at 1.6GHz. Adjust the divisor value to get 800MHz as needed by devices like UART etc
Signed-off-by: Hatim Ali hatim.rv@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V2: - None Changes in V3: - Incorported review comments from Minkyu Kang. Changes in V4: - None arch/arm/cpu/armv7/exynos/clock.c | 12 +++++++++++- arch/arm/include/asm/arch-exynos/clock.h | 3 +++ 2 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 330bd75..dbd5f11 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -98,7 +98,7 @@ static unsigned long exynos5_get_pll_clk(int pllreg) struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); unsigned long r, m, p, s, k = 0, mask, fout;
- unsigned int freq;
- unsigned int freq, pll_div2_sel, mpll_fout_sel;
switch (pllreg) { case APLL: @@ -155,6 +155,16 @@ static unsigned long exynos5_get_pll_clk(int pllreg) fout = m * (freq / (p * (1 << (s - 1)))); }
- /* According to the user manual, in EVT1 MPLL always gives
- * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
- if (pllreg == MPLL) {
- pll_div2_sel = readl(&clk->pll_div2_sel);
- mpll_fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
- & MPLL_FOUT_SEL_MASK;
- if (mpll_fout_sel == 0)
- fout /= 2;
- }
return fout; }
diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h index 90271f1..bf41c19 100644 --- a/arch/arm/include/asm/arch-exynos/clock.h +++ b/arch/arm/include/asm/arch-exynos/clock.h @@ -596,4 +596,7 @@ struct exynos5_clock { unsigned char res123[0xf5d8]; }; #endif
+#define MPLL_FOUT_SEL_SHIFT 4 +#define MPLL_FOUT_SEL_MASK 0x1 #endif -- 1.7.4.4
Acked-by: Joonyoung Shim jy0922.shim@samsung.com

This patch adds support for BPLL clock.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V3: - New Patch Changes in V4: - Removed the warning message. arch/arm/cpu/armv7/exynos/clock.c | 26 ++++++++++++++++++++------ arch/arm/include/asm/arch-exynos/clk.h | 1 + arch/arm/include/asm/arch-exynos/clock.h | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index dbd5f11..13e3641 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -98,7 +98,7 @@ static unsigned long exynos5_get_pll_clk(int pllreg) struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); unsigned long r, m, p, s, k = 0, mask, fout; - unsigned int freq, pll_div2_sel, mpll_fout_sel; + unsigned int freq, pll_div2_sel, fout_sel;
switch (pllreg) { case APLL: @@ -115,6 +115,9 @@ static unsigned long exynos5_get_pll_clk(int pllreg) r = readl(&clk->vpll_con0); k = readl(&clk->vpll_con1); break; + case BPLL: + r = readl(&clk->bpll_con0); + break; default: printf("Unsupported PLL (%d)\n", pllreg); return 0; @@ -125,8 +128,9 @@ static unsigned long exynos5_get_pll_clk(int pllreg) * MPLL_CON: MIDV [25:16] * EPLL_CON: MIDV [24:16] * VPLL_CON: MIDV [24:16] + * BPLL_CON: MIDV [25:16] */ - if (pllreg == APLL || pllreg == MPLL) + if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL) mask = 0x3ff; else mask = 0x1ff; @@ -155,13 +159,23 @@ static unsigned long exynos5_get_pll_clk(int pllreg) fout = m * (freq / (p * (1 << (s - 1)))); }
- /* According to the user manual, in EVT1 MPLL always gives + /* According to the user manual, in EVT1 MPLL and BPLL always gives * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/ - if (pllreg == MPLL) { + if (pllreg == MPLL || pllreg == BPLL) { pll_div2_sel = readl(&clk->pll_div2_sel); - mpll_fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT) + + switch (pllreg) { + case MPLL: + fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT) & MPLL_FOUT_SEL_MASK; - if (mpll_fout_sel == 0) + break; + case BPLL: + fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT) + & BPLL_FOUT_SEL_MASK; + break; + } + + if (fout_sel == 0) fout /= 2; }
diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h index 637fb4b..e99339a 100644 --- a/arch/arm/include/asm/arch-exynos/clk.h +++ b/arch/arm/include/asm/arch-exynos/clk.h @@ -27,6 +27,7 @@ #define EPLL 2 #define HPLL 3 #define VPLL 4 +#define BPLL 5
unsigned long get_pll_clk(int pllreg); unsigned long get_arm_clk(void); diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h index bf41c19..fce38ef 100644 --- a/arch/arm/include/asm/arch-exynos/clock.h +++ b/arch/arm/include/asm/arch-exynos/clock.h @@ -599,4 +599,6 @@ struct exynos5_clock {
#define MPLL_FOUT_SEL_SHIFT 4 #define MPLL_FOUT_SEL_MASK 0x1 +#define BPLL_FOUT_SEL_SHIFT 0 +#define BPLL_FOUT_SEL_MASK 0x1 #endif

2012/6/29 Rajeshwari Shinde rajeshwari.s@samsung.com:
This patch adds support for BPLL clock.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V3: - New Patch Changes in V4: - Removed the warning message. arch/arm/cpu/armv7/exynos/clock.c | 26 ++++++++++++++++++++------ arch/arm/include/asm/arch-exynos/clk.h | 1 + arch/arm/include/asm/arch-exynos/clock.h | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-)
Acked-by: Joonyoung Shim jy0922.shim@samsung.com

Dear Rajeshwari Shinde,
On 29 June 2012 21:59, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch adds support for BPLL clock.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V3: - New Patch Changes in V4: - Removed the warning message. arch/arm/cpu/armv7/exynos/clock.c | 26 ++++++++++++++++++++------ arch/arm/include/asm/arch-exynos/clk.h | 1 + arch/arm/include/asm/arch-exynos/clock.h | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index dbd5f11..13e3641 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -98,7 +98,7 @@ static unsigned long exynos5_get_pll_clk(int pllreg) struct exynos5_clock *clk = (struct exynos5_clock *)samsung_get_base_clock(); unsigned long r, m, p, s, k = 0, mask, fout;
- unsigned int freq, pll_div2_sel, mpll_fout_sel;
- unsigned int freq, pll_div2_sel, fout_sel;
switch (pllreg) { case APLL: @@ -115,6 +115,9 @@ static unsigned long exynos5_get_pll_clk(int pllreg) r = readl(&clk->vpll_con0); k = readl(&clk->vpll_con1); break;
- case BPLL:
- r = readl(&clk->bpll_con0);
- break;
default: printf("Unsupported PLL (%d)\n", pllreg); return 0; @@ -125,8 +128,9 @@ static unsigned long exynos5_get_pll_clk(int pllreg) * MPLL_CON: MIDV [25:16] * EPLL_CON: MIDV [24:16] * VPLL_CON: MIDV [24:16]
- * BPLL_CON: MIDV [25:16]
*/
- if (pllreg == APLL || pllreg == MPLL)
- if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
mask = 0x3ff; else mask = 0x1ff; @@ -155,13 +159,23 @@ static unsigned long exynos5_get_pll_clk(int pllreg) fout = m * (freq / (p * (1 << (s - 1)))); }
- /* According to the user manual, in EVT1 MPLL always gives
- /* According to the user manual, in EVT1 MPLL and BPLL always gives
* 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
- if (pllreg == MPLL) {
- if (pllreg == MPLL || pllreg == BPLL) {
pll_div2_sel = readl(&clk->pll_div2_sel);
- mpll_fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
- switch (pllreg) {
- case MPLL:
- fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
& MPLL_FOUT_SEL_MASK;
- if (mpll_fout_sel == 0)
- break;
- case BPLL:
- fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
- & BPLL_FOUT_SEL_MASK;
- break;
- }
indentation error. please fix it.
- if (fout_sel == 0)
fout /= 2; }
Thanks. Minkyu Kang.

This patch modifies the pinmux settings of MMC and UART as per Exynos5250 Rev 1.0. It also corrects the gpio offset calculations.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None. Changes in V3: - Corrected the pinmux settings and offset calcuation of gpio banks. Changes in V4: - None arch/arm/cpu/armv7/exynos/pinmux.c | 22 +++++++++++++--------- arch/arm/include/asm/arch-exynos/gpio.h | 7 +++++-- 2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index d2b7d2c..822410e 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -40,8 +40,8 @@ static void exynos5_uart_config(int peripheral) count = 4; break; case PERIPH_ID_UART1: - bank = &gpio1->a0; - start = 4; + bank = &gpio1->d0; + start = 0; count = 4; break; case PERIPH_ID_UART2: @@ -66,23 +66,27 @@ static int exynos5_mmc_config(int peripheral, int flags) struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1(); struct s5p_gpio_bank *bank, *bank_ext; - int i; + int i, start, gpio_func;
switch (peripheral) { case PERIPH_ID_SDMMC0: bank = &gpio1->c0; bank_ext = &gpio1->c1; + start = 0; + gpio_func = GPIO_FUNC(0x2); break; case PERIPH_ID_SDMMC1: - bank = &gpio1->c1; + bank = &gpio1->c2; bank_ext = NULL; break; case PERIPH_ID_SDMMC2: - bank = &gpio1->c2; - bank_ext = &gpio1->c3; + bank = &gpio1->c3; + bank_ext = &gpio1->c4; + start = 3; + gpio_func = GPIO_FUNC(0x3); break; case PERIPH_ID_SDMMC3: - bank = &gpio1->c3; + bank = &gpio1->c4; bank_ext = NULL; break; } @@ -92,8 +96,8 @@ static int exynos5_mmc_config(int peripheral, int flags) return -1; } if (flags & PINMUX_FLAG_8BIT_MODE) { - for (i = 3; i <= 6; i++) { - s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3)); + for (i = start; i <= (start + 3); i++) { + s5p_gpio_cfg_pin(bank_ext, i, gpio_func); s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); } diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h index 7a9bb90..97be4ea 100644 --- a/arch/arm/include/asm/arch-exynos/gpio.h +++ b/arch/arm/include/asm/arch-exynos/gpio.h @@ -100,7 +100,9 @@ struct exynos5_gpio_part1 { struct s5p_gpio_bank y4; struct s5p_gpio_bank y5; struct s5p_gpio_bank y6; - struct s5p_gpio_bank res1[0x980]; + struct s5p_gpio_bank res1[0x3]; + struct s5p_gpio_bank c4; + struct s5p_gpio_bank res2[0x48]; struct s5p_gpio_bank x0; struct s5p_gpio_bank x1; struct s5p_gpio_bank x2; @@ -122,9 +124,10 @@ struct exynos5_gpio_part2 { struct exynos5_gpio_part3 { struct s5p_gpio_bank v0; struct s5p_gpio_bank v1; + struct s5p_gpio_bank res1[0x1]; struct s5p_gpio_bank v2; struct s5p_gpio_bank v3; - struct s5p_gpio_bank res1[0x20]; + struct s5p_gpio_bank res2[0x1]; struct s5p_gpio_bank v4; };

2012/6/29 Rajeshwari Shinde rajeshwari.s@samsung.com:
This patch modifies the pinmux settings of MMC and UART as per Exynos5250 Rev 1.0. It also corrects the gpio offset calculations.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V2: - None. Changes in V3: - Corrected the pinmux settings and offset calcuation of gpio banks. Changes in V4: - None arch/arm/cpu/armv7/exynos/pinmux.c | 22 +++++++++++++--------- arch/arm/include/asm/arch-exynos/gpio.h | 7 +++++-- 2 files changed, 18 insertions(+), 11 deletions(-)
Acked-by: Joonyoung Shim jy0922.shim@samsung.com

This patch sets UART3 and MMC channle 0 for Exynos5250 Rev 1.0
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - None. Changes in V3: - None Changes in V4: - None board/samsung/smdk5250/smdk5250.c | 6 +++--- include/configs/smdk5250.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index 3b078da..b593325 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -130,13 +130,13 @@ int board_mmc_init(bd_t *bis) { int err;
- err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE); + err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE); if (err) { - debug("SDMMC2 not configured\n"); + debug("SDMMC0 not configured\n"); return err; }
- err = s5p_mmc_init(2, 4); + err = s5p_mmc_init(0, 8); return err; } #endif diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h index 405abd5..d4d370f 100644 --- a/include/configs/smdk5250.h +++ b/include/configs/smdk5250.h @@ -69,7 +69,7 @@
/* select serial console configuration */ #define CONFIG_SERIAL_MULTI -#define CONFIG_SERIAL1 /* use SERIAL 1 */ +#define CONFIG_SERIAL3 /* use SERIAL 3 */ #define CONFIG_BAUDRATE 115200 #define EXYNOS5_DEFAULT_UART_OFFSET 0x010000
participants (3)
-
Joonyoung Shim
-
Minkyu Kang
-
Rajeshwari Shinde