aboutsummaryrefslogtreecommitdiff
path: root/board/rda/rda8810h
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2017-07-31 17:23:07 +0100
committerDaniel Thompson <daniel.thompson@linaro.org>2017-07-31 17:23:07 +0100
commite5b9b8c8b78096e961f4a45b9d1418e4641f24f9 (patch)
treea88f532f386376fca6a376e2c362173f971dc144 /board/rda/rda8810h
parent415d386877df49eb051b85ef74fa59a16dc17c7d (diff)
Orangepi i96 support (mega patch)rda/v2012.04.01-r0
This is https://github.com/orangepi-xunlong/OrangePiRDA_u-boot 5ee06c1afb7c ("add new patch a patch") as a single patch against a guestimated upstream version. This is merely a reference tree for later comparisons. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> NOT-Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Diffstat (limited to 'board/rda/rda8810h')
-rw-r--r--board/rda/rda8810h/Makefile82
-rw-r--r--board/rda/rda8810h/clock.c1329
-rw-r--r--board/rda/rda8810h/clock_config.c149
-rw-r--r--board/rda/rda8810h/clock_config.h132
-rw-r--r--board/rda/rda8810h/config.mk15
-rw-r--r--board/rda/rda8810h/ddr3.c533
-rw-r--r--board/rda/rda8810h/ddr3.h50
-rw-r--r--board/rda/rda8810h/ddr3_init.h101
-rw-r--r--board/rda/rda8810h/debug.h9
-rw-r--r--board/rda/rda8810h/hal_config.c1451
-rw-r--r--board/rda/rda8810h/u-boot-spl.lds35
11 files changed, 3886 insertions, 0 deletions
diff --git a/board/rda/rda8810h/Makefile b/board/rda/rda8810h/Makefile
new file mode 100644
index 0000000000..7412489b30
--- /dev/null
+++ b/board/rda/rda8810h/Makefile
@@ -0,0 +1,82 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).o
+
+ifdef CONFIG_SPL_BUILD
+COBJS-y += clock_config.o clock.o ddr3.o
+else
+COBJS-$(CONFIG_MACH_RDA8810H) += hal_config.o
+endif
+
+RDA_TARGET_DEF_FILE := $(ANDROID_BUILD_TOP)/$(RDA_TARGET_DEVICE_DIR)/target.def
+RDA_GET_MAKEFILE_VAR_FUNC = $(strip $(shell sed -n 's/^[ ]*$(1)[ ]*[?:]\?=\([^\#]\+\)\#*.*$$/\1/p' $(2)))
+
+NUMBER_OF_SIM := $(call RDA_GET_MAKEFILE_VAR_FUNC,NUMBER_OF_SIM,$(RDA_TARGET_DEF_FILE))
+ifeq ($(NUMBER_OF_SIM),)
+$(error Failed to get NUMBER_OF_SIM in $(RDA_TARGET_DEF_FILE))
+endif
+
+USER_SIM_ORDER := $(call RDA_GET_MAKEFILE_VAR_FUNC,USER_SIM_ORDER,$(RDA_TARGET_DEF_FILE))
+ifeq ($(USER_SIM_ORDER),)
+$(error Failed to get USER_SIM_ORDER in $(RDA_TARGET_DEF_FILE))
+endif
+
+NULL_STRING :=
+SPACE := ${NULL_STRING} # end of the line
+COMMA := ,
+TGT_SIM_ORDER := $(foreach SIM,$(USER_SIM_ORDER),$(SIM)$(COMMA))
+TGT_SIM_ORDER := $(subst ${SPACE},,${TGT_SIM_ORDER})
+
+CPPFLAGS_board/$(BOARDDIR)/hal_config.o += -I$(TOPDIR)/board/$(VENDOR)/common/include -DTGT_SIM_ORDER=$(TGT_SIM_ORDER) -DNUMBER_OF_SIM=$(NUMBER_OF_SIM)
+
+ifeq ($(strip $(TARGET_TABLET_MODE)),true)
+CPPFLAGS_board/$(BOARDDIR)/clock.o += -DTARGET_TABLET_MODE
+endif
+
+COBJS := $(COBJS-y)
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak *~ .depend
+
+#########################################################################
+# This is for $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/rda/rda8810h/clock.c b/board/rda/rda8810h/clock.c
new file mode 100644
index 0000000000..45caa4177d
--- /dev/null
+++ b/board/rda/rda8810h/clock.c
@@ -0,0 +1,1329 @@
+#include <common.h>
+#include <errno.h>
+#include <asm/arch/rda_iomap.h>
+#include <asm/io.h>
+#include <asm/arch/reg_sysctrl.h>
+#include <asm/arch/hwcfg.h>
+#include <asm/arch/ispi.h>
+#include <asm/arch/rda_sys.h>
+#include "clock_config.h"
+#include "debug.h"
+#include "ddr3.h"
+#include "tgt_ap_clock_config.h"
+
+#if (PMU_VBUCK1_VAL < 0 || PMU_VBUCK1_VAL > 15)
+#error "Invalid PMU_VBUCK1_VAL"
+#endif
+#if (PMU_VBUCK3_VAL < 0 || PMU_VBUCK3_VAL > 15)
+#error "Invalid PMU_VBUCK3_VAL"
+#endif
+#ifdef PMU_VBUCK4_VAL
+#if (PMU_VBUCK4_VAL < 0 || PMU_VBUCK4_VAL > 15)
+#error "Invalid PMU_VBUCK4_VAL"
+#endif
+#endif
+
+//#define DO_SIMPLE_DDR_TEST
+//#define DO_DDR_PLL_DEBUG
+
+enum {
+ AP_CPU_CLK_IDX = 0,
+ AP_BUS_CLK_IDX,
+ AP_MEM_CLK_IDX,
+ AP_USB_CLK_IDX,
+};
+
+static int pll_enabled(int idx)
+{
+ if ((hwp_sysCtrlAp->Cfg_Pll_Ctrl[idx] &
+ (SYS_CTRL_AP_AP_PLL_ENABLE_MASK |
+ SYS_CTRL_AP_AP_PLL_LOCK_RESET_MASK)) ==
+ (SYS_CTRL_AP_AP_PLL_ENABLE_ENABLE |
+ SYS_CTRL_AP_AP_PLL_LOCK_RESET_NO_RESET))
+ return 1;
+ else
+ return 0;
+}
+
+static int usb_in_use = 0;
+
+static void check_usb_usage(void)
+{
+ unsigned int mask = SYS_CTRL_AP_BUS_SEL_FAST_SLOW |
+ SYS_CTRL_AP_PLL_LOCKED_BUS_MASK |
+ SYS_CTRL_AP_PLL_LOCKED_USB_MASK;
+ unsigned int reg = SYS_CTRL_AP_BUS_SEL_FAST_FAST |
+ SYS_CTRL_AP_PLL_LOCKED_BUS_LOCKED |
+ SYS_CTRL_AP_PLL_LOCKED_USB_LOCKED;
+
+ if ((hwp_sysCtrlAp->Sel_Clock & mask) == reg &&
+ pll_enabled(AP_BUS_CLK_IDX) &&
+ pll_enabled(AP_USB_CLK_IDX))
+ usb_in_use = 1;
+ else
+ usb_in_use = 0;
+}
+
+#ifdef DO_SIMPLE_DDR_TEST
+
+void mem_test_write(void)
+{
+ volatile unsigned int *addr;
+
+ printf("write ddr test!!!!!!\n");
+
+ addr = (volatile unsigned int *)(0x80000000);
+ while((unsigned int)addr < 0x81000000)
+ {
+ *addr = (unsigned int )addr;
+ addr++;
+ }
+}
+
+void mem_test_read(void)
+{
+ volatile unsigned int *addr;
+
+ printf("read ddr!!!!\n");
+
+ addr = (volatile unsigned int *)(0x80000000);
+
+ while((unsigned int)addr < 0x81000000)
+ {
+ if (*addr != (unsigned int)addr){
+ int i = 0;
+
+ printf("test error!!!!!, addr = %x\n", (unsigned int)addr);
+ for (i = 0; i < 80;i++){
+ printf("%x ", *(addr + i));
+ if ((i % 4) == 0)
+ printf("\n");
+ }
+
+ return;
+ }
+
+ addr++;
+ }
+ printf("test complete!\n");
+}
+
+#endif /* DO_SIMPLE_DDR_TEST */
+
+#ifndef CONFIG_RDA_FPGA
+
+// PMU bit fields
+#define PMU_SET_BITFIELD(dword, bitfield, value) \
+ (((dword) & ~(bitfield ## _MASK)) | (bitfield(value)))
+
+#define RDA_PMU_VBUCK1_BIT_ACT(n) (((n)&0xf)<<12)
+#define RDA_PMU_VBUCK1_BIT_ACT_MASK (0xf<<12)
+#define RDA_PMU_VBUCK1_BIT_ACT_SHIFT (12)
+
+#define RDA_PMU_VBUCK4_BIT_ACT_SHIFT (4)
+#define RDA_PMU_VBUCK4_BIT_ACT_MASK (0xf<<4)
+#define RDA_PMU_VBUCK4_BIT_ACT(n) (((n)&0xf)<<4)
+
+#define RDA_PMU_VBUCK3_BIT_ACT_SHIFT (12)
+#define RDA_PMU_VBUCK3_BIT_ACT_MASK (0xf<<12)
+#define RDA_PMU_VBUCK3_BIT_ACT(n) (((n)&0xf)<<12)
+
+struct pll_freq {
+ UINT32 freq_mhz;
+ UINT16 major;
+ UINT16 minor;
+ UINT16 with_div;
+ UINT16 div;
+};
+
+typedef enum {
+ PLL_REG_CPU_BASE = 0x00,
+ PLL_REG_BUS_BASE = 0x20,
+ PLL_REG_MEM_BASE = 0x60,
+ PLL_REG_USB_BASE = 0x80,
+} PLL_REG_BASE_INDEX_t;
+
+typedef enum {
+ PLL_REG_OFFSET_01H = 1,
+ PLL_REG_OFFSET_02H = 2,
+ PLL_REG_OFFSET_DIV = 3,
+ PLL_REG_OFFSET_04H = 4,
+ PLL_REG_OFFSET_MAJOR = 5,
+ PLL_REG_OFFSET_MINOR = 6,
+ PLL_REG_OFFSET_07H = 7,
+} PLL_REG_OFFSET_INDEX_t;
+
+static struct pll_freq pll_freq_table[] = {
+ /* MHz Major Minor div */
+ {1600, 0x7B13, 0xB138, 0, 0x0000},
+ {1200, 0x5C4E, 0xC4EC, 0, 0x0000},
+ {1000, 0x4BEC, 0x4EC4, 0, 0x0000},
+ { 988, 0x4000, 0x0000, 0, 0x0000},
+ { 800, 0x3C00, 0x0000, 0, 0x0000},
+ { 600, 0x2E27, 0x6274, 0, 0x0000},
+ { 533, 0x2900, 0x0000, 1, 0xc797},
+ { 519, 0x27EC, 0x4EC4, 1, 0xc797},
+ { 500, 0x2676, 0x2762, 1, 0xc797},
+ { 480, 0x24EC, 0x4EC4, 0, 0x0000},
+ { 455, 0x2300, 0x0000, 1, 0xC297},
+ { 416, 0x1FD8, 0x0000, 1, 0xCB97},
+ /* 800M div 1, PLL:800M DDR:400M for mem pll only */
+ { 400, 0x1F00, 0x0000, 1, 0xCA97},
+ { 355, 0x369D, 0x89D8, 1, 0xD597},
+ /* 702M div 1, PLL:702M DDR:351M for mem pll only */
+ { 351, 0x3600, 0x0000, 1, 0xD297},
+ { 333, 0x333B, 0x13B1, 1, 0xD097},
+ /* 624M div 1, PLL:624M DDR:312M for mem pll only */
+ { 312, 0x3000, 0x0000, 1, 0xD897},
+ { 290, 0x2C9D, 0x89D8, 1, 0xE097},
+ /* 520M div 1, PLL:520M DDR:260M for mem pll only */
+ { 260, 0x2800, 0x0000, 1, 0xE897},
+ /* 800M div 2, PLL:400M DDR:200M for mem pll only */
+ { 200, 0x3D89, 0xD89C, 1, 0x0006},
+ /* DDR:156M for mem pll only */
+ { 156, 0x3000, 0x0000, 1, 0x0006},
+ /* 800M div 4, PLL:200M DDR:100M for mem pll only */
+ { 100, 0x3D89, 0xD89C, 1, 0x0005},
+ /* 800M div 8, PLL:100M DDR:50M for mem pll only */
+ { 50, 0x3D89, 0xD89C, 1, 0x0004},
+};
+
+static const struct clock_config *g_clock_config;
+
+#ifdef DO_DDR_PLL_DEBUG
+static struct clock_config clock_debug_config;
+static UINT32 ddrfreq = 400, ddr32bit = 0;
+#endif
+
+static void sys_shutdown_pll(void)
+{
+ int i;
+
+ hwp_sysCtrlAp->REG_DBG = AP_CTRL_PROTECT_UNLOCK;
+
+ if (usb_in_use) {
+ hwp_sysCtrlAp->Sel_Clock = SYS_CTRL_AP_SLOW_SEL_RF_RF
+ | SYS_CTRL_AP_CPU_SEL_FAST_SLOW
+ | SYS_CTRL_AP_BUS_SEL_FAST_FAST
+ | SYS_CTRL_AP_TIMER_SEL_FAST_FAST;
+ } else {
+ hwp_sysCtrlAp->Sel_Clock = SYS_CTRL_AP_SLOW_SEL_RF_RF
+ | SYS_CTRL_AP_CPU_SEL_FAST_SLOW
+ | SYS_CTRL_AP_BUS_SEL_FAST_SLOW
+ | SYS_CTRL_AP_TIMER_SEL_FAST_FAST;
+ }
+
+ for (i = 0; i < 3; i++) {
+ /* In download mode, rom code has been set ap bus*/
+ if (usb_in_use) {
+ if (i == AP_BUS_CLK_IDX) // ap bus
+ continue;
+ }
+ hwp_sysCtrlAp->Cfg_Pll_Ctrl[i] =
+ SYS_CTRL_AP_AP_PLL_ENABLE_POWER_DOWN |
+ SYS_CTRL_AP_AP_PLL_LOCK_RESET_RESET;
+ }
+}
+
+static void sys_setup_pll(void)
+{
+ int i;
+ UINT32 mask;
+ UINT32 locked;
+ int cnt = 10; //10us, according to IC, the pll must be locked
+
+ hwp_sysCtrlAp->REG_DBG = AP_CTRL_PROTECT_UNLOCK;
+
+ for (i = 0; i < 3; i++) {
+ /* In download mode, rom code has been set ap bus*/
+ if (usb_in_use) {
+ if (i == AP_BUS_CLK_IDX) // ap bus
+ continue;
+ }
+
+ if (AP_MEM_CLK_IDX == i)
+ hwp_sysCtrlAp->Cfg_Pll_Ctrl[i] =
+ SYS_CTRL_AP_AP_PLL_ENABLE_ENABLE |
+ SYS_CTRL_AP_AP_PLL_LOCK_RESET_NO_RESET |
+ SYS_CTRL_AP_AP_PLL_LOCK_NUM_LOW(1)|
+ SYS_CTRL_AP_AP_PLL_LOCK_NUM_HIGH(30);
+ else
+ hwp_sysCtrlAp->Cfg_Pll_Ctrl[i] =
+ SYS_CTRL_AP_AP_PLL_ENABLE_ENABLE |
+ SYS_CTRL_AP_AP_PLL_LOCK_RESET_NO_RESET |
+ SYS_CTRL_AP_AP_PLL_LOCK_NUM_LOW(6)|
+ SYS_CTRL_AP_AP_PLL_LOCK_NUM_HIGH(30);
+ }
+
+ mask = SYS_CTRL_AP_PLL_LOCKED_CPU_MASK
+ | SYS_CTRL_AP_PLL_LOCKED_BUS_MASK
+ | SYS_CTRL_AP_PLL_LOCKED_MEM_MASK
+ //| SYS_CTRL_AP_PLL_LOCKED_USB_MASK
+ ;
+ locked = SYS_CTRL_AP_PLL_LOCKED_CPU_LOCKED
+ | SYS_CTRL_AP_PLL_LOCKED_BUS_LOCKED
+ | SYS_CTRL_AP_PLL_LOCKED_MEM_LOCKED
+ //| SYS_CTRL_AP_PLL_LOCKED_USB_LOCKED
+ ;
+
+ while (((hwp_sysCtrlAp->Sel_Clock & mask) != locked) && cnt) {
+ udelay(1);
+ cnt--;
+ }
+ if (cnt == 0) {
+ printf("WARNING, cannot lock cpu/bus/mem pll 0x%08x ",
+ hwp_sysCtrlAp->Sel_Clock);
+ printf("but we run anyway ...\n");
+ }
+
+ for (i = 0; i < 3; i++) {
+ hwp_sysCtrlAp->Cfg_Pll_Ctrl[i] |=
+ SYS_CTRL_AP_AP_PLL_CLK_FAST_ENABLE_ENABLE;
+ }
+
+ hwp_sysCtrlAp->Sel_Clock = SYS_CTRL_AP_SLOW_SEL_RF_RF
+ | SYS_CTRL_AP_CPU_SEL_FAST_FAST
+ | SYS_CTRL_AP_BUS_SEL_FAST_FAST
+ | SYS_CTRL_AP_TIMER_SEL_FAST_FAST;
+}
+
+static void sys_setup_clk(void)
+{
+ // Disable some power-consuming clocks
+#ifdef CONFIG_VPU_TEST
+ hwp_sysCtrlAp->Clk_APO_Enable = SYS_CTRL_AP_ENABLE_APOC_VPU;
+ //hwp_sysCtrlAp->Clk_MEM_Enable = SYS_CTRL_AP_ENABLE_MEM_VPU;
+#else
+ hwp_sysCtrlAp->Clk_APO_Disable = SYS_CTRL_AP_DISABLE_APOC_VPU;
+ //hwp_sysCtrlAp->Clk_MEM_Disable = SYS_CTRL_AP_DISABLE_MEM_VPU;
+#endif
+
+ // Init clock gating mode
+ hwp_sysCtrlAp->Clk_CPU_Mode = 0;
+#ifdef CONFIG_VPU_TEST
+ hwp_sysCtrlAp->Clk_AXI_Mode = SYS_CTRL_AP_MODE_AXI_DMA_MANUAL | SYS_CTRL_AP_MODE_APB0_CONF_MANUAL;
+#else
+ hwp_sysCtrlAp->Clk_AXI_Mode = SYS_CTRL_AP_MODE_AXI_DMA_MANUAL;
+#endif
+ hwp_sysCtrlAp->Clk_AXIDIV2_Mode = 0;
+ hwp_sysCtrlAp->Clk_GCG_Mode = SYS_CTRL_AP_MODE_GCG_GOUDA_MANUAL
+ | SYS_CTRL_AP_MODE_GCG_CAMERA_MANUAL;
+ hwp_sysCtrlAp->Clk_AHB1_Mode = 0;
+ hwp_sysCtrlAp->Clk_APB1_Mode = 0;
+ hwp_sysCtrlAp->Clk_APB2_Mode = 0;
+#ifdef CONFIG_VPU_TEST
+ hwp_sysCtrlAp->Clk_MEM_Mode = SYS_CTRL_AP_MODE_CLK_MEM_MANUAL;
+#else
+ hwp_sysCtrlAp->Clk_MEM_Mode = 0;
+#endif
+ //hwp_sysCtrlAp->Clk_APO_Mode = SYS_CTRL_AP_MODE_APOC_VPU_MANUAL;
+
+ // Init module frequency
+ hwp_sysCtrlAp->Cfg_Clk_AP_CPU = g_clock_config->CLK_CPU;
+ hwp_sysCtrlAp->Cfg_Clk_AP_AXI = g_clock_config->CLK_AXI;
+ hwp_sysCtrlAp->Cfg_Clk_AP_GCG = g_clock_config->CLK_GCG;
+
+ if (!usb_in_use) {
+ hwp_sysCtrlAp->Cfg_Clk_AP_AHB1 = g_clock_config->CLK_AHB1;
+ }
+
+ hwp_sysCtrlAp->Cfg_Clk_AP_APB1 = g_clock_config->CLK_APB1;
+ hwp_sysCtrlAp->Cfg_Clk_AP_APB2 = g_clock_config->CLK_APB2;
+ hwp_sysCtrlAp->Cfg_Clk_AP_MEM = g_clock_config->CLK_MEM;
+ hwp_sysCtrlAp->Cfg_Clk_AP_GPU = g_clock_config->CLK_GPU;
+ hwp_sysCtrlAp->Cfg_Clk_AP_VPU = g_clock_config->CLK_VPU;
+ hwp_sysCtrlAp->Cfg_Clk_AP_VOC = g_clock_config->CLK_VOC;
+ hwp_sysCtrlAp->Cfg_Clk_AP_SFLSH = g_clock_config->CLK_SFLSH;
+}
+
+static void print_sys_reg(char *name, UINT32 value)
+{
+ printf("clk %s = %lx\n", name, value);
+}
+
+static void sys_dump_clk(void)
+{
+ print_sys_reg("CPU", hwp_sysCtrlAp->Cfg_Clk_AP_CPU);
+ print_sys_reg("AXI", hwp_sysCtrlAp->Cfg_Clk_AP_AXI);
+ print_sys_reg("GCG", hwp_sysCtrlAp->Cfg_Clk_AP_GCG);
+ print_sys_reg("AHB1", hwp_sysCtrlAp->Cfg_Clk_AP_AHB1);
+ print_sys_reg("APB1", hwp_sysCtrlAp->Cfg_Clk_AP_APB1);
+ print_sys_reg("APB2", hwp_sysCtrlAp->Cfg_Clk_AP_APB2);
+ print_sys_reg("MEM", hwp_sysCtrlAp->Cfg_Clk_AP_MEM);
+ print_sys_reg("GPU", hwp_sysCtrlAp->Cfg_Clk_AP_GPU);
+ print_sys_reg("VPU", hwp_sysCtrlAp->Cfg_Clk_AP_VPU);
+ print_sys_reg("VOC", hwp_sysCtrlAp->Cfg_Clk_AP_VOC);
+ print_sys_reg("SFLSH", hwp_sysCtrlAp->Cfg_Clk_AP_SFLSH);
+}
+
+static int pll_freq_set(UINT32 reg_base, UINT32 freq_mhz)
+{
+ int i;
+ struct pll_freq *freq;
+ unsigned int major, minor;
+ unsigned short value_02h;
+
+ /* find pll_freq */
+ for (i = 0; i < ARRAY_SIZE(pll_freq_table); i++) {
+ if (pll_freq_table[i].freq_mhz == freq_mhz)
+ break;
+ }
+ if (i >= ARRAY_SIZE(pll_freq_table)) {
+ printf("pll_freq_set, fail to find freq\n");
+ return -1;
+ }
+
+ freq = &pll_freq_table[i];
+ if (freq->with_div && (reg_base == PLL_REG_MEM_BASE)) {
+ ispi_reg_write(reg_base + PLL_REG_OFFSET_DIV,
+ freq->div);
+ // Calculate the real MEM PLL freq
+ freq_mhz *= (1 << (8 - (freq->div & 0x7)));
+ }
+ if (freq_mhz >= 800 || reg_base == PLL_REG_USB_BASE) {
+ value_02h = 0x0309;
+ // Div PLL freq by 2
+ minor = ((freq->major & 0xFFFF) << 14) |
+ ((freq->minor >> 2) & 0x3FFF);
+ minor >>= 1;
+ // Recalculate the divider
+ major = (minor >> 14) & 0xFFFF;
+ minor = (minor << 2) & 0xFFFF;
+ } else {
+ value_02h = 0x0209;
+ major = freq->major;
+ minor = freq->minor;
+ }
+ if (reg_base == PLL_REG_USB_BASE)
+ value_02h ^= (1 << 8);
+ ispi_reg_write(reg_base + PLL_REG_OFFSET_02H, value_02h);
+ ispi_reg_write(reg_base + PLL_REG_OFFSET_MAJOR, major);
+ ispi_reg_write(reg_base + PLL_REG_OFFSET_MINOR, minor);
+ ispi_reg_write(reg_base + PLL_REG_OFFSET_07H, 0x0010);
+
+ return 0;
+}
+
+static void pll_setup_freq(void)
+{
+ pll_freq_set(PLL_REG_CPU_BASE, g_clock_config->PLL_FREQ_CPU);
+ // Always configure BUS PLL, even when it is being used
+ pll_freq_set(PLL_REG_BUS_BASE, g_clock_config->PLL_FREQ_BUS);
+ pll_freq_set(PLL_REG_MEM_BASE, g_clock_config->PLL_FREQ_MEM);
+ pll_freq_set(PLL_REG_USB_BASE, g_clock_config->PLL_FREQ_USB);
+}
+
+static void print_pll_freq(char *name, UINT32 value)
+{
+ printf("pll freq %s = %d\n", name, (int)value);
+}
+
+static void sys_dump_pll_freq(void)
+{
+ print_pll_freq("CPU", g_clock_config->PLL_FREQ_CPU);
+ print_pll_freq("BUS", g_clock_config->PLL_FREQ_BUS);
+ print_pll_freq("MEM", g_clock_config->PLL_FREQ_MEM);
+ //print_pll_freq("USB", g_clock_config->PLL_FREQ_USB);
+}
+
+static void pmu_get_efuse_dcdc(int buckVoltLow[])
+{
+ static const u8 setBitCnt[8] = { 0, 1, 1, 2, 1, 2, 2, 3, };
+ u16 dcdc;
+ int i;
+
+ ispi_reg_write(0x51, 0x02ed);
+ udelay(2000);
+ ispi_reg_write(0x51, 0x02fd);
+ dcdc = ispi_reg_read(0x52);
+ ispi_reg_write(0x51, 0x0200);
+
+ for (i = 0; i < 4; i++) {
+ buckVoltLow[i] = (setBitCnt[dcdc & 0x7] > 1);
+ dcdc >>= 3;
+ }
+}
+
+static void pmu_setup_init(void)
+{
+ u32 value;
+ int buck_volt_low[4] = { 0, };
+
+ rda_nand_iodrive_set();
+
+#ifdef CONFIG_RDA_PDL
+ enable_charger(0);
+#endif
+
+ ispi_open(1);
+
+ // Disable vibrator
+ ispi_reg_write(0x03, 0x9FFF);
+ // Enable bandgap chopper mode
+ ispi_reg_write(0x0F, 0x1E90);
+ // Enable high AC throttling
+ ispi_reg_write(0x12, 0x1218);
+#ifdef TARGET_TABLET_MODE
+ // Charger current (cc = 6, pre = 7)
+ ispi_reg_write(0x13, 0x1B70);
+#else
+ // Charger current (cc = 2, pre = 7)
+ ispi_reg_write(0x13, 0x1970);
+#endif
+ // Vcore DCDC freq
+ ispi_reg_write(0x2D, 0x96BA);
+ ispi_reg_write(0x2E, 0x12AA);
+ // Get efuse dcdc
+ pmu_get_efuse_dcdc(buck_volt_low);
+ // Vcore voltage
+ value = 0x9244;
+ value = PMU_SET_BITFIELD(value, RDA_PMU_VBUCK1_BIT_ACT,
+ PMU_VBUCK1_VAL +
+ ((PMU_VBUCK1_VAL < 15 && buck_volt_low[0]) ? 1 : 0));
+ ispi_reg_write(0x2F, value);
+ // DDR PWM mode
+ ispi_reg_write(0x0D, 0x92D0);
+ // DDR voltage
+ value = 0xAAB5;
+ value = PMU_SET_BITFIELD(value, RDA_PMU_VBUCK3_BIT_ACT,
+ PMU_VBUCK3_VAL +
+ ((PMU_VBUCK3_VAL < 15 && buck_volt_low[2]) ? 1 : 0));
+#ifdef PMU_VBUCK4_VAL
+ value = PMU_SET_BITFIELD(value, RDA_PMU_VBUCK4_BIT_ACT,
+ PMU_VBUCK4_VAL +
+ ((PMU_VBUCK4_VAL < 15 && buck_volt_low[3]) ? 1 : 0));
+ value ^= RDA_PMU_VBUCK4_BIT_ACT(8);
+ // vBuck4 in low voltage range
+ ispi_reg_write(0x36, 0x6E45);
+#else
+ ispi_reg_write(0x36, 0x6E54);
+#endif
+ ispi_reg_write(0x2A, value);
+ // DDR power parameters
+ ispi_reg_write(0x4A, 0x96AA);
+ ispi_reg_write(0x4B, 0x96AA);
+
+ ispi_open(0);
+}
+
+static void setup_ddr_vtt(int vtt)
+{
+ printf("setup ddr vtt to %d\n", vtt);
+ ispi_reg_write(0x69, g_clock_config->DDR_TIMING_069H);
+}
+
+#if 0
+/*
+ * we initialize usb clock, but this won't cause the usb clock jitter,
+ * because wo don't setup the usb pll
+ */
+static void usb_clock_pre_init(void)
+{
+ ispi_reg_write(0x83, 0x72ef);
+ ispi_reg_write(0x89, 0x7400);
+}
+#endif
+
+static void pll_setup_init(void)
+{
+ setup_ddr_vtt(DDR_VTT_VAL);
+
+ if (g_clock_config->DDR_CHAN_1_VALID) {
+ ispi_reg_write(0x100, g_clock_config->DDR_TIMING_100H);
+ ispi_reg_write(0x101, g_clock_config->DDR_TIMING_101H);
+ ispi_reg_write(0x102, g_clock_config->DDR_TIMING_102H);
+ ispi_reg_write(0x103, g_clock_config->DDR_TIMING_103H);
+ ispi_reg_write(0x104, g_clock_config->DDR_TIMING_104H);
+ ispi_reg_write(0x105, g_clock_config->DDR_TIMING_105H);
+ ispi_reg_write(0x106, g_clock_config->DDR_TIMING_106H);
+ ispi_reg_write(0x107, g_clock_config->DDR_TIMING_107H);
+ ispi_reg_write(0x108, g_clock_config->DDR_TIMING_108H);
+ ispi_reg_write(0x109, g_clock_config->DDR_TIMING_109H);
+ ispi_reg_write(0x10A, g_clock_config->DDR_TIMING_10AH);
+ ispi_reg_write(0x10B, g_clock_config->DDR_TIMING_10BH);
+ ispi_reg_write(0x10C, g_clock_config->DDR_TIMING_10CH);
+ ispi_reg_write(0x10D, g_clock_config->DDR_TIMING_10DH);
+ ispi_reg_write(0x10E, g_clock_config->DDR_TIMING_10EH);
+ ispi_reg_write(0x10F, g_clock_config->DDR_TIMING_10FH);
+ }
+
+ if (g_clock_config->DDR_CHAN_2_VALID) {
+ ispi_reg_write(0x120, g_clock_config->DDR_TIMING_120H);
+ ispi_reg_write(0x121, g_clock_config->DDR_TIMING_121H);
+ ispi_reg_write(0x122, g_clock_config->DDR_TIMING_122H);
+ ispi_reg_write(0x123, g_clock_config->DDR_TIMING_123H);
+ ispi_reg_write(0x124, g_clock_config->DDR_TIMING_124H);
+ ispi_reg_write(0x125, g_clock_config->DDR_TIMING_125H);
+ ispi_reg_write(0x126, g_clock_config->DDR_TIMING_126H);
+ ispi_reg_write(0x127, g_clock_config->DDR_TIMING_127H);
+ ispi_reg_write(0x128, g_clock_config->DDR_TIMING_128H);
+ ispi_reg_write(0x129, g_clock_config->DDR_TIMING_129H);
+ ispi_reg_write(0x12A, g_clock_config->DDR_TIMING_12AH);
+ ispi_reg_write(0x12B, g_clock_config->DDR_TIMING_12BH);
+ ispi_reg_write(0x12C, g_clock_config->DDR_TIMING_12CH);
+ ispi_reg_write(0x12D, g_clock_config->DDR_TIMING_12DH);
+ ispi_reg_write(0x12E, g_clock_config->DDR_TIMING_12EH);
+ ispi_reg_write(0x12F, g_clock_config->DDR_TIMING_12FH);
+ }
+
+ if (g_clock_config->DDR_CHAN_3_VALID) {
+ ispi_reg_write(0x140, g_clock_config->DDR_TIMING_140H);
+ ispi_reg_write(0x141, g_clock_config->DDR_TIMING_141H);
+ ispi_reg_write(0x142, g_clock_config->DDR_TIMING_142H);
+ ispi_reg_write(0x143, g_clock_config->DDR_TIMING_143H);
+ ispi_reg_write(0x144, g_clock_config->DDR_TIMING_144H);
+ ispi_reg_write(0x145, g_clock_config->DDR_TIMING_145H);
+ ispi_reg_write(0x146, g_clock_config->DDR_TIMING_146H);
+ ispi_reg_write(0x147, g_clock_config->DDR_TIMING_147H);
+ ispi_reg_write(0x148, g_clock_config->DDR_TIMING_148H);
+ ispi_reg_write(0x149, g_clock_config->DDR_TIMING_149H);
+ ispi_reg_write(0x14A, g_clock_config->DDR_TIMING_14AH);
+ ispi_reg_write(0x14B, g_clock_config->DDR_TIMING_14BH);
+ ispi_reg_write(0x14C, g_clock_config->DDR_TIMING_14CH);
+ ispi_reg_write(0x14D, g_clock_config->DDR_TIMING_14DH);
+ ispi_reg_write(0x14E, g_clock_config->DDR_TIMING_14EH);
+ ispi_reg_write(0x14F, g_clock_config->DDR_TIMING_14FH);
+ }
+
+ if (g_clock_config->DDR_CHAN_4_VALID) {
+ ispi_reg_write(0x160, g_clock_config->DDR_TIMING_160H);
+ ispi_reg_write(0x161, g_clock_config->DDR_TIMING_161H);
+ ispi_reg_write(0x162, g_clock_config->DDR_TIMING_162H);
+ ispi_reg_write(0x163, g_clock_config->DDR_TIMING_163H);
+ ispi_reg_write(0x164, g_clock_config->DDR_TIMING_164H);
+ ispi_reg_write(0x165, g_clock_config->DDR_TIMING_165H);
+ ispi_reg_write(0x166, g_clock_config->DDR_TIMING_166H);
+ ispi_reg_write(0x167, g_clock_config->DDR_TIMING_167H);
+ ispi_reg_write(0x168, g_clock_config->DDR_TIMING_168H);
+ ispi_reg_write(0x169, g_clock_config->DDR_TIMING_169H);
+ ispi_reg_write(0x16A, g_clock_config->DDR_TIMING_16AH);
+ ispi_reg_write(0x16B, g_clock_config->DDR_TIMING_16BH);
+ ispi_reg_write(0x16C, g_clock_config->DDR_TIMING_16CH);
+ ispi_reg_write(0x16D, g_clock_config->DDR_TIMING_16DH);
+ ispi_reg_write(0x16E, g_clock_config->DDR_TIMING_16EH);
+ ispi_reg_write(0x16F, g_clock_config->DDR_TIMING_16FH);
+ }
+
+ ispi_reg_write(0x180, g_clock_config->DDR_TIMING_180H);
+ ispi_reg_write(0x181, g_clock_config->DDR_TIMING_181H);
+ ispi_reg_write(0x182, g_clock_config->DDR_TIMING_182H);
+ ispi_reg_write(0x183, g_clock_config->DDR_TIMING_183H);
+ ispi_reg_write(0x184, g_clock_config->DDR_TIMING_184H);
+ ispi_reg_write(0x185, g_clock_config->DDR_TIMING_185H);
+ ispi_reg_write(0x186, g_clock_config->DDR_TIMING_186H);
+ ispi_reg_write(0x187, g_clock_config->DDR_TIMING_187H);
+ ispi_reg_write(0x188, g_clock_config->DDR_TIMING_188H);
+ ispi_reg_write(0x189, g_clock_config->DDR_TIMING_189H);
+ ispi_reg_write(0x18A, g_clock_config->DDR_TIMING_18AH);
+ ispi_reg_write(0x18B, g_clock_config->DDR_TIMING_18BH);
+ ispi_reg_write(0x18C, g_clock_config->DDR_TIMING_18CH);
+
+ //usb_clock_pre_init();
+
+ udelay(5000);
+}
+
+static void pll_setup_mem(void)
+{
+}
+
+static void pll_setup_mem_cal(void)
+{
+}
+
+static void print_pll_reg(UINT32 index, UINT32 value)
+{
+ printf("pll reg %lx = %lx\n", index, value);
+}
+
+static void pll_dump_reg(void)
+{
+ print_pll_reg(0x005, ispi_reg_read(0x005));
+ print_pll_reg(0x006, ispi_reg_read(0x006));
+ print_pll_reg(0x063, ispi_reg_read(0x063));
+ print_pll_reg(0x065, ispi_reg_read(0x065));
+ print_pll_reg(0x066, ispi_reg_read(0x066));
+ print_pll_reg(0x069, ispi_reg_read(0x069));
+
+ if (g_clock_config->DDR_CHAN_1_VALID)
+ {
+ print_pll_reg(0x100, ispi_reg_read(0x100));
+ print_pll_reg(0x101, ispi_reg_read(0x101));
+ print_pll_reg(0x102, ispi_reg_read(0x102));
+ print_pll_reg(0x103, ispi_reg_read(0x103));
+ print_pll_reg(0x104, ispi_reg_read(0x104));
+ print_pll_reg(0x105, ispi_reg_read(0x105));
+ print_pll_reg(0x106, ispi_reg_read(0x106));
+ print_pll_reg(0x107, ispi_reg_read(0x107));
+ print_pll_reg(0x108, ispi_reg_read(0x108));
+ print_pll_reg(0x109, ispi_reg_read(0x109));
+ print_pll_reg(0x10A, ispi_reg_read(0x10A));
+ print_pll_reg(0x10B, ispi_reg_read(0x10B));
+ print_pll_reg(0x10C, ispi_reg_read(0x10C));
+ print_pll_reg(0x10D, ispi_reg_read(0x10D));
+ print_pll_reg(0x10E, ispi_reg_read(0x10E));
+ print_pll_reg(0x10F, ispi_reg_read(0x10F));
+ }
+
+ if (g_clock_config->DDR_CHAN_2_VALID)
+ {
+ print_pll_reg(0x120, ispi_reg_read(0x120));
+ print_pll_reg(0x121, ispi_reg_read(0x121));
+ print_pll_reg(0x122, ispi_reg_read(0x122));
+ print_pll_reg(0x123, ispi_reg_read(0x123));
+ print_pll_reg(0x124, ispi_reg_read(0x124));
+ print_pll_reg(0x125, ispi_reg_read(0x125));
+ print_pll_reg(0x126, ispi_reg_read(0x126));
+ print_pll_reg(0x127, ispi_reg_read(0x127));
+ print_pll_reg(0x128, ispi_reg_read(0x128));
+ print_pll_reg(0x129, ispi_reg_read(0x129));
+ print_pll_reg(0x12A, ispi_reg_read(0x12A));
+ print_pll_reg(0x12B, ispi_reg_read(0x12B));
+ print_pll_reg(0x12C, ispi_reg_read(0x12C));
+ print_pll_reg(0x12D, ispi_reg_read(0x12D));
+ print_pll_reg(0x12E, ispi_reg_read(0x12E));
+ print_pll_reg(0x12F, ispi_reg_read(0x12F));
+ }
+
+ if (g_clock_config->DDR_CHAN_3_VALID)
+ {
+ print_pll_reg(0x140, ispi_reg_read(0x140));
+ print_pll_reg(0x141, ispi_reg_read(0x141));
+ print_pll_reg(0x142, ispi_reg_read(0x142));
+ print_pll_reg(0x143, ispi_reg_read(0x143));
+ print_pll_reg(0x144, ispi_reg_read(0x144));
+ print_pll_reg(0x145, ispi_reg_read(0x145));
+ print_pll_reg(0x146, ispi_reg_read(0x146));
+ print_pll_reg(0x147, ispi_reg_read(0x147));
+ print_pll_reg(0x148, ispi_reg_read(0x148));
+ print_pll_reg(0x149, ispi_reg_read(0x149));
+ print_pll_reg(0x14A, ispi_reg_read(0x14A));
+ print_pll_reg(0x14B, ispi_reg_read(0x14B));
+ print_pll_reg(0x14C, ispi_reg_read(0x14C));
+ print_pll_reg(0x14D, ispi_reg_read(0x14D));
+ print_pll_reg(0x14E, ispi_reg_read(0x14E));
+ print_pll_reg(0x14F, ispi_reg_read(0x14F));
+ }
+
+ if (g_clock_config->DDR_CHAN_4_VALID)
+ {
+ print_pll_reg(0x160, ispi_reg_read(0x160));
+ print_pll_reg(0x161, ispi_reg_read(0x161));
+ print_pll_reg(0x162, ispi_reg_read(0x162));
+ print_pll_reg(0x163, ispi_reg_read(0x163));
+ print_pll_reg(0x164, ispi_reg_read(0x164));
+ print_pll_reg(0x165, ispi_reg_read(0x165));
+ print_pll_reg(0x166, ispi_reg_read(0x166));
+ print_pll_reg(0x167, ispi_reg_read(0x167));
+ print_pll_reg(0x168, ispi_reg_read(0x168));
+ print_pll_reg(0x169, ispi_reg_read(0x169));
+ print_pll_reg(0x16A, ispi_reg_read(0x16A));
+ print_pll_reg(0x16B, ispi_reg_read(0x16B));
+ print_pll_reg(0x16C, ispi_reg_read(0x16C));
+ print_pll_reg(0x16D, ispi_reg_read(0x16D));
+ print_pll_reg(0x16E, ispi_reg_read(0x16E));
+ print_pll_reg(0x16F, ispi_reg_read(0x16F));
+ }
+
+ print_pll_reg(0x180, ispi_reg_read(0x180));
+ print_pll_reg(0x181, ispi_reg_read(0x181));
+ print_pll_reg(0x182, ispi_reg_read(0x182));
+ print_pll_reg(0x183, ispi_reg_read(0x183));
+ print_pll_reg(0x184, ispi_reg_read(0x184));
+ print_pll_reg(0x185, ispi_reg_read(0x185));
+ print_pll_reg(0x186, ispi_reg_read(0x186));
+ print_pll_reg(0x187, ispi_reg_read(0x187));
+ print_pll_reg(0x188, ispi_reg_read(0x188));
+ print_pll_reg(0x189, ispi_reg_read(0x189));
+ print_pll_reg(0x18A, ispi_reg_read(0x18A));
+ print_pll_reg(0x18B, ispi_reg_read(0x18B));
+ print_pll_reg(0x18C, ispi_reg_read(0x18C));
+}
+
+static int clock_save_config(void)
+{
+ /* save config to nand */
+ return 1;
+}
+
+#ifdef DO_DDR_PLL_DEBUG
+
+static int ddr_get_freq(UINT8 chioce)
+{
+ switch(chioce)
+ {
+ case 1:
+ return 50;
+ case 2:
+ return 100;
+ case 3:
+ return 156;
+ case 4:
+ return 200;
+ case 5:
+ return 290;
+ case 6:
+ return 333;
+ case 7:
+ return 355;
+ case 8:
+ return 400;
+ case 9:
+ return 416;
+ case 10:
+ return 455;
+ case 11:
+ return 519;
+ case 12:
+ return 533;
+ case 13:
+ return 260;
+ default:
+ return -1;
+ }
+}
+
+static void freq_choose(void)
+{
+ UINT8 i = 0, buf[3] = {0}, choice = 0;
+ INT32 freq_temp = 0;
+
+ printf("\nPlese choose the ddr Freq:");
+ printf("\n1.50M 2.100M 3.156M 4.200M 5.290M 6.333M 7.355M 8.400M 9.416M 10.455M 11.519M 12.533M 13.260M");
+ printf("\nThe number is:");
+
+ while(1)
+ {
+ if (i > 2)
+ {
+ printf("\n Sorry, you input is wrong. Please input again:");
+ i = 0;
+ }
+ buf[i] = serial_getc();
+ serial_putc(buf[i]);
+
+ if ( ('\r' == buf[i]) || ('\n' == buf[i]))
+ {
+ serial_puts("\n");
+ break;
+ }
+
+ i++;
+ }
+
+ if (1 == i)
+ choice = buf[0] - 0x30;
+ else if (2 == i)
+ choice = 10*(buf[0] - 0x30) + (buf[1] - 0x30);
+ else
+ return;
+
+ freq_temp = ddr_get_freq(choice);
+ if (-1 == freq_temp )
+ printf("\n Sorry, the fre you choose is wrong");
+ ddrfreq = freq_temp;
+}
+
+static void data_bits_choose(void)
+{
+ UINT8 i = 0, buf[2] = {0};
+
+ printf("\nPlese choose the ddr data bits:");
+ printf("\n1.16 2.32");
+ printf("\nThe number is:");
+
+ while(1)
+ {
+ buf[i] =serial_getc();
+
+ if (i == 1)
+ {
+ if (('\r' == buf[i]) || ('\n' == buf[i]))
+ {
+ if (1 == (buf[0] - 0x30))
+ ddr32bit = 0;
+ else
+ ddr32bit = 1;
+ return;
+ }
+ else
+ {
+ printf("\n Sorry, you input is wrong. Please input again:");
+ i = 0;
+ continue;
+ }
+ }
+
+ serial_putc(buf[i]);
+
+ if ((buf[i] - 0x30) > 2 || 0 == (buf[i] - 0x30))
+ printf("\n Sorry, you input is wrong. Please input again:");
+ else
+ i++;
+ }
+}
+
+#if 0
+static void pmu_setup_calibration_voltage(UINT8 vcoreselect)
+{
+ UINT8 buf[3] = {0}, voltage = 0;
+ int i = 0;
+ UINT32 reg_value,temp, regid = 0;
+
+ ispi_open(1);
+ if (1 == vcoreselect)
+ {
+ regid = 0x2f;
+ printf("\nPlese input vcore voltage(0 ~ 15):");
+ }
+ else
+ {
+ regid = 0x2a;
+ printf("\nPlese input DDR voltage(0 ~ 15):");
+ }
+
+
+ while(1)
+ {
+ if (i > 2)
+ {
+ printf("\n Sorry, you input is wrong. Please input again:");
+ i = 0;
+ }
+ buf[i] = serial_getc();
+ serial_putc(buf[i]);
+
+ if ( ('\r' == buf[i]) || ('\n' == buf[i]))
+ {
+ printf("\n");
+ break;
+ }
+
+ i++;
+ }
+
+ if (1 == i)
+ voltage = buf[0] - 0x30;
+ else if (2 == i)
+ voltage = 10*(buf[0] - 0x30) + (buf[1] - 0x30);
+ else
+ return;
+
+ temp = (UINT32)voltage;
+ temp = (temp & 0xf) << 12;
+ reg_value = ispi_reg_read(regid);
+ reg_value &= ~(0xf << 12);
+ reg_value |= temp ;
+ ispi_reg_write(regid, reg_value);
+ mdelay(100);
+}
+#endif
+
+static void pmu_setup_calibration_voltage(UINT8 vcoreselect)
+{
+ UINT8 buf[3] = {0}, voltage = 0;
+ int i = 0;
+ UINT32 reg_value,temp, regid = 0;
+
+ ispi_open(1);
+ if (1 == vcoreselect)
+ {
+ regid = 0x2f;
+ printf("\nPlese input vcore voltage(0 ~ 15):");
+ }
+ else
+ {
+ regid = 0x2a;
+ if (2 == vcoreselect)
+ printf("\nPlese input DDR buck3 voltage(0 ~ 15):");
+ else
+ printf("\nPlese input DDR buck4 voltage(0 ~ 15):");
+ }
+
+ while(1)
+ {
+ if (i > 2)
+ {
+ printf("\n Sorry, you input is wrong. Please input again:");
+ i = 0;
+ }
+ buf[i] = serial_getc();
+ serial_putc(buf[i]);
+
+ if ( ('\r' == buf[i]) || ('\n' == buf[i]))
+ {
+ printf("\n");
+ break;
+ }
+
+ i++;
+ }
+
+ if (1 == i)
+ voltage = buf[0] - 0x30;
+ else if (2 == i)
+ voltage = 10*(buf[0] - 0x30) + (buf[1] - 0x30);
+ else
+ return;
+
+ if ((vcoreselect == 1) || (vcoreselect == 2))
+ {
+ temp = (UINT32)voltage;
+ temp = (temp & 0xf) << 12;
+ reg_value = ispi_reg_read(regid);
+ reg_value &= ~(0xf << 12);
+ reg_value |= temp ;
+ ispi_reg_write(regid, reg_value);
+ mdelay(100);
+ }
+ else
+ {
+ temp = (UINT32)voltage;
+ temp = (temp & 0xf) << 4;
+ reg_value = ispi_reg_read(regid);
+ reg_value &= ~(0xf << 4);
+ reg_value |= temp ;
+ reg_value ^= RDA_PMU_VBUCK4_BIT_ACT(8);
+ ispi_reg_write(regid, reg_value);
+ ispi_reg_write(0x0D, 0x92D0);
+ ispi_reg_write(0x4B, 0x96A8);
+ mdelay(100);
+ }
+}
+
+static void pmu_buck4_buck3_choose(void)
+{
+ UINT8 i = 0, buf[2] = {0};
+ UINT8 ddr_voltage_source = 0;
+
+ printf("\nPlese choose the ddr voltage:");
+ printf("\n1.DDR3L 2.DDR3");
+ printf("\nThe number is:");
+
+ while(1)
+ {
+ buf[i] =serial_getc();
+
+ if (i == 1)
+ {
+ if (('\r' == buf[i]) || ('\n' == buf[i]))
+ {
+ if (1 == (buf[0] - 0x30))
+ ddr_voltage_source =2;
+ else{
+ ddr_voltage_source = 3;
+ pmu_setup_calibration_voltage(2);
+ }
+ pmu_setup_calibration_voltage(ddr_voltage_source);
+ return;
+ }
+ else
+ {
+ printf("\n Sorry, you input is wrong. Please input again:");
+ i = 0;
+ continue;
+ }
+ }
+
+ serial_putc(buf[i]);
+
+ if ((buf[i] - 0x30) > 2 || 0 == (buf[i] - 0x30))
+ printf("\n Sorry, you input is wrong. Please input again:");
+ else
+ i++;
+ }
+}
+
+
+void clock_load_ddr_cal_config(void)
+{
+ clock_debug_config.PLL_FREQ_MEM = ddrfreq;
+ if (ddrfreq < 200)
+ clock_debug_config.DDR_FLAGS |= DDR_FLAGS_DLLOFF;
+ else
+ clock_debug_config.DDR_FLAGS &= ~DDR_FLAGS_DLLOFF;
+
+ if (0 == ddr32bit)
+ {
+ clock_debug_config.DDR_CHAN_3_VALID = 0;
+ clock_debug_config.DDR_CHAN_4_VALID = 0;
+ }
+
+ clock_debug_config.DDR_PARA &= ~DDR_PARA_MEM_BITS_MASK;
+ if (0 == ddr32bit)
+ clock_debug_config.DDR_PARA |= DDR_PARA_MEM_BITS(1);
+ else
+ clock_debug_config.DDR_PARA |= DDR_PARA_MEM_BITS(2);
+}
+
+static int serial_gets(UINT8 *pstr)
+{
+ UINT32 length;
+
+ length = 0;
+ while(1) {
+ pstr[length] = serial_getc();
+ if(pstr[length] == '\r') {
+ pstr[length] = 0x00;
+ break;
+ }
+ else if( pstr[length] == '\b' ) {
+ if(length>0) {
+ length --;
+ printf("\b");
+ }
+ }
+ else {
+ serial_putc(pstr[length]);
+ length ++;
+ }
+
+ if(length > 32)
+ return -1;
+ }
+ return length;
+}
+
+UINT32 asc2hex(UINT8 *pstr, UINT8 len)
+{
+ UINT8 i,ch,mylen;
+ UINT32 hexvalue;
+
+ for(mylen=0,i=0; i<8; i++)
+ {
+ if( pstr[i] == 0 )
+ break;
+ mylen ++;
+ }
+ if( len != 0 )
+ {
+ if(mylen>len)
+ mylen = len;
+ }
+ if(mylen>8)
+ mylen = 8;
+
+ hexvalue = 0;
+ for (i = 0; i < mylen; i++)
+ {
+ hexvalue <<= 4;
+ ch = *(pstr+i);
+ if((ch>='0') && (ch<='9'))
+ hexvalue |= ch - '0';
+ else if((ch>='A') && (ch<='F'))
+ hexvalue |= ch - ('A' - 10);
+ else if((ch>='a') && (ch<='f'))
+ hexvalue |= ch - ('a' - 10);
+ else
+ ;
+ }
+ return(hexvalue);
+}
+
+static int process_cmd(char * cmd)
+{
+ char cmd_element[3][16] = {{0}};
+ char * cmd_temp = cmd;
+ UINT8 i = 0, cmd_element_num = 0, former_space = 1;
+ UINT16 reg = 0, reg_value = 0;
+
+ if (NULL == cmd)
+ return -1;
+
+ while(('\0' != *cmd_temp) && ('\r' != *cmd_temp) && ('\n' != *cmd_temp))
+ {
+ if (' ' == * cmd_temp)
+ {
+ if (0 == former_space)
+ {
+ former_space = 1;
+ cmd_element[cmd_element_num][i] = '\0';
+ cmd_element_num++;
+ if (cmd_element_num > 2)
+ return -1;
+
+ i = 0;
+ }
+ }
+ else
+ {
+ former_space = 0;
+ cmd_element[cmd_element_num][i] = *cmd_temp;
+ i++;
+ if (i > 6)
+ return -1;
+ }
+
+ cmd_temp++;
+ }
+
+ cmd_element[cmd_element_num][i] = '\0';
+
+ if (!strcmp(cmd_element[0], "read"))
+ {
+ if (cmd_element_num == 2)
+ return -1;
+ if (('0' != cmd_element[1][0]) || ('x' != cmd_element[1][1]))
+ return -1;
+ reg = (UINT16)asc2hex((UINT8 *)&cmd_element[1][2], 4);
+ reg_value = ispi_reg_read(reg);
+ printf("value = 0x%x", reg_value);
+ printf("\nddrPll#");
+ }
+ else if (!strcmp(cmd_element[0], "write"))
+ {
+ if (cmd_element_num != 2)
+ return -1;
+ if (('0' != cmd_element[1][0]) || ('x' != cmd_element[1][1])
+ || ('0' != cmd_element[2][0]) || ('x' != cmd_element[2][1]))
+ return -1;
+
+ reg = (UINT16)asc2hex((UINT8 *)&cmd_element[1][2], 4);
+ reg_value = (UINT16)asc2hex((UINT8 *)&cmd_element[2][2], 4);
+ ispi_reg_write(reg, reg_value);
+ }
+ else if (!strcmp(cmd_element[0], "finish"))
+ {
+ return 1;
+ }
+ else if (!strcmp(cmd_element[0], "dump"))
+ {
+ pll_dump_reg();
+ printf("ddrPll#");
+ }
+ else
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+static void cmd_input(void)
+{
+ char cmd[48] = {0};
+ int len = 0;
+
+ ispi_open(0);
+ printf("\nddrPll#");
+ while(1)
+ {
+ len = serial_gets((UINT8 *)cmd);
+ printf("\nddrPll#");
+ if (len > 0)
+ {
+ int result = 0;
+
+ result = process_cmd(cmd);
+ if (-1 == result)
+ printf("command error! \nddrPll#");
+ else if (1 == result)
+ break;
+ else
+ continue;
+ }
+ }
+
+ return;
+}
+
+#endif /* DO_DDR_PLL_DEBUG */
+
+int clock_init(void)
+{
+#ifdef DO_DDR_PLL_DEBUG
+ char choice = 'n';
+#endif
+
+ /* First check current usb usage */
+ check_usb_usage();
+
+ printf("Init Clock ...\n");
+ g_clock_config = get_default_clock_config();
+
+ printf("Clock config ver: %d.%d\n",
+ g_clock_config->VERSION_MAJOR, g_clock_config->VERSION_MINOR);
+
+ pmu_setup_init();
+
+#ifdef DO_DDR_PLL_DEBUG
+ printf("If you want to config the ddr para manully ?(y = yes, n = no) \n");
+ choice = serial_getc();
+ if (choice == 'y')
+ {
+ memcpy(&clock_debug_config, g_clock_config,
+ sizeof(clock_debug_config));
+ g_clock_config = &clock_debug_config;
+ pmu_setup_calibration_voltage(1);
+ pmu_buck4_buck3_choose();
+ freq_choose();
+ data_bits_choose();
+ clock_load_ddr_cal_config();
+ }
+#endif
+
+ sys_shutdown_pll();
+ ispi_open(0);
+ pll_setup_init();
+#ifdef DO_DDR_PLL_DEBUG
+ if (choice == 'y')
+ cmd_input();
+#endif
+ pll_setup_freq();
+ sys_setup_pll();
+ sys_setup_clk();
+
+ if (g_clock_config->DDR_CAL) {
+ printf("Init DDR for ddr_cal\n");
+ ddr_init(g_clock_config->DDR_FLAGS, g_clock_config->DDR_PARA);
+ printf("Done\n");
+ pll_setup_mem_cal();
+ clock_save_config();
+ } else {
+ pll_setup_mem();
+ }
+
+ sys_dump_pll_freq();
+ sys_dump_clk();
+ pll_dump_reg();
+
+ printf("Init DDR, flag = 0x%04x, para = 0x%08lx\n",
+ g_clock_config->DDR_FLAGS, g_clock_config->DDR_PARA);
+ ddr_init(g_clock_config->DDR_FLAGS, g_clock_config->DDR_PARA);
+ printf("Done\n");
+
+ #ifdef DO_SIMPLE_DDR_TEST
+ mem_test_write();
+ mem_test_read();
+#endif
+
+ return 0;
+}
+
+#else /* CONFIG_RDA_FPGA */
+
+int clock_init(void)
+{
+ u16 ddr_flags = DDR_FLAGS_DLLOFF
+ | DDR_FLAGS_ODT(1)
+ | DDR_FLAGS_RON(0);
+ //16bit
+ u32 ddr_para = DDR_PARA_MEM_BITS(2)
+ | DDR_PARA_BANK_BITS(3)
+ | DDR_PARA_ROW_BITS(3)
+ | DDR_PARA_COL_BITS(1);
+
+ printf("Init DDR\n");
+ ddr_init(ddr_flags, ddr_para);
+ printf("Done\n");
+
+#ifdef DO_SIMPLE_DDR_TEST
+ mem_test_write();
+ mem_test_read();
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_RDA_FPGA */
+
diff --git a/board/rda/rda8810h/clock_config.c b/board/rda/rda8810h/clock_config.c
new file mode 100644
index 0000000000..85254c90d7
--- /dev/null
+++ b/board/rda/rda8810h/clock_config.c
@@ -0,0 +1,149 @@
+#ifndef TARGET_TOOL
+#include <common.h>
+#include <asm/arch/factory.h>
+#include "clock_config.h"
+#endif
+
+#include "ddr3.h"
+#include "tgt_ap_clock_config.h"
+
+static const struct clock_config clock_default_config = {
+ /* Header */
+ 0, // MAGIC;
+ CLOCK_VER_MAJOR, // VERSION_MAJOR;
+ CLOCK_VER_MINOR, // VERSION_MINOR;
+ /* PLL Freqs (MHz) */
+ _TGT_AP_PLL_CPU_FREQ, // PLL_FREQ_CPU; /* 05, 06 */
+ _TGT_AP_PLL_BUS_FREQ, // PLL_FREQ_BUS; /* 25, 26 */
+ _TGT_AP_PLL_MEM_FREQ, // PLL_FREQ_MEM; /* 65, 66 */
+ _TGT_AP_PLL_USB_FREQ, // PLL_FREQ_USB; /* 85, 86 */
+ /* DDR Cal */
+ 0, // DDR_CAL;
+ /* DDR_FLAGS */
+ DDR_FLAGS_ODT(_TGT_AP_DDR_ODT) // 010 -- 120 Ohm
+#if (_TGT_AP_DDR_CLOCK < 200)
+ | DDR_FLAGS_DLLOFF
+#endif
+#ifdef _TGT_AP_DDR_LOWPWR
+ | DDR_FLAGS_LOWPWR
+#endif
+ | DDR_FLAGS_RON(_TGT_AP_DDR_RON), // 00 -- 40 Ohm
+ /* DDR_PARA */
+ DDR_PARA_CHIP_BITS(_TGT_AP_DDR_CHIP_BITS)
+ | DDR_PARA_MEM_BITS(_TGT_AP_DDR_MEM_BITS)
+ | DDR_PARA_BANK_BITS(_TGT_AP_DDR_BANK_BITS)
+ | DDR_PARA_ROW_BITS(_TGT_AP_DDR_ROW_BITS )
+ | DDR_PARA_COL_BITS(_TGT_AP_DDR_COL_BITS),
+
+ /* AP sysctrl */
+ _TGT_AP_CLK_CPU, // CLK_CPU;
+ _TGT_AP_CLK_AXI, // CLK_AXI;
+ _TGT_AP_CLK_GCG, // CLK_GCG;
+ _TGT_AP_CLK_AHB1, // CLK_AHB1;
+ _TGT_AP_CLK_APB1, // CLK_APB1;
+ _TGT_AP_CLK_APB2, // CLK_APB2;
+ _TGT_AP_CLK_MEM, // CLK_MEM;
+ _TGT_AP_CLK_GPU, // CLK_GPU;
+ _TGT_AP_CLK_VPU, // CLK_VPU;
+ _TGT_AP_CLK_VOC, // CLK_VOC;
+ _TGT_AP_CLK_SFLSH, // CLK_SFLSH;
+ 0, // RESERVE;
+
+ /* DDR timings, defined in target */
+ DDR_CHAN_1_VALID_VAL, // DDR_CHAN_1_VALID;
+ DDR_TIMING_100H_VAL, // DDR_TIMING_100H;
+ DDR_TIMING_101H_VAL, // DDR_TIMING_101H;
+ DDR_TIMING_102H_VAL, // DDR_TIMING_102H;
+ DDR_TIMING_103H_VAL, // DDR_TIMING_103H;
+ DDR_TIMING_104H_VAL, // DDR_TIMING_104H;
+ DDR_TIMING_105H_VAL, // DDR_TIMING_105H;
+ DDR_TIMING_106H_VAL, // DDR_TIMING_106H;
+ DDR_TIMING_107H_VAL, // DDR_TIMING_107H;
+ DDR_TIMING_108H_VAL, // DDR_TIMING_108H;
+ DDR_TIMING_109H_VAL, // DDR_TIMING_109H;
+ DDR_TIMING_10AH_VAL, // DDR_TIMING_10AH;
+ DDR_TIMING_10BH_VAL, // DDR_TIMING_10BH;
+ DDR_TIMING_10CH_VAL, // DDR_TIMING_10CH;
+ DDR_TIMING_10DH_VAL, // DDR_TIMING_10DH;
+ DDR_TIMING_10EH_VAL, // DDR_TIMING_10EH;
+ DDR_TIMING_10FH_VAL, // DDR_TIMING_10FH;
+
+ DDR_CHAN_2_VALID_VAL, // DDR_CHAN_2_VALID;
+ DDR_TIMING_120H_VAL, // DDR_TIMING_120H;
+ DDR_TIMING_121H_VAL, // DDR_TIMING_121H;
+ DDR_TIMING_122H_VAL, // DDR_TIMING_122H;
+ DDR_TIMING_123H_VAL, // DDR_TIMING_123H;
+ DDR_TIMING_124H_VAL, // DDR_TIMING_124H;
+ DDR_TIMING_125H_VAL, // DDR_TIMING_125H;
+ DDR_TIMING_126H_VAL, // DDR_TIMING_126H;
+ DDR_TIMING_127H_VAL, // DDR_TIMING_127H;
+ DDR_TIMING_128H_VAL, // DDR_TIMING_128H;
+ DDR_TIMING_129H_VAL, // DDR_TIMING_129H;
+ DDR_TIMING_12AH_VAL, // DDR_TIMING_12AH;
+ DDR_TIMING_12BH_VAL, // DDR_TIMING_12BH;
+ DDR_TIMING_12CH_VAL, // DDR_TIMING_12CH;
+ DDR_TIMING_12DH_VAL, // DDR_TIMING_12DH;
+ DDR_TIMING_12EH_VAL, // DDR_TIMING_12EH;
+ DDR_TIMING_12FH_VAL, // DDR_TIMING_12FH;
+
+ DDR_CHAN_3_VALID_VAL, // DDR_CHAN_3_VALID;
+ DDR_TIMING_140H_VAL, // DDR_TIMING_140H;
+ DDR_TIMING_141H_VAL, // DDR_TIMING_141H;
+ DDR_TIMING_142H_VAL, // DDR_TIMING_142H;
+ DDR_TIMING_143H_VAL, // DDR_TIMING_143H;
+ DDR_TIMING_144H_VAL, // DDR_TIMING_144H;
+ DDR_TIMING_145H_VAL, // DDR_TIMING_145H;
+ DDR_TIMING_146H_VAL, // DDR_TIMING_146H;
+ DDR_TIMING_147H_VAL, // DDR_TIMING_147H;
+ DDR_TIMING_148H_VAL, // DDR_TIMING_148H;
+ DDR_TIMING_149H_VAL, // DDR_TIMING_149H;
+ DDR_TIMING_14AH_VAL, // DDR_TIMING_14AH;
+ DDR_TIMING_14BH_VAL, // DDR_TIMING_14BH;
+ DDR_TIMING_14CH_VAL, // DDR_TIMING_14CH;
+ DDR_TIMING_14DH_VAL, // DDR_TIMING_14DH;
+ DDR_TIMING_14EH_VAL, // DDR_TIMING_14EH;
+ DDR_TIMING_14FH_VAL, // DDR_TIMING_14FH;
+
+ DDR_CHAN_4_VALID_VAL, // DDR_CHAN_4_VALID;
+ DDR_TIMING_160H_VAL, // DDR_TIMING_160H;
+ DDR_TIMING_161H_VAL, // DDR_TIMING_161H;
+ DDR_TIMING_162H_VAL, // DDR_TIMING_162H;
+ DDR_TIMING_163H_VAL, // DDR_TIMING_163H;
+ DDR_TIMING_164H_VAL, // DDR_TIMING_164H;
+ DDR_TIMING_165H_VAL, // DDR_TIMING_165H;
+ DDR_TIMING_166H_VAL, // DDR_TIMING_166H;
+ DDR_TIMING_167H_VAL, // DDR_TIMING_167H;
+ DDR_TIMING_168H_VAL, // DDR_TIMING_168H;
+ DDR_TIMING_169H_VAL, // DDR_TIMING_169H;
+ DDR_TIMING_16AH_VAL, // DDR_TIMING_16AH;
+ DDR_TIMING_16BH_VAL, // DDR_TIMING_16BH;
+ DDR_TIMING_16CH_VAL, // DDR_TIMING_16CH;
+ DDR_TIMING_16DH_VAL, // DDR_TIMING_16DH;
+ DDR_TIMING_16EH_VAL, // DDR_TIMING_16EH;
+ DDR_TIMING_16FH_VAL, // DDR_TIMING_16FH;
+
+ DDR_TIMING_180H_VAL, // DDR_TIMING_180H;
+ DDR_TIMING_181H_VAL, // DDR_TIMING_181H;
+ DDR_TIMING_182H_VAL, // DDR_TIMING_182H;
+ DDR_TIMING_183H_VAL, // DDR_TIMING_183H;
+ DDR_TIMING_184H_VAL, // DDR_TIMING_184H;
+ DDR_TIMING_185H_VAL, // DDR_TIMING_185H;
+ DDR_TIMING_186H_VAL, // DDR_TIMING_186H;
+ DDR_TIMING_187H_VAL, // DDR_TIMING_187H;
+ DDR_TIMING_188H_VAL, // DDR_TIMING_188H;
+ DDR_TIMING_189H_VAL, // DDR_TIMING_189H;
+ DDR_TIMING_18AH_VAL, // DDR_TIMING_18AH;
+ DDR_TIMING_18BH_VAL, // DDR_TIMING_18BH;
+ DDR_TIMING_18CH_VAL, // DDR_TIMING_18CH;
+ DDR_TIMING_069H_VAL // DDR_TIMING_18CH;
+};
+
+const struct clock_config *get_default_clock_config(void)
+{
+#ifndef TARGET_TOOL
+ BUILD_BUG_ON(sizeof(struct clock_config) > AP_FACTORY_CLOCK_CFG_LEN);
+#endif
+
+ return &clock_default_config;
+}
+
diff --git a/board/rda/rda8810h/clock_config.h b/board/rda/rda8810h/clock_config.h
new file mode 100644
index 0000000000..3e472df08d
--- /dev/null
+++ b/board/rda/rda8810h/clock_config.h
@@ -0,0 +1,132 @@
+#ifndef __CLOCK_CONFIG_H__
+#define __CLOCK_CONFIG_H__
+
+typedef unsigned long UINT32;
+typedef unsigned short UINT16;
+typedef long INT32;
+typedef short INT16;
+typedef unsigned char UINT8;
+typedef char INT8;
+
+#define CLOCK_VER_MAJOR 2
+#define CLOCK_VER_MINOR 0
+
+struct clock_config {
+ /* Header */
+ UINT32 MAGIC;
+ UINT16 VERSION_MAJOR;
+ UINT16 VERSION_MINOR;
+ /* PLL Freqs (MHz) */
+ UINT32 PLL_FREQ_CPU; /* 05, 06 */
+ UINT32 PLL_FREQ_BUS; /* 25, 26 */
+ UINT32 PLL_FREQ_MEM; /* 65, 66 */
+ UINT32 PLL_FREQ_USB; /* 85, 86 */
+ /* DDR Flags */
+ UINT16 DDR_CAL;
+ UINT16 DDR_FLAGS;
+ UINT32 DDR_PARA;
+ /* AP sysctrl */
+ UINT16 CLK_CPU;
+ UINT16 CLK_AXI;
+ UINT16 CLK_GCG;
+ UINT16 CLK_AHB1;
+ UINT16 CLK_APB1;
+ UINT16 CLK_APB2;
+ UINT16 CLK_MEM;
+ UINT16 CLK_GPU;
+ UINT16 CLK_VPU;
+ UINT16 CLK_VOC;
+ UINT16 CLK_SFLSH;
+ UINT16 RESERVE;
+ /* DDR timings */
+ UINT16 DDR_CHAN_1_VALID;
+ UINT16 DDR_TIMING_100H;
+ UINT16 DDR_TIMING_101H;
+ UINT16 DDR_TIMING_102H;
+ UINT16 DDR_TIMING_103H;
+ UINT16 DDR_TIMING_104H;
+ UINT16 DDR_TIMING_105H;
+ UINT16 DDR_TIMING_106H;
+ UINT16 DDR_TIMING_107H;
+ UINT16 DDR_TIMING_108H;
+ UINT16 DDR_TIMING_109H;
+ UINT16 DDR_TIMING_10AH;
+ UINT16 DDR_TIMING_10BH;
+ UINT16 DDR_TIMING_10CH;
+ UINT16 DDR_TIMING_10DH;
+ UINT16 DDR_TIMING_10EH;
+ UINT16 DDR_TIMING_10FH;
+
+ UINT16 DDR_CHAN_2_VALID;
+ UINT16 DDR_TIMING_120H;
+ UINT16 DDR_TIMING_121H;
+ UINT16 DDR_TIMING_122H;
+ UINT16 DDR_TIMING_123H;
+ UINT16 DDR_TIMING_124H;
+ UINT16 DDR_TIMING_125H;
+ UINT16 DDR_TIMING_126H;
+ UINT16 DDR_TIMING_127H;
+ UINT16 DDR_TIMING_128H;
+ UINT16 DDR_TIMING_129H;
+ UINT16 DDR_TIMING_12AH;
+ UINT16 DDR_TIMING_12BH;
+ UINT16 DDR_TIMING_12CH;
+ UINT16 DDR_TIMING_12DH;
+ UINT16 DDR_TIMING_12EH;
+ UINT16 DDR_TIMING_12FH;
+
+ UINT16 DDR_CHAN_3_VALID;
+ UINT16 DDR_TIMING_140H;
+ UINT16 DDR_TIMING_141H;
+ UINT16 DDR_TIMING_142H;
+ UINT16 DDR_TIMING_143H;
+ UINT16 DDR_TIMING_144H;
+ UINT16 DDR_TIMING_145H;
+ UINT16 DDR_TIMING_146H;
+ UINT16 DDR_TIMING_147H;
+ UINT16 DDR_TIMING_148H;
+ UINT16 DDR_TIMING_149H;
+ UINT16 DDR_TIMING_14AH;
+ UINT16 DDR_TIMING_14BH;
+ UINT16 DDR_TIMING_14CH;
+ UINT16 DDR_TIMING_14DH;
+ UINT16 DDR_TIMING_14EH;
+ UINT16 DDR_TIMING_14FH;
+
+ UINT16 DDR_CHAN_4_VALID;
+ UINT16 DDR_TIMING_160H;
+ UINT16 DDR_TIMING_161H;
+ UINT16 DDR_TIMING_162H;
+ UINT16 DDR_TIMING_163H;
+ UINT16 DDR_TIMING_164H;
+ UINT16 DDR_TIMING_165H;
+ UINT16 DDR_TIMING_166H;
+ UINT16 DDR_TIMING_167H;
+ UINT16 DDR_TIMING_168H;
+ UINT16 DDR_TIMING_169H;
+ UINT16 DDR_TIMING_16AH;
+ UINT16 DDR_TIMING_16BH;
+ UINT16 DDR_TIMING_16CH;
+ UINT16 DDR_TIMING_16DH;
+ UINT16 DDR_TIMING_16EH;
+ UINT16 DDR_TIMING_16FH;
+
+ UINT16 DDR_TIMING_180H;
+ UINT16 DDR_TIMING_181H;
+ UINT16 DDR_TIMING_182H;
+ UINT16 DDR_TIMING_183H;
+ UINT16 DDR_TIMING_184H;
+ UINT16 DDR_TIMING_185H;
+ UINT16 DDR_TIMING_186H;
+ UINT16 DDR_TIMING_187H;
+ UINT16 DDR_TIMING_188H;
+ UINT16 DDR_TIMING_189H;
+ UINT16 DDR_TIMING_18AH;
+ UINT16 DDR_TIMING_18BH;
+ UINT16 DDR_TIMING_18CH;
+ UINT16 DDR_TIMING_069H;
+};
+
+const struct clock_config *get_default_clock_config(void);
+
+#endif
diff --git a/board/rda/rda8810h/config.mk b/board/rda/rda8810h/config.mk
new file mode 100644
index 0000000000..39782ba05e
--- /dev/null
+++ b/board/rda/rda8810h/config.mk
@@ -0,0 +1,15 @@
+#
+#the spl code should not exceed the SPL_MAX_SIZE,and if
+#the spl don't up to the max size, paddint the last with
+#zero(or 0xff?)
+
+#48kbytes, 48*1024
+#SPL_APPENDING_TO := 48
+#SPL_MAX_SIZE := 49512
+
+# space for spl(48KiB) & mtd partition table(4KiB),
+# so uboot offset 52KiB(48 + 4).
+
+SPL_APPENDING_TO := 52
+
+CONFIG_SPL_SIGNATURE_CHECK_IMAGE := y
diff --git a/board/rda/rda8810h/ddr3.c b/board/rda/rda8810h/ddr3.c
new file mode 100644
index 0000000000..a0f49e6efe
--- /dev/null
+++ b/board/rda/rda8810h/ddr3.c
@@ -0,0 +1,533 @@
+#include <common.h>
+#include <asm/arch/rda_iomap.h>
+
+#include "ddr3.h"
+#include "ddr3_init.h"
+#include "tgt_ap_clock_config.h"
+
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+
+#define DDR_TYPE _TGT_AP_DDR_TYPE
+
+#define DF_DELAY (0x10000)
+
+#define DMC_REG_BASE RDA_DMC400_BASE
+#define PHY_REG_BASE RDA_DDRPHY_BASE
+
+#define PHY_RDLAT 0
+#define PHYWRDATA 1
+#define STA 3
+#define CLKSEL 4
+#define PSSTART 5
+#define PSDONE 6
+#define LOCKED 6
+#define CTRL_DELAY 7
+#define RDELAY_SEL 8
+#define WDELAY_SEL 9
+#define PHY_RESET 10
+#define RESET_DDR3 11
+#define ODT_DELAY 12
+#define DDR3_USED 13
+#define WRITE_ENABLE_LAT 14
+#define WRITE_DATA_LAT 15
+#define DQOUT_ENABLE_LAT 16
+#define DATA_ODT_ENABLE_REG 20
+#define DATA_WRITE_ENABLE_REG 48
+#define DMC_READY 128
+#define USE_ADDR 129
+
+#define ARRAY_NUM(n) (sizeof(n))/(sizeof(n[0]))
+
+#if (DDR_TYPE == 1)
+static dmc_reg_t dmc_reg_cfg[] = {
+ {T_REFI, 0x186, 0x186},
+ {T_RFC, 0x230024, 0x230024},
+ {T_RFC, 0x540024, 0x540024},
+ {T_MRR, 0x2, 0x2},
+ {T_MRW, 0x5, 0x5},
+ {T_RCD, 0x8, 0x8},
+ {T_RAS, 0x11, 0x11},
+ {T_RP, 0x8, 0x8},
+ {T_RPALL, 0x9, 0x9},
+ {T_RRD, 0x4, 0x4},
+ {T_FAW, 0x14, 0x14},
+ {T_RTR, 0x4, 0x4},
+ {T_RTW, 0xb, 0xb},
+ {T_RTP, 0x6, 0x6},
+ {T_WR, 0xe, 0xe},
+ {T_WTR, 0x4000b, 0x4000b},
+ {T_WTR, 0x4000b, 0x4000b},
+ {T_WTW, 0x40000, 0x40000},
+ {RD_LATENCY, 0x6, 0x6},
+ {WR_LATENCY, 0x3, 0x3},
+ {T_RDDATA_EN, 0x3, 0x3},
+ {T_PHYWRLAT, 0x101, 0x101},
+ {T_PHYWRLAT, 0x101, 0x101},
+ {T_XP, 0x20003, 0x20003},
+ {T_XP, 0x80003, 0x80003},
+ {T_ESR, 0x6, 0x6},
+ {T_XSR, 0x1000058, 0x1000058},
+ {T_XSR, 0x580058, 0x580058},
+ {T_SRCKD, 0x5, 0x5},
+ {T_CKSRD, 0x5, 0x5},
+ {T_ECKD, 0x5, 0x5},
+ {T_XCKD, 0x5, 0x5},
+ {T_EP, 0x5, 0x5},
+ {RDLVL_CTRL, 0x1010, 0x1010},
+ {RDLVL_CTRL, 0x1110, 0x1110},
+ {RDLVL_CTRL, 0x11110, 0x11110},
+ {REFRESH_CTRL, 0x0, 0x0},
+ {REFRESH_CTRL, 0x0, 0x0},
+ {ECC_CTRL, 0x0, 0x0},
+ {ADDR_CTRL, 0x30200, 0x30200},
+ {ADDR_CTRL, 0x30200, 0x30200},
+ {ADDR_CTRL, 0x30200, 0x30200},
+};
+#elif (DDR_TYPE == 2)
+static dmc_reg_t dmc_reg_cfg[] = {
+ {T_REFI, 0x3f, 0x3f},
+ {T_RFC, 0x230024, 0x230024},
+ {T_RFC, 0x540024, 0x540024},
+ {T_MRR, 0x3f, 0x3f},
+ {T_MRW, 0x3f, 0x3f},
+ {T_RCD, 0x8, 0x8},
+ {T_RAS, 0x11, 0x11},
+ {T_RP, 0x8, 0x8},
+ {T_RPALL, 0x9, 0x9},
+ {T_RRD, 0x4, 0x4},
+ {T_FAW, 0x14, 0x14},
+ {T_RTR, 0xf, 0xf},
+ {T_RTW, 0x1f, 0x1f},
+ {T_RTP, 0x6, 0x6},
+ {T_WR, 0xe, 0xe},
+ {T_WTR, 0x4001f, 0x4001f},
+ {T_WTR, 0x4001f, 0x4001f},
+ {T_WTW, 0x40000, 0x40000},
+ {RD_LATENCY, 0x8, 0x8},
+ {WR_LATENCY, 0x4, 0x4},
+ {T_RDDATA_EN, 0x8, 0x8},
+ {T_PHYWRLAT, 0x103, 0x103},
+ {T_PHYWRLAT, 0x103, 0x103},
+ {T_XP, 0x20003, 0x20003},
+ {T_XP, 0x80003, 0x80003},
+ {T_ESR, 0x6, 0x6},
+ {T_XSR, 0x1000058, 0x1000058},
+ {T_XSR, 0x580058, 0x580058},
+ {T_SRCKD, 0x5, 0x5},
+ {T_CKSRD, 0x5, 0x5},
+ {T_ECKD, 0x5, 0x5},
+ {T_XCKD, 0x5, 0x5},
+ {T_EP, 0x5, 0x5},
+ {RDLVL_CTRL, 0x1010, 0x1010},
+ {RDLVL_CTRL, 0x1110, 0x1110},
+ {RDLVL_CTRL, 0x11110, 0x11110},
+ {REFRESH_CTRL, 0x1, 0x1},
+ {ECC_CTRL, 0x0, 0x0},
+ {QOSX_CTRL7, 0x0f, 0x0f},
+ {TURNAROUND_PRIO,0x1A, 0x1A},
+ {HIT_PRIO, 0x1A, 0x1A},
+ {ADDR_CTRL, 0x30200, 0x30200},
+ {ADDR_CTRL, 0x30200, 0x30200},
+ {ADDR_CTRL, 0x30200, 0x30200},
+};
+#elif (DDR_TYPE == 3)
+static dmc_reg_t dmc_reg_cfg[] = {
+ {QOSX_CTRL7, 0x08, 0x08},
+ {TURNAROUND_PRIO,0x1A, 0x0},
+ {HIT_PRIO, 0x1A, 0x0},
+ {T_REFI, 0x186, 0x3f},
+ {QUEUE_CTRL, 0xffff, 0x0},
+ {T_RFC, 0x23008c, 0x23008c},
+ {T_RFC, 0x8c008c, 0x8c008c},
+ {T_MRR, 0x4, 0x4},
+ {T_MRW, 0xc, 0xc},
+ {T_RCD, 0x6, 0x6},
+ {T_RAS, 0xf, 0xf},
+ {T_RP, 0x6, 0x6},
+ {T_RPALL, 0x6, 0x5},
+ {T_RRD, 0x4, 0x4},
+ {T_FAW, 0x14, 0x14},
+ {T_RTR, 0x6, 0x6},
+// {T_RTW, 0x7, 0x6},
+ {T_RTW, 0x0c, 0x6},// turn for now
+ {T_RTW, 0x1f, 0x1f},//for low speed
+ {T_RTP, 0x4, 0x4},
+ {T_WR, 0xf, 0x10},
+ {T_WTR, 0x4000d, 0x4000d},
+ {T_WTR, 0x6000d, 0x6000f},
+// {T_WTR, 0x6001f, 0x6001f},//for low speed
+ {T_WTW, 0x60000, 0x60000},
+ {RD_LATENCY, 0x5, 0x5},
+ {WR_LATENCY, 0x5, 0x5},
+ {T_RDDATA_EN, 0x8, 0x3},
+ {T_PHYWRLAT, 0x102, 0x102},
+ {T_PHYWRLAT, 0x102, 0x103},
+ {T_EP, 0x3, 0x3},
+ {T_XP, 0x20003, 0x20003},
+ {T_XP, 0xa0003, 0xa0003},
+ {T_ESR, 0x4, 0x4},
+ {T_XSR, 0x1000090, 0x1000090},
+ {T_XSR, 0x2000090, 0x2000090},
+ {T_SRCKD, 0x5, 0x5},
+ {T_CKSRD, 0x5, 0x5},
+ {T_ECKD, 0x5, 0x5},
+ {T_XCKD, 0x5, 0x5},
+ {ECC_CTRL, 0x0, 0x0},
+ {ADDR_CTRL, 0x30200, 0x30200},
+ {ADDR_CTRL, 0x30200, 0x30200},
+ {ADDR_CTRL, 0x30200, 0x30200},
+};
+#else
+#error "Wrong DDR Type"
+#endif
+
+void config_ddr_phy(UINT16 flag)
+{
+ int wait_idle;
+ UINT16 __attribute__((unused)) dll_off;
+
+ wait_idle = DF_DELAY + 16;
+ dll_off = flag & DDR_FLAGS_DLLOFF;
+
+ while (wait_idle--);
+
+#if (DDR_TYPE == 1)
+ *((volatile UINT32*)(PHY_REG_BASE + CTRL_DELAY * 4)) = 1;
+ printf("ddr1 phy init done!\n");
+#elif (DDR_TYPE ==2)
+ *((volatile UINT32*)(PHY_REG_BASE + USE_ADDR * 4)) = 0;
+ *((volatile UINT32*)(PHY_REG_BASE + DATA_WRITE_ENABLE_REG *4)) = 0xf;
+ *((volatile UINT32*)(PHY_REG_BASE + DATA_ODT_ENABLE_REG *4)) = 0xf;
+ *((volatile UINT32*)(PHY_REG_BASE + WRITE_DATA_LAT *4)) = 0x0;
+ *((volatile UINT32*)(PHY_REG_BASE + WRITE_ENABLE_LAT *4)) = 0x0;
+ *((volatile UINT32*)(PHY_REG_BASE + WDELAY_SEL *4)) = 0x7;
+ *((volatile UINT32*)(PHY_REG_BASE + RDELAY_SEL *4)) = 0x6;
+ *((volatile UINT32*)(PHY_REG_BASE + DQOUT_ENABLE_LAT *4)) = 0x1;
+ printf("ddr2 phy init done!\n");
+#else
+ *((volatile UINT32*)(PHY_REG_BASE + DMC_READY *4)) = 0x0;
+ *((volatile UINT32*)(PHY_REG_BASE + RESET_DDR3 * 4)) = 1;
+
+ if (dll_off)
+ *((volatile UINT32*)(PHY_REG_BASE + WRITE_DATA_LAT * 4)) = 1;
+
+ *((volatile UINT32*)(PHY_REG_BASE + DDR3_USED * 4)) = 1;
+ *((volatile UINT32*)(PHY_REG_BASE + WDELAY_SEL * 4)) = 3;
+
+ if (!dll_off){
+ *((volatile UINT32*)(PHY_REG_BASE + PHY_RDLAT * 4)) = 7;
+ *((volatile UINT32*)(PHY_REG_BASE + CTRL_DELAY * 4)) =2;
+ *((volatile UINT32*)(PHY_REG_BASE + WRITE_ENABLE_LAT * 4)) =2;
+ *((volatile UINT32*)(PHY_REG_BASE + WRITE_DATA_LAT * 4)) = 3;
+ *((volatile UINT32*)(PHY_REG_BASE + DQOUT_ENABLE_LAT * 4)) = 3;
+ }else
+ *((volatile UINT32*)(PHY_REG_BASE + DQOUT_ENABLE_LAT * 4)) = 1;
+
+ *((volatile UINT32*)(PHY_REG_BASE + DATA_ODT_ENABLE_REG *4)) = 0xf;
+ *((volatile UINT32*)(PHY_REG_BASE + DATA_WRITE_ENABLE_REG *4)) = 0xf;
+
+ serial_puts("ddr3 phy init done!\n");
+#endif
+}
+
+void config_dmc400(UINT16 flag, UINT32 para)
+{
+ int i, wait_idle;
+ UINT32 val, tmp;
+ volatile UINT32 *addr;
+ UINT16 __attribute__((unused)) dll_off, lpw, odt, ron;
+ UINT32 mem_width, col_bits, row_bits, bank_bits;
+
+ dll_off = flag & DDR_FLAGS_DLLOFF;
+ lpw = flag & DDR_FLAGS_LOWPWR;
+ odt = (flag & DDR_FLAGS_ODT_MASK) >> DDR_FLAGS_ODT_SHIFT;
+ ron = (flag & DDR_FLAGS_RON_MASK) >> DDR_FLAGS_RON_SHIFT;
+ mem_width = (para & DDR_PARA_MEM_BITS_MASK) >> DDR_PARA_MEM_BITS_SHIFT;
+ bank_bits = (para & DDR_PARA_BANK_BITS_MASK) >> DDR_PARA_BANK_BITS_SHIFT;
+ row_bits = (para & DDR_PARA_ROW_BITS_MASK) >> DDR_PARA_ROW_BITS_SHIFT;
+ col_bits = (para & DDR_PARA_COL_BITS_MASK) >> DDR_PARA_COL_BITS_SHIFT;
+
+
+ wait_idle = 0x4e;
+ while (wait_idle--);
+
+ for (i=0; i<ARRAY_NUM(dmc_reg_cfg); i++) {
+ addr = (volatile UINT32*)(DMC_REG_BASE + dmc_reg_cfg[i].reg_offset);
+ if (dll_off)
+ val = dmc_reg_cfg[i].dll_off_val;
+ else
+ val = dmc_reg_cfg[i].dll_on_val;
+
+ *addr = val;
+ wait_idle = 0x5;
+ while (wait_idle--);
+ }
+
+#if (DDR_TYPE == 3)
+ //config low power control register
+ if (lpw) {
+ addr = (volatile UINT32*)(DMC_REG_BASE + LOWPWR_CTRL);//0x20
+ *addr = 0x48;
+ wait_idle = 0x5;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + T_ESR);//0x260
+ *addr = 0xa;
+ wait_idle = 0x5;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + T_XSR);//0x264
+ *addr = 0x200;
+ wait_idle = 0x5;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + T_SRCKD);//0x268
+ *addr = 0xa;
+ wait_idle = 0x5;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + T_CKSRD);//0x26C
+ *addr = 0xa;
+ wait_idle = 0x5;
+ while (wait_idle--);
+ }
+#elif (DDR_TYPE == 2)
+ addr = (volatile UINT32*)(DMC_REG_BASE + LOWPWR_CTRL);//0x20
+ *addr = 0x38;
+ wait_idle = 0x5;
+ while (wait_idle--);
+#endif
+
+ //config format control register
+ addr = (volatile UINT32*)(DMC_REG_BASE + FORMAT_CTRL);
+ val = *addr;
+ val &= ~0xf;
+ if (mem_width == 2)
+ val |= 0x2; //for 32bit DDR
+ else if ((mem_width == 1) || (mem_width == 0))
+ val |= 0x1; //for 16bit & 8bit DDR
+ else
+ printf("unsupported DDR width: %lx\n", mem_width);
+ *addr = val;
+
+ printf("format ctrl value: %lx\n", val);
+
+ wait_idle = 0x1d;
+ while (wait_idle--);
+
+ //config address control register
+ addr = (volatile UINT32*)(DMC_REG_BASE + ADDR_CTRL);
+ if (mem_width == 2)
+ tmp = col_bits; //for 32bit
+ else if (mem_width == 1)
+ tmp = col_bits - 1; //for 16bit
+ else if (mem_width == 0)
+ tmp = col_bits - 2; //for 8bit
+ else {
+ printf("unsupported DDR width: %lx\n", mem_width);
+ tmp = col_bits;
+ }
+ val = (bank_bits << 16) | (row_bits << 8) | tmp;
+
+ *addr = val;
+
+ printf("address ctrl value: %lx\n", val);
+ wait_idle = 0x5;
+ while (wait_idle--);
+
+ //config decode control register
+ addr = (volatile UINT32*)(DMC_REG_BASE + DECODE_CTRL);
+ tmp = 12 - (8 + col_bits + mem_width);
+ if (tmp < 8)
+ val = tmp << 4;
+ else
+ printf("unsupported stripe decode: %lx\n", tmp);
+ *addr = val;
+
+ printf("decode ctrl value: %lx\n", val);
+ wait_idle = 0x6;
+ while (wait_idle--);
+
+ wait_idle = DF_DELAY;
+ while (wait_idle--);
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+ *addr = 0x0;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+#if (DDR_TYPE == 1)
+ val = 0;
+#elif (DDR_TYPE == 2)
+ val = 0;
+#else
+ //config MR2
+ if (dll_off)
+ val = 0x10020008;
+ else
+ val = 0x10020000;
+#endif
+ *addr = val;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+#if (DDR_TYPE == 1)
+ val = 0x20000000;
+#elif (DDR_TYPE == 2)
+ val = 0x1000003f;
+#else
+ //config MR3
+ val = 0x10030000;
+#endif
+ *addr = val;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+#if (DDR_TYPE == 1)
+ val = 0x30000000;
+#elif (DDR_TYPE == 2)
+ val = 0x1000ff0a;
+#else
+ //config MR1 ODT [9,6,2] RON [5,1] DLLOFF [0]
+ val = 0x10010000;
+ val |= (odt & 0x4)<<7 | (odt & 0x2)<<5 | (odt & 0x1)<<2;
+ val |= (ron & 0x2)<<4 | (ron & 0x1)<<1;
+ if (dll_off)
+ val |= 0x1;
+#endif
+ *addr = val;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+#if (DDR_TYPE == 1)
+ val = 0x30000000;
+#elif (DDR_TYPE == 2)
+ val = 0x10008301;
+#else
+ //config MR0
+ val = 0x10000520;
+#endif
+ *addr = val;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+#if (DDR_TYPE == 1)
+ val = 0x10000033;
+#elif (DDR_TYPE == 2)
+ val = 0x10000602;//0ld 0x10000102
+#else
+ val = 0x50000400;
+#endif
+ *addr = val;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+
+#if (DDR_TYPE == 2)
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+ val = 0x10000103;//0ld 0x10000102
+ *addr = val;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+#endif
+
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+#if (DDR_TYPE == 1)
+ val = 0x10020000;
+#elif (DDR_TYPE == 2)
+ val = 0x30000000;
+#else
+ val = 0x30000000;
+#endif
+ *addr = val;
+ wait_idle = DF_DELAY + 0x10;
+ while (wait_idle--);
+
+#if (DDR_TYPE == 2)
+/* zhangli for MCP */
+ addr = (volatile UINT32*)(DMC_REG_BASE + DIRECT_CMD);
+ *addr = 0x10000103;
+ wait_idle = DF_DELAY + 0x9;
+ while (wait_idle--);
+#endif
+
+#if (DDR_TYPE == 2)
+ addr = (volatile UINT32*)(DMC_REG_BASE + MEMC_CMD);
+ val = 0x4;
+ *addr = val;
+#endif
+
+ //config ECC control
+ wait_idle = 0x6;
+ while (wait_idle--);
+ addr = (volatile UINT32*)(DMC_REG_BASE + ECC_CTRL);
+ val = 0x0;
+ *addr = val;
+ wait_idle = 0x8;
+ while (wait_idle--);
+
+ //config MEMC CMD
+ addr = (volatile UINT32*)(DMC_REG_BASE + MEMC_CMD);
+ val = 0x3;
+ *addr = val;
+
+ //READ MEMC STATUS
+ addr = (volatile UINT32*)(DMC_REG_BASE + MEMC_STATUS);
+ val = 0;
+ do {
+ val = *addr;
+ //printf("MEMC_STATUS value: %x\n", val);
+ } while (val != 3);
+}
+
+void axi_prio_init(void)
+{
+ *(volatile UINT32*)(0x20900100) = 0xaa0000aa;
+ *(volatile UINT32*)(0x21054100) = 0x00000008;
+ *(volatile UINT32*)(0x21054104) = 0x00000008;
+}
+
+void axi_outstandings_init(void)
+{
+ *(volatile UINT32*)(0x2104210C) = 0x00000060;
+ *(volatile UINT32*)(0x21042110) = 0x00000300;
+}
+
+int ddr_init(UINT16 flags, UINT32 para)
+{
+ UINT16 dll_off;
+ UINT32 mem_width;
+
+ axi_prio_init();
+ //axi_outstandings_init();
+
+ dll_off = flags & DDR_FLAGS_DLLOFF;
+ mem_width = (para & DDR_PARA_MEM_BITS_MASK) >> DDR_PARA_MEM_BITS_SHIFT;
+
+ switch (mem_width) {
+ case 0:
+ printf("8bit ");
+ break;
+ case 1:
+ printf("16bit ");
+ break;
+ case 2:
+ printf("32bit ");
+ break;
+ }
+ if (dll_off)
+ printf("dll-off Mode ...\n");
+ else
+ printf("dll-on Mode ...\n");
+
+ config_ddr_phy(flags);
+ config_dmc400(flags, para);
+ printf("dram init done ...\n");
+
+ return 0;
+}
+
diff --git a/board/rda/rda8810h/ddr3.h b/board/rda/rda8810h/ddr3.h
new file mode 100644
index 0000000000..7481954144
--- /dev/null
+++ b/board/rda/rda8810h/ddr3.h
@@ -0,0 +1,50 @@
+#ifndef _SYS_DDR3_H_
+#define _SYS_DDR3_H_
+
+#include "clock_config.h"
+
+/*
+ * defination of ddr flags
+ */
+/* [Debug] DLL off mode, 0 is dll on mode */
+#define DDR_FLAGS_DLLOFF 0x8000
+/* [Debug] LowSpeed mode*/
+#define DDR_FLAGS_RESERVE 0x4000
+/* DDR LowPower mode */
+#define DDR_FLAGS_LOWPWR 0x2000
+/* ODT: 000--Null 001--60 010--120 011--40 100--20 101--30 */
+#define DDR_FLAGS_ODT(n) (((n)<<0)&0x0007)
+#define DDR_FLAGS_ODT_SHIFT 0
+#define DDR_FLAGS_ODT_MASK 0x0007
+/* RON: 00--40 01--30 */
+#define DDR_FLAGS_RON(n) (((n)<<3)&0x0018)
+#define DDR_FLAGS_RON_SHIFT 3
+#define DDR_FLAGS_RON_MASK 0x0018
+
+/*
+ * defination of ddr parameters
+ */
+#define DDR_PARA_CHIP_BITS(n) (((n)<<0)&0x00000003)
+#define DDR_PARA_CHIP_BITS_SHIFT 0
+#define DDR_PARA_CHIP_BITS_MASK 0x00000003
+/* memory width 0--8bit 1--16bit 2--32bit */
+#define DDR_PARA_MEM_BITS(n) (((n)<<2)&0x0000000c)
+#define DDR_PARA_MEM_BITS_SHIFT 2
+#define DDR_PARA_MEM_BITS_MASK 0x0000000c
+/* 2--4banks 3--8banks */
+#define DDR_PARA_BANK_BITS(n) (((n)<<4)&0x000000f0)
+#define DDR_PARA_BANK_BITS_SHIFT 4
+#define DDR_PARA_BANK_BITS_MASK 0x000000f0
+/* 2--13rbs 3--14rbs 4--15rbs 5--16rbs */
+#define DDR_PARA_ROW_BITS(n) (((n)<<8)&0x00000f00)
+#define DDR_PARA_ROW_BITS_SHIFT 8
+#define DDR_PARA_ROW_BITS_MASK 0x00000f00
+/* 0--8cbs 1--9cbs 2--10cbs 3--11cbs 4--12cbs */
+#define DDR_PARA_COL_BITS(n) (((n)<<12)&0x0000f000)
+#define DDR_PARA_COL_BITS_SHIFT 12
+#define DDR_PARA_COL_BITS_MASK 0x0000f000
+
+int ddr_init(UINT16 flags, UINT32 para);
+
+#endif /* _SYS_DDR3_H_ */
+
diff --git a/board/rda/rda8810h/ddr3_init.h b/board/rda/rda8810h/ddr3_init.h
new file mode 100644
index 0000000000..402375d269
--- /dev/null
+++ b/board/rda/rda8810h/ddr3_init.h
@@ -0,0 +1,101 @@
+#ifndef _SYS_RAM_INIT_H_
+#define _SYS_RAM_INIT_H_
+
+#define MEMC_STATUS 0x000
+#define MEMC_CONFIG 0x004
+#define MEMC_CMD 0x008
+#define ADDR_CTRL 0x010
+#define DECODE_CTRL 0x014
+#define FORMAT_CTRL 0x018
+#define LOWPWR_CTRL 0x020
+#define TURNAROUND_PRIO 0x030
+#define HIT_PRIO 0x034
+//QOS0~QOS15:038~078
+#define QOSX_CTRL 0x038
+#define QOSX_CTRL7 0x058
+#define QOSX_CTRL15 0x078
+#define TIMEOUT_CTRL 0x07C
+#define QUEUE_CTRL 0x080
+#define WR_PRIO_CTRL 0x088
+#define WR_PRIO_CTRL2 0x08C
+#define RD_PRIO_CTRL 0x090
+#define RD_PRIO_CTRL2 0x094
+#define ACCESS_ADDR_MATCH 0x098
+#define ACCESS_ADDR_MATCH_63_32 0x09C
+#define ACCESS_ADDR_MASK 0x0A0
+#define ACCESS_ADDR_MASK_63_32 0x0A4
+
+#define CHANNEL_STATUS 0x100
+#define DIRECT_CMD 0x108
+#define MR_DATA 0x110
+#define REFRESH_CTRL 0x120
+#define INTR_CTRL 0x128
+#define INTR_CLR 0x130
+#define INTR_STATUS 0x138
+#define INTR_INFO 0x140
+#define ECC_CTRL 0x148
+
+#define T_REFI 0x200
+#define T_RFC 0x204
+#define T_MRR 0x208
+#define T_MRW 0x20C
+#define T_RCD 0x218
+#define T_RAS 0x21C
+#define T_RP 0x220
+#define T_RPALL 0x224
+#define T_RRD 0x228
+#define T_FAW 0x22C
+#define RD_LATENCY 0x230
+#define T_RTR 0x234
+#define T_RTW 0x238
+#define T_RTP 0x23C
+#define WR_LATENCY 0x240
+#define T_WR 0x244
+#define T_WTR 0x248
+#define T_WTW 0x24C
+#define T_ECKD 0x250
+#define T_XCKD 0x254
+#define T_EP 0x258
+#define T_XP 0x25C
+#define T_ESR 0x260
+#define T_XSR 0x264
+#define T_SRCKD 0x268
+#define T_CKSRD 0x26C
+
+#define T_RDDATA_EN 0x300
+#define T_PHYWRLAT 0x304
+#define RDLVL_CTRL 0x308
+#define RDLVL_DIRECT 0x310
+#define T_RDLVL_EN 0x318
+#define T_RDLVL_RR 0x31C
+#define WRLVL_CTRL 0x328
+#define WRLVL_DIRECT 0x330
+#define T_WRLVL_EN 0x338
+#define T_WRLVL_WW 0x33C
+
+#define PHY_PWR_CTRL 0x348
+#define PHY_UPD_CTRL 0x350
+
+#define USER_STATUS 0x400
+#define USER_CONFIG0 0x404
+#define USER_CONFIG1 0x408
+
+#define INTEG_CFG 0xE00
+#define INTEG_OUTPUTS 0xE08
+
+#define PERIPH_ID_0 0xFE0
+#define PERIPH_ID_1 0xFE4
+#define PERIPH_ID_2 0xFE8
+#define PERIPH_ID_3 0xFEC
+#define COMPONENT_ID_0 0xFF0
+#define COMPONENT_ID_1 0xFF4
+#define COMPONENT_ID_2 0xFF8
+#define COMPONENT_ID_3 0xFFC
+
+typedef struct {
+ UINT32 reg_offset;
+ UINT32 dll_on_val;
+ UINT32 dll_off_val;
+} dmc_reg_t;
+
+#endif /* _SYS_RAM_INIT_H_ */
diff --git a/board/rda/rda8810h/debug.h b/board/rda/rda8810h/debug.h
new file mode 100644
index 0000000000..1d4f03bedb
--- /dev/null
+++ b/board/rda/rda8810h/debug.h
@@ -0,0 +1,9 @@
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+void print_u8(u8 ch);
+void print_u16(u16 data);
+void print_u32(u32 data);
+void dump_buf(u8 *buf, u32 size);
+
+#endif /* _DEBUG_H_ */
diff --git a/board/rda/rda8810h/hal_config.c b/board/rda/rda8810h/hal_config.c
new file mode 100644
index 0000000000..ade97c4b5a
--- /dev/null
+++ b/board/rda/rda8810h/hal_config.c
@@ -0,0 +1,1451 @@
+////////////////////////////////////////////////////////////////////////////////
+// //
+// Copyright (C) 2013, RDA Microeletronics. //
+// All Rights Reserved //
+// //
+// This source code is the property of RDA Microeletronics and is //
+// confidential. Any modification, distribution, reproduction or //
+// exploitation of any content of this file is totally forbidden, //
+// except with the written permission of RDA Microeletronics. //
+// //
+////////////////////////////////////////////////////////////////////////////////
+// //
+// $HeadURL: http://svn.rdamicro.com/svn/developing1/Sources/chip/branches/8810/hal/8810/src/hal_config.c $ //
+// $Author: huazeng $ //
+// $Date: 2013-08-31 17:48:58 +0800 (Sat, 31 Aug 2013) $ //
+// $Revision: 21005 $ //
+// //
+////////////////////////////////////////////////////////////////////////////////
+// //
+/// @file hal_config.c
+/// Implementation of HAL initialization related with the particular instance
+/// of the IP.
+// //
+////////////////////////////////////////////////////////////////////////////////
+
+/* uboot */
+#include <common.h>
+
+/* common */
+#include <asm/arch/rda_iomap.h>
+#include <asm/arch/hwcfg.h>
+#include <asm/arch/chip_id.h>
+#include <asm/arch/cs_types.h>
+#include <asm/arch/global_macros.h>
+#include <asm/arch/reg_gpio.h>
+
+/* device */
+#include "hal_sys.h"
+#include "halp_sys.h"
+#include "halp_gpio.h"
+#include "bootp_mode.h"
+#include "hal_config.h"
+#include "hal_ap_gpio.h"
+#include "hal_ap_config.h"
+#include <asm/arch/reg_cfg_regs.h>
+
+/* target */
+#include "tgt_board_cfg.h"
+#include "tgt_ap_gpio_setting.h"
+#define HAL_ASSERT(cond, fmt, ...) \
+ if(!(cond)) { \
+ hal_assert(fmt, ##__VA_ARGS__); \
+ g_halConfigError = TRUE; \
+ }
+
+//// =============================================================================
+//// GLOBAL VARIABLES
+//// =============================================================================
+PRIVATE CONST UINT8 g_halCfgSimOrder[] = { TGT_SIM_ORDER };
+PRIVATE HAL_CFG_CONFIG_T hal_cfg = TGT_HAL_CONFIG;
+PRIVATE UINT32 g_bootBootMode = 0;
+PRIVATE BOOL g_halConfigError = FALSE;
+
+
+// =============================================================================
+// FUNCTIONS
+// =============================================================================
+// HAL_ASSERT
+PRIVATE VOID hal_assert(const char *fmt, ...)
+{
+ va_list args;
+ puts("\n#-------Board Mux config found error-------#\n");
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ putc('\n');
+ puts("--------------------------------------------\n\n");
+ va_end(args);
+}
+
+// =============================================================================
+// hal_BoardSimUsed
+// -----------------------------------------------------------------------------
+/// Check whether a SIM card interface is used.
+// ============================================================================
+PRIVATE BOOL hal_BoardSimUsed(UINT32 simId)
+{
+ UINT32 i;
+ for (i=0; i<ARRAY_SIZE(g_halCfgSimOrder) && i<NUMBER_OF_SIM; i++)
+ {
+ if (g_halCfgSimOrder[i] == simId)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+#if 0
+// =============================================================================
+// hal_BoardConfigClk32k
+// -----------------------------------------------------------------------------
+/// Configure CLK_32K output.
+/// @param enable TRUE to configure, and FALSE to disable.
+// ============================================================================
+PROTECTED VOID hal_BoardConfigClk32k(BOOL enable)
+{
+ HAL_ASSERT(g_halCfg->useClk32k == TRUE, "32K clock is not configured");
+
+ if (enable)
+ {
+ // Setup the pin as 32K clock output
+ hwp_configRegs->Alt_mux_select =
+ (hwp_configRegs->Alt_mux_select & ~CFG_REGS_GPO_2_MASK) |
+ CFG_REGS_GPO_2_CLK_32K;
+ }
+ else
+ {
+ // Setup the pin as GPO (and low ouput has been
+ // configured in hal_BoardSetup())
+ hwp_configRegs->Alt_mux_select =
+ (hwp_configRegs->Alt_mux_select & ~CFG_REGS_GPO_2_MASK) |
+ CFG_REGS_GPO_2_GPO_2;
+ }
+}
+#endif
+
+// =============================================================================
+// hal_BoardSetupGeneral
+// -----------------------------------------------------------------------------
+/// Apply board dependent configuration to HAL for general purpose
+/// @param halCfg Pointer to HAL configuration structure (from the target
+/// module).
+// ============================================================================
+PROTECTED VOID hal_BoardSetupGeneral(CONST HAL_CFG_CONFIG_T* halCfg)
+{
+ UINT32 altMux = 0;
+ UINT32 altMux2 = 0;
+
+ UINT32 availableGpo_A = 0;
+
+ UINT32 availableGpio_C = 0;
+ UINT32 availableGpio_A = 0;
+ UINT32 availableGpio_B = 0;
+ UINT32 availableGpio_D = 0;
+ UINT32 availableGpio_E = 0;
+
+ UINT32 bootModeGpio_C = 0;
+ UINT32 bootModeGpio_A = 0;
+ UINT32 bootModeGpio_B = 0;
+ UINT32 bootModeGpio_D = 0;
+ UINT32 bootModeGpio_E = 0;
+
+ UINT32 noConnectMask_C = 0;
+ UINT32 noConnectMask_A = 0;
+ UINT32 noConnectMask_B = 0;
+ UINT32 noConnectMask_D = 0;
+ UINT32 noConnectMask_E = 0;
+
+ UINT32 gpoClr_A = 0;
+
+#ifdef CONFIG_RDA_FPGA
+
+ // no muxing, do nothing
+ // add support for sd card
+ hwp_configRegs->BB_GPIO_Mode &= ~(0x3F<<9);
+
+#else // !FPGA
+
+ // GPIOs as boot mode pins
+ bootModeGpio_C = HAL_GPIO_BIT(1)
+ | HAL_GPIO_BIT(2)
+ | HAL_GPIO_BIT(3)
+ | HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(5);
+ bootModeGpio_A = HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(5)
+ | HAL_GPIO_BIT(6)
+ | HAL_GPIO_BIT(7);
+ bootModeGpio_B = HAL_GPIO_BIT(0);
+ bootModeGpio_D = 0;
+ bootModeGpio_E = 0;
+
+ // Available GPIOs
+ availableGpio_C |= HAL_GPIO_BIT(0)
+ | HAL_GPIO_BIT(1)
+ | HAL_GPIO_BIT(2)
+ | HAL_GPIO_BIT(3)
+ | HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(5);
+ // Volume down/up keys
+ availableGpio_D |= HAL_GPIO_BIT(5)
+ | HAL_GPIO_BIT(6);
+
+ // Boot modes
+ BOOL spiFlashCam = FALSE;
+ BOOL spiFlashNand = FALSE;
+ if (g_bootBootMode & BOOT_MODE_BOOT_SPI)
+ {
+ if (g_bootBootMode & BOOT_MODE_SPI_PIN_NAND)
+ {
+ HAL_ASSERT((g_bootBootMode & BOOT_MODE_BOOT_EMMC),
+ "Emmc boot pin should be pulled up to boot on SPI flash over NAND pins");
+ spiFlashNand = TRUE;
+ }
+ else
+ {
+ spiFlashCam = TRUE;
+ }
+ }
+
+ //UINT32 metalId = rda_metal_id_get();
+ UINT32 emmcBootModeMask;
+ if (1) //metalId < 0x02)
+ {
+ emmcBootModeMask = BOOT_MODE_BOOT_EMMC
+ | BOOT_MODE_BOOT_SPI
+ | BOOT_MODE_BOOT_SPI_NAND;
+ }
+ else
+ {
+ emmcBootModeMask = BOOT_MODE_BOOT_EMMC
+ | BOOT_MODE_BOOT_SPI;
+ }
+ if ((g_bootBootMode & emmcBootModeMask) == BOOT_MODE_BOOT_EMMC)
+ {
+ // Boot from EMMC
+ HAL_ASSERT(halCfg->sdmmcCfg.sdmmc3Used, "SDMMC3 (EMMC) should be used");
+ }
+
+ if (1) //metalId < 0x02)
+ {
+ if ( (g_bootBootMode & (BOOT_MODE_BOOT_SPI|BOOT_MODE_BOOT_SPI_NAND))
+ == BOOT_MODE_BOOT_SPI_NAND ||
+ (g_bootBootMode & (BOOT_MODE_BOOT_SPI|BOOT_MODE_NAND_PAGE_SIZE_L))
+ == (BOOT_MODE_BOOT_SPI|BOOT_MODE_NAND_PAGE_SIZE_L)
+ )
+ {
+ // Boot from SDMMC1
+ HAL_ASSERT(halCfg->sdmmcCfg.sdmmcUsed, "SDMMC1 should be used");
+ }
+ }
+
+ // For convenience, we do not consider spiFlashCam at present.
+ // We assume that SPI flash always uses parallel nand pins.
+#if 0
+ BOOL parallelNandUsed = halCfg->parallelNandUsed;
+#else
+ BOOL parallelNandUsed = !spiFlashNand && !halCfg->sdmmcCfg.sdmmc3Used;
+#endif
+ BOOL nand8_15Cam = FALSE;
+ BOOL nand8_15Lcd = FALSE;
+ if ((g_bootBootMode & (BOOT_MODE_BOOT_SPI|BOOT_MODE_BOOT_EMMC)) == 0)
+ {
+ HAL_ASSERT(parallelNandUsed, "Parallel NAND should be used");
+ }
+ if (parallelNandUsed)
+ {
+ HAL_ASSERT(!spiFlashNand, "SPI flash uses parallel NAND pins");
+ HAL_ASSERT(!halCfg->sdmmcCfg.sdmmc3Used,
+ "SDMMC3 (EMMC) uses parallel NAND pins");
+ if ((g_bootBootMode & BOOT_MODE_NAND_8BIT) == 0)
+ {
+ if (g_bootBootMode & BOOT_MODE_NAND_HIGH_PIN_CAM)
+ {
+ HAL_ASSERT(!spiFlashCam, "SPI flash uses NAND 8-15 bits on cam pins");
+ nand8_15Cam = TRUE;
+ }
+ else
+ {
+ nand8_15Lcd = TRUE;
+ }
+ }
+ }
+
+ if (!parallelNandUsed)
+ {
+ availableGpio_D |= HAL_GPIO_BIT(9);
+
+#ifdef NAND_IO_RECONFIG_WORKROUND
+ if (spiFlashNand)
+ {/*GPIO_B:25,26,27,28,29; GPIO_D:4 the output level is inverted*/
+ availableGpio_B |= HAL_GPIO_BIT(25)
+ | HAL_GPIO_BIT(26)
+ | HAL_GPIO_BIT(27)
+ | HAL_GPIO_BIT(28)
+ | HAL_GPIO_BIT(29);
+ availableGpio_D |= HAL_GPIO_BIT(4);
+ }else{
+ availableGpio_D |= HAL_GPIO_BIT(8);
+ }
+#else
+ if (!spiFlashNand)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(25)
+ | HAL_GPIO_BIT(26)
+ | HAL_GPIO_BIT(27)
+ | HAL_GPIO_BIT(28)
+ | HAL_GPIO_BIT(29);
+ availableGpio_D |= HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(8);
+ }
+#endif
+
+ if (!halCfg->sdmmcCfg.sdmmc3Used)
+ {
+ availableGpio_D |= HAL_GPIO_BIT(10);
+ }
+ }
+#ifdef NAND_IO_RECONFIG_WORKROUND
+ else
+ {/*GPIO_B:25,26,27,28,29; GPIO_D:4 the output level is inverted*/
+ availableGpio_B |= HAL_GPIO_BIT(25)
+ | HAL_GPIO_BIT(26)
+ | HAL_GPIO_BIT(27)
+ | HAL_GPIO_BIT(28)
+ | HAL_GPIO_BIT(29);
+ availableGpio_D |= HAL_GPIO_BIT(4);
+ }
+#endif
+
+ CONST HAL_CFG_CAM_T *camCfg = &halCfg->camCfg;
+ CONST HAL_CFG_CAM_T *cam2Cfg = &halCfg->cam2Cfg;
+ CONST HAL_LCD_MODE_T lcdMode = halCfg->goudaCfg.lcdMode;
+
+ // LCD
+ if (lcdMode == HAL_LCD_MODE_PARALLEL_16BIT)
+ {
+ /* Check LCD 8-15 bits */
+ HAL_ASSERT(!nand8_15Lcd, "NAND uses LCD 8-15 bits");
+ HAL_ASSERT(!halCfg->goudaCfg.lcd8_23Cam2, "Parallel LCD 8-5 bits should use NAND pins only");
+ altMux |= CFG_REGS_LCD_MODE_PARALLEL_16BIT;
+ }
+ else if (lcdMode == HAL_LCD_MODE_DSI)
+ {
+ altMux |= CFG_REGS_LCD_MODE_DSI;
+ availableGpio_A |= HAL_GPIO_BIT(22)
+ | HAL_GPIO_BIT(23);
+ }
+ else if (lcdMode == HAL_LCD_MODE_RGB_16BIT ||
+ lcdMode == HAL_LCD_MODE_RGB_18BIT ||
+ lcdMode == HAL_LCD_MODE_RGB_24BIT)
+ {
+ /* Check LCD 8-15 bits */
+ if (halCfg->goudaCfg.lcd8_23Cam2)
+ {
+ HAL_ASSERT(!(cam2Cfg->camUsed || cam2Cfg->cam1Used),
+ "Camera2 uses LCD 8-15 bits");
+ altMux2 |= CFG_REGS_RGB_CAM_2_ENABLE;
+ }
+ else
+ {
+ HAL_ASSERT(!nand8_15Lcd, "NAND uses LCD 8-15 bits");
+ }
+ if (lcdMode == HAL_LCD_MODE_RGB_18BIT ||
+ lcdMode == HAL_LCD_MODE_RGB_24BIT)
+ {
+ /* Check LCD 16-23 bits */
+ if (lcdMode == HAL_LCD_MODE_RGB_18BIT && halCfg->goudaCfg.lcd16_17Cs)
+ {
+ HAL_ASSERT(!halCfg->goudaCfg.lcd16_23Cam,
+ "LCD 16-17 bits have been configured on camera pins");
+ HAL_ASSERT(!(halCfg->goudaCfg.cs0Used || halCfg->goudaCfg.cs1Used),
+ "LCD CS 0/1 use LCD 16-17 bits");
+ altMux2 |= CFG_REGS_LCD_RGB_17_16_LCD_DATA;
+ }
+ else if (halCfg->goudaCfg.lcd8_23Cam2)
+ {
+ HAL_ASSERT(!halCfg->goudaCfg.lcd16_23Cam,
+ "LCD 16-23 bits have been configured on camera pins");
+ HAL_ASSERT(halCfg->goudaCfg.lcd16_17Cs,
+ "LCD 16-17 bits should use LCD CS 0/1");
+ HAL_ASSERT(!(halCfg->goudaCfg.cs0Used || halCfg->goudaCfg.cs1Used),
+ "LCD CS 0/1 use LCD 16-17 bits");
+ HAL_ASSERT(!(cam2Cfg->camUsed || cam2Cfg->cam1Used),
+ "Camera2 uses LCD 18-23 bits");
+ altMux2 |= CFG_REGS_LCD_RGB_17_16_LCD_DATA;
+ altMux2 |= CFG_REGS_RGB_CAM_2_ENABLE;
+ }
+ else if (halCfg->goudaCfg.lcd16_23Cam)
+ {
+ HAL_ASSERT(!(halCfg->goudaCfg.lcd16_17Cs || halCfg->goudaCfg.lcd8_23Cam2),
+ "LCD 16-23 bits have been configured on LCD CS 0/1 and camera2 pins");
+ HAL_ASSERT(
+ !(camCfg->camMode == HAL_CAM_MODE_PARALLEL &&
+ (camCfg->camUsed || camCfg->cam1Used)),
+ "Parallel camera uses LCD 16-23 bits");
+ HAL_ASSERT(
+ !(halCfg->i2cCfg.i2c2Used && halCfg->i2cCfg.i2c2PinsCam),
+ "I2C2 uses LCD 22-23 bits");
+ HAL_ASSERT(!spiFlashCam, "SPI flash uses LCD 16-21 bits");
+ HAL_ASSERT(!nand8_15Cam, "NAND uses LCD 16-23 bits");
+ HAL_ASSERT(
+ !(camCfg->camMode == HAL_CAM_MODE_CSI &&
+ ((camCfg->camUsed && camCfg->camCsiId == HAL_CAM_CSI_1) ||
+ (camCfg->cam1Used && camCfg->cam1CsiId == HAL_CAM_CSI_1))),
+ "Camera CSI1 uses LCD 16-21 bits");
+ altMux |= CFG_REGS_RGB_CAM_ENABLE;
+ }
+ else
+ {
+ HAL_ASSERT(!parallelNandUsed, "NAND uses LCD 16-23 bits");
+ HAL_ASSERT(!halCfg->sdmmcCfg.sdmmc3Used, "SDMMC3 uses LCD 16-23 bits");
+ altMux |= CFG_REGS_RGB_CAM_DISABLE;
+ }
+ }
+ altMux |= CFG_REGS_LCD_MODE_RGB_24BIT;
+ }
+ else if (lcdMode == HAL_LCD_MODE_SPI)
+ {
+ HAL_ASSERT(!(halCfg->goudaCfg.cs0Used || halCfg->goudaCfg.cs1Used),
+ "LCD CS 0/1 use SPI LCD pins");
+ HAL_ASSERT((halCfg->usedGpo_A & (HAL_GPO_BIT(3)|HAL_GPO_BIT(4))) == 0,
+ "GPO 3/4 use SPI LCD pins");
+ altMux |= CFG_REGS_SPI_LCD_SPI_LCD;
+ availableGpio_A |= HAL_GPIO_BIT(18)
+ | HAL_GPIO_BIT(19)
+ | HAL_GPIO_BIT(20)
+ | HAL_GPIO_BIT(21);
+ }
+ else
+ {
+ HAL_ASSERT(FALSE, "Lcd mode not defined!");
+ }
+
+ if (lcdMode == HAL_LCD_MODE_DSI ||
+ lcdMode == HAL_LCD_MODE_SPI ||
+ ((lcdMode == HAL_LCD_MODE_RGB_16BIT ||
+ lcdMode == HAL_LCD_MODE_RGB_18BIT ||
+ lcdMode == HAL_LCD_MODE_RGB_24BIT) &&
+ halCfg->goudaCfg.lcd8_23Cam2))
+ {
+ if (!nand8_15Lcd)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(24)
+ | HAL_GPIO_BIT(25)
+ | HAL_GPIO_BIT(26)
+ | HAL_GPIO_BIT(27)
+ | HAL_GPIO_BIT(28)
+ | HAL_GPIO_BIT(29)
+ | HAL_GPIO_BIT(30)
+ | HAL_GPIO_BIT(31);
+ }
+ }
+
+ if (halCfg->goudaCfg.cs0Used)
+ {
+ altMux |= CFG_REGS_GPO_4_LCD_CS_0;
+ }
+ else
+ {
+ altMux |= CFG_REGS_GPO_4_GPO_4;
+ availableGpo_A |= HAL_GPO_BIT(4);
+ }
+
+ if (halCfg->goudaCfg.cs1Used)
+ {
+ altMux |= CFG_REGS_GPO_3_LCD_CS_1;
+ }
+ else
+ {
+ altMux |= CFG_REGS_GPO_3_GPO_3;
+ availableGpo_A |= HAL_GPO_BIT(3);
+ }
+
+ // I2C
+ if (!halCfg->i2cCfg.i2cUsed)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(30)
+ | HAL_GPIO_BIT(31);
+ }
+
+ if (halCfg->i2cCfg.i2c2Used)
+ {
+ if (halCfg->i2cCfg.i2c2PinsCam)
+ {
+ if (camCfg->camUsed)
+ {
+ HAL_ASSERT(camCfg->camPdnRemap == GPIO_NONE &&
+ camCfg->camRstRemap == GPIO_NONE,
+ "Cam uses PDN/RST pins");
+ }
+ if (camCfg->cam1Used)
+ {
+ HAL_ASSERT(camCfg->cam1PdnRemap == GPIO_NONE &&
+ camCfg->cam1RstRemap == GPIO_NONE,
+ "Cam1 uses PDN/RST pins");
+ }
+ HAL_ASSERT(!nand8_15Cam, "NAND uses cam PDN/RST pins");
+ availableGpio_A |= HAL_GPIO_BIT(0)
+ | HAL_GPIO_BIT(1);
+ altMux |= CFG_REGS_CAM_I2C2_I2C2;
+ }
+ else
+ {
+ // I2C2 does not use cam pins
+ altMux |= CFG_REGS_CAM_I2C2_CAM;
+ }
+ }
+ else
+ {
+ // I2C2 does not use cam pins
+ altMux |= CFG_REGS_CAM_I2C2_CAM;
+ availableGpio_A |= HAL_GPIO_BIT(0)
+ | HAL_GPIO_BIT(1);
+ }
+
+ if (halCfg->i2cCfg.i2c3Used)
+ {
+ HAL_ASSERT((halCfg->keyOutMask & 0x18) == 0, "Keyout 3/4 use I2C3 pins");
+ altMux |= CFG_REGS_KEYOUT_3_4_I2C3;
+ }
+ else
+ {
+ altMux |= CFG_REGS_KEYOUT_3_4_KEYOUT_3_4;
+ if ((halCfg->keyOutMask & 0x8) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(6);
+ }
+ if ((halCfg->keyOutMask & 0x10) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(7);
+ }
+ }
+
+ if (halCfg->i2cCfg.modemI2cUsed)
+ {
+ HAL_ASSERT(!halCfg->emacUsed, "EMAC uses modem I2C pins");
+ }
+ else
+ {
+ if (!halCfg->emacUsed)
+ {
+ availableGpio_E |= HAL_GPIO_BIT(0)
+ | HAL_GPIO_BIT(1);
+ }
+ }
+
+ // Camera
+ if (camCfg->camUsed || camCfg->cam1Used)
+ {
+ if(camCfg->camMode == HAL_CAM_MODE_PARALLEL)
+ {
+ HAL_ASSERT(!spiFlashCam, "SPI flash uses cam pins");
+ HAL_ASSERT(!nand8_15Cam, "NAND 8-15 bits use cam pins");
+ altMux |= CFG_REGS_CSI2_PARALLEL_CAM;
+ availableGpio_B |= HAL_GPIO_BIT(24);
+ }
+ else if (camCfg->camMode == HAL_CAM_MODE_SPI)
+ {
+ altMux |= CFG_REGS_CSI2_SPI_CAM;
+ availableGpio_B |= HAL_GPIO_BIT(14);
+ if (!(spiFlashCam || nand8_15Cam ||
+ (lcdMode == HAL_LCD_MODE_RGB_24BIT &&
+ halCfg->goudaCfg.lcd16_23Cam)
+ )
+ )
+ {
+ availableGpio_B |= HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(20)
+ | HAL_GPIO_BIT(21)
+ | HAL_GPIO_BIT(22)
+ | HAL_GPIO_BIT(23)
+ | HAL_GPIO_BIT(24);
+ }
+ }
+ else if (camCfg->camMode == HAL_CAM_MODE_CSI)
+ {
+ if ((camCfg->camUsed && camCfg->camCsiId == HAL_CAM_CSI_1) ||
+ (camCfg->cam1Used && camCfg->cam1CsiId == HAL_CAM_CSI_1))
+ {
+ HAL_ASSERT(!spiFlashCam, "SPI flash uses CSI1 pins");
+ HAL_ASSERT(!nand8_15Cam, "NAND 8-15 bits use CSI1 pins");
+ }
+ else
+ {
+ // CSI1 is unused
+ if (!(spiFlashCam || nand8_15Cam ||
+ (lcdMode == HAL_LCD_MODE_RGB_24BIT &&
+ halCfg->goudaCfg.lcd16_23Cam)
+ )
+ )
+ {
+ availableGpio_B |= HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(20)
+ | HAL_GPIO_BIT(21)
+ | HAL_GPIO_BIT(22)
+ | HAL_GPIO_BIT(23)
+ | HAL_GPIO_BIT(24);
+ }
+ }
+ altMux |= CFG_REGS_CSI2_CSI2;
+ // If CSI2 is unused
+ if (!((camCfg->camUsed && camCfg->camCsiId == HAL_CAM_CSI_2) ||
+ (camCfg->cam1Used && camCfg->cam1CsiId == HAL_CAM_CSI_2)))
+ {
+ availableGpio_B |= HAL_GPIO_BIT(14)
+ | HAL_GPIO_BIT(15)
+ | HAL_GPIO_BIT(16)
+ | HAL_GPIO_BIT(17)
+ | HAL_GPIO_BIT(18)
+ | HAL_GPIO_BIT(19);
+ }
+ }
+ else
+ {
+ HAL_ASSERT(FALSE, "Invalid cam mode: %d", camCfg->camMode);
+ }
+
+ // Cam PDN/RST pins
+ if (!(nand8_15Cam ||
+ (lcdMode == HAL_LCD_MODE_RGB_24BIT && halCfg->goudaCfg.lcd16_23Cam) ||
+ (halCfg->i2cCfg.i2c2Used && halCfg->i2cCfg.i2c2PinsCam)
+ )
+ )
+ {
+ if (!((camCfg->camUsed && camCfg->camRstRemap == GPIO_NONE) ||
+ (camCfg->cam1Used && camCfg->cam1RstRemap == GPIO_NONE)))
+ {
+ availableGpio_B |= HAL_GPIO_BIT(10);
+ }
+ if (!((camCfg->camUsed && camCfg->camPdnRemap == GPIO_NONE) ||
+ (camCfg->cam1Used && camCfg->cam1PdnRemap == GPIO_NONE)))
+ {
+ availableGpio_B |= HAL_GPIO_BIT(11);
+ }
+ }
+ }
+ else // cam is unused
+ {
+ availableGpio_B |= HAL_GPIO_BIT(12)
+ | HAL_GPIO_BIT(14)
+ | HAL_GPIO_BIT(15)
+ | HAL_GPIO_BIT(16)
+ | HAL_GPIO_BIT(17)
+ | HAL_GPIO_BIT(18)
+ | HAL_GPIO_BIT(19);
+ if (!(nand8_15Cam ||
+ (lcdMode == HAL_LCD_MODE_RGB_24BIT && halCfg->goudaCfg.lcd16_23Cam) ||
+ (halCfg->i2cCfg.i2c2Used && halCfg->i2cCfg.i2c2PinsCam)
+ )
+ )
+ {
+ availableGpio_B |= HAL_GPIO_BIT(10)
+ | HAL_GPIO_BIT(11);
+ }
+ if (!(spiFlashCam || nand8_15Cam ||
+ (lcdMode == HAL_LCD_MODE_RGB_24BIT && halCfg->goudaCfg.lcd16_23Cam)
+ )
+ )
+ {
+ availableGpio_B |= HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(20)
+ | HAL_GPIO_BIT(21)
+ | HAL_GPIO_BIT(22)
+ | HAL_GPIO_BIT(23)
+ | HAL_GPIO_BIT(24);
+ }
+ }
+
+ // Camera2
+ if (cam2Cfg->camUsed || cam2Cfg->cam1Used)
+ {
+ if(cam2Cfg->camMode == HAL_CAM_MODE_PARALLEL)
+ {
+ altMux2 |= CFG_REGS_CSI2_2_PARALLEL_CAM;
+ }
+ else if (cam2Cfg->camMode == HAL_CAM_MODE_SPI)
+ {
+ altMux2 |= CFG_REGS_CSI2_2_SPI_CAM;
+ availableGpio_E |= HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(5)
+ | HAL_GPIO_BIT(6)
+ | HAL_GPIO_BIT(12)
+ | HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(14)
+ | HAL_GPIO_BIT(15);
+ }
+ else if (cam2Cfg->camMode == HAL_CAM_MODE_CSI)
+ {
+ if ((cam2Cfg->camUsed && (cam2Cfg->camCsiId == HAL_CAM_CSI_1 ||
+ cam2Cfg->camCsiId == HAL_CAM_CSI_2)) ||
+ (cam2Cfg->cam1Used && (cam2Cfg->cam1CsiId == HAL_CAM_CSI_1 ||
+ cam2Cfg->cam1CsiId == HAL_CAM_CSI_2)))
+ {
+ altMux2 |= CFG_REGS_CSI2_2_CSI2;
+ }
+ else
+ {
+ availableGpio_E |= HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(5)
+ | HAL_GPIO_BIT(6)
+ | HAL_GPIO_BIT(7)
+ | HAL_GPIO_BIT(8)
+ | HAL_GPIO_BIT(9)
+ | HAL_GPIO_BIT(10)
+ | HAL_GPIO_BIT(11)
+ | HAL_GPIO_BIT(12)
+ | HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(14)
+ | HAL_GPIO_BIT(15);
+ }
+ }
+ else
+ {
+ HAL_ASSERT(FALSE, "Invalid cam2 mode: %d", cam2Cfg->camMode);
+ }
+
+ // Cam2 PDN/RST pins
+ if (!((cam2Cfg->camUsed && cam2Cfg->camRstRemap == GPIO_NONE) ||
+ (cam2Cfg->cam1Used && cam2Cfg->cam1RstRemap == GPIO_NONE)))
+ {
+ availableGpio_E |= HAL_GPIO_BIT(2);
+ }
+ if (!((cam2Cfg->camUsed && cam2Cfg->camPdnRemap == GPIO_NONE) ||
+ (cam2Cfg->cam1Used && cam2Cfg->cam1PdnRemap == GPIO_NONE) ||
+ (altMux2 & CFG_REGS_CSI2_2_CSI2)))
+ {
+ availableGpio_E |= HAL_GPIO_BIT(3);
+ }
+ }
+ else // cam2 is unused
+ {
+ if (!((lcdMode == HAL_LCD_MODE_RGB_16BIT ||
+ lcdMode == HAL_LCD_MODE_RGB_18BIT ||
+ lcdMode == HAL_LCD_MODE_RGB_24BIT) &&
+ halCfg->goudaCfg.lcd8_23Cam2))
+ {
+ availableGpio_E |= HAL_GPIO_BIT(2)
+ | HAL_GPIO_BIT(3)
+ | HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(5)
+ | HAL_GPIO_BIT(6)
+ | HAL_GPIO_BIT(7)
+ | HAL_GPIO_BIT(8)
+ | HAL_GPIO_BIT(9)
+ | HAL_GPIO_BIT(10)
+ | HAL_GPIO_BIT(11)
+ | HAL_GPIO_BIT(12)
+ | HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(14)
+ | HAL_GPIO_BIT(15);
+ }
+ }
+
+ // UART 1 Pin configuration
+ switch (halCfg->uartCfg[0])
+ {
+ case HAL_UART_CONFIG_NONE:
+ altMux |= CFG_REGS_KEYOUT_7_KEYOUT_7;
+ availableGpio_C |= HAL_GPIO_BIT(6);
+ availableGpio_A |= HAL_GPIO_BIT(14);
+ if ((halCfg->keyInMask & 0x80) == 0)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(15);
+ }
+ if ((halCfg->keyInMask & 0x80) == 0)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(16);
+ }
+ break;
+ case HAL_UART_CONFIG_DATA:
+ // use UART1 TXD, RXD
+ altMux |= CFG_REGS_KEYOUT_7_KEYOUT_7;
+ if ((halCfg->keyInMask & 0x80) == 0)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(15);
+ }
+ if ((halCfg->keyInMask & 0x80) == 0)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(16);
+ }
+ break;
+ case HAL_UART_CONFIG_FLOWCONTROL:
+ // use UART1 TXD, RXD, CTS, RTS
+ HAL_ASSERT((halCfg->keyInMask & 0x80) == 0, "Keyin 7 uses UART1 CTS");
+ HAL_ASSERT((halCfg->keyOutMask & 0x80) == 0, "Keyout 7 uses UART1 RTS");
+ altMux |= CFG_REGS_KEYOUT_7_UART1_RTS;
+ break;
+ case HAL_UART_CONFIG_MODEM:
+ // use UART1 TXD, RXD, CTS, RTS, RI, DSR, DCD, DTR
+ HAL_ASSERT((halCfg->keyInMask & 0x80) == 0, "Keyin 7 uses UART1 CTS");
+ HAL_ASSERT((halCfg->keyOutMask & 0x80) == 0, "Keyout 7 uses UART1 RTS");
+ HAL_ASSERT(!halCfg->hostUartUsed, "Host UART uses UART1 DCD/DTR");
+ HAL_ASSERT(halCfg->uartCfg[1] == HAL_UART_CONFIG_NONE,
+ "UART 2 must be unused to use UART1 Modem lines.");
+ HAL_ASSERT((halCfg->keyInMask & 0x40) == 0, "Keyin 6 uses UART1 DSR");
+ HAL_ASSERT((halCfg->keyOutMask & 0x40) == 0, "Keyout 6 uses UART1 RI");
+ altMux |= CFG_REGS_KEYOUT_7_UART1_RTS
+ | CFG_REGS_UART1_8LINE_UART1_8_LINE;
+ break;
+ default:
+ HAL_ASSERT(FALSE,
+ "Invalid Uart 1 Configuration (%d).",
+ halCfg->uartCfg[0]);
+ break;
+ }
+
+ // Host UART
+ if (halCfg->hostUartUsed)
+ {
+ HAL_ASSERT(halCfg->uartCfg[1] == HAL_UART_CONFIG_NONE,
+ "UART2 uses host UART RXD/TXD.");
+ }
+
+ // UART 2 Pin configuration
+ switch (halCfg->uartCfg[1])
+ {
+ case HAL_UART_CONFIG_NONE:
+ altMux |= CFG_REGS_UART2_HOST_UART
+ | CFG_REGS_KEYOUT_6_KEYOUT_6;
+ if (halCfg->uartCfg[0] != HAL_UART_CONFIG_MODEM)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(7)
+ | HAL_GPIO_BIT(8);
+ }
+ if ((halCfg->keyInMask & 0x40) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(8);
+ }
+ if ((halCfg->keyOutMask & 0x40) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(9);
+ }
+ break;
+ case HAL_UART_CONFIG_DATA:
+ // use UART2 TXD, RXD
+ altMux |= CFG_REGS_UART2_UART2
+ | CFG_REGS_KEYOUT_6_KEYOUT_6;
+ if ((halCfg->keyInMask & 0x40) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(8);
+ }
+ if ((halCfg->keyOutMask & 0x40) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(9);
+ }
+ break;
+ case HAL_UART_CONFIG_FLOWCONTROL:
+ // use UART2 TXD, RXD, CTS, RTS
+ HAL_ASSERT((halCfg->keyInMask & 0x40) == 0, "Keyin 6 uses UART2 CTS");
+ HAL_ASSERT((halCfg->keyOutMask & 0x40) == 0, "Keyout 6 uses UART2 RTS");
+ altMux |= CFG_REGS_UART2_UART2
+ | CFG_REGS_KEYOUT_6_UART2_RTS;
+ break;
+ case HAL_UART_CONFIG_MODEM:
+ default:
+ HAL_ASSERT(FALSE,
+ "Invalid Uart2 Configuration (%d).",
+ halCfg->uartCfg[1]);
+ break;
+ }
+
+ // UART 3 Pin configuration
+ switch (halCfg->uartCfg[2])
+ {
+ case HAL_UART_CONFIG_NONE:
+ availableGpio_D |= HAL_GPIO_BIT(0)
+ | HAL_GPIO_BIT(1)
+ | HAL_GPIO_BIT(2)
+ | HAL_GPIO_BIT(3);
+ break;
+ case HAL_UART_CONFIG_DATA:
+ // use UART3 TXD, RXD
+ availableGpio_D |= HAL_GPIO_BIT(2)
+ | HAL_GPIO_BIT(3);
+ break;
+ case HAL_UART_CONFIG_FLOWCONTROL:
+ // use UART3 TXD, RXD, CTS, RTS
+ break;
+ case HAL_UART_CONFIG_MODEM:
+ default:
+ HAL_ASSERT(FALSE,
+ "Invalid Uart3 Configuration (%d).",
+ halCfg->uartCfg[2]);
+ break;
+ }
+
+ // I2S
+ altMux |= CFG_REGS_DAI_I2S;
+ if (halCfg->i2sCfg.di0Used || halCfg->i2sCfg.di1Used ||
+ halCfg->i2sCfg.di2Used || halCfg->i2sCfg.doUsed)
+ {
+ if (!halCfg->i2sCfg.di0Used)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(11);
+ }
+ if (!halCfg->i2sCfg.di1Used)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(12);
+ }
+ if (halCfg->i2sCfg.di2Used)
+ {
+ HAL_ASSERT((halCfg->keyInMask & 0x4) == 0, "Keyin 2 uses I2S DI2");
+ altMux |= CFG_REGS_I2S_DI_2_I2S_DI_2;
+ }
+ else
+ {
+ altMux |= CFG_REGS_I2S_DI_2_KEYIN_2;
+ if ((halCfg->keyInMask & 0x4) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(2);
+ }
+ }
+ if (!halCfg->i2sCfg.doUsed)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(13);
+ }
+ }
+ else
+ {
+ availableGpio_A |= HAL_GPIO_BIT(9)
+ | HAL_GPIO_BIT(10)
+ | HAL_GPIO_BIT(11)
+ | HAL_GPIO_BIT(12)
+ | HAL_GPIO_BIT(13);
+ }
+
+ // I2S2
+ if (halCfg->i2s2Cfg.di0Used || halCfg->i2s2Cfg.di1Used ||
+ halCfg->i2s2Cfg.di2Used || halCfg->i2s2Cfg.doUsed)
+ {
+ HAL_ASSERT(!halCfg->emacUsed, "EMAC uses I2S2 pins");
+ if (!halCfg->i2s2Cfg.di0Used)
+ {
+ availableGpio_D |= HAL_GPIO_BIT(13);
+ }
+ if (!halCfg->i2s2Cfg.di1Used)
+ {
+ availableGpio_D |= HAL_GPIO_BIT(14);
+ }
+ if (!halCfg->i2s2Cfg.doUsed)
+ {
+ availableGpio_D |= HAL_GPIO_BIT(15);
+ }
+ }
+ else
+ {
+ availableGpio_D |= HAL_GPIO_BIT(11)
+ | HAL_GPIO_BIT(12)
+ | HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(14)
+ | HAL_GPIO_BIT(15);
+ }
+
+ // LPS CO1
+ if (halCfg->useLpsCo1)
+ {
+ HAL_ASSERT((halCfg->keyInMask & 0x10) == 0, "Keyin 4 uses LPS_CO1");
+ altMux |= CFG_REGS_LPSCO_1_LPSCO_1;
+ }
+ else
+ {
+ altMux |= CFG_REGS_LPSCO_1_KEYIN_4;
+ if ((halCfg->keyInMask & 0x10) == 0)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(7);
+ }
+ }
+
+ // TCO
+ if (halCfg->usedTco & 0x1)
+ {
+ HAL_ASSERT((halCfg->keyOutMask & 0x1) == 0, "Keyout 0 uses TCO0");
+ altMux |= CFG_REGS_TCO_0_TCO_0;
+ }
+ else
+ {
+ altMux |= CFG_REGS_TCO_0_KEYOUT_0;
+ if ((halCfg->keyOutMask & 0x1) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(3);
+ }
+ }
+
+ if (halCfg->usedTco & 0x2)
+ {
+ HAL_ASSERT((halCfg->keyOutMask & 0x2) == 0, "Keyout 1 uses TCO1");
+ altMux |= CFG_REGS_TCO_1_TCO_1;
+ }
+ else
+ {
+ altMux |= CFG_REGS_TCO_1_KEYOUT_1;
+ if ((halCfg->keyOutMask & 0x2) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(4);
+ }
+ }
+
+ if (halCfg->usedTco & 0x4)
+ {
+ HAL_ASSERT((halCfg->keyOutMask & 0x4) == 0, "Keyout 2 uses TCO2");
+ altMux |= CFG_REGS_TCO_2_TCO_2;
+ }
+ else
+ {
+ altMux |= CFG_REGS_TCO_2_KEYOUT_2;
+ if ((halCfg->keyOutMask & 0x4) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(5);
+ }
+ }
+
+ // PWM
+ if (halCfg->pwmCfg.pwtUsed)
+ {
+ HAL_ASSERT((halCfg->keyInMask & 0x20) == 0, "Keyin 5 uses PWT");
+ altMux |= CFG_REGS_GPO_0_PWT;
+ }
+ else if (halCfg->keyInMask & 0x20)
+ {
+ altMux |= CFG_REGS_GPO_0_KEYIN_5;
+ }
+ else
+ {
+ altMux |= CFG_REGS_GPO_0_GPO_0;
+ availableGpo_A |= HAL_GPO_BIT(0);
+ }
+
+ if (halCfg->pwmCfg.lpgUsed)
+ {
+ HAL_ASSERT((halCfg->keyOutMask & 0x20) == 0, "Keyout 5 uses LPG");
+ altMux |= CFG_REGS_GPO_1_LPG;
+ }
+ else if (halCfg->keyOutMask & 0x20)
+ {
+ altMux |= CFG_REGS_GPO_1_KEYOUT_5;
+ }
+ else
+ {
+ altMux |= CFG_REGS_GPO_1_GPO_1;
+ availableGpo_A |= HAL_GPO_BIT(1);
+ }
+
+ if (halCfg->pwmCfg.pwl1Used)
+ {
+ HAL_ASSERT(!halCfg->useClk32k, "Clk 32k uses PWL1");
+ altMux |= CFG_REGS_GPO_2_PWL_1;
+ }
+ else if (halCfg->useClk32k)
+ {
+ // Default to GPO low output
+ // 32K clock will be enabled per request
+ //altMux |= CFG_REGS_GPO_2_CLK_32K;
+ altMux |= CFG_REGS_GPO_2_GPO_2;
+ }
+ else
+ {
+ altMux |= CFG_REGS_GPO_2_GPO_2;
+ availableGpo_A |= HAL_GPO_BIT(2);
+ }
+
+ // Clock out and host clock
+ if (halCfg->clkOutUsed)
+ {
+ HAL_ASSERT(!halCfg->hostClkUsed, "HST_CLK uses CLK_OUT pin");
+ altMux |= CFG_REGS_CLK_OUT_CLK_OUT;
+ }
+ else if (halCfg->hostClkUsed)
+ {
+ altMux |= CFG_REGS_CLK_OUT_HST_CLK;
+ }
+ else
+ {
+ altMux |= CFG_REGS_CLK_OUT_HST_CLK;
+ availableGpo_A |= HAL_GPO_BIT(8);
+ }
+
+ // SPI
+ if (halCfg->spiCfg[0].cs0Used || halCfg->spiCfg[0].cs1Used ||
+ halCfg->spiCfg[0].cs2Used)
+ {
+ HAL_ASSERT(!(halCfg->modemSpiCfg[0].cs0Used ||
+ halCfg->modemSpiCfg[0].cs1Used ||
+ halCfg->modemSpiCfg[0].cs2Used), "Modem SPI1 is in use");
+ altMux |= CFG_REGS_AP_SPI1_AP_SPI1;
+ if (!halCfg->spiCfg[0].cs0Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(22);
+ }
+ if (!halCfg->spiCfg[0].cs1Used)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(17);
+ }
+ if (halCfg->spiCfg[0].cs2Used)
+ {
+ HAL_ASSERT((halCfg->keyInMask & 0x2) == 0, "Keyin 1 uses SPI1 CS2");
+ altMux |= CFG_REGS_SPI1_CS_2_SPI1_CS_2;
+ }
+ else
+ {
+ altMux |= CFG_REGS_SPI1_CS_2_KEYIN_1;
+ if ((halCfg->keyInMask & 0x2) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(1);
+ }
+ }
+ if (!halCfg->spiCfg[0].di0Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(23);
+ }
+ if (!halCfg->spiCfg[0].di1Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(24);
+ }
+ }
+ else // AP SPI1 unused
+ {
+ altMux |= CFG_REGS_AP_SPI1_BB_SPI1;
+ if (halCfg->modemSpiCfg[0].cs0Used || halCfg->modemSpiCfg[0].cs1Used ||
+ halCfg->modemSpiCfg[0].cs2Used)
+ {
+ if (!halCfg->modemSpiCfg[0].cs0Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(22);
+ }
+ if (!halCfg->modemSpiCfg[0].cs1Used)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(17);
+ }
+ if (!halCfg->modemSpiCfg[0].di0Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(23);
+ }
+ if (!halCfg->modemSpiCfg[0].di1Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(24);
+ }
+ }
+ else
+ {
+ availableGpio_A |= HAL_GPIO_BIT(17);
+ availableGpio_C |= HAL_GPIO_BIT(21)
+ | HAL_GPIO_BIT(22)
+ | HAL_GPIO_BIT(23)
+ | HAL_GPIO_BIT(24);
+ if ((halCfg->keyInMask & 0x2) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(1);
+ }
+ }
+ }
+ if (halCfg->spiCfg[1].cs0Used || halCfg->spiCfg[1].cs1Used)
+ {
+ if (!halCfg->spiCfg[1].cs0Used)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(5);
+ }
+ if (halCfg->spiCfg[1].cs1Used)
+ {
+ HAL_ASSERT((halCfg->keyInMask & 0x8) == 0, "Keyin 3 uses SPI2 CS1");
+ altMux |= CFG_REGS_KEYIN_3_SPI2_CS_1;
+ }
+ else
+ {
+ altMux |= CFG_REGS_KEYIN_3_KEYIN_3;
+ if ((halCfg->keyInMask & 0x8) == 0)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(6);
+ }
+ }
+ if (!halCfg->spiCfg[1].di0Used)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(3);
+ }
+ if (!halCfg->spiCfg[1].di1Used)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(4);
+ }
+ }
+ else // AP SPI2 unused
+ {
+ availableGpio_A |= HAL_GPIO_BIT(2)
+ | HAL_GPIO_BIT(3)
+ | HAL_GPIO_BIT(4)
+ | HAL_GPIO_BIT(5);
+ if ((halCfg->keyInMask & 0x8) == 0)
+ {
+ availableGpio_A |= HAL_GPIO_BIT(6);
+ }
+ }
+
+ // Standalone keyin/out
+ if ((halCfg->keyInMask & 0x1) == 0)
+ {
+ availableGpio_B |= HAL_GPIO_BIT(0);
+ }
+
+ // SDMMC
+ if (!halCfg->sdmmcCfg.sdmmcUsed)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(9)
+ | HAL_GPIO_BIT(10)
+ | HAL_GPIO_BIT(11)
+ | HAL_GPIO_BIT(12)
+ | HAL_GPIO_BIT(13)
+ | HAL_GPIO_BIT(14);
+ }
+ if (!halCfg->sdmmcCfg.sdmmc2Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(15)
+ | HAL_GPIO_BIT(16);
+ if (!halCfg->sdio2Uart1Used)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(17)
+ | HAL_GPIO_BIT(18)
+ | HAL_GPIO_BIT(19)
+ | HAL_GPIO_BIT(20);
+ }
+ }
+ HAL_ASSERT(!(parallelNandUsed && halCfg->sdmmcCfg.sdmmc3Used),
+ "Parallel NAND uses SDMMC3 pins");
+
+ // SDIO2_UART1
+ if (halCfg->sdio2Uart1Used)
+ {
+ HAL_ASSERT(halCfg->uartCfg[0] == HAL_UART_CONFIG_NONE,
+ "UART1 has been configured on UART1 pins");
+ altMux2 |= CFG_REGS_UART1_SDIO2_UART1;
+ }
+ else
+ {
+ altMux2 |= CFG_REGS_UART1_SDIO2_SDIO2;
+ }
+
+ // EMAC
+ if (halCfg->emacUsed)
+ {
+ altMux2 |= CFG_REGS_MAC_EN_ENABLE;
+ }
+ else
+ {
+ altMux2 |= CFG_REGS_MAC_EN_DISABLE;
+ }
+
+ // SIM
+ if (!hal_BoardSimUsed(2))
+ {
+ availableGpio_C |= HAL_GPIO_BIT(25)
+ | HAL_GPIO_BIT(26)
+ | HAL_GPIO_BIT(27);
+ }
+
+ if (hal_BoardSimUsed(3))
+ {
+ HAL_ASSERT(!halCfg->emacUsed, "EMAC uses SIM3 pins");
+ }
+ else
+ {
+ if (!halCfg->emacUsed)
+ {
+ availableGpio_C |= HAL_GPIO_BIT(28)
+ | HAL_GPIO_BIT(29)
+ | HAL_GPIO_BIT(30);
+ }
+ }
+
+ UINT32 gpioMask;
+ // GPIO_C mask check
+ gpioMask = ~availableGpio_C & halCfg->usedGpio_C;
+ HAL_ASSERT(gpioMask == 0,
+ "Some used GPIO C are not available (0x%x)",
+ gpioMask);
+ gpioMask = ~availableGpio_C & halCfg->noConnectGpio_C;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO C declared as not connected are not available (0x%x)",
+ gpioMask);
+ gpioMask = halCfg->usedGpio_C & halCfg->noConnectGpio_C;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO C declared as not connected are used (0x%x)",
+ gpioMask);
+#ifdef CHECK_GPIO_ALT_FUNC
+ gpioMask = availableGpio_C &
+ (~halCfg->usedGpio_C & ~halCfg->noConnectGpio_C);
+ HAL_ASSERT(gpioMask == 0,
+ "Some available GPIO C declared as alt function (0x%x)",
+ gpioMask);
+#endif
+
+ // GPIO_A mask check
+ gpioMask = ~availableGpio_A & halCfg->usedGpio_A;
+ HAL_ASSERT(gpioMask == 0,
+ "Some used GPIO A are not available (0x%x)",
+ gpioMask);
+ gpioMask = ~availableGpio_A & halCfg->noConnectGpio_A;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO A declared as not connected are not available (0x%x)",
+ gpioMask);
+ gpioMask = halCfg->usedGpio_A & halCfg->noConnectGpio_A;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO A declared as not connected are used (0x%x)",
+ gpioMask);
+#ifdef CHECK_GPIO_ALT_FUNC
+ gpioMask = availableGpio_A &
+ (~halCfg->usedGpio_A & ~halCfg->noConnectGpio_A);
+ HAL_ASSERT(gpioMask == 0,
+ "Some available GPIO A declared as alt function (0x%x)",
+ gpioMask);
+#endif
+
+ // GPIO_B mask check
+ gpioMask = ~availableGpio_B & halCfg->usedGpio_B;
+ HAL_ASSERT(gpioMask == 0,
+ "Some used GPIO B are not available (0x%x)",
+ gpioMask);
+ gpioMask = ~availableGpio_B & halCfg->noConnectGpio_B;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO B declared as not connected are not available (0x%x)",
+ gpioMask);
+ gpioMask = halCfg->usedGpio_B & halCfg->noConnectGpio_B;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO B declared as not connected are used (0x%x)",
+ gpioMask);
+#ifdef CHECK_GPIO_ALT_FUNC
+ gpioMask = availableGpio_B &
+ (~halCfg->usedGpio_B & ~halCfg->noConnectGpio_B);
+ HAL_ASSERT(gpioMask == 0,
+ "Some available GPIO B declared as alt function (0x%x)",
+ gpioMask);
+#endif
+
+ // GPIO_D mask check
+ gpioMask = ~availableGpio_D & halCfg->usedGpio_D;
+ HAL_ASSERT(gpioMask == 0,
+ "Some used GPIO D are not available (0x%x)",
+ gpioMask);
+ gpioMask = ~availableGpio_D & halCfg->noConnectGpio_D;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO D declared as not connected are not available (0x%x)",
+ gpioMask);
+ gpioMask = halCfg->usedGpio_D & halCfg->noConnectGpio_D;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO D declared as not connected are used (0x%x)",
+ gpioMask);
+#ifdef CHECK_GPIO_ALT_FUNC
+ gpioMask = availableGpio_D &
+ (~halCfg->usedGpio_D & ~halCfg->noConnectGpio_D);
+ HAL_ASSERT(gpioMask == 0,
+ "Some available GPIO D declared as alt function (0x%x)",
+ gpioMask);
+#endif
+
+ // GPIO_E mask check
+ gpioMask = ~availableGpio_E & halCfg->usedGpio_E;
+ HAL_ASSERT(gpioMask == 0,
+ "Some used GPIO E are not available (0x%x)",
+ gpioMask);
+ gpioMask = ~availableGpio_E & halCfg->noConnectGpio_E;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO E declared as not connected are not available (0x%x)",
+ gpioMask);
+ gpioMask = halCfg->usedGpio_E & halCfg->noConnectGpio_E;
+ HAL_ASSERT(gpioMask == 0,
+ "Some GPIO E declared as not connected are used (0x%x)",
+ gpioMask);
+#ifdef CHECK_GPIO_ALT_FUNC
+ gpioMask = availableGpio_E &
+ (~halCfg->usedGpio_E & ~halCfg->noConnectGpio_E);
+ HAL_ASSERT(gpioMask == 0,
+ "Some available GPIO E declared as alt function (0x%x)",
+ gpioMask);
+#endif
+
+ // GPO_A mask check
+ gpioMask = ~availableGpo_A & halCfg->usedGpo_A;
+ HAL_ASSERT(gpioMask == 0,
+ "Some used GPO A are not available (0x%x)",
+ gpioMask);
+
+#endif // !FPGA
+
+ // Set IO drive
+ hwp_configRegs->IO_Drive1_Select = halCfg->ioDrive.select1;
+ hwp_configRegs->IO_Drive2_Select = halCfg->ioDrive.select2;
+
+ // Set the not connected ones as output and drive 0
+ // But keep boot mode GPIOs as input to avoid current leakage
+ noConnectMask_C = halCfg->noConnectGpio_C & ~bootModeGpio_C;
+ noConnectMask_A = halCfg->noConnectGpio_A & ~bootModeGpio_A;
+ noConnectMask_B = halCfg->noConnectGpio_B & ~bootModeGpio_B;
+ noConnectMask_D = halCfg->noConnectGpio_D & ~bootModeGpio_D;
+ noConnectMask_E = halCfg->noConnectGpio_E & ~bootModeGpio_E;
+
+ hwp_gpio->gpio_clr = noConnectMask_C;
+ hwp_gpio->gpio_oen_set_out = noConnectMask_C;
+
+ hwp_apGpioA->gpio_clr = noConnectMask_A;
+ hwp_apGpioA->gpio_oen_set_out = noConnectMask_A;
+
+ hwp_apGpioB->gpio_clr = noConnectMask_B;
+ hwp_apGpioB->gpio_oen_set_out = noConnectMask_B;
+
+ hwp_apGpioD->gpio_clr = noConnectMask_D;
+ hwp_apGpioD->gpio_oen_set_out = noConnectMask_D;
+
+ hwp_apGpioE->gpio_clr = noConnectMask_E;
+ hwp_apGpioE->gpio_oen_set_out = noConnectMask_E;
+
+ // Init GPO_A values
+ gpoClr_A = availableGpo_A;
+ if (halCfg->useClk32k)
+ {
+ // Init 32K clock pin to low (by setting up GPO)
+ gpoClr_A |= HAL_GPO_BIT(2);
+ }
+#ifdef _TGT_AP_GPIO_USBID_CTRL
+ // if GPO_1 used for usb id, it should be high
+ gpoClr_A &= ~(HAL_GPO_BIT(1));
+#endif
+ hwp_apGpioA->gpo_clr = gpoClr_A;
+
+ // Configure MUX after initializing all the GPO pins
+ // (GPIO pins are in input mode by default)
+
+ // Set GPIO mode
+ hwp_configRegs->BB_GPIO_Mode = availableGpio_C;
+ hwp_configRegs->AP_GPIO_A_Mode = availableGpio_A;
+ hwp_configRegs->AP_GPIO_B_Mode = availableGpio_B;
+ hwp_configRegs->AP_GPIO_D_Mode = availableGpio_D;
+ hwp_configRegs->AP_GPIO_E_Mode = availableGpio_E;
+ // Set Alt Mux configuration
+ hwp_configRegs->Alt_mux_select = altMux;
+ hwp_configRegs->Alt_mux_select2 = altMux2;
+
+ // --------------------------------------------------
+ // As of now, all connected GPIOs, which are as GPIO
+ // or not used at all but connected are configured as
+ // GPIOs in input mode, except for Gouda reset pins
+ // --------------------------------------------------
+
+}
+
+
+// =============================================================================
+// hal_BoardSetup
+// -----------------------------------------------------------------------------
+/// Apply board dependent configuration to HAL
+/// @param halCfg Pointer to HAL configuration structure (from the target
+/// module).
+// ============================================================================
+//PROTECTED VOID hal_BoardSetup(CONST HAL_CFG_CONFIG_T* halCfg)
+PUBLIC INT32 hal_BoardSetup(INT8 run_mode)
+{
+ g_bootBootMode = rda_hwcfg_get();
+ hal_BoardSetupGeneral(&hal_cfg);
+
+ if(g_halConfigError)
+ return CMD_RET_FAILURE;
+ else
+ return CMD_RET_SUCCESS;
+}
diff --git a/board/rda/rda8810h/u-boot-spl.lds b/board/rda/rda8810h/u-boot-spl.lds
new file mode 100644
index 0000000000..afe35fd2a8
--- /dev/null
+++ b/board/rda/rda8810h/u-boot-spl.lds
@@ -0,0 +1,35 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00100100;
+ . = ALIGN(4);
+ .text :
+ {
+ __start = .;
+ arch/arm/cpu/armv7/start.o (.text)
+ *(.text)
+ }
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+ . = ALIGN(4);
+ .data : {
+ *(.data)
+ }
+ . = ALIGN(4);
+ . = .;
+ . = ALIGN(4);
+ __image_copy_end = .;
+ _end = .;
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ ASSERT((ABSOLUTE(__bss_end__) < 0x00110000), \
+ "too big data in spl, don't exceed intrenal ram");
+ }
+}