Commit 9ac4ffbde1a5015c9929ee8578d3811b716e2fd3

Authored by York Sun
1 parent 9a17eb5b7e

Driver/DDR: Add Freescale DDR driver for ARM

Make PowerPC specific code conditional so ARM SoCs can reuse
this driver. Add DDR3 driver for ARM.

Signed-off-by: York Sun <yorksun@freescale.com>

Showing 5 changed files with 230 additions and 4 deletions Side-by-side Diff

... ... @@ -450,6 +450,9 @@
450 450 CONFIG_SYS_FSL_DDRC_GEN3
451 451 Freescale DDR3 controller.
452 452  
  453 + CONFIG_SYS_FSL_DDRC_ARM_GEN3
  454 + Freescale DDR3 controller for ARM-based SoCs.
  455 +
453 456 CONFIG_SYS_FSL_DDR1
454 457 Board config to use DDR1. It can be enabled for SoCs with
455 458 Freescale DDR1 or DDR2 controllers, depending on the board
drivers/ddr/fsl/Makefile
... ... @@ -31,5 +31,5 @@
31 31 obj-$(CONFIG_SYS_FSL_DDRC_GEN2) += mpc85xx_ddr_gen2.o
32 32 obj-$(CONFIG_SYS_FSL_DDRC_GEN3) += mpc85xx_ddr_gen3.o
33 33 obj-$(CONFIG_SYS_FSL_DDR_86XX) += mpc86xx_ddr.o
34   -obj-$(CONFIG_FSL_DDR_INTERACTIVE) += interactive.o
  34 +obj-$(CONFIG_SYS_FSL_DDRC_ARM_GEN3) += arm_ddr_gen3.o
drivers/ddr/fsl/arm_ddr_gen3.c
  1 +/*
  2 + * Copyright 2013 Freescale Semiconductor, Inc.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + *
  6 + * Derived from mpc85xx_ddr_gen3.c, removed all workarounds
  7 + */
  8 +
  9 +#include <common.h>
  10 +#include <asm/io.h>
  11 +#include <fsl_ddr_sdram.h>
  12 +#include <asm/processor.h>
  13 +#include <fsl_immap.h>
  14 +
  15 +#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
  16 +#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
  17 +#endif
  18 +
  19 +
  20 +/*
  21 + * regs has the to-be-set values for DDR controller registers
  22 + * ctrl_num is the DDR controller number
  23 + * step: 0 goes through the initialization in one pass
  24 + * 1 sets registers and returns before enabling controller
  25 + * 2 resumes from step 1 and continues to initialize
  26 + * Dividing the initialization to two steps to deassert DDR reset signal
  27 + * to comply with JEDEC specs for RDIMMs.
  28 + */
  29 +void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
  30 + unsigned int ctrl_num, int step)
  31 +{
  32 + unsigned int i, bus_width;
  33 + struct ccsr_ddr __iomem *ddr;
  34 + u32 temp_sdram_cfg;
  35 + u32 total_gb_size_per_controller;
  36 + int timeout;
  37 +
  38 + switch (ctrl_num) {
  39 + case 0:
  40 + ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
  41 + break;
  42 +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
  43 + case 1:
  44 + ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
  45 + break;
  46 +#endif
  47 +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
  48 + case 2:
  49 + ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
  50 + break;
  51 +#endif
  52 +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
  53 + case 3:
  54 + ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
  55 + break;
  56 +#endif
  57 + default:
  58 + printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
  59 + return;
  60 + }
  61 +
  62 + if (step == 2)
  63 + goto step2;
  64 +
  65 + if (regs->ddr_eor)
  66 + out_be32(&ddr->eor, regs->ddr_eor);
  67 + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
  68 + if (i == 0) {
  69 + out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
  70 + out_be32(&ddr->cs0_config, regs->cs[i].config);
  71 + out_be32(&ddr->cs0_config_2, regs->cs[i].config_2);
  72 +
  73 + } else if (i == 1) {
  74 + out_be32(&ddr->cs1_bnds, regs->cs[i].bnds);
  75 + out_be32(&ddr->cs1_config, regs->cs[i].config);
  76 + out_be32(&ddr->cs1_config_2, regs->cs[i].config_2);
  77 +
  78 + } else if (i == 2) {
  79 + out_be32(&ddr->cs2_bnds, regs->cs[i].bnds);
  80 + out_be32(&ddr->cs2_config, regs->cs[i].config);
  81 + out_be32(&ddr->cs2_config_2, regs->cs[i].config_2);
  82 +
  83 + } else if (i == 3) {
  84 + out_be32(&ddr->cs3_bnds, regs->cs[i].bnds);
  85 + out_be32(&ddr->cs3_config, regs->cs[i].config);
  86 + out_be32(&ddr->cs3_config_2, regs->cs[i].config_2);
  87 + }
  88 + }
  89 +
  90 + out_be32(&ddr->timing_cfg_3, regs->timing_cfg_3);
  91 + out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
  92 + out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
  93 + out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
  94 + out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
  95 + out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
  96 + out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
  97 + out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
  98 + out_be32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
  99 + out_be32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
  100 + out_be32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
  101 + out_be32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
  102 + out_be32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
  103 + out_be32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
  104 + out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
  105 + out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
  106 + out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
  107 + out_be32(&ddr->init_addr, regs->ddr_init_addr);
  108 + out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
  109 +
  110 + out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4);
  111 + out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
  112 + out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
  113 + out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
  114 +#ifndef CONFIG_SYS_FSL_DDR_EMU
  115 + /*
  116 + * Skip these two registers if running on emulator
  117 + * because emulator doesn't have skew between bytes.
  118 + */
  119 +
  120 + if (regs->ddr_wrlvl_cntl_2)
  121 + out_be32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
  122 + if (regs->ddr_wrlvl_cntl_3)
  123 + out_be32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
  124 +#endif
  125 +
  126 + out_be32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
  127 + out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
  128 + out_be32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
  129 + out_be32(&ddr->ddr_cdr1, regs->ddr_cdr1);
  130 + out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2);
  131 + out_be32(&ddr->err_disable, regs->err_disable);
  132 + out_be32(&ddr->err_int_en, regs->err_int_en);
  133 + for (i = 0; i < 32; i++) {
  134 + if (regs->debug[i]) {
  135 + debug("Write to debug_%d as %08x\n", i + 1,
  136 + regs->debug[i]);
  137 + out_be32(&ddr->debug[i], regs->debug[i]);
  138 + }
  139 + }
  140 +
  141 + /*
  142 + * For RDIMMs, JEDEC spec requires clocks to be stable before reset is
  143 + * deasserted. Clocks start when any chip select is enabled and clock
  144 + * control register is set. Because all DDR components are connected to
  145 + * one reset signal, this needs to be done in two steps. Step 1 is to
  146 + * get the clocks started. Step 2 resumes after reset signal is
  147 + * deasserted.
  148 + */
  149 + if (step == 1) {
  150 + udelay(200);
  151 + return;
  152 + }
  153 +
  154 +step2:
  155 + /* Set, but do not enable the memory */
  156 + temp_sdram_cfg = regs->ddr_sdram_cfg;
  157 + temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
  158 + out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
  159 +
  160 + /*
  161 + * 500 painful micro-seconds must elapse between
  162 + * the DDR clock setup and the DDR config enable.
  163 + * DDR2 need 200 us, and DDR3 need 500 us from spec,
  164 + * we choose the max, that is 500 us for all of case.
  165 + */
  166 + udelay(500);
  167 + asm volatile("dsb sy;isb");
  168 +
  169 + /* Let the controller go */
  170 + temp_sdram_cfg = in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
  171 + out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
  172 + asm volatile("dsb sy;isb");
  173 +
  174 + total_gb_size_per_controller = 0;
  175 + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
  176 + if (!(regs->cs[i].config & 0x80000000))
  177 + continue;
  178 + total_gb_size_per_controller += 1 << (
  179 + ((regs->cs[i].config >> 14) & 0x3) + 2 +
  180 + ((regs->cs[i].config >> 8) & 0x7) + 12 +
  181 + ((regs->cs[i].config >> 0) & 0x7) + 8 +
  182 + 3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) -
  183 + 26); /* minus 26 (count of 64M) */
  184 + }
  185 + if (regs->cs[0].config & 0x20000000) {
  186 + /* 2-way interleaving */
  187 + total_gb_size_per_controller <<= 1;
  188 + }
  189 + /*
  190 + * total memory / bus width = transactions needed
  191 + * transactions needed / data rate = seconds
  192 + * to add plenty of buffer, double the time
  193 + * For example, 2GB on 666MT/s 64-bit bus takes about 402ms
  194 + * Let's wait for 800ms
  195 + */
  196 + bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
  197 + >> SDRAM_CFG_DBW_SHIFT);
  198 + timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
  199 + (get_ddr_freq(0) >> 20)) << 1;
  200 + total_gb_size_per_controller >>= 4; /* shift down to gb size */
  201 + debug("total %d GB\n", total_gb_size_per_controller);
  202 + debug("Need to wait up to %d * 10ms\n", timeout);
  203 +
  204 + /* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
  205 + while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
  206 + (timeout >= 0)) {
  207 + udelay(10000); /* throttle polling rate */
  208 + timeout--;
  209 + }
  210 +
  211 + if (timeout <= 0)
  212 + printf("Waiting for D_INIT timeout. Memory may not work.\n");
  213 +}
drivers/ddr/fsl/main.c
... ... @@ -15,16 +15,18 @@
15 15 #include <common.h>
16 16 #include <i2c.h>
17 17 #include <fsl_ddr_sdram.h>
18   -#include <asm/fsl_law.h>
19   -
20 18 #include <fsl_ddr.h>
21 19  
  20 +#ifdef CONFIG_PPC
  21 +#include <asm/fsl_law.h>
  22 +
22 23 void fsl_ddr_set_lawbar(
23 24 const common_timing_params_t *memctl_common_params,
24 25 unsigned int memctl_interleaved,
25 26 unsigned int ctrl_num);
26   -void fsl_ddr_set_intl3r(const unsigned int granule_size);
  27 +#endif
27 28  
  29 +void fsl_ddr_set_intl3r(const unsigned int granule_size);
28 30 #if defined(SPD_EEPROM_ADDRESS) || \
29 31 defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \
30 32 defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4)
31 33  
... ... @@ -549,7 +551,9 @@
549 551 phys_size_t fsl_ddr_sdram(void)
550 552 {
551 553 unsigned int i;
  554 +#ifdef CONFIG_PPC
552 555 unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
  556 +#endif
553 557 unsigned long long total_memory;
554 558 fsl_ddr_info_t info;
555 559 int deassert_reset;
... ... @@ -621,6 +625,7 @@
621 625 }
622 626 }
623 627  
  628 +#ifdef CONFIG_PPC
624 629 /* program LAWs */
625 630 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
626 631 if (info.memctl_opts[i].memctl_interleaving) {
... ... @@ -681,6 +686,7 @@
681 686 law_memctl, i);
682 687 }
683 688 }
  689 +#endif
684 690  
685 691 debug("total_memory by %s = %llu\n", __func__, total_memory);
686 692  
drivers/ddr/fsl/util.c
... ... @@ -7,7 +7,9 @@
7 7 */
8 8  
9 9 #include <common.h>
  10 +#ifdef CONFIG_PPC
10 11 #include <asm/fsl_law.h>
  12 +#endif
11 13 #include <div64.h>
12 14  
13 15 #include <fsl_ddr.h>
... ... @@ -79,6 +81,7 @@
79 81 return get_memory_clk_period_ps() * mclk;
80 82 }
81 83  
  84 +#ifdef CONFIG_PPC
82 85 void
83 86 __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
84 87 unsigned int law_memctl,
... ... @@ -113,6 +116,7 @@
113 116 fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
114 117 unsigned int memctl_interleaved,
115 118 unsigned int ctrl_num);
  119 +#endif
116 120  
117 121 void fsl_ddr_set_intl3r(const unsigned int granule_size)
118 122 {