+/*
+ * Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
#include <config.h>
#include <common.h>
-#include <command.h>
-#include <asm/mipsregs.h>
#include <asm/addrspace.h>
+#include <soc/qca_soc_common.h>
-#include "ar7240_soc.h"
-
-#if !defined(COMPRESSED_UBOOT)
-extern void ar933x_ddr_init(void);
-#endif
-
-extern int ar7240_ddr_find_size(void);
-extern void ar933x_ddr_tap_init(void);
-
-int ar7240_mem_config(void)
-{
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
- #ifndef COMPRESSED_UBOOT
- ar933x_ddr_init();
- #endif
-
- /* Default tap values for starting the tap_init*/
- ar7240_reg_wr(AR7240_DDR_TAP_CONTROL0, CFG_DDR_TAP0_VAL);
- ar7240_reg_wr(AR7240_DDR_TAP_CONTROL1, CFG_DDR_TAP1_VAL);
-#endif
-
- all_led_off();
-
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
- ar933x_ddr_tap_init();
-#endif
-
- // return memory size
- return ar7240_ddr_find_size();
-}
-
+/*
+ * DRAM init
+ */
long int dram_init()
{
- return (long int)ar7240_mem_config();
+ qca_dram_init();
+
+ return (long int)qca_dram_size();
}
/*
- * Common functions for QC/A WiSoCs support
+ * Common functions for QC/A WiSoCs based boards support
+ *
* Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
*
+ * Partially based on:
+ * Linux/arch/mips/ath79/setup.c
+ *
* SPDX-License-Identifier: GPL-2.0
*/
static u32 mac_is_not_valid = 1;
+/*
+ * Put QCA SOC name, version and revision in buffer
+ */
+void qca_soc_name_rev(char *buf)
+{
+ u32 id;
+ u32 major;
+ u32 rev = 0;
+
+ if (buf == NULL)
+ return;
+
+ /* Get revision ID value */
+ id = qca_soc_reg_read(QCA_RST_REVISION_ID_REG);
+
+ major = id & QCA_RST_REVISION_ID_MAJOR_MASK;
+ rev = id & QCA_RST_REVISION_ID_REV_MASK;
+
+ switch (major) {
+#if (SOC_TYPE & QCA_AR933X_SOC)
+ case QCA_RST_REVISION_ID_MAJOR_AR9330_VAL:
+ sprintf(buf, "AR9330 rev. %d", rev);
+ break;
+ case QCA_RST_REVISION_ID_MAJOR_AR9331_VAL:
+ sprintf(buf, "AR9331 rev. %d", rev);
+ break;
+#endif
+#if (SOC_TYPE & QCA_AR934X_SOC)
+ case QCA_RST_REVISION_ID_MAJOR_AR9341_VAL:
+ sprintf(buf, "AR9341 rev. %d", rev);
+ break;
+ case QCA_RST_REVISION_ID_MAJOR_AR9344_VAL:
+ sprintf(buf, "AR9344 rev. %d", rev);
+ break;
+#endif
+#if (SOC_TYPE & QCA_QCA953X_SOC)
+ case QCA_RST_REVISION_ID_MAJOR_QCA953X_VAL:
+ sprintf(buf, "QCA953x ver. 1 rev. %d", rev);
+ break;
+ case QCA_RST_REVISION_ID_MAJOR_QCA953X_V2_VAL:
+ sprintf(buf, "QCA953x ver. 2 rev. %d", rev);
+ break;
+#endif
+#if (SOC_TYPE & QCA_QCA955X_SOC)
+ case QCA_RST_REVISION_ID_MAJOR_QCA9558_VAL:
+ sprintf(buf, "QCA9558 rev. %d", rev);
+ break;
+#endif
+ default:
+ sprintf(buf, "Unknown");
+ break;
+ }
+}
+
/*
* Prints available information about the board
*/
#include <asm/addrspace.h>
#include <config.h>
#include <version.h>
+#include <soc/qca_soc_common.h>
#include "ar7240_soc.h"
extern int wasp_ddr_initial_config(uint32_t refresh);
-extern int ar7240_ddr_find_size(void);
void ath_set_tuning_caps(void)
{
#endif
// return memory size
- return ar7240_ddr_find_size();
+ return (int)qca_dram_size();
}
long int dram_init()
OBJS += qca_common.o
OBJS += qca_clocks.o
OBJS += qca_sf.o
+OBJS += qca_dram.o
SOBJS += qca_gpio_init.o
ifeq ($(BOARD), ap121)
OBJS += qca_hs_uart.o
OBJS += ag7240.o
- SOBJS += ar933x_ddr_init.o
+ OBJS += ar933x_dram.o
SOBJS += ar933x_pll_init.o
else
OBJS += qca_ls_uart.o
+++ /dev/null
-/*
- * Startup Code for MIPS32 CPU-core
- *
- * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-
-#include <config.h>
-#include <version.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <ar7240_soc.h>
-
- .globl ar933x_ddr_init
- .text
- .align 4
-
-#define set_mem(_mem, _val) \
- li t9, _mem; \
- sw _val, 0(t9);
-
-//============================================
-// init DDR1 parameter before rel_start
-//===========================================
-ar933x_ddr_init:
- // 0x18000000 (DDR_CONFIG, p. 54)
- // CFG_DDR_CONFIG_VAL = 0x7fbc8cd0 (ap121.h)
- li t8, CFG_DDR_CONFIG_VAL;
- set_mem(0xB8000000, t8);
-
- // 0x18000004 (DDR_CONFIG2, p. 55)
- // CFG_DDR_CONFIG2_VAL = 0x99d0e6a8 (ap121.h)
- li t8, CFG_DDR_CONFIG2_VAL;
- set_mem(0xB8000004, t8);
-
-/*
- * WR720N v3 (CH version) has wrong bootstrap configuration,
- * so the memory type cannot be recognized automatically
- */
-#if !defined(CONFIG_FOR_TPLINK_WR720N_V3)
-mem_type:
- // TODO: what about SDRAM?
- // 0x180600AC (BOOT_STRAP, p. 81)
- li t8, 0xB80600AC // load BOOT_STRAP reg address
- lw t9, 0(t8) // and its value
- li t8, 0x2000 // 0x2000 -> BIT13 is set
- and t9, t9, t8
- beq t9, zero, ddr1_config // jump if we have DDR1
-
-ddr2_config:
- // Enable DDR2
- // 0x1800008C (DDR_DDR2_CONFIG, p. 58)
- li t8, 0xA59;
- set_mem(0xB800008C, t8);
-
- // Precharge All
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x8;
- set_mem(0xB8000010, t8);
-
- // Disable High Temperature Self-Refresh Rate
- // 0x18000090 (DDR_EMR2, p. 58)
- li t8, 0x0;
- set_mem(0xB8000090, t8);
-
- // Extended Mode Register 2 Set (EMR2S)
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x10;
- set_mem(0xB8000010, t8);
-
- // 0x18000094 (DDR_EMR3, p. 58)
- li t8, 0x0;
- set_mem(0xB8000094, t8);
-
- // Extended Mode Register 3 Set (EMR3S)
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x20;
- set_mem(0xB8000010, t8);
-
- // Enable DLL
- // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
- li t8, 0x0;
- set_mem(0xB800000C, t8);
-
- // Extended Mode Register Set (EMRS)
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x2;
- set_mem(0xB8000010, t8);
-
- // Reset DLL
- // 0x18000008 (DDR_MODE_REGISTER, p. 55)
- li t8, 0x100;
- set_mem(0xB8000008, t8);
-
- // Mode Register Set (MRS)
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x1;
- set_mem(0xB8000010, t8);
-
- // Precharge All
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x8;
- set_mem(0xB8000010, t8);
-
- // Auto Refresh
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x4;
- set_mem(0xB8000010, t8);
-
- // Auto Refresh
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x4;
- set_mem(0xB8000010, t8);
-
- // Write recovery (WR) 6 clock, CAS Latency 3, Burst Length 8
- // 0x18000008 (DDR_MODE_REGISTER, p. 55)
- li t8, 0xa33;
- set_mem(0xB8000008, t8);
-
- // Mode Register Set (MRS)
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x1;
- set_mem(0xB8000010, t8);
-
- // E7,E8,E9 equal to 1(Enable OCD defaults), Enable DLL, Reduced Drive Strength
- // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
- li t8, 0x382;
- set_mem(0xB800000C, t8);
-
- // Extended Mode Register Set (EMRS)
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x2;
- set_mem(0xB8000010, t8);
-
- // E7,E8,E9 equal to 0(OCD exit), Enable DLL, Reduced Drive Strength
- // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
- li t8, 0x402;
- set_mem(0xB800000C, t8);
-
- // Extended Mode Register Set (EMRS)
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x2;
- set_mem(0xB8000010, t8);
-
- // Refresh control. Bit 14 is enable. Bits<13:0> Refresh time
- // 0x18000014 (DDR_REFRESH, p. 56)
- li t8, CFG_DDR_REFRESH_VAL;
- set_mem(0xB8000014, t8);
-
- // DQS 0 Tap Control (needs tuning)
- // 0x1800001C (TAP_CONTROL_0, p. 56)
- li t8, CFG_DDR_TAP0_VAL;
- set_mem(0xB800001C, t8);
-
- // DQS 1 Tap Control (needs tuning)
- // 0x18000020 (TAP_CONTROL_1, p. 57)
- li t8, CFG_DDR_TAP1_VAL;
- set_mem(0xB8000020, t8);
-
- // For 16-bit DDR
- // 0x18000018 (DDR_RD_DATA_THIS_CYCLE, p. 56)
- li t8, 0x00ff;
- set_mem(0xB8000018, t8);
-
- nop
- jr ra
-#endif /* !defined(CONFIG_FOR_TPLINK_WR720N_V3) */
-
-ddr1_config:
- // Precharge All
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x8;
- set_mem(0xB8000010, t8);
-
- // 0x18000008 (DDR_MODE_REGISTER, p. 55)
- li t8, CFG_DDR_MODE_VAL_INIT;
- set_mem(0xB8000008, t8);
-
- // Write Mode Word in DDR
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x1;
- set_mem(0xB8000010, t8);
-
- // Enable DLL, High drive strength from DDR
- // 0x1800000C (DDR_EXTENDED_MODE_REGISTER, p. 55)
- li t8, 0x2;
- set_mem(0xB800000C, t8);
-
- // Write Extended Mode Word of DDR
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x2;
- set_mem(0xB8000010, t8);
-
- // Precharge All
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x8;
- set_mem(0xB8000010, t8);
-
- // DLL out of reset, CAS Latency 3
- // 0x18000008 (DDR_MODE_REGISTER, p. 55)
- li t8, CFG_DDR_MODE_VAL;
- set_mem(0xB8000008, t8);
-
- // Write mode word
- // 0x18000010 (DDR_CONTROL, p. 56)
- li t8, 0x1;
- set_mem(0xB8000010, t8);
-
- // Refresh control. Bit 14 is enable. Bits<13:0> Refresh time
- // 0x18000014 (DDR_REFRESH, p. 56)
- li t8, CFG_DDR_REFRESH_VAL;
- set_mem(0xB8000014, t8);
-
- // DQS 0 Tap Control (needs tuning)
- // 0x1800001C (TAP_CONTROL_0, p. 56)
- li t8, CFG_DDR_TAP0_VAL;
- set_mem(0xB800001C, t8);
-
- // DQS 1 Tap Control (needs tuning)
- // 0x18000020 (TAP_CONTROL_1, p. 57)
- li t8, CFG_DDR_TAP1_VAL;
- set_mem(0xB8000020, t8);
-
- // For 16-bit DDR
- // 0x18000018 (DDR_RD_DATA_THIS_CYCLE, p. 56)
- li t8, 0x00ff;
- set_mem(0xB8000018, t8);
-
- nop
- jr ra
-
-/*
- * void ar933x_ddr_tap_init(void)
- *
- * This "function" is used to find the tap settings for the DDR
- */
- .globl ar933x_ddr_tap_init
- .ent ar933x_ddr_tap_init
-ar933x_ddr_tap_init: /* { */
-
- li t1,0x80500000
- li t0,0xffffffff
-
- sw t0,0x0(t1)
- sw t0,0x4(t1)
- sw t0,0x8(t1)
- sw t0,0xc(t1)
-
- nop
- nop
-
-ddr_pat_init:
- li t8, 0xa0002000
- li t0, 0x00
- li t1, 0x100
-
-write_loop_start:
- andi t2, t0, 0x03
-
-pat_000:
- li t3, 0x00
- bne t2, t3,pat_001
- li t9, 0x00000000
- sw t9, 0x0 (t8)
- b pat_004
-
-pat_001:
- li t3, 0x01
- bne t2, t3,pat_002
- li t9, 0x0000ffff
- sw t9, 0x0 (t8)
- b pat_004
-
-pat_002:
- li t3, 0x02
- bne t2, t3,pat_003
- li t9, 0xffff0000
- sw t9, 0x0 (t8)
- b pat_004
-
-pat_003:
- li t3, 0x03
- bne t2, t3,pat_004
- li t9, 0xffffffff
- sw t9, 0x0 (t8)
-
-pat_004:
- andi t2, t0, 0x0c
- li t3, 0x00
- bne t2, t3,pat_005
- li t9, 0x00000000
- sw t9, 0x4 (t8)
- b pat_008
-
-pat_005:
- li t3, 0x04
- bne t2, t3,pat_006
- li t9, 0x0000ffff
- sw t9, 0x4 (t8)
- b pat_008
-
-pat_006:
- li t3, 0x08
- bne t2, t3,pat_007
- li t9, 0xffff0000
- sw t9, 0x4 (t8)
- b pat_008
-
-pat_007:
- li t3, 0x0c
- bne t2, t3,pat_008
- li t9, 0xffffffff
- sw t9, 0x4 (t8)
-
-pat_008:
- andi t2, t0, 0x30
- li t3, 0x00
- bne t2, t3,pat_009
- li t9, 0x00000000
- sw t9, 0x8 (t8)
- b pat_00c
-
-pat_009:
- li t3, 0x10
- bne t2, t3,pat_00a
- li t9, 0x0000ffff
- sw t9, 0x8 (t8)
- b pat_00c
-
-pat_00a:
- li t3, 0x20
- bne t2, t3,pat_00b
- li t9, 0xffff0000
- sw t9, 0x8 (t8)
- b pat_00c
-
-pat_00b:
- li t3, 0x30
- bne t2, t3,pat_00c
- li t9, 0xffffffff
- sw t9, 0x8 (t8)
-
-pat_00c:
- andi t2, t0, 0xc0
- li t3, 0x00
- bne t2, t3,pat_00d
- li t9, 0x00000000
- sw t9, 0xc (t8)
- b pat_done
-
-pat_00d:
- li t3, 0x40
- bne t2, t3,pat_00e
- li t9, 0x0000ffff
- sw t9, 0xc (t8)
- b pat_done
-
-pat_00e:
- li t3, 0x80
- bne t2, t3,pat_00f
- li t9, 0xffff0000
- sw t9, 0xc (t8)
- b pat_done
-
-pat_00f:
- li t3, 0xc0
- bne t2, t3,pat_done
- li t9, 0xffffffff
- sw t9, 0xc (t8)
-
-pat_done:
- addiu t0, t0, 0x1
- addiu t8, t8, 0x10
- bne t0, t1, write_loop_start
-
-###### ddr init over #########
-
- li a0, 0xa0002000
- li a1, 0x80002000 ### Start address of the pattern 200
- li a2, 0x80003000 ### End Address of the pattern 220
- li t0, 0xb800001c ## Tap settings addr
- lw a3, 0x0(t0) ## loading default tap value
- nop
- ori t0, a3, 0x0
- nop
- li t1, 0x1 ## $t1=1 indicates increasing tap value, 0 = decreasing
-
-load_tap:
- li t7, 0x2
- #li t7, 0x200 ## No. of times read has to happen for 1 tap setting
- li t8, 0xb8000000 #### Loading Tap Setting
- sw t0, 0x1c(t8)
- nop
- sw t0, 0x20(t8)
- nop
- #if 0 /* Hornet doesn't have DQS2, DQS3*/
- sw t0, 0x24(t8)
- nop
- sw t0, 0x28(t8)
- nop
- #endif
-
-###### t0 stores current tap setting under test
-###### t1 indicates increment or decrement of tap
-
-pat_read:
- ori t2, a0, 0x0
- nop
- ori t3, a1, 0x0
- nop
- ori t4, a2, 0x0
- nop
-
-tap_addr_loop:
- lw t5, 0x0(t2)
- nop
- lw t6, 0x0(t3)
- nop
- nop
-
- bne t5, t6, tap_fail # jump to fail if not equal
- nop
- nop
- nop
-
- addiu t2, t2, 0x4 #incrementing addr
- addiu t3, t3, 0x4
- nop
- nop
-
- bne t3, t4, tap_addr_loop # compare new addr if end addr not reached
- nop
-
- addiu t7, t7, -1 # read passed for all locations once hence decrement t7
- nop
- bnez t7, pat_read # t7 = 0 represents passing of all locations for given tap
- nop
- nop
-
- bnez t1, tap_incr # increment tap if t1 = 1
- nop
- nop
-
- bnez t0, tap_decr ## $t0=0 implies tap=0 works
- nop ## so low limit=0, else decrement tap value
- nop
- li t8, 0x80500000 ## assigning lower limit = 0
- sw t0, 0x0(t8)
- add t9, t9, t0 ##adding lower limit to upper limit (used to calc mid value)
- nop
- nop
-
- b tap_calc
- nop
- nop
-
-tap_decr: # decrement t0 by 1 and move to loading this new tap
- addiu t0, t0 , -1
- nop
- b load_tap
- nop
- nop
-
-tap_incr:
- addiu t0, t0 , 0x1
- nop
- xori v1, t0, 0x20 # limiting upper limit to 0x20
- nop
- bnez v1, load_tap
- nop
- nop
- b up_limit
- nop
- nop
-
-tap_fail:
- bnez t1, up_limit # t1=0 means lower limit detected @ fail else upper limit
- nop
- nop
- nop
- addiu t0, t0, 0x1
- nop
- li t8, 0x80500000 # storing lower limit
- nop
- sw t0, 0x0(t8)
- add t9, t9, t0 # storing lower limit# adding lower limit and upper limit
- nop
- nop
- nop
-
- b tap_calc
- nop
- nop
-
-up_limit:
- addiu t0, t0, -1
- li t1, 0x0 ## changing to decreasing tap mode
- li t8, 0x80500000 ## storing upper limit
- sw t0, 0x4(t8)
- ori t9, t0, 0x0
- nop
- nop
- nop
-
- ori t0, a3, 0x0 # loading default tap value
- nop
- b load_tap
- nop
- nop
-
-tap_calc: ## calculating mid value of the tap, storing DQS0, DQS1 in 0x80500008, 0x8050000c resp.
- li t7, 0x2
- nop
- div t9, t7
- nop
- mfhi t6
- mflo t5
- nop
- nop
- add t6, t6, t5
- li t8, 0x80500000
- nop
- sw t5, 0x8(t8)
- nop
- sw t6, 0xc(t8)
- nop
- nop
- li t8, 0xb8000000 #### Loading Tap Setting
- nop
- sw t5, 0x1c(t8)
- nop
- sw t6, 0x20(t8)
- nop
- nop
- nop
-
-end:
- nop
- nop
- nop
- jr ra
-
- .end ar933x_ddr_tap_init
-/* } */
--- /dev/null
+/*
+ * Atheros AR933x WiSoC DRAM related functions
+ *
+ * Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
+ * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Copyright (C) 2013 Qualcomm Atheros, Inc.
+ * Copyright (C) 2008-2010 Atheros Communications Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/addrspace.h>
+#include <soc/qca_soc_common.h>
+#include <soc/qca_dram.h>
+
+/*
+ * DQS delay tap tune
+ *
+ * This function is a modified C version of the original
+ * ar933x_ddr_tap_init(void) function, written in asm,
+ * included in Atheros SDK code
+ *
+ * Below is, slightly modified version based on:
+ * https://patchwork.ozlabs.org/patch/569046/
+ */
+
+#define DQS_DELAY_TAP_LIMIT_VAL 31
+#define DQS_DELAY_TAP_START_VAL (DQS_DELAY_TAP_LIMIT_VAL / 2)
+#define DQS_DELAY_TAP_PATTERN_OFFSET 0x2000
+#define DQS_DELAY_TAP_PATTERN_SIZE 0x1000
+
+/* Setup DQS_{0,1} tap setting */
+static inline void ar933x_ddr_tap_save(u32 tap)
+{
+ /* Awlays bypass higher 32-level delay chain (use only lower) */
+ tap = tap | QCA_DDR_TAP_CTRL_TAP_H_BYPASS_MASK;
+
+ qca_soc_reg_write(QCA_DDR_TAP_CTRL_0_REG, tap);
+ qca_soc_reg_write(QCA_DDR_TAP_CTRL_1_REG, tap);
+}
+
+static void ar933x_ddr_tap_tune(void)
+{
+ u32 *addr, *addr_k0, *addr_k1;
+ u32 cnt_up, done, err, i, j;
+ u32 tap, tap_hi, tap_lo;
+
+ /* Use middle value as starting point */
+ ar933x_ddr_tap_save(DQS_DELAY_TAP_START_VAL);
+
+ /* Prepare 4M (256 x 4 x 4 bytes) pattern */
+ addr = (void *)KSEG0ADDR(DQS_DELAY_TAP_PATTERN_OFFSET);
+
+ for (i = 0; i < 256; i++) {
+ tap = 0;
+
+ for (j = 0; j < 8; j++) {
+ if (i & (1 << j)) {
+ if (j % 2)
+ tap |= 0xFFFF0000;
+ else
+ tap |= 0x0000FFFF;
+ }
+
+ if (j % 2) {
+ *addr++ = tap;
+ tap = 0;
+ }
+ }
+ }
+
+ tap = DQS_DELAY_TAP_START_VAL;
+
+ /* 1 -> incrementing, 0 -> decrementing */
+ cnt_up = 1;
+ tap_lo = 0;
+ tap_hi = DQS_DELAY_TAP_LIMIT_VAL;
+
+ addr = (void *)KSEG0ADDR(DQS_DELAY_TAP_PATTERN_OFFSET
+ + DQS_DELAY_TAP_PATTERN_SIZE);
+
+ done = 0;
+
+ while (!done) {
+ ar933x_ddr_tap_save(tap);
+
+ err = 0;
+
+ /* 2 passes per each tested tap value */
+ for (i = 0; i < 2; i++) {
+ addr_k1 = (void *)KSEG1ADDR(DQS_DELAY_TAP_PATTERN_OFFSET);
+ addr_k0 = (void *)KSEG0ADDR(DQS_DELAY_TAP_PATTERN_OFFSET);
+
+ while (addr_k0 < addr) {
+ if (*addr_k1++ != *addr_k0++) {
+ err = 1;
+ break;
+ }
+ }
+
+ if (err)
+ break;
+ }
+
+ if (err) {
+ if (cnt_up) {
+ /* Upper value found */
+ tap--;
+ tap_hi = tap;
+
+ cnt_up = 0;
+ tap = DQS_DELAY_TAP_START_VAL;
+ } else {
+ /* Lower value found */
+ tap++;
+ tap_lo = tap;
+ done = 1;
+ }
+ } else {
+ if (cnt_up) {
+ if (tap < DQS_DELAY_TAP_LIMIT_VAL) {
+ tap++;
+ } else {
+ /* Reached max. possible value */
+ tap_hi = tap;
+
+ cnt_up = 0;
+ tap = DQS_DELAY_TAP_START_VAL;
+ }
+ } else {
+ if (tap == 0) {
+ /* Reached min. possible value */
+ tap_lo = tap;
+ done = 1;
+ } else {
+ tap--;
+ }
+ }
+ }
+ }
+
+ /* Use average value as target tap */
+ tap = (tap_hi + tap_lo) / 2;
+ ar933x_ddr_tap_save(tap);
+}
+
+/*
+ * Initial DRAM configuration
+ */
+void qca_dram_init(void)
+{
+ u32 mem_type = qca_dram_type();
+
+ /* DDR timings (if not defined, use values from old SDK code) */
+#ifdef CONFIG_QCA_DDR_CFG_REG_VAL
+ qca_soc_reg_write(QCA_DDR_CFG_REG, CONFIG_QCA_DDR_CFG_REG_VAL);
+#else
+ /*
+ * tRAS = 16, tRCD = 6, tRP = 6, tRRD = 4, tRFC = 30, tMRD = 15
+ * CAS = 7, page closed
+ */
+ qca_soc_reg_write(QCA_DDR_CFG_REG,
+ _qca_ddr_cfg_reg_val(16, 6, 6, 4, 30, 15, 7, 1));
+#endif
+
+#ifdef CONFIG_QCA_DDR_CFG2_REG_VAL
+ qca_soc_reg_write(QCA_DDR_CFG2_REG, CONFIG_QCA_DDR_CFG2_REG_VAL);
+#else
+ /*
+ * Burst length always 8, burst type: sequential,
+ * 3-state addr/ctrl outputs, output phase 0, CKE = 1,
+ * tWR = 6, tRTW = 14, tRTP = 8, tWTR = 14,
+ * gate open latency = 7, use low half width of DQ bus
+ */
+ qca_soc_reg_write(QCA_DDR_CFG2_REG,
+ _qca_ddr_cfg2_reg_val(0, 1, 0, 1, 6, 14, 8, 14, 7, 1));
+#endif
+
+ if (mem_type == RAM_MEMORY_TYPE_SDR) {
+ /* Enable SDR */
+ qca_soc_reg_write(QCA_SDR_CFG_REG, 1);
+ }
+
+ if (mem_type == RAM_MEMORY_TYPE_DDR2) {
+ /* Enable DDR2 */
+ qca_soc_reg_write(QCA_DDR_DDR2_CFG_REG,
+ _qca_ddr_ddr2_cfg_reg_val(1, 22, 2));
+ }
+
+ /* Precharge all */
+ qca_dram_force_preall();
+
+ if (mem_type == RAM_MEMORY_TYPE_DDR2) {
+ /* Setup target EMR2 (full array, no dcc, no srf) */
+ qca_dram_set_emr2(_ddr_sdram_emr2_val(0, 0, 0));
+
+ /* Setup target EMR3 */
+ qca_dram_set_emr3(_ddr_sdram_emr2_val(0, 0, 0));
+ }
+
+ /* Enable and reset DLL */
+ qca_dram_set_emr(_ddr_sdram_emr_val(0, 1, 0, 0, 0, 0));
+
+ qca_dram_set_mr(_ddr_sdram_mr_val(0, 0, 1, 0));
+
+ /* Precharge all and 2x auto refresh */
+ qca_dram_force_preall();
+
+ qca_dram_force_aref();
+ qca_dram_force_aref();
+
+ if (mem_type == RAM_MEMORY_TYPE_DDR2) {
+ /* Setup target MR (burst sequential, CAS3, wr recoery 6) */
+ qca_dram_set_mr(_ddr_sdram_mr_val(0, 3, 0, 6));
+
+ /* OCD calibration, target EMR (nDQS disable, weak strength) */
+ qca_dram_set_emr(
+ _ddr_sdram_emr_val(0, 1, DDR_SDRAM_EMR_OCD_DEFAULT_VAL, 1, 0, 0));
+
+ qca_dram_set_emr(
+ _ddr_sdram_emr_val(0, 1, DDR_SDRAM_EMR_OCD_EXIT_VAL, 1, 0, 0));
+ } else {
+ /* Setup target MR (burst sequential, CAS3) */
+ qca_dram_set_mr(_ddr_sdram_mr_val(0, 3, 0, 0));
+ }
+
+ /* Enable DDR refresh and setup refresh period */
+ qca_dram_set_en_refresh();
+
+ /* AR933x supports only 16-bit memory */
+ qca_soc_reg_write(QCA_DDR_RD_DATA_THIS_CYCLE_REG, 0xFF);
+
+ ar933x_ddr_tap_tune();
+}
#include <asm/addrspace.h>
#include "ar7240_soc.h"
-// We check for size in 16M increments
-#define AR7240_DDR_SIZE_INCR (16*1024*1024)
-int ar7240_ddr_find_size(void){
- uint8_t *p = (uint8_t *)KSEG1, pat = 0x77;
- int i;
-
- *p = pat;
-
- for(i = 1;; i++){
- *(p + i * AR7240_DDR_SIZE_INCR) = (uint8_t)(i);
-
- if(*p != pat){
- break;
- }
- }
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
- return(i * AR7240_DDR_SIZE_INCR);
-#else
- // TODO: something is wrong with relocation,
- // need to fix it for boards with > 32M of RAM
- return((i * AR7240_DDR_SIZE_INCR) - 1024*1024);
-#endif
-}
-
#if defined(CONFIG_WASP)
int wasp_ddr_initial_config(uint32_t refresh){
int ddr_config, ddr_config2, ext_mod, mod_val, mod_val_init, cycle_val, tap_val, type;
/*
- * Qualcomm/Atheros common/helper functions
+ * Qualcomm/Atheros WiSoCs common/helper functions
*
* Copyright (C) 2015 Piotr Dymacz <piotr@dymacz.pl>
*
- * Partially based on:
- * Linux/arch/mips/ath79/setup.c
- *
- * SPDX-License-Identifier:GPL-2.0
+ * SPDX-License-Identifier: GPL-2.0
*/
#include <config.h>
QCA_RST_BOOTSTRAP_REF_CLK_MASK) >> QCA_RST_BOOTSTRAP_REF_CLK_SHIFT);
}
-/*
- * Return memory type value from BOOT_STRAP register
- */
-u32 qca_dram_type(void)
-{
-#if defined(CONFIG_BOARD_CONST_DRAM_TYPE_SDR)
- return RAM_MEMORY_TYPE_SDR;
-#elif defined(CONFIG_BOARD_CONST_DRAM_TYPE_DDR1)
- return RAM_MEMORY_TYPE_DDR1;
-#elif defined(CONFIG_BOARD_CONST_DRAM_TYPE_DDR2)
- return RAM_MEMORY_TYPE_DDR2;
-#else
- static u32 dram_type = 0;
-
- if (dram_type == 0) {
- dram_type = ((qca_soc_reg_read(QCA_RST_BOOTSTRAP_REG) &
- QCA_RST_BOOTSTRAP_MEM_TYPE_MASK) >> QCA_RST_BOOTSTRAP_MEM_TYPE_SHIFT);
-
- switch (dram_type) {
- case QCA_RST_BOOTSTRAP_MEM_TYPE_SDR_VAL:
- dram_type = RAM_MEMORY_TYPE_SDR;
- break;
- case QCA_RST_BOOTSTRAP_MEM_TYPE_DDR1_VAL:
- dram_type = RAM_MEMORY_TYPE_DDR1;
- break;
- case QCA_RST_BOOTSTRAP_MEM_TYPE_DDR2_VAL:
- dram_type = RAM_MEMORY_TYPE_DDR2;
- break;
- default:
- dram_type = RAM_MEMORY_TYPE_UNKNOWN;
- break;
- }
- }
-
- return dram_type;
-#endif
-}
-
-/*
- * Put QCA SOC name, version and revision in buffer
- */
-void qca_soc_name_rev(char *buf)
-{
- u32 id;
- u32 major;
- u32 rev = 0;
-
- if (buf == NULL)
- return;
-
- /* Get revision ID value */
- id = qca_soc_reg_read(QCA_RST_REVISION_ID_REG);
-
- major = id & QCA_RST_REVISION_ID_MAJOR_MASK;
- rev = id & QCA_RST_REVISION_ID_REV_MASK;
-
- switch (major) {
-#if (SOC_TYPE & QCA_AR933X_SOC)
- case QCA_RST_REVISION_ID_MAJOR_AR9330_VAL:
- sprintf(buf, "AR9330 rev. %d", rev);
- break;
- case QCA_RST_REVISION_ID_MAJOR_AR9331_VAL:
- sprintf(buf, "AR9331 rev. %d", rev);
- break;
-#endif
-#if (SOC_TYPE & QCA_AR934X_SOC)
- case QCA_RST_REVISION_ID_MAJOR_AR9341_VAL:
- sprintf(buf, "AR9341 rev. %d", rev);
- break;
- case QCA_RST_REVISION_ID_MAJOR_AR9344_VAL:
- sprintf(buf, "AR9344 rev. %d", rev);
- break;
-#endif
-#if (SOC_TYPE & QCA_QCA953X_SOC)
- case QCA_RST_REVISION_ID_MAJOR_QCA953X_VAL:
- sprintf(buf, "QCA953x ver. 1 rev. %d", rev);
- break;
- case QCA_RST_REVISION_ID_MAJOR_QCA953X_V2_VAL:
- sprintf(buf, "QCA953x ver. 2 rev. %d", rev);
- break;
-#endif
-#if (SOC_TYPE & QCA_QCA955X_SOC)
- case QCA_RST_REVISION_ID_MAJOR_QCA9558_VAL:
- sprintf(buf, "QCA9558 rev. %d", rev);
- break;
-#endif
- default:
- sprintf(buf, "Unknown");
- break;
- }
-}
-
/*
* Performs full chip reset
*/
--- /dev/null
+/*
+ * Qualcomm/Atheros WiSoCs DRAM related common functions
+ *
+ * Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
+ * Copyright (C) 2013 Qualcomm Atheros, Inc.
+ * Copyright (C) 2008-2010 Atheros Communications Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/addrspace.h>
+#include <soc/qca_soc_common.h>
+#include <soc/qca_dram.h>
+
+#define QCA_DDR_SIZE_INCREMENT (8 * 1024 * 1024)
+
+/*
+ * Returns size (in bytes) of the DRAM memory
+ *
+ * DDR wraps around, write a pattern to 0x00000000
+ * at 8M, 16M, 32M etc. and check when it gets overwritten
+ */
+u32 qca_dram_size(void)
+{
+ u8 *p = (u8 *)KSEG1;
+ u8 pattern = 0x77;
+ u32 i;
+
+ *p = pattern;
+
+ #define max_i (QCA_DRAM_MAX_SIZE_VAL / QCA_DDR_SIZE_INCREMENT)
+
+ for (i = 1; (i < max_i); i++) {
+ *(p + i * QCA_DDR_SIZE_INCREMENT) = (u8)i;
+
+ if (*p != pattern) {
+ break;
+ }
+ }
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ return ((i < max_i) ?
+ (i * QCA_DDR_SIZE_INCREMENT) : QCA_DRAM_MAX_SIZE_VAL);
+#else
+ /*
+ * TODO:
+ * something is wrong with relocation,
+ * need to fix it for boards with > 32M of RAM
+ *
+ * For now just return 1 MB smaller size
+ */
+ return ((i < max_i) ?
+ (i * QCA_DDR_SIZE_INCREMENT) : QCA_DRAM_MAX_SIZE_VAL) - 1024 * 1024;
+#endif
+}
+
+/*
+ * Return memory type value from BOOT_STRAP register
+ */
+u32 qca_dram_type(void)
+{
+#if defined(CONFIG_BOARD_DRAM_TYPE_SDR)
+ return RAM_MEMORY_TYPE_SDR;
+#elif defined(CONFIG_BOARD_DRAM_TYPE_DDR1)
+ return RAM_MEMORY_TYPE_DDR1;
+#elif defined(CONFIG_BOARD_DRAM_TYPE_DDR2)
+ return RAM_MEMORY_TYPE_DDR2;
+#else
+ u32 dram_type;
+
+ dram_type = ((qca_soc_reg_read(QCA_RST_BOOTSTRAP_REG)
+ & QCA_RST_BOOTSTRAP_MEM_TYPE_MASK) >> QCA_RST_BOOTSTRAP_MEM_TYPE_SHIFT);
+
+ switch (dram_type) {
+ case QCA_RST_BOOTSTRAP_MEM_TYPE_SDR_VAL:
+ dram_type = RAM_MEMORY_TYPE_SDR;
+ break;
+ case QCA_RST_BOOTSTRAP_MEM_TYPE_DDR1_VAL:
+ dram_type = RAM_MEMORY_TYPE_DDR1;
+ break;
+ case QCA_RST_BOOTSTRAP_MEM_TYPE_DDR2_VAL:
+ dram_type = RAM_MEMORY_TYPE_DDR2;
+ break;
+ default:
+ dram_type = RAM_MEMORY_TYPE_UNKNOWN;
+ break;
+ }
+
+ return dram_type;
+#endif
+}
la t9, lowlevel_init
jalr t9
nop
- nop
-
-#if (SOC_TYPE & QCA_AR933X_SOC)
- la t9, ar933x_ddr_init
- jalr t9
- nop
- nop
-#endif
la t0, rel_start
j t0
la t9, lowlevel_init
jalr t9
nop
- nop
-
-#if (SOC_TYPE & QCA_AR933X_SOC)
- la t9, ar933x_ddr_init
- jalr t9
- nop
- nop
-#endif
la t0, rel_start
j t0
#define CONFIG_NETCONSOLE
#define CONFIG_NETCONSOLE_PORT 6666
-/* DDR init values */
-#if CONFIG_40MHZ_XTAL_SUPPORT
- #define CFG_DDR_REFRESH_VAL 0x4270
-#else
- #define CFG_DDR_REFRESH_VAL 0x4186
-#endif
-
-#define CFG_DDR_CONFIG_VAL 0x7fbc8cd0
-#define CFG_DDR_MODE_VAL_INIT 0x133
-
-#ifdef LOW_DRIVE_STRENGTH
- #define CFG_DDR_EXT_MODE_VAL 0x2
-#else
- #define CFG_DDR_EXT_MODE_VAL 0x0
-#endif
-
-#define CFG_DDR_MODE_VAL 0x33
-#define CFG_DDR_TRTW_VAL 0x1f
-#define CFG_DDR_TWTR_VAL 0x1e
-
-//#define CFG_DDR_CONFIG2_VAL 0x99d0e6a8 // HORNET 1.0
-#define CFG_DDR_CONFIG2_VAL 0x9dd0e6a8 // HORNET 1.1
-#define CFG_DDR_RD_DATA_THIS_CYCLE_VAL 0x00ff
-#define CFG_DDR_TAP0_VAL 0x8
-#define CFG_DDR_TAP1_VAL 0x9
-
-/* DDR2 Init values */
-#define CFG_DDR2_EXT_MODE_VAL 0x402
-
#define CONFIG_NET_MULTI
/* choose eth1 first for tftpboot interface added by ZJin, 110328 */
--- /dev/null
+/*
+ * Qualcomm/Atheros WiSoCs DRAM related functions and defines
+ *
+ * Copyright (C) 2016 Piotr Dymacz <piotr@dymacz.pl>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _QCA_DRAM_H_
+#define _QCA_DRAM_H_
+
+/*
+ * Prepare DDR SDRAM mode register value
+ * For now use always burst length == 8
+ */
+#define DDR_SDRAM_MR_BURST_LEN_SHIFT 0
+#define DDR_SDRAM_MR_BURST_LEN_MASK BITS(DDR_SDRAM_MR_BURST_LEN_SHIFT, 3)
+#define DDR_SDRAM_MR_BURST_INTERLEAVE_SHIFT 3
+#define DDR_SDRAM_MR_BURST_INTERLEAVE_MASK (1 << DDR_SDRAM_MR_BURST_INTERLEAVE_SHIFT)
+#define DDR_SDRAM_MR_CAS_LAT_SHIFT 4
+#define DDR_SDRAM_MR_CAS_LAT_MASK BITS(DDR_SDRAM_MR_CAS_LAT_SHIFT, 3)
+#define DDR_SDRAM_MR_DLL_RESET_SHIFT 8
+#define DDR_SDRAM_MR_DLL_RESET_MASK (1 << DDR_SDRAM_MR_DLL_RESET_SHIFT)
+#define DDR_SDRAM_MR_WR_RECOVERY_SHIFT 9
+#define DDR_SDRAM_MR_WR_RECOVERY_MASK BITS(DDR_SDRAM_MR_WR_RECOVERY_SHIFT, 3)
+
+#define _ddr_sdram_mr_val(_burst_i, \
+ _cas_lat, \
+ _dll_res, \
+ _wr_rcov) \
+ \
+ ((0x3 << DDR_SDRAM_MR_BURST_LEN_SHIFT) & DDR_SDRAM_MR_BURST_LEN_MASK) |\
+ ((_cas_lat << DDR_SDRAM_MR_CAS_LAT_SHIFT) & DDR_SDRAM_MR_CAS_LAT_MASK) |\
+ ((_dll_res << DDR_SDRAM_MR_DLL_RESET_SHIFT) & DDR_SDRAM_MR_DLL_RESET_MASK) |\
+ (((_wr_rcov - 1) << DDR_SDRAM_MR_WR_RECOVERY_SHIFT) & DDR_SDRAM_MR_WR_RECOVERY_MASK) |\
+ ((_burst_i << DDR_SDRAM_MR_BURST_INTERLEAVE_SHIFT) & DDR_SDRAM_MR_BURST_INTERLEAVE_MASK)
+
+/* Prepare DDR SDRAM extended mode register value */
+#define DDR_SDRAM_EMR_DLL_EN_SHIFT 0
+#define DDR_SDRAM_EMR_DLL_EN_MASK (1 << DDR_SDRAM_EMR_DLL_EN_SHIFT)
+#define DDR_SDRAM_EMR_WEAK_STRENGTH_SHIFT 1
+#define DDR_SDRAM_EMR_WEAK_STRENGTH_MASK (1 << DDR_SDRAM_EMR_WEAK_STRENGTH_SHIFT)
+#define DDR_SDRAM_EMR_OCD_PRG_SHIFT 7
+#define DDR_SDRAM_EMR_OCD_PRG_MASK BITS(DDR_SDRAM_EMR_OCD_PRG_SHIFT, 3)
+#define DDR_SDRAM_EMR_OCD_EXIT_VAL 0
+#define DDR_SDRAM_EMR_OCD_DEFAULT_VAL 7
+#define DDR_SDRAM_EMR_NDQS_DIS_SHIFT 10
+#define DDR_SDRAM_EMR_NDQS_DIS_MASK (1 << DDR_SDRAM_EMR_NDQS_DIS_SHIFT)
+#define DDR_SDRAM_EMR_RDQS_EN_SHIFT 11
+#define DDR_SDRAM_EMR_RDQS_EN_MASK (1 << DDR_SDRAM_EMR_RDQS_EN_SHIFT)
+#define DDR_SDRAM_EMR_OBUF_DIS_SHIFT 12
+#define DDR_SDRAM_EMR_OBUF_DIS_MASK (1 << DDR_SDRAM_EMR_OBUF_DIS_SHIFT)
+
+#define _ddr_sdram_emr_val(_dll_dis, \
+ _drv_weak, \
+ _ocd_prg, \
+ _ndqs_dis, \
+ _rdqs_en, \
+ _obuf_dis) \
+ \
+ ((_dll_dis << DDR_SDRAM_EMR_DLL_EN_SHIFT) & DDR_SDRAM_EMR_DLL_EN_MASK) |\
+ ((_ocd_prg << DDR_SDRAM_EMR_OCD_PRG_SHIFT) & DDR_SDRAM_EMR_OCD_PRG_MASK) |\
+ ((_ndqs_dis << DDR_SDRAM_EMR_NDQS_DIS_SHIFT) & DDR_SDRAM_EMR_NDQS_DIS_MASK) |\
+ ((_rdqs_en << DDR_SDRAM_EMR_RDQS_EN_SHIFT) & DDR_SDRAM_EMR_RDQS_EN_MASK) |\
+ ((_obuf_dis << DDR_SDRAM_EMR_OBUF_DIS_SHIFT) & DDR_SDRAM_EMR_OBUF_DIS_MASK) |\
+ ((_drv_weak << DDR_SDRAM_EMR_WEAK_STRENGTH_SHIFT) & DDR_SDRAM_EMR_WEAK_STRENGTH_MASK)
+
+/* Prepare DDR SDRAM extended mode register 2 value */
+#define DDR_SDRAM_EMR2_PASR_SHIFT 0
+#define DDR_SDRAM_EMR2_PASR_MASK BITS(DDR_SDRAM_EMR2_PASR_SHIFT, 3)
+#define DDR_SDRAM_EMR2_DCC_EN_SHIFT 3
+#define DDR_SDRAM_EMR2_DCC_EN_MASK (1 << DDR_SDRAM_EMR2_DCC_EN_SHIFT)
+#define DDR_SDRAM_EMR2_SRF_EN_SHIFT 7
+#define DDR_SDRAM_EMR2_SRF_EN_MASK (1 << DDR_SDRAM_EMR2_SRF_EN_SHIFT)
+
+#define _ddr_sdram_emr2_val(_pasr, \
+ _dcc_en, \
+ _srf_en) \
+ \
+ ((_pasr << DDR_SDRAM_EMR2_PASR_SHIFT) & DDR_SDRAM_EMR2_PASR_MASK) |\
+ ((_dcc_en << DDR_SDRAM_EMR2_DCC_EN_SHIFT) & DDR_SDRAM_EMR2_DCC_EN_MASK) |\
+ ((_srf_en << DDR_SDRAM_EMR2_SRF_EN_SHIFT) & DDR_SDRAM_EMR2_SRF_EN_MASK)
+
+/*
+ * DDR timing related controller register values
+ */
+
+/* DDR_CONFIG */
+#define _qca_ddr_cfg_reg_val(_tras, \
+ _trcd, \
+ _trp, \
+ _trrd, \
+ _trfc, \
+ _tmrd, \
+ _cas, \
+ _opage) \
+ \
+ ((_tras << QCA_DDR_CFG_TRAS_SHIFT) & QCA_DDR_CFG_TRAS_MASK) |\
+ ((_trcd << QCA_DDR_CFG_TRCD_SHIFT) & QCA_DDR_CFG_TRCD_MASK) |\
+ ((_trp << QCA_DDR_CFG_TRP_SHIFT) & QCA_DDR_CFG_TRP_MASK) |\
+ ((_trrd << QCA_DDR_CFG_TRRD_SHIFT) & QCA_DDR_CFG_TRRD_MASK) |\
+ ((_trfc << QCA_DDR_CFG_TRFC_SHIFT) & QCA_DDR_CFG_TRFC_MASK) |\
+ ((_tmrd << QCA_DDR_CFG_TMRD_SHIFT) & QCA_DDR_CFG_TMRD_MASK) |\
+ ((_cas << QCA_DDR_CFG_CAS_3LSB_SHIFT) & QCA_DDR_CFG_CAS_3LSB_MASK) |\
+ ((_opage << QCA_DDR_CFG_OPEN_PAGE_SHIFT) & QCA_DDR_CFG_OPEN_PAGE_MASK) |\
+ (((_cas & 0x8) >> 3) << QCA_DDR_CFG_CAS_MSB_SHIFT)
+
+/* DDR_CONFIG2 */
+#define _qca_ddr_cfg2_reg_val(_burst_type, \
+ _ctrl_oe_en, \
+ _phase_sel, \
+ _cke, \
+ _twr, \
+ _trtw, \
+ _trtp, \
+ _twtr, \
+ _gate_lat, \
+ _half_width) \
+ \
+ (0x8 << QCA_DDR_CFG2_BURST_LEN_SHIFT) |\
+ ((_burst_type << QCA_DDR_CFG2_BURST_TYPE_SHIFT) & QCA_DDR_CFG2_BURST_TYPE_MASK) |\
+ ((_ctrl_oe_en << QCA_DDR_CFG2_CTRL_OE_EN_SHIFT) & QCA_DDR_CFG2_CTRL_OE_EN_MASK) |\
+ ((_phase_sel << QCA_DDR_CFG2_PHASE_SEL_SHIFT) & QCA_DDR_CFG2_PHASE_SEL_MASK) |\
+ ((_cke << QCA_DDR_CFG2_CKE_SHIFT) & QCA_DDR_CFG2_CKE_MASK) |\
+ ((_twr << QCA_DDR_CFG2_TWR_SHIFT) & QCA_DDR_CFG2_TWR_MASK) |\
+ ((_trtw << QCA_DDR_CFG2_TRTW_SHIFT) & QCA_DDR_CFG2_TRTW_MASK) |\
+ ((_trtp << QCA_DDR_CFG2_TRTP_SHIFT) & QCA_DDR_CFG2_TRTP_MASK) |\
+ ((_twtr << QCA_DDR_CFG2_TWTR_SHIFT) & QCA_DDR_CFG2_TWTR_MASK) |\
+ ((_half_width << QCA_DDR_CFG2_HALF_WIDTH_LOW_SHIFT) & QCA_DDR_CFG2_HALF_WIDTH_LOW_MASK) |\
+ ((_gate_lat << QCA_DDR_CFG2_GATE_OPEN_LATENCY_SHIFT) & QCA_DDR_CFG2_GATE_OPEN_LATENCY_MASK)
+
+/* DDR_DDR2_CONFIG */
+#define _qca_ddr_ddr2_cfg_reg_val(_ddr2_en, \
+ _tfaw, \
+ _twl) \
+ \
+ ((_ddr2_en << QCA_DDR_DDR2_CFG_DDR2_EN_SHIFT) & QCA_DDR_DDR2_CFG_DDR2_EN_MASK) |\
+ ((_tfaw << QCA_DDR_DDR2_CFG_DDR2_TFAW_SHIFT) & QCA_DDR_DDR2_CFG_DDR2_TFAW_MASK) |\
+ ((_twl << QCA_DDR_DDR2_CFG_DDR2_TWL_SHIFT) & QCA_DDR_DDR2_CFG_DDR2_TWL_MASK)
+
+/*
+ * DDR control functions
+ */
+
+/* Force MRS (mode register set) */
+static inline void qca_dram_force_mrs(void)
+{
+ qca_soc_reg_write(QCA_DDR_CTRL_REG,
+ QCA_DDR_CTRL_FORCE_MRS_MASK);
+}
+
+/* Force EMRS (extended mode register set) */
+static inline void qca_dram_force_emrs(void)
+{
+ qca_soc_reg_write(QCA_DDR_CTRL_REG,
+ QCA_DDR_CTRL_FORCE_EMRS_MASK);
+}
+
+/* Force EMR2S (extended mode register 2 set) */
+static inline void qca_dram_force_emr2s(void)
+{
+ qca_soc_reg_write(QCA_DDR_CTRL_REG,
+ QCA_DDR_CTRL_FORCE_EMR2S_MASK);
+}
+
+/* Force EMR3S (extended mode register 3 set) */
+static inline void qca_dram_force_emr3s(void)
+{
+ qca_soc_reg_write(QCA_DDR_CTRL_REG,
+ QCA_DDR_CTRL_FORCE_EMR3S_MASK);
+}
+
+/* Force auto refresh */
+static inline void qca_dram_force_aref(void)
+{
+ qca_soc_reg_write(QCA_DDR_CTRL_REG,
+ QCA_DDR_CTRL_FORCE_AUTO_REFRESH_MASK);
+}
+
+/* Force precharge all */
+static inline void qca_dram_force_preall(void)
+{
+ qca_soc_reg_write(QCA_DDR_CTRL_REG,
+ QCA_DDR_CTRL_FORCE_PRECHARGE_ALL_MASK);
+}
+
+/*
+ * DDR setup related functions
+ */
+
+/* Sets DDR mode register value and issue MRS update */
+static inline void qca_dram_set_mr(u32 value)
+{
+ qca_soc_reg_write(QCA_DDR_MR_REG, value);
+ qca_dram_force_mrs();
+}
+
+/* Sets DDR extended mode register value and issue EMRS update */
+static inline void qca_dram_set_emr(u32 value)
+{
+ qca_soc_reg_write(QCA_DDR_EMR_REG, value);
+ qca_dram_force_emrs();
+}
+
+/* Sets DDR extended mode register 2 value and issue EMR2S update */
+static inline void qca_dram_set_emr2(u32 value)
+{
+ qca_soc_reg_write(QCA_DDR_EMR2_REG, value);
+ qca_dram_force_emr2s();
+}
+
+/* Sets DDR extended mode register 3 value and issue EMR3S update */
+static inline void qca_dram_set_emr3(u32 value)
+{
+ qca_soc_reg_write(QCA_DDR_EMR3_REG, value);
+ qca_dram_force_emr3s();
+}
+
+/* Enables DDR refresh and sets refresh period based on XTAL */
+static inline void qca_dram_set_en_refresh(void)
+{
+ /*
+ * Enable DDR refresh and setup refresh period:
+ * 1. We assume 7.8 us maximum average period refresh interval
+ * 2. 7.8 us ~= 0.1282 MHz
+ * 3. For 25 MHz XTAL: (25 / 0.1282) ~= 195
+ * 4. For 40 MHz XTAL: (40 / 0.1282) ~= 312
+ */
+ if (qca_xtal_is_40mhz()) {
+ qca_soc_reg_write(QCA_DDR_REFRESH_REG,
+ QCA_DDR_REFRESH_EN_MASK
+ | (312 << QCA_DDR_REFRESH_PERIOD_SHIFT));
+ } else {
+ qca_soc_reg_write(QCA_DDR_REFRESH_REG,
+ QCA_DDR_REFRESH_EN_MASK
+ | (195 << QCA_DDR_REFRESH_PERIOD_SHIFT));
+ }
+}
+
+#endif /* _QCA_DRAM_H_ */
#define QCA_DDR_TAP_CTRL_TAP_H_SHIFT 8
#define QCA_DDR_TAP_CTRL_TAP_H_MASK BITS(QCA_DDR_TAP_CTRL_TAP_H_SHIFT, 2)
#define QCA_DDR_TAP_CTRL_TAP_H_BYPASS_SHIFT 16
- #define QCA_DDR_TAP_CTRL_TAP_H_BYPASS_MASK QCA_DDR_TAP_CTRL_TAP_H_BYPASS_SHIFT
+ #define QCA_DDR_TAP_CTRL_TAP_H_BYPASS_MASK (1 << QCA_DDR_TAP_CTRL_TAP_H_BYPASS_SHIFT)
#else
#define QCA_DDR_TAP_CTRL_TAP_SHIFT 0
#define QCA_DDR_TAP_CTRL_TAP_MASK BITS(QCA_DDR_TAP_CTRL_TAP_SHIFT, 6)