Merge branch 'master' of git://www.denx.de/git/u-boot-socfpga
[oweals/u-boot.git] / drivers / ddr / fsl / util.c
index 58b519b4036aca64690bf9cd2e261b03934898ae..ce55aea1b48e51084e8499c356cc4eb457a23a20 100644 (file)
 
 #define ULL_8FS 0xFFFFFFFFULL
 
-u32 fsl_ddr_get_version(void)
+u32 fsl_ddr_get_version(unsigned int ctrl_num)
 {
        struct ccsr_ddr __iomem *ddr;
        u32 ver_major_minor_errata;
 
-       ddr = (void *)_DDR_ADDR;
+       switch (ctrl_num) {
+       case 0:
+               ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+               break;
+#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+       case 1:
+               ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+               break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+       case 2:
+               ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+               break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+       case 3:
+               ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+               break;
+#endif
+       default:
+               printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
+               return 0;
+       }
        ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
        ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
 
@@ -43,9 +65,9 @@ u32 fsl_ddr_get_version(void)
  * propagation, compute a suitably rounded mclk_ps to compute
  * a working memory controller configuration.
  */
-unsigned int get_memory_clk_period_ps(void)
+unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num)
 {
-       unsigned int data_rate = get_ddr_freq(0);
+       unsigned int data_rate = get_ddr_freq(ctrl_num);
        unsigned int result;
 
        /* Round to nearest 10ps, being careful about 64-bit multiply/divide */
@@ -59,10 +81,10 @@ unsigned int get_memory_clk_period_ps(void)
 }
 
 /* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
-unsigned int picos_to_mclk(unsigned int picos)
+unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos)
 {
        unsigned long long clks, clks_rem;
-       unsigned long data_rate = get_ddr_freq(0);
+       unsigned long data_rate = get_ddr_freq(ctrl_num);
 
        /* Short circuit for zero picos */
        if (!picos)
@@ -88,9 +110,9 @@ unsigned int picos_to_mclk(unsigned int picos)
        return (unsigned int) clks;
 }
 
-unsigned int mclk_to_picos(unsigned int mclk)
+unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk)
 {
-       return get_memory_clk_period_ps() * mclk;
+       return get_memory_clk_period_ps(ctrl_num) * mclk;
 }
 
 #ifdef CONFIG_PPC
@@ -212,7 +234,7 @@ void print_ddr_info(unsigned int start_ctrl)
 
        /* Calculate CAS latency based on timing cfg values */
        cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
-       if (fsl_ddr_get_version() <= 0x40400)
+       if (fsl_ddr_get_version(0) <= 0x40400)
                cas_lat += 1;
        else
                cas_lat += 2;
@@ -308,3 +330,58 @@ void board_add_ram_info(int use_default)
 {
        detail_board_ddr_info();
 }
+
+#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
+#define DDRC_DEBUG20_INIT_DONE 0x80000000
+#define DDRC_DEBUG2_RF         0x00000040
+void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
+                                unsigned int last_ctrl)
+{
+       unsigned int i;
+       u32 ddrc_debug20;
+       u32 ddrc_debug2[CONFIG_NUM_DDR_CONTROLLERS] = {};
+       u32 *ddrc_debug2_p[CONFIG_NUM_DDR_CONTROLLERS] = {};
+       struct ccsr_ddr __iomem *ddr;
+
+       for (i = first_ctrl; i <= last_ctrl; i++) {
+               switch (i) {
+               case 0:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+                       break;
+#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+               case 1:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+                       break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+               case 2:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+                       break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+               case 3:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+                       break;
+#endif
+               default:
+                       printf("%s unexpected ctrl = %u\n", __func__, i);
+                       return;
+               }
+               ddrc_debug20 = ddr_in32(&ddr->debug[19]);
+               ddrc_debug2_p[i] = &ddr->debug[1];
+               while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) {
+                       /* keep polling until DDRC init is done */
+                       udelay(100);
+                       ddrc_debug20 = ddr_in32(&ddr->debug[19]);
+               }
+               ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF;
+       }
+       /*
+        * Sync refresh
+        * This is put together to make sure the refresh reqeusts are sent
+        * closely to each other.
+        */
+       for (i = first_ctrl; i <= last_ctrl; i++)
+               ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
+}
+#endif /* CONFIG_FSL_DDR_SYNC_REFRESH */