summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H
blob: 6b5df447a695ead545f88f2ff9372a2ef86de998 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file cas_latency.H
/// @brief CAS latency class declaration
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_CAS_LATENCY_H_
#define _MSS_CAS_LATENCY_H_

#include <map>
#include <memory>
#include <cstdint>

#include <fapi2.H>
#include <lib/spd/spd_decoder.H>

namespace mss
{


enum constants : std::uint64_t
{
    // From JEDEC Standard No. 79-4A
    // Speed Bins pg. 164
    /// Time in picoseconds
    TAA_MAX_DDR4 = 18000,

    // Low range CAS latency from SPD
    LOW_RANGE_MIN_CL_DDR4 = 7,
    LOW_RANGE_MAX_CL_DDR4 = 36,

    // High range CAS latency SPD
    HIGH_RANGE_MIN_CL_DDR4 = 23,
    HIGH_RANGE_MAX_CL_DDR4 = 52,
};


///
/// @class decoder
/// @brief CAS latency class that encapsulates JEDEC calculation algorithm
///
class cas_latency
{
    public:
        bool iv_dimm_list_empty;

        /////////////////////////
        // Public Member Methods
        /////////////////////////

        // Default constructor
        // class dependent on SPD data obtained internally
        // won't work when instantiated w/o neccesary params
        cas_latency() = delete;

        ///
        /// @brief      Class constructor that retrieves required SPD data held by internal state
        /// @param[in]  i_target the controller target
        /// @param[in]  i_caches decoder caches
        ///
        cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs,
                    const std::map<uint32_t, std::shared_ptr<spd::decoder> >& i_caches);

        // Default destructor
        ~cas_latency() = default;

        ///
        /// @brief      Calculates CAS latency and checks if it is supported and within JEDEC spec.
        /// @param[in]  i_target the controller target
        /// @param[out] o_cas_latency selected CAS latency
        /// @param[out] o_tCK cycle time corresponding to seleted CAS latency
        /// @return     fapi2::FAPI2_RC_SUCCESS if ok
        ///
        fapi2::ReturnCode find_CL(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs,
                                  uint64_t& o_cas_latency,
                                  uint64_t& o_tCK);

        ///
        /// @brief      Retrieves SDRAM Minimum CAS Latency Time (tAAmin) from SPD
        /// @param[in]  i_target the dimm target
        /// @param[in]  i_pDecoder the SPD decoder
        /// @param[out] o_value tCKmin value in ps
        /// @return     FAPI2_RC_SUCCESS iff ok
        ///
        fapi2::ReturnCode get_taamin(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                     const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
                                     uint64_t& o_value);
        ///
        /// @brief      Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD
        /// @param[in]  i_target the dimm target
        /// @param[in]  i_pDecoder the SPD decoder
        /// @param[out] o_value tCKmin value in ps
        /// @return     FAPI2_RC_SUCCESS iff ok
        ///
        fapi2::ReturnCode get_tckmin(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                     const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
                                     uint64_t& o_value);

        ///
        /// @brief      Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD
        /// @param[in]  i_target the dimm target
        /// @param[in]  i_pDecoder SPD decoder
        /// @param[out] o_value tCKmax value in ps
        /// @return     FAPI2_RC_SUCCESS iff ok
        ///
        fapi2::ReturnCode get_tckmax(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                     const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
                                     uint64_t& o_value);

        ///
        /// @brief      Gets max CAS latency (CL) for the appropriate High/Low Range
        /// @param[in]  i_supported_CL
        /// @return     the maximum supported CL
        /// @note       Depends on bit 7 of byte 23 from the DDR4 SPD
        ///
        inline uint64_t get_max_CL(const fapi2::buffer<uint64_t> i_supported_CL) const;

        ///
        /// @brief      Gets min CAS latency (CL) for the appropriate High/Low Range
        /// @param[in]  i_supported_CL
        /// @return     the minimum supported CL
        /// @note       Depends on bit 7 of byte 23 from the DDR4 SPD
        ///
        inline uint64_t get_min_CL(const fapi2::buffer<uint64_t>& i_supported_CL) const;

        ///
        /// @brief Calculates CAS latency time from tCK and tAA
        /// @param[in]  i_tAA cas latency time
        /// @param[in]  i_tCK min cycle time
        /// @return     o_cas_latency calculated CAS latency
        ///
        inline uint64_t calc_cas_latency(const uint64_t i_tAA, const uint64_t i_tCK) const;

        ///
        /// @brief      Helper function to create a vector of supported CAS latencies from a bitmap
        /// @param[in]  i_common_CL common CAS latency bitmap
        /// @return     vector of supported CAS latencies
        ///
        std::vector<uint64_t> create_common_cl_vector(const uint64_t i_common_CL) const;

        ///
        /// @brief      Determines if a requested CAS latency (CL) is supported in the bin of common CLs
        /// @param[in]  i_common_CLs vector of common CAS latencies
        /// @param[in]  i_cas_latency CAS latency we are comparing against
        /// @return     true if CAS latency is supported
        ///
        inline bool is_CL_supported_in_common(const std::vector<uint64_t>& i_common_CLs,
                                              const uint64_t i_cas_latency) const;


        ///
        /// @brief      Checks that CAS latency doesn't exceed largest CAS latency time
        /// @param[in]  i_cas_latency cas latency
        /// @param[in]  i_tCK cycle time
        /// @return     bool true if CAS latency exceeds the largest CAS latency time
        ///             false otherwise
        ///
        inline bool is_CL_exceeding_tAAmax(const uint64_t i_cas_latency,
                                           const uint64_t i_tCK) const;

        ///
        /// @brief Helper function to determines next lowest CAS latency (CL)
        /// @param[in] i_common_CLs vector of common CAS latencies
        /// @param[in] i_desired_cas_latency current CAS latency
        /// @return the next lowest CL
        ///
        inline uint64_t next_lowest_CL(const std::vector<uint64_t>& i_common_CLs,
                                       const uint64_t i_desired_cas_latency);

        ///
        /// @brief          Checks that CAS latency (CL) is supported among all dimms
        ///                 and if it isn't we try to find a CL that is.
        /// @param[in]      i_common_CLs vector of common CAS latencies
        /// @param[in]      i_tAA CAS latency time
        /// @param[in,out]  io_tCK cycle time that corresponds to cas latency
        /// @param[in,out]  io_desired_cas_lat cas latency supported for all dimms
        /// @return         fapi2::FAPI2_RC_SUCCESS if we find a valid CL also common among all dimms
        ///
        fapi2::ReturnCode choose_actual_CL (const std::vector<uint64_t>& i_common_CLs,
                                            const uint64_t i_tAA,
                                            uint64_t& io_tCK,
                                            uint64_t& io_desired_cas_lat);
        ///
        /// @brief          Checks that CAS latency (CL) doesn't exceed max CAS latency time (tAAmax)
        ///                 and if it does it tries to find a valid CL that doesn't exceed tAAmax.
        /// @param[in]      i_common_CLs vector of common CAS latencies
        /// @param[in]      i_tAA CAS latency time
        /// @param[in,out]  io_tCK cycle time that corresponds to cas latency
        /// @param[in,out]  io_desired_cas_lat cas latency supported for all dimms
        /// @return         fapi2::FAPI2_RC_SUCCESS if CL doesn't exceed tAAmax
        ///
        fapi2::ReturnCode validate_valid_CL (const std::vector<uint64_t>& i_common_CLs,
                                             const uint64_t i_tAA,
                                             uint64_t& io_tCK,
                                             uint64_t& io_desired_cas_lat);

    private:

        /////////////////////////
        // Private variables
        /////////////////////////
        uint64_t iv_largest_taamin;// cas latency time
        uint64_t iv_proposed_tck;// cycle time
        uint64_t iv_common_CL; // common cas latency

};// cas_latency


}// mss

#endif //_MSS_CAS_LATENCY_H_
OpenPOWER on IntegriCloud