Skip to content
  • Doug Anderson's avatar
    Exynos: Fix L2 cache timings on Exynos5420 and Exynos5800 · 306f527e
    Doug Anderson authored
    
    
    It was found that the L2 cache timings that we had before could cause
    freezes and hangs.  We should make things more robust with better
    timings.  Currently the production ChromeOS kernel applies these
    timings, but it's nice to fixup firmware too (and upstream probably
    won't take our kernel hacks).
    
    This also provides a big cleanup of the L2 cache init code avoiding
    some duplication.  The way things used to work:
    * low_power_start() was installed by the SPL (both at boot and resume
      time) and left resident in iRAM for the kernel to use when bringing
      up additional CPUs.  It used configure_l2_ctlr() and
      configure_l2_actlr() when it detected it was on an A15.  This was
      needed (despite the L2 cache registers being shared among all A15s)
      because we might have been the first man in after the whole A15
      cluster was shutdown.
    * secondary_cores_configure() was called on at boot time and at resume
      time.  Strangely this called configure_l2_ctlr() but not
      configure_l2_actlr() which was almost certainly wrong.  Given that
      we'll call both (see next bullet) later in the boot process it
      didn't matter for normal boot, but I guess this is how L2 cache
      settings got set on 5420/5800 (but not 5250?) at resume time.
    * exynos5_set_l2cache_params() was called as part of cache enablement.
      This should happen at boot time (normally in the SPL except for USB
      boot where it happens in main U-Boot).
    
    Note that the old code wasn't setting ECC/parity in the cache
    enablement code but we happened to get it anyway because we'd call
    secondary_cores_configure() at boot time.  For resume time we'd get it
    anyway when the 2nd A15 core came up.
    
    Let's make this a whole lot simpler.  Now we always set these
    parameters in the same place for all boots and use the same code for
    setting up secondary CPUs.
    
    Intended net effects of this change (other than cleanup):
    * Timings go from before:
        data: 0 cycle setup, 3 cycles (0x2) latency
        tag:  0 cycle setup, 3 cycles (0x2) latency
      after:
        data: 1 cycle setup, 4 cycles (0x3) latency
        tag:  1 cycle setup, 4 cycles (0x3) latency
    * L2ACTLR is properly initted on 5420/5800 in all cases.
    
    One note is that we're still relying on luck to keep low_power_start()
    working.  The compiler is being nice and not storing anything on the
    stack.
    
    Another note is that on its own this patch won't help to fix cache
    settings in an RW U-Boot update where we still have the RO SPL.  The
    plan for that is:
    * Have RW U-Boot re-init the cache right before calling the kernel
      (after it has turned the L2 cache off).  This is why the functions
      are in a header file instead of lowlevel_init.c.
    
    * Have the kernel save the L2 cache settings of the boot CPU and apply
      them to all other CPUs.  We get a little lucky here because the old
      code was using "|=" to modify the registers and all of the bits that
      it's setting are also present in the new settings (!).  That means
      that when the 2nd CPU in the A15 cluster comes up it doesn't
      actually mess up the settings of the 1st CPU in the A15 cluster.  An
      alternative option is to have the kernel write its own
      low_power_start() code.
    
    Signed-off-by: default avatarDoug Anderson <dianders@chromium.org>
    Signed-off-by: default avatarAkshay Saraswat <akshay.s@samsung.com>
    Signed-off-by: default avatarMinkyu Kang <mk7.kang@samsung.com>
    306f527e