1. 01 Apr, 2016 1 commit
  2. 19 May, 2015 1 commit
    • Hans de Goede's avatar
      sunxi: Make DRAM_ODT_EN Kconfig setting a bool · 8975cdf4
      Hans de Goede authored
      Make DRAM_ODT_EN Kconfig setting a bool, add a separate DRAM_ODT_CORRECTION
      setting for A23 SoCs and use DRAM_ODT_EN Kconfig everywhere instead of
      only in dram_sun4i.c and hardcoding odt_en elsewhere.
      
      Note this commit makes no functional changes for existing boards,
      its purpose is to allow changing the odt_en value on future A33 boards.
      
      For sun4i/sun5i/sun7i boards which set DRAM_ODT_EN=y (which no defconfigs
      currently do) this patch turns on odt for both the DQ and the DQS lines,
      whereas previously it was possibly (but not desirable) to turn odt on only
      for one of them by setting the in DRAM_ODT_EN option to 1 or 2 instead of 3.
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      Acked-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      8975cdf4
  3. 14 Jan, 2015 1 commit
  4. 25 Nov, 2014 1 commit
  5. 13 Nov, 2014 1 commit
  6. 05 Nov, 2014 1 commit
  7. 24 Oct, 2014 2 commits
  8. 12 Aug, 2014 16 commits
    • Siarhei Siamashka's avatar
      sunxi: dram: Autodetect DDR3 bus width and density · bf4ca384
      Siarhei Siamashka authored
      In the case if the 'dram_para' struct does not specify the exact bus
      width or chip density, just use a trial and error method to find a
      usable configuration.
      
      Because all the major bugs in the DRAM initialization sequence are
      now hopefully fixed, it should be safe to re-initialize the DRAM
      controller multiple times until we get it configured right. The
      original Allwinner's boot0 bootloader also used a similar
      autodetection trick.
      
      The DDR3 spec contains the package pinout and addressing table for
      different possible chip densities. It appears to be impossible to
      distinguish between a single chip with 16 I/O data lines and a pair
      of chips with 8 I/O data lines in the case if they provide the same
      storage capacity. Because a single 16-bit chip has a higher density
      than a pair of equivalent 8-bit chips, it has stricter refresh timings.
      So in the case of doubt, we assume that 16-bit chips are used.
      Additionally, only Allwinner A20 has all A0-A15 address lines and
      can support densities up to 8192. The older Allwinner A10 and
      Allwinner A13 can only support densities up to 4096.
      
      We deliberately leave out DDR2, dual-rank configurations and the
      special case of a 8-bit chip with density 8192. None of these
      configurations seem to have been ever used in real devices. And no
      new devices are likely to use these exotic configurations (because
      only up to 2GB of RAM can be populated in any case).
      
      This DRAM autodetection feature potentially allows to have a single
      low performance fail-safe DDR3 initialiazation for a universal single
      bootloader binary, which can be compatible with all Allwinner
      A10/A13/A20 based devices (if the ifdefs are replaced with a runtime
      SoC type detection).
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      bf4ca384
    • Siarhei Siamashka's avatar
      sunxi: dram: Derive write recovery delay from DRAM clock speed · 935758b1
      Siarhei Siamashka authored
      The write recovery time is 15ns for all JEDEC DDR3 speed bins. And
      instead of hardcoding it to 10 cycles, it is possible to set tighter
      timings based on accurate calculations. For example, DRAM clock
      frequencies up to 533MHz need only 8 cycles for write recovery.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      935758b1
    • Siarhei Siamashka's avatar
      sunxi: dram: Drop DDR2 support and assume only single rank DDR3 memory · b5c71f5f
      Siarhei Siamashka authored
      All the known Allwinner A10/A13/A20 devices are using just single rank
      DDR3 memory. So don't pretend that we support DDR2 or more than one
      rank, because nobody could ever test these configurations for real and
      they are likely broken. Support for these features can be added back
      in the case if such hardware actually exists.
      
      As part of this code cleanup, also replace division by 1024 with
      division by 1000 for the refresh timing calculations. This allows
      to use the original non-skewed tRFC timing table from the DRR3 spec
      and make code less confusing.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      b5c71f5f
    • Siarhei Siamashka's avatar
      sunxi: dram: Configurable DQS gating window mode and delay · d755a5fb
      Siarhei Siamashka authored
      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: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      d755a5fb
    • Siarhei Siamashka's avatar
      sunxi: dram: Add a helper function 'mctl_get_number_of_lanes' · e044daa3
      Siarhei Siamashka authored
      It is going to be useful in more than one place.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      e044daa3
    • Siarhei Siamashka's avatar
      sunxi: dram: Improve DQS gate data training error handling · b8f7cb6a
      Siarhei Siamashka authored
      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: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      b8f7cb6a
    • Siarhei Siamashka's avatar
      sunxi: dram: Use divisor P=1 for PLL5 · 013f2d74
      Siarhei Siamashka authored
      This configures the PLL5P clock frequency to something in the ballpark
      of 1GHz and allows more choices for MBUS and G2D clock frequency
      selection (using their own divisors). In particular, it enables the use
      of 2/3 clock speed ratio between MBUS and DRAM.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      013f2d74
    • Siarhei Siamashka's avatar
      sunxi: dram: Configurable MBUS clock speed (use PLL5 or PLL6) · 1a9717cb
      Siarhei Siamashka authored
      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: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      1a9717cb
    • Siarhei Siamashka's avatar
      sunxi: dram: Re-introduce the impedance calibration ond ODT · 5c18384d
      Siarhei Siamashka authored
      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: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      5c18384d
    • Siarhei Siamashka's avatar
      sunxi: dram: Add 'await_bits_clear'/'await_bits_set' helper functions · 94cd3019
      Siarhei Siamashka authored
      The old 'await_completion' function is not sufficient, because
      in some cases we want to wait for bits to be cleared, and in the
      other cases we want to wait for bits to be set. So split the
      'await_completion' into two new 'await_bits_clear' and
      'await_bits_set' functions.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      94cd3019
    • Siarhei Siamashka's avatar
      sunxi: dram: Do DDR3 reset in the same way on sun4i/sun5i/sun7i · cfc89b00
      Siarhei Siamashka authored
      The older differences were likely justified by the need to mitigate
      the CKE delay timing violations on sun4i/sun5i. The CKE problem is
      already resolved, so now we can use the sun7i variant of this code
      everywhere.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      cfc89b00
    • Siarhei Siamashka's avatar
      sunxi: dram: Remove broken impedance and ODT configuration code · 7e40e192
      Siarhei Siamashka authored
      We can safely remove it, because none of the currently supported
      boards uses these features.
      
      The existing implementation had multiple problems:
         - unnecessary code duplication between sun4i/sun5i/sun7i
         - ZQ calibration was never initiated explicitly, and could be
           only triggered by setting the highest bit in the 'zq' parameter
           in the 'dram_para' struct (this was never actually done for
           any of the known Allwinner devices).
         - even if the ZQ calibration could be started, no attempts were
           made to wait for its completion, or checking whether the
           default automatically initiated ZQ calibration is still
           in progress
         - ODT was only ever enabled on sun4i, but not on sun5i/sun7i
      
      Additionally, SDR_IOCR was set to 0x00cc0000 only on sun4i. There
      are some hints in the Rockchip Linux kernel sources, indicating
      that these bits are related to the automatic I/O power down
      feature, which is poorly understood on sunxi hardware at the
      moment. Avoiding to set these bits on sun4i too does not seem to
      have any measurable/visible impact.
      
      The impedance and ODT configuration code will be re-introdeced in
      one of the next comits.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      7e40e192
    • Siarhei Siamashka's avatar
      sunxi: dram: Fix CKE delay handling for sun4i/sun5i · f8e88b68
      Siarhei Siamashka authored
      Before driving the CKE pin (Clock Enable) high, the DDR3 spec requires
      to wait for additional 500 us after the RESET pin is de-asserted.
      
      The DRAM controller takes care of this delay by itself, using a
      configurable counter in the SDR_IDCR register. This works in the same
      way on sun4i/sun5i/sun7i hardware (even the default register value
      0x00c80064 is identical). Except that the counter is ticking a bit
      slower on sun7i (3 DRAM clock cycles instead of 2), resulting in
      longer actual delays for the same settings.
      
      This patch configures the SDR_IDCR register for all sun4i/sun5i/sun7i
      SoC variants and not just for sun7i alone. Also an explicit udelay(500)
      is added immediately after DDR3 reset for extra safety. This is a
      duplicated functionality. But since we don't have perfect documentation,
      it may be reasonable to play safe. Half a millisecond boot time increase
      is not that significant. Boot time can be always optimized later.
      Preferebly by the people, who have the hardware equipment to check the
      actual signals on the RESET and CKE lines and verify all the timings.
      
      The old code did not configure the SDR_IDCR register for sun4i/sun5i,
      but performed the DDR3 reset very early for sun4i/sun5i. This resulted
      in a larger time gap between the DDR3 reset and the DDR3 initialization
      steps and reduced the chances of CKE delay timing violation to cause
      real troubles.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      f8e88b68
    • Siarhei Siamashka's avatar
      sunxi: dram: Respect the DDR3 reset timing requirements · e626d2d4
      Siarhei Siamashka authored
      The RESET pin needs to be kept low for at least 200 us according
      to the DDR3 spec. So just do it the right way.
      
      This issue did not cause any visible major problems earlier, because
      the DRAM RESET pin is usually already low after the board reset. And
      the time gap before reaching the sunxi u-boot DRAM initialization
      code appeared to be sufficient.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      e626d2d4
    • Siarhei Siamashka's avatar
      sunxi: dram: Remove broken super-standby remnants · f2577967
      Siarhei Siamashka authored
      If the dram->ppwrsctl (SDR_DPCR) register has the lowest bit set to 1,
      this means that DRAM is currently in self-refresh mode and retaining the
      old data. Since we have no idea what to do in this situation yet, just
      set this register to 0 and initialize DRAM in the same way as on any
      normal reboot (discarding whatever was stored there).
      
      This part of code was apparently used by the Allwinner boot0 bootloader
      to handle resume from the so-called super-standby mode. But this
      particular code got somehow mangled on the way from the boot0 bootloader
      to the u-boot-sunxi bootloader and has no chance of doing anything even
      remotely sane. For example:
      1. in the original boot0 code we had "mctl_write_w(SDR_DPCR,
         0x16510000)" (write to the register) and in the u-boot it now looks
         like "setbits_le32(&dram->ppwrsctl, 0x16510000)" (set bits in the
         register)
      2. in the original boot0 code it was issuing three commands "0x12, 0x17,
         0x13" (Self-Refresh entry, Self-Refresh exit, Refresh), but in the
         u-boot they have become "0x12, 0x12, 0x13" (Self-Refresh entry,
         Self-Refresh entry, Refresh)
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      f2577967
    • Siarhei Siamashka's avatar
      sunxi: dram: Remove useless 'dramc_scan_dll_para()' function · 34759d74
      Siarhei Siamashka authored
      The attempt to do DRAM parameters calibration in 'dramc_scan_dll_para()'
      function by trying different DLL adjustments and using the hardware
      DQS gate training result as a feedback is a great source of inspiration,
      but it just can't work properly the way it is implemented now. The fatal
      problem of this implementation is that the DQS gating window can be
      successfully found for almost every DLL delay adjustment setup that
      gets tried. Thus making it unable to see any real difference between
      'good' and 'bad' settings.
      
      Also this code was supposed to be only activated by setting the highest
      bit in the 'dram_tpr3' variable of the 'dram_para' struct (per-board
      dram configuration). But none of the linux-sunxi devices has ever used
      it for real. Basically, this code is just a dead weight.
      Signed-off-by: default avatarSiarhei Siamashka <siarhei.siamashka@gmail.com>
      Acked-by: default avatarIan Campbell <ijc@hellion.org.uk>
      Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
      34759d74
  9. 06 Jul, 2014 2 commits
  10. 25 May, 2014 1 commit