1 /*
2 * Copyright (C) Marvell International Ltd. and its affiliates
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7 #include <common.h>
8 #include <i2c.h>
9 #include <spl.h>
10 #include <asm/io.h>
11 #include <asm/arch/cpu.h>
12 #include <asm/arch/soc.h>
13
14 #include "ddr3_init.h"
15
16 #define REG_READ_DATA_SAMPLE_DELAYS_ADDR 0x1538
17 #define REG_READ_DATA_SAMPLE_DELAYS_MASK 0x1f
18 #define REG_READ_DATA_SAMPLE_DELAYS_OFFS 8
19
20 #define REG_READ_DATA_READY_DELAYS_ADDR 0x153c
21 #define REG_READ_DATA_READY_DELAYS_MASK 0x1f
22 #define REG_READ_DATA_READY_DELAYS_OFFS 8
23
ddr3_if_ecc_enabled(void)24 int ddr3_if_ecc_enabled(void)
25 {
26 struct hws_topology_map *tm = ddr3_get_topology_map();
27
28 if (DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask) ||
29 DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
30 return 1;
31 else
32 return 0;
33 }
34
ddr3_pre_algo_config(void)35 int ddr3_pre_algo_config(void)
36 {
37 struct hws_topology_map *tm = ddr3_get_topology_map();
38
39 /* Set Bus3 ECC training mode */
40 if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask)) {
41 /* Set Bus3 ECC MUX */
42 CHECK_STATUS(ddr3_tip_if_write
43 (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
44 REG_SDRAM_PINS_MUX, 0x100, 0x100));
45 }
46
47 /* Set regular ECC training mode (bus4 and bus 3) */
48 if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
49 (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))) {
50 /* Enable ECC Write MUX */
51 CHECK_STATUS(ddr3_tip_if_write
52 (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
53 TRAINING_SW_2_REG, 0x100, 0x100));
54 /* General ECC enable */
55 CHECK_STATUS(ddr3_tip_if_write
56 (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
57 REG_SDRAM_CONFIG_ADDR, 0x40000, 0x40000));
58 /* Disable Read Data ECC MUX */
59 CHECK_STATUS(ddr3_tip_if_write
60 (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
61 TRAINING_SW_2_REG, 0x0, 0x2));
62 }
63
64 return MV_OK;
65 }
66
ddr3_post_algo_config(void)67 int ddr3_post_algo_config(void)
68 {
69 struct hws_topology_map *tm = ddr3_get_topology_map();
70 int status;
71
72 status = ddr3_post_run_alg();
73 if (MV_OK != status) {
74 printf("DDR3 Post Run Alg - FAILED 0x%x\n", status);
75 return status;
76 }
77
78 /* Un_set ECC training mode */
79 if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
80 (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))) {
81 /* Disable ECC Write MUX */
82 CHECK_STATUS(ddr3_tip_if_write
83 (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
84 TRAINING_SW_2_REG, 0x0, 0x100));
85 /* General ECC and Bus3 ECC MUX remains enabled */
86 }
87
88 return MV_OK;
89 }
90
ddr3_hws_hw_training(void)91 int ddr3_hws_hw_training(void)
92 {
93 enum hws_algo_type algo_mode = ALGO_TYPE_DYNAMIC;
94 int status;
95 struct init_cntr_param init_param;
96
97 status = ddr3_silicon_pre_init();
98 if (MV_OK != status) {
99 printf("DDR3 Pre silicon Config - FAILED 0x%x\n", status);
100 return status;
101 }
102
103 init_param.do_mrs_phy = 1;
104 #if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
105 init_param.is_ctrl64_bit = 0;
106 #else
107 init_param.is_ctrl64_bit = 1;
108 #endif
109 #if defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_38X) || \
110 defined(CONFIG_ARMADA_39X)
111 init_param.init_phy = 1;
112 #else
113 init_param.init_phy = 0;
114 #endif
115 init_param.msys_init = 1;
116 status = hws_ddr3_tip_init_controller(0, &init_param);
117 if (MV_OK != status) {
118 printf("DDR3 init controller - FAILED 0x%x\n", status);
119 return status;
120 }
121
122 status = ddr3_silicon_post_init();
123 if (MV_OK != status) {
124 printf("DDR3 Post Init - FAILED 0x%x\n", status);
125 return status;
126 }
127
128 status = ddr3_pre_algo_config();
129 if (MV_OK != status) {
130 printf("DDR3 Pre Algo Config - FAILED 0x%x\n", status);
131 return status;
132 }
133
134 /* run algorithm in order to configure the PHY */
135 status = hws_ddr3_tip_run_alg(0, algo_mode);
136 if (MV_OK != status) {
137 printf("DDR3 run algorithm - FAILED 0x%x\n", status);
138 return status;
139 }
140
141 status = ddr3_post_algo_config();
142 if (MV_OK != status) {
143 printf("DDR3 Post Algo Config - FAILED 0x%x\n", status);
144 return status;
145 }
146
147 return MV_OK;
148 }
149