17ff86223cd8c735c3a26989ede0343adcea19e5
[openwrt/openwrt.git] / package / boot / uboot-mvebu / patches / 010-ddr-marvell-a38x-fix-split-out-mix.patch
1 From 3fc92a215b69ad448c151489228eb340df9a8703 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@nic.cz>
3 Date: Wed, 12 Jan 2022 17:06:59 +0100
4 Subject: [PATCH] ddr: marvell: a38x: fix SPLIT_OUT_MIX state decision
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 This is a cleaned up and fixed version of a patch
10 mv_ddr: a380: fix SPLIT_OUT_MIX state decision
11
12 in each pattern cycle the bus state can be changed
13 in order to avoide it, need to back to the same bus state on each
14 pattern cycle
15 by
16 Moti Boskula <motib@marvell.com>
17
18 The original patch is not in Marvell's mv-ddr-marvell repository. It was
19 gives to us by Marvell to fix an issues with DDR training on some
20 boards, but it cannot be applied as is to mv-ddr-marvell, because it is
21 a very dirty draft patch that would certainly break other things, mainly
22 DDR4 training code in mv-ddr-marvell, since it changes common functions.
23
24 I have cleaned up the patch and removed stuff that seemed unnecessary
25 (when removed, it still fixed things). Note that I don't understand
26 completely what the code does exactly, since I haven't studied the DDR
27 training code extensively (and I suspect that no one besides some few
28 people in Marvell understand the code completely).
29
30 Anyway after the cleanup the patch still fixes isssues with DDR training
31 on the failing boards.
32
33 There was also a problem with the original patch on some of the Allied
34 Telesis' x530 boards, reported by Chris Packham. I have asked Chris to
35 send me some logs, and managed to fix it:
36 - if you look at the change, you'll notice that it introduces
37 subtraction of cur_start_win[] and cur_end_win[] members, depending on
38 a bit set in the current_byte_status variable
39 - the original patch subtracted cur_start_win[] if either
40 BYTE_SPLIT_OUT_MIX or BYTE_HOMOGENEOUS_SPLIT_OUT bits were set, but
41 subtracted cur_end_win[] only if the first one (BYTE_SPLIT_OUT_MIX)
42 was set
43 - from Chris Packham logs I discovered that the x530 board where the
44 original patch introduced DDR training failure, only the
45 BYTE_HOMOGENEOUS_SPLIT_OUT bit was set, and on our boards where the
46 patch is needed only the BYTE_SPLIT_OUT_MIX is set in the
47 current_byte_status variable
48 - this led me to the hypothesis that both cur_start_win[] and
49 cur_end_win[] should be subtracted only if BYTE_SPLIT_OUT_MIX bit is
50 set, the BYTE_HOMOGENEOUS_SPLIT_OUT bit shouldn't be considered at all
51 - this hypothesis also gains credibility when considering the commit
52 title ("fix SPLIT_OUT_MIX state decision")
53
54 Hopefully this will fix things without breaking anything else.
55
56 Signed-off-by: Marek BehĂșn <marek.behun@nic.cz>
57 Reviewed-by: Stefan Roese <sr@denx.de>
58 Tested-by: Chris Packham <judge.packham@gmail.com>
59 ---
60 .../a38x/ddr3_training_centralization.c | 26 +++++++++++++++++++
61 1 file changed, 26 insertions(+)
62
63 --- a/drivers/ddr/marvell/a38x/ddr3_training_centralization.c
64 +++ b/drivers/ddr/marvell/a38x/ddr3_training_centralization.c
65 @@ -55,6 +55,7 @@ static int ddr3_tip_centralization(u32 d
66 enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
67 u32 if_id, pattern_id, bit_id;
68 u8 bus_id;
69 + u8 current_byte_status;
70 u8 cur_start_win[BUS_WIDTH_IN_BITS];
71 u8 centralization_result[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
72 u8 cur_end_win[BUS_WIDTH_IN_BITS];
73 @@ -166,6 +167,10 @@ static int ddr3_tip_centralization(u32 d
74 result[search_dir_id][7]));
75 }
76
77 + current_byte_status =
78 + mv_ddr_tip_sub_phy_byte_status_get(if_id,
79 + bus_id);
80 +
81 for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
82 bit_id++) {
83 /* check if this code is valid for 2 edge, probably not :( */
84 @@ -174,11 +179,32 @@ static int ddr3_tip_centralization(u32 d
85 [HWS_LOW2HIGH]
86 [bit_id],
87 EDGE_1);
88 + if (current_byte_status &
89 + BYTE_SPLIT_OUT_MIX) {
90 + if (cur_start_win[bit_id] >= 64)
91 + cur_start_win[bit_id] -= 64;
92 + else
93 + cur_start_win[bit_id] = 0;
94 + DEBUG_CENTRALIZATION_ENGINE
95 + (DEBUG_LEVEL_INFO,
96 + ("pattern %d IF %d pup %d bit %d subtract 64 adll from start\n",
97 + pattern_id, if_id, bus_id, bit_id));
98 + }
99 cur_end_win[bit_id] =
100 GET_TAP_RESULT(result
101 [HWS_HIGH2LOW]
102 [bit_id],
103 EDGE_1);
104 + if (cur_end_win[bit_id] >= 64 &&
105 + (current_byte_status &
106 + BYTE_SPLIT_OUT_MIX)) {
107 + cur_end_win[bit_id] -= 64;
108 + DEBUG_CENTRALIZATION_ENGINE
109 + (DEBUG_LEVEL_INFO,
110 + ("pattern %d IF %d pup %d bit %d subtract 64 adll from end\n",
111 + pattern_id, if_id, bus_id, bit_id));
112 + }
113 +
114 /* window length */
115 current_window[bit_id] =
116 cur_end_win[bit_id] -