blob: 1cf01a26e02587ebddb5231bc37f008bd60bdc2f [file] [log] [blame]
David Hendricks2004b932018-03-09 13:58:27 -08001/***********************license start***********************************
2* Copyright (c) 2003-2017 Cavium Inc. (support@cavium.com). All rights
3* reserved.
4*
5*
6* Redistribution and use in source and binary forms, with or without
7* modification, are permitted provided that the following conditions are
8* met:
9*
10* * Redistributions of source code must retain the above copyright
11* notice, this list of conditions and the following disclaimer.
12*
13* * Redistributions in binary form must reproduce the above
14* copyright notice, this list of conditions and the following
15* disclaimer in the documentation and/or other materials provided
16* with the distribution.
17*
18* * Neither the name of Cavium Inc. nor the names of
19* its contributors may be used to endorse or promote products
20* derived from this software without specific prior written
21* permission.
22*
23* This Software, including technical data, may be subject to U.S. export
24* control laws, including the U.S. Export Administration Act and its
25* associated regulations, and may be subject to export or import
26* regulations in other countries.
27*
28* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
31* TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
32* REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
33* DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
34* OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
35* PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT,
36* QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK
37* ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38***********************license end**************************************/
39#include <bdk.h>
David Hendricks7d48ac52018-03-09 14:30:38 -080040#include <string.h>
41#include <libbdk-hal/bdk-config.h>
42#include <libbdk-hal/bdk-l2c.h>
David Hendricks2004b932018-03-09 13:58:27 -080043
44BDK_REQUIRE_DEFINE(DRAM_CONFIG);
45
46/**
47 * Lookup a DRAM configuration by name and initialize DRAM using it
48 *
49 * @param node Node to configure
50 * @param ddr_clock_override
51 * If non zero, override the DRAM frequency specified
52 * in the config with this value
53 *
54 * @return Amount of DRAM in MB, or negative on failure
55 */
56int bdk_dram_config(int node, int ddr_clock_override)
57{
58 const dram_config_t *config = libdram_config_load(node);
59 if (!config)
60 {
61 printf("N%d: No DRAM config specified, skipping DRAM init\n", node);
62 return 0;
63 }
64
65 BDK_TRACE(DRAM, "N%d: Starting DRAM init (config=%p, ddr_clock_override=%d)\n", node, config, ddr_clock_override);
66 int mbytes = libdram_config(node, config, ddr_clock_override);
67 BDK_TRACE(DRAM, "N%d: DRAM init returned %d\n", node, mbytes);
68 if (mbytes <= 0)
69 {
70 printf("ERROR: DDR initialization failed\n");
71 return -1;
72 }
73
74 return mbytes;
75}
76
77/**
Peter Lemenkov7bbe3bb2018-12-07 11:23:21 +010078 * Do all the DRAM Margin tests
David Hendricks2004b932018-03-09 13:58:27 -080079 *
80 * @param node Node to test
81 *
82 * @return Success or Fail
83 */
84void bdk_dram_margin(int node)
85{
86 BDK_TRACE(DRAM, "N%d: Starting DRAM margining\n", node);
87 libdram_margin(node);
88 BDK_TRACE(DRAM, "N%d: Finished DRAM margining.\n", node);
89 return;
90}
91
92/**
93 * Return the string of the DRAM configuration info at the specified node.
94 * If the node is not configured, NULL is returned.
95 *
96 * @param node node to retrieve
97 *
98 * @return string or NULL
99 */
100const char* bdk_dram_get_info_string(int node)
101{
102 #define INFO_STRING_LEN 40
103 static char info_string[INFO_STRING_LEN];
104 static const char *info_ptr = info_string;
105
106 snprintf(info_string, INFO_STRING_LEN,
107 " %ld MB, %ld MT/s, %s %s",
108 bdk_dram_get_size_mbytes(node),
Patrick Rudolph25318652018-07-12 13:05:01 +0200109 libdram_get_freq_from_pll(node, 0) / 1000000,
David Hendricks2004b932018-03-09 13:58:27 -0800110 (__bdk_dram_is_ddr4(node, 0)) ? "DDR4" : "DDR3",
111 (__bdk_dram_is_rdimm(node, 0)) ? "RDIMM" : "UDIMM");
112
113 return info_ptr;
114}
115
116
117/**
118 * Return the highest address currently used by the BDK. This address will
119 * be about 4MB above the top of the BDK to make sure small growths between the
120 * call and its use don't cause corruption. Any call to memory allocation can
121 * change this value.
122 *
123 * @return Size of the BDK in bytes
124 */
125uint64_t bdk_dram_get_top_of_bdk(void)
126{
127 /* Make sure the start address is higher that the BDK's active range.
128 *
129 * As sbrk() returns a node address, mask off the node portion of
130 * the address to make it a physical offset. Doing this simplifies the
131 * address checks and calculations which only work with physical offsets.
132 */
David Hendricks7d48ac52018-03-09 14:30:38 -0800133 /* FIXME(dhendrix): we only care about node 0 */
134// uint64_t top_of_bdk = (bdk_ptr_to_phys(sbrk(0)) & bdk_build_mask(40));
135 uint64_t top_of_bdk = 0;
David Hendricks2004b932018-03-09 13:58:27 -0800136 uint64_t l2_size = bdk_l2c_get_cache_size_bytes(bdk_numa_master());
137 if (top_of_bdk <= l2_size)
138 {
139 /* Early BDK code takes care of the first L2 sized area of memory */
140 top_of_bdk = l2_size;
141 }
142 else
143 {
144 /* Give 4MB of extra so the BDK has room to grow */
145 top_of_bdk += 4 << 20;
146 /* Align it on a 64KB boundary */
147 top_of_bdk >>= 16;
148 top_of_bdk <<= 16;
149 }
150 return top_of_bdk;
151}