blob: 48aeddbae5ec7983e29fadee0a23326063bb8d17 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Martin Rothe899e512012-12-05 16:07:11 -07003
Michał Żygowski2317b4f2019-11-28 12:59:44 +01004#include <amdblocks/acpimmio.h>
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +02005#include <device/device.h>
Martin Rothe899e512012-12-05 16:07:11 -07006#include <device/pci.h> /* device_operations */
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02007#include <device/pci_ops.h>
Martin Rothe899e512012-12-05 16:07:11 -07008#include "SBPLATFORM.h"
9#include "sb_cimx.h"
10#include "chip.h" /* struct southbridge_amd_cimx_sb800_config */
11#include "fan.h"
12
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +020013void init_sb800_MANUAL_fans(struct device *dev)
Martin Rothe899e512012-12-05 16:07:11 -070014{
15 int i;
16 struct southbridge_amd_cimx_sb800_config *sb_chip =
17 (struct southbridge_amd_cimx_sb800_config *)(dev->chip_info);
18
19 /* Init Fan 0 */
20 if (sb_chip->fan0_enabled)
21 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010022 pm2_write8(FAN_0_OFFSET + i, sb_chip->fan0_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070023
24 /* Init Fan 1 */
25 if (sb_chip->fan1_enabled)
26 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010027 pm2_write8(FAN_1_OFFSET + i, sb_chip->fan1_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070028
29 /* Init Fan 2 */
30 if (sb_chip->fan2_enabled)
31 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010032 pm2_write8(FAN_2_OFFSET + i, sb_chip->fan2_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070033
34 /* Init Fan 3 */
35 if (sb_chip->fan3_enabled)
36 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010037 pm2_write8(FAN_3_OFFSET + i, sb_chip->fan3_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070038
39 /* Init Fan 4 */
40 if (sb_chip->fan4_enabled)
41 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010042 pm2_write8(FAN_4_OFFSET + i, sb_chip->fan4_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070043
44}
45
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +020046void init_sb800_IMC_fans(struct device *dev)
Martin Rothe899e512012-12-05 16:07:11 -070047{
48
49 AMDSBCFG sb_config;
50 unsigned char *message_ptr;
51 int i;
52 struct southbridge_amd_cimx_sb800_config *sb_chip =
53 (struct southbridge_amd_cimx_sb800_config *)(dev->chip_info);
54
55 /*
56 * The default I/O address of the IMC configuration register index
57 * port is 0x6E. Change the IMC Config port I/O Address if it
58 * conflicts with other components in the system.
59 *
60 * Device 20, Function 3, Reg 0xA4
61 * [0]: if 1, the address specified in IMC_PortAddress is used.
Elyes HAOUASa342f392018-10-17 10:56:26 +020062 * [15:1] IMC_PortAddress bits 15:1 (0x17 - address 0x2E)
Martin Rothe899e512012-12-05 16:07:11 -070063 */
64
65 pci_write_config16(dev, 0xA4, sb_chip->imc_port_address | 0x01);
66
67
68 /*
69 * Do an initial manual setup of the fans for things like polarity
70 * and frequency.
71 */
72 init_sb800_MANUAL_fans(dev);
73
74 /*
75 * FLAG for Func 81/83/85/89 support (1=On,0=Off)
76 * Bit0-3 = Func 81 Zone0-Zone3
77 * Bit4-7 = Func 83 Zone0-Zone3
78 * Bit8-11 = Func 85 Zone0-Zone3
79 * Bit12-15 = Func 89 Tempin Channel0-Channel3
80 */
81 sb_config.Pecstruct.IMCFUNSupportBitMap = 0;
82
83/*
84 ********** Zone 0 **********
85 */
86if (sb_chip->imc_fan_zone0_enabled) {
87
88 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE0;
89
90 /* EC LDN9 function 81 zone 0 */
91 sb_config.Pecstruct.MSGFun81zone0MSGREG0 = 0x00;
92 sb_config.Pecstruct.MSGFun81zone0MSGREG1 = IMC_ZONE0;
93 message_ptr = &sb_config.Pecstruct.MSGFun81zone0MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +020094 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -070095 *(message_ptr + i) = sb_chip->imc_zone0_config_vals[i];
96
97 /* EC LDN9 function 83 zone 0 - Temperature Thresholds */
98 sb_config.Pecstruct.MSGFun83zone0MSGREG0 = 0x00;
99 sb_config.Pecstruct.MSGFun83zone0MSGREG1 = IMC_ZONE0;
100 sb_config.Pecstruct.MSGFun83zone0MSGREGB = 0x00;
101 message_ptr = &sb_config.Pecstruct.MSGFun83zone0MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200102 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700103 *(message_ptr + i) = sb_chip->imc_zone0_thresholds[i];
104
105 /*EC LDN9 function 85 zone 0 - Fan Speeds */
106 sb_config.Pecstruct.MSGFun85zone0MSGREG0 = 0x00;
107 sb_config.Pecstruct.MSGFun85zone0MSGREG1 = IMC_ZONE0;
108 message_ptr = &sb_config.Pecstruct.MSGFun85zone0MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200109 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700110 *(message_ptr + i) = sb_chip->imc_zone0_fanspeeds[i];
111
112}
113
114/*
115 ********** Zone 1 **********
116 */
117if (sb_chip->imc_fan_zone1_enabled) {
118
119 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE1;
120
121 /* EC LDN9 function 81 zone 1 */
122 sb_config.Pecstruct.MSGFun81zone1MSGREG0 = 0x00;
123 sb_config.Pecstruct.MSGFun81zone1MSGREG1 = IMC_ZONE1;
124 message_ptr = &sb_config.Pecstruct.MSGFun81zone1MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200125 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700126 *(message_ptr + i) = sb_chip->imc_zone1_config_vals[i];
127
128 /* EC LDN9 function 83 zone 1 - Temperature Thresholds */
129 sb_config.Pecstruct.MSGFun83zone1MSGREG0 = 0x00;
130 sb_config.Pecstruct.MSGFun83zone1MSGREG1 = IMC_ZONE1;
131 sb_config.Pecstruct.MSGFun83zone1MSGREGB = 0x00;
132 message_ptr = &sb_config.Pecstruct.MSGFun83zone1MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200133 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700134 *(message_ptr + i) = sb_chip->imc_zone1_thresholds[i];
135
136 /* EC LDN9 function 85 zone 1 - Fan Speeds */
137 sb_config.Pecstruct.MSGFun85zone1MSGREG0 = 0x00;
138 sb_config.Pecstruct.MSGFun85zone1MSGREG1 = IMC_ZONE1;
139 message_ptr = &sb_config.Pecstruct.MSGFun85zone1MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200140 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700141 *(message_ptr + i) = sb_chip->imc_zone1_fanspeeds[i];
142
143}
144
145
146/*
147 ********** Zone 2 **********
148 */
149if (sb_chip->imc_fan_zone2_enabled) {
150
151 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE2;
152
153 /* EC LDN9 function 81 zone 2 */
154 sb_config.Pecstruct.MSGFun81zone2MSGREG0 = 0x00;
155 sb_config.Pecstruct.MSGFun81zone2MSGREG1 = IMC_ZONE2;
156 message_ptr = &sb_config.Pecstruct.MSGFun81zone2MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200157 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700158 *(message_ptr + i) = sb_chip->imc_zone2_config_vals[i];
159
160 /* EC LDN9 function 83 zone 2 */
161 sb_config.Pecstruct.MSGFun83zone2MSGREG0 = 0x00;
162 sb_config.Pecstruct.MSGFun83zone2MSGREG1 = IMC_ZONE2;
163 sb_config.Pecstruct.MSGFun83zone2MSGREGB = 0x00;
164 message_ptr = &sb_config.Pecstruct.MSGFun83zone2MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200165 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700166 *(message_ptr + i) = sb_chip->imc_zone2_thresholds[i];
167
168 /* EC LDN9 function 85 zone 2 */
169 sb_config.Pecstruct.MSGFun85zone2MSGREG0 = 0x00;
170 sb_config.Pecstruct.MSGFun85zone2MSGREG1 = IMC_ZONE2;
171 message_ptr = &sb_config.Pecstruct.MSGFun85zone2MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200172 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700173 *(message_ptr + i) = sb_chip->imc_zone2_fanspeeds[i];
174
175}
176
177/*
178 ********** Zone 3 **********
179 */
180
181if (sb_chip->imc_fan_zone3_enabled) {
182
183 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE3;
184
185 /* EC LDN9 function 81 zone 3 */
186 sb_config.Pecstruct.MSGFun81zone3MSGREG0 = 0x00;
187 sb_config.Pecstruct.MSGFun81zone3MSGREG1 = IMC_ZONE3;
188 message_ptr = &sb_config.Pecstruct.MSGFun81zone3MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200189 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700190 *(message_ptr + i) = sb_chip->imc_zone3_config_vals[i];
191
192 /* EC LDN9 function 83 zone 3 */
193 sb_config.Pecstruct.MSGFun83zone3MSGREG0 = 0x00;
194 sb_config.Pecstruct.MSGFun83zone3MSGREG1 = IMC_ZONE3;
195 sb_config.Pecstruct.MSGFun83zone3MSGREGB = 0x00;
196 message_ptr = &sb_config.Pecstruct.MSGFun83zone3MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200197 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700198 *(message_ptr + i) = sb_chip->imc_zone3_thresholds[i];
199
200 /* EC LDN9 function 85 zone 3 */
201 sb_config.Pecstruct.MSGFun85zone3MSGREG0 = 0x00;
202 sb_config.Pecstruct.MSGFun85zone3MSGREG1 = IMC_ZONE3;
203 message_ptr = &sb_config.Pecstruct.MSGFun85zone3MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200204 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700205 *(message_ptr + i) = sb_chip->imc_zone3_fanspeeds[i];
206
207}
208
209 /*
Martin Roth3c3a50c2014-12-16 20:50:26 -0700210 * EC LDN9 function 89 - Set HWM TEMPIN Temperature Calculation Parameters
Martin Rothe899e512012-12-05 16:07:11 -0700211 * This function provides the critical parameters of the HWM TempIn
212 * sensors, IMC would not perform temperature measurement using those
213 * sensors until the parameters are provided.
214 */
215
216if (sb_chip->imc_tempin0_enabled) {
217
218 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN0;
219
Martin Roth3c3a50c2014-12-16 20:50:26 -0700220 /* EC LDN9 function 89 TEMPIN channel 0 */
Martin Rothe899e512012-12-05 16:07:11 -0700221 sb_config.Pecstruct.MSGFun89zone0MSGREG0 = 0x00;
222 sb_config.Pecstruct.MSGFun89zone0MSGREG1 = 0x00;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200223 sb_config.Pecstruct.MSGFun89zone0MSGREG2 = (sb_chip->imc_tempin0_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700224 sb_config.Pecstruct.MSGFun89zone0MSGREG3 = ((sb_chip->imc_tempin0_at >> 8) & 0xff);
225 sb_config.Pecstruct.MSGFun89zone0MSGREG4 = ((sb_chip->imc_tempin0_at >> 16) & 0xff);
226 sb_config.Pecstruct.MSGFun89zone0MSGREG5 = ((sb_chip->imc_tempin0_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200227 sb_config.Pecstruct.MSGFun89zone0MSGREG6 = (sb_chip->imc_tempin0_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700228 sb_config.Pecstruct.MSGFun89zone0MSGREG7 = ((sb_chip->imc_tempin0_ct >> 8) & 0xff);
229 sb_config.Pecstruct.MSGFun89zone0MSGREG8 = ((sb_chip->imc_tempin0_ct >> 16) & 0xff);
230 sb_config.Pecstruct.MSGFun89zone0MSGREG9 = ((sb_chip->imc_tempin0_ct >> 24) & 0xff);
231 sb_config.Pecstruct.MSGFun89zone0MSGREGA = sb_chip->imc_tempin0_tuning_param;
232}
233
234if (sb_chip->imc_tempin1_enabled) {
235
236 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN1;
237
Martin Roth3c3a50c2014-12-16 20:50:26 -0700238 /* EC LDN9 function 89 TEMPIN channel 1 */
Martin Rothe899e512012-12-05 16:07:11 -0700239 sb_config.Pecstruct.MSGFun89zone1MSGREG0 = 0x00;
240 sb_config.Pecstruct.MSGFun89zone1MSGREG1 = 0x01;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200241 sb_config.Pecstruct.MSGFun89zone1MSGREG2 = (sb_chip->imc_tempin1_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700242 sb_config.Pecstruct.MSGFun89zone1MSGREG3 = ((sb_chip->imc_tempin1_at >> 8) & 0xff);
243 sb_config.Pecstruct.MSGFun89zone1MSGREG4 = ((sb_chip->imc_tempin1_at >> 16) & 0xff);
244 sb_config.Pecstruct.MSGFun89zone1MSGREG5 = ((sb_chip->imc_tempin1_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200245 sb_config.Pecstruct.MSGFun89zone1MSGREG6 = (sb_chip->imc_tempin1_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700246 sb_config.Pecstruct.MSGFun89zone1MSGREG7 = ((sb_chip->imc_tempin1_ct >> 8) & 0xff);
247 sb_config.Pecstruct.MSGFun89zone1MSGREG8 = ((sb_chip->imc_tempin1_ct >> 16) & 0xff);
248 sb_config.Pecstruct.MSGFun89zone1MSGREG9 = ((sb_chip->imc_tempin1_ct >> 24) & 0xff);
249 sb_config.Pecstruct.MSGFun89zone1MSGREGA = sb_chip->imc_tempin1_tuning_param;
250}
251
252if (sb_chip->imc_tempin2_enabled) {
253
254 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN2;
255
Martin Roth3c3a50c2014-12-16 20:50:26 -0700256 /* EC LDN9 function 89 TEMPIN channel 2 */
Martin Rothe899e512012-12-05 16:07:11 -0700257 sb_config.Pecstruct.MSGFun89zone2MSGREG0 = 0x00;
258 sb_config.Pecstruct.MSGFun89zone2MSGREG1 = 0x02;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200259 sb_config.Pecstruct.MSGFun89zone2MSGREG2 = (sb_chip->imc_tempin2_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700260 sb_config.Pecstruct.MSGFun89zone2MSGREG3 = ((sb_chip->imc_tempin2_at >> 8) & 0xff);
261 sb_config.Pecstruct.MSGFun89zone2MSGREG4 = ((sb_chip->imc_tempin2_at >> 16) & 0xff);
262 sb_config.Pecstruct.MSGFun89zone2MSGREG5 = ((sb_chip->imc_tempin2_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200263 sb_config.Pecstruct.MSGFun89zone2MSGREG6 = (sb_chip->imc_tempin2_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700264 sb_config.Pecstruct.MSGFun89zone2MSGREG7 = ((sb_chip->imc_tempin2_ct >> 8) & 0xff);
265 sb_config.Pecstruct.MSGFun89zone2MSGREG8 = ((sb_chip->imc_tempin2_ct >> 16) & 0xff);
266 sb_config.Pecstruct.MSGFun89zone2MSGREG9 = ((sb_chip->imc_tempin2_ct >> 24) & 0xff);
267 sb_config.Pecstruct.MSGFun89zone2MSGREGA = sb_chip->imc_tempin2_tuning_param;
268}
269
270if (sb_chip->imc_tempin3_enabled) {
271
272 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN3;
273
Martin Roth3c3a50c2014-12-16 20:50:26 -0700274 /* EC LDN9 function 89 TEMPIN channel 3 */
Martin Rothe899e512012-12-05 16:07:11 -0700275 sb_config.Pecstruct.MSGFun89zone3MSGREG0 = 0x00;
276 sb_config.Pecstruct.MSGFun89zone3MSGREG1 = 0x03;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200277 sb_config.Pecstruct.MSGFun89zone3MSGREG2 = (sb_chip->imc_tempin3_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700278 sb_config.Pecstruct.MSGFun89zone3MSGREG3 = ((sb_chip->imc_tempin3_at >> 8) & 0xff);
279 sb_config.Pecstruct.MSGFun89zone3MSGREG4 = ((sb_chip->imc_tempin3_at >> 16) & 0xff);
280 sb_config.Pecstruct.MSGFun89zone3MSGREG5 = ((sb_chip->imc_tempin3_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200281 sb_config.Pecstruct.MSGFun89zone3MSGREG6 = (sb_chip->imc_tempin3_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700282 sb_config.Pecstruct.MSGFun89zone3MSGREG7 = ((sb_chip->imc_tempin3_ct >> 8) & 0xff);
283 sb_config.Pecstruct.MSGFun89zone3MSGREG8 = ((sb_chip->imc_tempin3_ct >> 16) & 0xff);
284 sb_config.Pecstruct.MSGFun89zone3MSGREG9 = ((sb_chip->imc_tempin3_ct >> 24) & 0xff);
285 sb_config.Pecstruct.MSGFun89zone3MSGREGA = sb_chip->imc_tempin3_tuning_param;
286}
287
288 /* Set up the sb_config structure for the fan control initialization */
289 sb_config.StdHeader.Func = SB_EC_FANCONTROL;
290
291 AmdSbDispatcher(&sb_config);
292
293 return;
294}