From 95251c3ad5b1c9a0228f0c3f49b355fb39c0750c Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Wed, 9 Mar 2016 02:25:42 +0100 Subject: [PATCH] Introduce new DRAM related init code for QC/A (for now AR933x) --- u-boot/board/ar7240/ap121/ap121.c | 47 +- u-boot/board/ar7240/common/common.c | 60 ++- u-boot/board/ar7240/db12x/db12x.c | 4 +- u-boot/cpu/mips/ar7240/Makefile | 3 +- u-boot/cpu/mips/ar7240/ar933x_ddr_init.S | 563 ----------------------- u-boot/cpu/mips/ar7240/ar933x_dram.c | 236 ++++++++++ u-boot/cpu/mips/ar7240/meminit.c | 24 - u-boot/cpu/mips/ar7240/qca_common.c | 99 +--- u-boot/cpu/mips/ar7240/qca_dram.c | 93 ++++ u-boot/cpu/mips/start.S | 8 - u-boot/cpu/mips/start_bootstrap.S | 8 - u-boot/include/configs/ap121.h | 29 -- u-boot/include/soc/qca_dram.h | 240 ++++++++++ u-boot/include/soc/qca_soc_common.h | 2 +- 14 files changed, 648 insertions(+), 768 deletions(-) delete mode 100644 u-boot/cpu/mips/ar7240/ar933x_ddr_init.S create mode 100644 u-boot/cpu/mips/ar7240/ar933x_dram.c create mode 100644 u-boot/cpu/mips/ar7240/qca_dram.c create mode 100644 u-boot/include/soc/qca_dram.h diff --git a/u-boot/board/ar7240/ap121/ap121.c b/u-boot/board/ar7240/ap121/ap121.c index 5c4ea5c..5573738 100644 --- a/u-boot/board/ar7240/ap121/ap121.c +++ b/u-boot/board/ar7240/ap121/ap121.c @@ -1,41 +1,20 @@ +/* + * Copyright (C) 2016 Piotr Dymacz + * + * SPDX-License-Identifier: GPL-2.0 + */ + #include #include -#include -#include #include +#include -#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(); } diff --git a/u-boot/board/ar7240/common/common.c b/u-boot/board/ar7240/common/common.c index e572d25..3f9ed0e 100644 --- a/u-boot/board/ar7240/common/common.c +++ b/u-boot/board/ar7240/common/common.c @@ -1,7 +1,11 @@ /* - * Common functions for QC/A WiSoCs support + * Common functions for QC/A WiSoCs based boards support + * * Copyright (C) 2016 Piotr Dymacz * + * Partially based on: + * Linux/arch/mips/ath79/setup.c + * * SPDX-License-Identifier: GPL-2.0 */ @@ -22,6 +26,60 @@ DECLARE_GLOBAL_DATA_PTR; 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 */ diff --git a/u-boot/board/ar7240/db12x/db12x.c b/u-boot/board/ar7240/db12x/db12x.c index ab556e3..f1c71be 100644 --- a/u-boot/board/ar7240/db12x/db12x.c +++ b/u-boot/board/ar7240/db12x/db12x.c @@ -4,10 +4,10 @@ #include #include #include +#include #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) { @@ -66,7 +66,7 @@ int wasp_mem_config(void) #endif // return memory size - return ar7240_ddr_find_size(); + return (int)qca_dram_size(); } long int dram_init() diff --git a/u-boot/cpu/mips/ar7240/Makefile b/u-boot/cpu/mips/ar7240/Makefile index 7f21c65..c622068 100644 --- a/u-boot/cpu/mips/ar7240/Makefile +++ b/u-boot/cpu/mips/ar7240/Makefile @@ -10,12 +10,13 @@ OBJS += meminit.o 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 diff --git a/u-boot/cpu/mips/ar7240/ar933x_ddr_init.S b/u-boot/cpu/mips/ar7240/ar933x_ddr_init.S deleted file mode 100644 index c379321..0000000 --- a/u-boot/cpu/mips/ar7240/ar933x_ddr_init.S +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Startup Code for MIPS32 CPU-core - * - * Copyright (c) 2003 Wolfgang Denk - * - * 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 -#include -#include -#include -#include -#include - - .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 -/* } */ diff --git a/u-boot/cpu/mips/ar7240/ar933x_dram.c b/u-boot/cpu/mips/ar7240/ar933x_dram.c new file mode 100644 index 0000000..971a4fa --- /dev/null +++ b/u-boot/cpu/mips/ar7240/ar933x_dram.c @@ -0,0 +1,236 @@ +/* + * Atheros AR933x WiSoC DRAM related functions + * + * Copyright (C) 2016 Piotr Dymacz + * Copyright (C) 2015-2016 Wills Wang + * Copyright (C) 2013 Qualcomm Atheros, Inc. + * Copyright (C) 2008-2010 Atheros Communications Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include + +/* + * 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(); +} diff --git a/u-boot/cpu/mips/ar7240/meminit.c b/u-boot/cpu/mips/ar7240/meminit.c index bfedccf..49a16b7 100644 --- a/u-boot/cpu/mips/ar7240/meminit.c +++ b/u-boot/cpu/mips/ar7240/meminit.c @@ -53,30 +53,6 @@ #include #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; diff --git a/u-boot/cpu/mips/ar7240/qca_common.c b/u-boot/cpu/mips/ar7240/qca_common.c index 791ff84..6d50f80 100644 --- a/u-boot/cpu/mips/ar7240/qca_common.c +++ b/u-boot/cpu/mips/ar7240/qca_common.c @@ -1,12 +1,9 @@ /* - * Qualcomm/Atheros common/helper functions + * Qualcomm/Atheros WiSoCs common/helper functions * * Copyright (C) 2015 Piotr Dymacz * - * Partially based on: - * Linux/arch/mips/ath79/setup.c - * - * SPDX-License-Identifier:GPL-2.0 + * SPDX-License-Identifier: GPL-2.0 */ #include @@ -23,98 +20,6 @@ inline u32 qca_xtal_is_40mhz(void) 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 */ diff --git a/u-boot/cpu/mips/ar7240/qca_dram.c b/u-boot/cpu/mips/ar7240/qca_dram.c new file mode 100644 index 0000000..2cfc7a5 --- /dev/null +++ b/u-boot/cpu/mips/ar7240/qca_dram.c @@ -0,0 +1,93 @@ +/* + * Qualcomm/Atheros WiSoCs DRAM related common functions + * + * Copyright (C) 2016 Piotr Dymacz + * Copyright (C) 2013 Qualcomm Atheros, Inc. + * Copyright (C) 2008-2010 Atheros Communications Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include + +#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 +} diff --git a/u-boot/cpu/mips/start.S b/u-boot/cpu/mips/start.S index 5a1ba33..6ea74cd 100644 --- a/u-boot/cpu/mips/start.S +++ b/u-boot/cpu/mips/start.S @@ -258,14 +258,6 @@ reset: 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 diff --git a/u-boot/cpu/mips/start_bootstrap.S b/u-boot/cpu/mips/start_bootstrap.S index b17c44c..15257dd 100644 --- a/u-boot/cpu/mips/start_bootstrap.S +++ b/u-boot/cpu/mips/start_bootstrap.S @@ -249,14 +249,6 @@ reset: 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 diff --git a/u-boot/include/configs/ap121.h b/u-boot/include/configs/ap121.h index 5c25430..eb37e8c 100644 --- a/u-boot/include/configs/ap121.h +++ b/u-boot/include/configs/ap121.h @@ -438,35 +438,6 @@ #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 */ diff --git a/u-boot/include/soc/qca_dram.h b/u-boot/include/soc/qca_dram.h new file mode 100644 index 0000000..1989efe --- /dev/null +++ b/u-boot/include/soc/qca_dram.h @@ -0,0 +1,240 @@ +/* + * Qualcomm/Atheros WiSoCs DRAM related functions and defines + * + * Copyright (C) 2016 Piotr Dymacz + * + * 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_ */ diff --git a/u-boot/include/soc/qca_soc_common.h b/u-boot/include/soc/qca_soc_common.h index fc55f5a..e75d810 100644 --- a/u-boot/include/soc/qca_soc_common.h +++ b/u-boot/include/soc/qca_soc_common.h @@ -193,7 +193,7 @@ #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) -- 2.25.1