drivers/ddr/fsl: Enable detection of one DDR controller operation for LSCH3
authorYork Sun <yorksun@freescale.com>
Wed, 4 Nov 2015 17:53:10 +0000 (09:53 -0800)
committerYork Sun <yorksun@freescale.com>
Mon, 30 Nov 2015 17:11:11 +0000 (09:11 -0800)
Freescale LSCH3 platforms use two DDR controlers interleaving mode out of
reset. It can be configured to disable one controller. To support this
operation, the driver needs to detect and skip the disabled controller.

Signed-off-by: York Sun <yorksun@freescale.com>
arch/arm/include/asm/arch-fsl-layerscape/config.h
drivers/ddr/fsl/main.c
drivers/ddr/fsl/util.c
include/fsl_ddr.h

index 5ce916c4d096f677e19040145803703f32b504b1..afc329ad6b68bf322da2db8a4ab74ca0a4eed598 100644 (file)
 #define CCI_MN_DVM_DOMAIN_CTL          0x200
 #define CCI_MN_DVM_DOMAIN_CTL_SET      0x210
 
+#define CCI_HN_F_0_BASE                        (CCI_MN_BASE + 0x200000)
+#define CCI_HN_F_1_BASE                        (CCI_MN_BASE + 0x210000)
+#define CCN_HN_F_SAM_CTL               0x8     /* offset on base HN_F base */
+#define CCN_HN_F_SAM_NODEID_MASK       0x7f
+#define CCN_HN_F_SAM_NODEID_DDR0       0x4
+#define CCN_HN_F_SAM_NODEID_DDR1       0xe
+
 #define CCI_RN_I_0_BASE                        (CCI_MN_BASE + 0x800000)
 #define CCI_RN_I_2_BASE                        (CCI_MN_BASE + 0x820000)
 #define CCI_RN_I_6_BASE                        (CCI_MN_BASE + 0x860000)
index 72ec1be65d12c6e1e1034e8261762519a61c1210..c68663220d8b94d7b0f93c8d16eada41ffe8ecf0 100644 (file)
@@ -813,6 +813,7 @@ phys_size_t fsl_ddr_sdram(void)
        info.board_need_mem_reset = board_need_mem_reset;
        info.board_mem_reset = board_assert_mem_reset;
        info.board_mem_de_reset = board_deassert_mem_reset;
+       remove_unused_controllers(&info);
 
        return __fsl_ddr_sdram(&info);
 }
index ce55aea1b48e51084e8499c356cc4eb457a23a20..1a49b28f3313aad9f0bea78e97eb454e6f75516e 100644 (file)
@@ -385,3 +385,43 @@ void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
                ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
 }
 #endif /* CONFIG_FSL_DDR_SYNC_REFRESH */
+
+void remove_unused_controllers(fsl_ddr_info_t *info)
+{
+#ifdef CONFIG_FSL_LSCH3
+       int i;
+       u64 nodeid;
+       void *hnf_sam_ctrl = (void *)(CCI_HN_F_0_BASE + CCN_HN_F_SAM_CTL);
+       bool ddr0_used = false;
+       bool ddr1_used = false;
+
+       for (i = 0; i < 8; i++) {
+               nodeid = in_le64(hnf_sam_ctrl) & CCN_HN_F_SAM_NODEID_MASK;
+               if (nodeid == CCN_HN_F_SAM_NODEID_DDR0) {
+                       ddr0_used = true;
+               } else if (nodeid == CCN_HN_F_SAM_NODEID_DDR1) {
+                       ddr1_used = true;
+               } else {
+                       printf("Unknown nodeid in HN-F SAM control: 0x%llx\n",
+                              nodeid);
+               }
+               hnf_sam_ctrl += (CCI_HN_F_1_BASE - CCI_HN_F_0_BASE);
+       }
+       if (!ddr0_used && !ddr1_used) {
+               printf("Invalid configuration in HN-F SAM control\n");
+               return;
+       }
+
+       if (!ddr0_used && info->first_ctrl == 0) {
+               info->first_ctrl = 1;
+               info->num_ctrls = 1;
+               debug("First DDR controller disabled\n");
+               return;
+       }
+
+       if (!ddr1_used && info->first_ctrl + info->num_ctrls > 1) {
+               info->num_ctrls = 1;
+               debug("Second DDR controller disabled\n");
+       }
+#endif
+}
index 1ac092bb92d047231eb4675f7f859ad5edb0543a..9aaf6b334cda4713a1dee5fc211d9bc6c1a9a325 100644 (file)
@@ -131,6 +131,7 @@ void board_add_ram_info(int use_default);
 /* processor specific function */
 void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
                                   unsigned int ctrl_num, int step);
+void remove_unused_controllers(fsl_ddr_info_t *info);
 
 /* board specific function */
 int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,