From 5c18384dea60a9acbbc6f2f95a5e291089db7e94 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 3 Aug 2014 05:32:46 +0300 Subject: sunxi: dram: Re-introduce the impedance calibration ond ODT The DRAM controller allows to configure impedance either by using the calibration against an external high precision 240 ohm resistor, or by skipping the calibration and loading pre-defined data. The DRAM controller register guide is available here: http://linux-sunxi.org/A10_DRAM_Controller_Register_Guide#SDR_ZQCR0 The new code supports both of the impedance configuration modes: - If the higher bits of the 'zq' parameter in the 'dram_para' struct are zero, then the lowest 8 bits are used as the ZPROG value, where two divisors encoded in lower and higher 4 bits. One divisor is used for calibrating the termination impedance, and another is used for the output impedance. - If bits 27:8 in the 'zq' parameters are non-zero, then they are used as the pre-defined ZDATA value instead of performing the ZQ calibration. Two lowest bits in the 'odt_en' parameter enable ODT for the DQ and DQS lines individually. Enabling ODT for both DQ and DQS means that the 'odt_en' parameter needs to be set to 3. Signed-off-by: Siarhei Siamashka Acked-by: Ian Campbell Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/dram.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/include/asm') diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 67fbfad07ea..4433eeb29e9 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -159,6 +159,10 @@ struct dram_para { #define DRAM_ZQCR0_IMP_DIV(n) (((n) & 0xff) << 20) #define DRAM_ZQCR0_IMP_DIV_MASK DRAM_ZQCR0_IMP_DIV(0xff) +#define DRAM_ZQCR0_ZCAL (1 << 31) /* Starts ZQ calibration when set to 1 */ +#define DRAM_ZQCR0_ZDEN (1 << 28) /* Uses ZDATA instead of doing calibration */ + +#define DRAM_ZQSR_ZDONE (1 << 31) /* ZQ calibration completion flag */ #define DRAM_IOCR_ODT_EN(n) ((((n) & 0x3) << 30) | ((n) & 0x3) << 0) #define DRAM_IOCR_ODT_EN_MASK DRAM_IOCR_ODT_EN(0x3) -- cgit v1.2.3 From 1a9717cbb3753ea93d156621b3082434b8417c9f Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 3 Aug 2014 05:32:47 +0300 Subject: sunxi: dram: Configurable MBUS clock speed (use PLL5 or PLL6) The sun5i hardware (Allwinner A13) introduced configurable MBUS clock speed. Allwinner A13 uses only 16-bit data bus width to connect the external DRAM, which is halved compared to the 32-bit data bus of sun4i (Allwinner A10), so it does not make much sense to clock a wider internal bus at a very high speed. The Allwinner A13 manual specifies 300 MHz MBUS clock speed limit and 533 MHz DRAM clock speed limit. Newer sun7i hardware (Allwinner A20) has a full width 32-bit external memory interface again, but still keeps the MBUS clock speed configurable. Clocking MBUS too low inhibits memory performance and one has to find the optimal MBUS/DRAM clock speed ratio, which may depend on many factors: http://linux-sunxi.org/A10_DRAM_Controller_Performance This patch introduces a new 'mbus_clock' parameter for the 'dram_para' struct and uses it as a desired MBUS clock speed target. If 'mbus_clock' is not set, 300 MHz is used by default to match the older hardcoded settings. PLL5P and PLL6 are both evaluated as possible clock sources. Preferring the one, which can provide higher clock frequency that is lower or equal to the 'mbus_clock' target. In the case of a tie, PLL5P has higher priority. Attempting to set the MBUS clock speed has no effect on sun4i, but does no harm either. Signed-off-by: Siarhei Siamashka Acked-by: Ian Campbell Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/dram.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/include/asm') diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 4433eeb29e9..3c2925625d1 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -69,6 +69,7 @@ struct sunxi_dram_reg { struct dram_para { u32 clock; + u32 mbus_clock; u32 type; u32 rank_num; u32 density; -- cgit v1.2.3 From b8f7cb6ae31d3c2de7349e58889ed3c5a1a77c42 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 3 Aug 2014 05:32:49 +0300 Subject: sunxi: dram: Improve DQS gate data training error handling The stale error status should be cleared for all sun4i/sun5i/sun7i hardware and not just for sun7i. Also there are two types of DQS gate training errors ("found no result" and "found more than one possible result"). Both are handled now. Signed-off-by: Siarhei Siamashka Acked-by: Ian Campbell Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/dram.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/include/asm') diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 3c2925625d1..11e35077f43 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -133,7 +133,9 @@ struct dram_para { #define DRAM_DCR_MODE_SEQ 0x0 #define DRAM_DCR_MODE_INTERLEAVE 0x1 -#define DRAM_CSR_FAILED (0x1 << 20) +#define DRAM_CSR_DTERR (0x1 << 20) +#define DRAM_CSR_DTIERR (0x1 << 21) +#define DRAM_CSR_FAILED (DRAM_CSR_DTERR | DRAM_CSR_DTIERR) #define DRAM_DRR_TRFC(n) ((n) & 0xff) #define DRAM_DRR_TREFI(n) (((n) & 0xffff) << 8) -- cgit v1.2.3 From e044daa33e28947c34b855643e5d16a030da8fe8 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 3 Aug 2014 05:32:50 +0300 Subject: sunxi: dram: Add a helper function 'mctl_get_number_of_lanes' It is going to be useful in more than one place. Signed-off-by: Siarhei Siamashka Acked-by: Ian Campbell Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/dram.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/arm/include/asm') diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 11e35077f43..71301dbf33f 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -122,9 +122,6 @@ struct dram_para { #define DRAM_DCR_BUS_WIDTH_32BIT 0x3 #define DRAM_DCR_BUS_WIDTH_16BIT 0x1 #define DRAM_DCR_BUS_WIDTH_8BIT 0x0 -#define DRAM_DCR_NR_DLLCR_32BIT 5 -#define DRAM_DCR_NR_DLLCR_16BIT 3 -#define DRAM_DCR_NR_DLLCR_8BIT 2 #define DRAM_DCR_RANK_SEL(n) (((n) & 0x3) << 10) #define DRAM_DCR_RANK_SEL_MASK DRAM_DCR_CMD_RANK(0x3) #define DRAM_DCR_CMD_RANK_ALL (0x1 << 12) -- cgit v1.2.3 From d755a5fb20a7e3192d301d6d6a44814b10fb4f46 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 3 Aug 2014 05:32:51 +0300 Subject: sunxi: dram: Configurable DQS gating window mode and delay The hardware DQS gate training is a bit unreliable and does not always find the best delay settings. So we introduce a 32-bit 'dqs_gating_delay' variable, where each byte encodes the DQS gating delay for each byte lane. The delay granularity is 1/4 cycle. Also we allow to enable the active DQS gating window mode, which works better than the passive mode in practice. The DDR3 spec says that there is a 0.9 cycles preamble and 0.3 cycle postamble. The DQS window has to be opened during preamble and closed during postamble. In the passive window mode, the gating window is opened and closed by just using the gating delay settings. And because of the 1/4 cycle delay granularity, accurately hitting the 0.3 cycle long postamble is a bit tough. In the active window mode, the gating window is auto-closing with the help of monitoring the DQS line, which relaxes the gating delay accuracy requirements. But the hardware DQS gate training is still performed in the passive window mode. It is a more strict test, which is reducing the results variance compared to the training with active window mode. Signed-off-by: Siarhei Siamashka Acked-by: Ian Campbell Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/dram.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/include/asm') diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 71301dbf33f..1945f75441f 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -88,6 +88,8 @@ struct dram_para { u32 emr1; u32 emr2; u32 emr3; + u32 dqs_gating_delay; + u32 active_windowing; }; #define DRAM_CCR_COMMAND_RATE_1T (0x1 << 5) -- cgit v1.2.3