Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / powerpc / cpu / mpc83xx / spd_sdram.c
index 44aaa9abc2130b9b046f06698e93493f6e4fb9bd..aeff007fb0639eff57b93a77bd1552ca75c32e3d 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2006-2007 Freescale Semiconductor, Inc.
  *
@@ -7,33 +8,23 @@
  * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
  * (C) Copyright 2003 Motorola Inc.
  * Xianghua Xiao (X.Xiao@motorola.com)
- *
- * 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
  */
 
+#ifndef CONFIG_MPC83XX_SDRAM
+
 #include <common.h>
+#include <cpu_func.h>
+#include <log.h>
+#include <time.h>
+#include <vsprintf.h>
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <i2c.h>
 #include <spd.h>
 #include <asm/mmu.h>
 #include <spd_sdram.h>
+#include <asm/bitops.h>
+#include <linux/delay.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -46,10 +37,19 @@ void board_add_ram_info(int use_default)
        printf(" (DDR%d", ((ddr->sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK)
                           >> SDRAM_CFG_SDRAM_TYPE_SHIFT) - 1);
 
+#if defined(CONFIG_ARCH_MPC8308) || defined(CONFIG_ARCH_MPC831X)
+       if ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) == SDRAM_CFG_DBW_16)
+               puts(", 16-bit");
+       else if ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) == SDRAM_CFG_DBW_32)
+               puts(", 32-bit");
+       else
+               puts(", unknown width");
+#else
        if (ddr->sdram_cfg & SDRAM_CFG_32_BE)
                puts(", 32-bit");
        else
                puts(", 64-bit");
+#endif
 
        if (ddr->sdram_cfg & SDRAM_CFG_ECC_EN)
                puts(", ECC on");
@@ -68,6 +68,12 @@ void board_add_ram_info(int use_default)
 #ifndef        CONFIG_SYS_READ_SPD
 #define CONFIG_SYS_READ_SPD    i2c_read
 #endif
+#ifndef SPD_EEPROM_OFFSET
+#define SPD_EEPROM_OFFSET      0
+#endif
+#ifndef SPD_EEPROM_ADDR_LEN
+#define SPD_EEPROM_ADDR_LEN     1
+#endif
 
 /*
  * Convert picoseconds into clock cycles (rounding up if needed).
@@ -134,7 +140,7 @@ long int spd_sdram()
        unsigned int memsize;
        unsigned int law_size;
        unsigned char caslat, caslat_ctrl;
-       unsigned int trfc, trfc_clk, trfc_low, trfc_high;
+       unsigned int trfc, trfc_clk, trfc_low;
        unsigned int trcd_clk, trtp_clk;
        unsigned char cke_min_clk;
        unsigned char add_lat, wr_lat;
@@ -160,7 +166,8 @@ long int spd_sdram()
        isync();
 
        /* Read SPD parameters with I2C */
-       CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
+       CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, SPD_EEPROM_OFFSET,
+               SPD_EEPROM_ADDR_LEN, (uchar *) &spd, sizeof(spd));
 #ifdef SPD_DEBUG
        spd_debug(&spd);
 #endif
@@ -280,7 +287,7 @@ long int spd_sdram()
        /*
         * Set up LAWBAR for all of DDR.
         */
-       ecm->bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000;
+       ecm->bar = CONFIG_SYS_SDRAM_BASE & 0xfffff000;
        ecm->ar  = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & law_size));
        debug("DDR:bar=0x%08x\n", ecm->bar);
        debug("DDR:ar=0x%08x\n", ecm->ar);
@@ -425,7 +432,7 @@ long int spd_sdram()
 
        /*
         * Errata DDR6 work around: input enable 2 cycles earlier.
-        * including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2.
+        * including MPC834X Rev1.0/1.1 and MPC8360 Rev1.1/1.2.
         */
        if(PVR_MAJ(pvr) <= 1 && spd.mem_type == SPD_MEMTYPE_DDR){
                if (caslat == 2)
@@ -435,7 +442,7 @@ long int spd_sdram()
                else if (caslat == 4)
                        ddr->debug_reg = 0x202c0000; /* CL=3.0 */
 
-               __asm__ __volatile__ ("sync");
+               sync();
 
                debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg);
        }
@@ -526,7 +533,6 @@ long int spd_sdram()
         * so preadjust it down 8 first before splitting it up.
         */
        trfc_low = (trfc_clk - 8) & 0xf;
-       trfc_high = ((trfc_clk - 8) >> 4) & 0x3;
 
        ddr->timing_cfg_1 =
            (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) |    /* PRETOACT */
@@ -562,6 +568,9 @@ long int spd_sdram()
         * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
         */
        wr_data_delay = 2;
+#ifdef CONFIG_SYS_DDR_WRITE_DATA_DELAY
+       wr_data_delay = CONFIG_SYS_DDR_WRITE_DATA_DELAY;
+#endif
 
        /*
         * Write Latency
@@ -597,10 +606,13 @@ long int spd_sdram()
 
        /*
         * Empirically set ~MCAS-to-preamble override for DDR 2.
-        * Your milage will vary.
+        * Your mileage will vary.
         */
        cpo = 0;
        if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+#ifdef CONFIG_SYS_DDR_CPO
+               cpo = CONFIG_SYS_DDR_CPO;
+#else
                if (effective_data_rate == 266) {
                        cpo = 0x4;              /* READ_LAT + 1/2 */
                } else if (effective_data_rate == 333) {
@@ -611,6 +623,7 @@ long int spd_sdram()
                        /* Automatic calibration */
                        cpo = 0x1f;
                }
+#endif
        }
 
        ddr->timing_cfg_2 = (0
@@ -679,6 +692,9 @@ long int spd_sdram()
                ddr->sdram_mode =
                        (0
                         | (1 << (16 + 10))             /* DQS Differential disable */
+#ifdef CONFIG_SYS_DDR_MODE_WEAK
+                        | (1 << (16 + 1))              /* weak driver (~60%) */
+#endif
                         | (add_lat << (16 + 3))        /* Additive Latency in EMRS1 */
                         | (mode_odt_enable << 16)      /* ODT Enable in EMRS1 */
                         | ((twr_clk - 1) << 9)         /* Write Recovery Autopre */
@@ -755,7 +771,8 @@ long int spd_sdram()
 #endif
        debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl);
 
-       asm("sync;isync");
+       sync();
+       isync();
 
        udelay(600);
 
@@ -824,7 +841,8 @@ long int spd_sdram()
 #endif
        /* Enable controller, and GO! */
        ddr->sdram_cfg = sdram_cfg;
-       asm("sync;isync");
+       sync();
+       isync();
        udelay(500);
 
        debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);
@@ -833,8 +851,24 @@ long int spd_sdram()
 #endif /* CONFIG_SPD_EEPROM */
 
 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+static inline u32 mftbu(void)
+{
+       u32 rval;
+
+       asm volatile("mftbu %0" : "=r" (rval));
+       return rval;
+}
+
+static inline u32 mftb(void)
+{
+       u32 rval;
+
+       asm volatile("mftb %0" : "=r" (rval));
+       return rval;
+}
+
 /*
- * Use timebase counter, get_timer() is not availabe
+ * Use timebase counter, get_timer() is not available
  * at this point of initialization yet.
  */
 static __inline__ unsigned long get_tbms (void)
@@ -848,9 +882,9 @@ static __inline__ unsigned long get_tbms (void)
 
        /* get the timebase ticks */
        do {
-               asm volatile ("mftbu %0":"=r" (tbu1):);
-               asm volatile ("mftb %0":"=r" (tbl):);
-               asm volatile ("mftbu %0":"=r" (tbu2):);
+               tbu1 = mftbu();
+               tbl = mftb();
+               tbu2 = mftbu();
        } while (tbu1 != tbu2);
 
        /* convert ticks to ms */
@@ -887,7 +921,7 @@ void ddr_enable_ecc(unsigned int dram_size)
        for (p = 0; p < (u64*)(size); p++) {
                ppcDWstore((u32*)p, pattern);
        }
-       __asm__ __volatile__ ("sync");
+       sync();
 #endif
 
        t_end = get_tbms();
@@ -912,7 +946,9 @@ void ddr_enable_ecc(unsigned int dram_size)
        /* Enable errors for ECC */
        ddr->err_disable &= ECC_ERROR_ENABLE;
 
-       __asm__ __volatile__ ("sync");
-       __asm__ __volatile__ ("isync");
+       sync();
+       isync();
 }
 #endif /* CONFIG_DDR_ECC */
+
+#endif /* !CONFIG_MPC83XX_SDRAM */