blob: f5e0a48f4dfb7b5842d31ab0710b35829eb0c6f5 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Martin Rothe899e512012-12-05 16:07:11 -07002
Michał Żygowski2317b4f2019-11-28 12:59:44 +01003#include <amdblocks/acpimmio.h>
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +02004#include <device/device.h>
Martin Rothe899e512012-12-05 16:07:11 -07005#include <device/pci.h> /* device_operations */
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02006#include <device/pci_ops.h>
Martin Rothe899e512012-12-05 16:07:11 -07007#include "SBPLATFORM.h"
8#include "sb_cimx.h"
9#include "chip.h" /* struct southbridge_amd_cimx_sb800_config */
10#include "fan.h"
11
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +020012void init_sb800_MANUAL_fans(struct device *dev)
Martin Rothe899e512012-12-05 16:07:11 -070013{
14 int i;
15 struct southbridge_amd_cimx_sb800_config *sb_chip =
16 (struct southbridge_amd_cimx_sb800_config *)(dev->chip_info);
17
18 /* Init Fan 0 */
19 if (sb_chip->fan0_enabled)
20 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010021 pm2_write8(FAN_0_OFFSET + i, sb_chip->fan0_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070022
23 /* Init Fan 1 */
24 if (sb_chip->fan1_enabled)
25 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010026 pm2_write8(FAN_1_OFFSET + i, sb_chip->fan1_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070027
28 /* Init Fan 2 */
29 if (sb_chip->fan2_enabled)
30 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010031 pm2_write8(FAN_2_OFFSET + i, sb_chip->fan2_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070032
33 /* Init Fan 3 */
34 if (sb_chip->fan3_enabled)
35 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010036 pm2_write8(FAN_3_OFFSET + i, sb_chip->fan3_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070037
38 /* Init Fan 4 */
39 if (sb_chip->fan4_enabled)
40 for (i = 0; i < FAN_REGISTER_COUNT; i++)
Michał Żygowski2317b4f2019-11-28 12:59:44 +010041 pm2_write8(FAN_4_OFFSET + i, sb_chip->fan4_config_vals[i]);
Martin Rothe899e512012-12-05 16:07:11 -070042}
43
Elyes HAOUAS1a4abb72018-05-19 16:49:20 +020044void init_sb800_IMC_fans(struct device *dev)
Martin Rothe899e512012-12-05 16:07:11 -070045{
Martin Rothe899e512012-12-05 16:07:11 -070046 AMDSBCFG sb_config;
47 unsigned char *message_ptr;
48 int i;
49 struct southbridge_amd_cimx_sb800_config *sb_chip =
50 (struct southbridge_amd_cimx_sb800_config *)(dev->chip_info);
51
52 /*
53 * The default I/O address of the IMC configuration register index
54 * port is 0x6E. Change the IMC Config port I/O Address if it
55 * conflicts with other components in the system.
56 *
57 * Device 20, Function 3, Reg 0xA4
58 * [0]: if 1, the address specified in IMC_PortAddress is used.
Elyes HAOUASa342f392018-10-17 10:56:26 +020059 * [15:1] IMC_PortAddress bits 15:1 (0x17 - address 0x2E)
Martin Rothe899e512012-12-05 16:07:11 -070060 */
61
62 pci_write_config16(dev, 0xA4, sb_chip->imc_port_address | 0x01);
63
Martin Rothe899e512012-12-05 16:07:11 -070064 /*
65 * Do an initial manual setup of the fans for things like polarity
66 * and frequency.
67 */
68 init_sb800_MANUAL_fans(dev);
69
70 /*
71 * FLAG for Func 81/83/85/89 support (1=On,0=Off)
72 * Bit0-3 = Func 81 Zone0-Zone3
73 * Bit4-7 = Func 83 Zone0-Zone3
74 * Bit8-11 = Func 85 Zone0-Zone3
75 * Bit12-15 = Func 89 Tempin Channel0-Channel3
76 */
77 sb_config.Pecstruct.IMCFUNSupportBitMap = 0;
78
79/*
80 ********** Zone 0 **********
81 */
82if (sb_chip->imc_fan_zone0_enabled) {
83
84 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE0;
85
86 /* EC LDN9 function 81 zone 0 */
87 sb_config.Pecstruct.MSGFun81zone0MSGREG0 = 0x00;
88 sb_config.Pecstruct.MSGFun81zone0MSGREG1 = IMC_ZONE0;
89 message_ptr = &sb_config.Pecstruct.MSGFun81zone0MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +020090 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -070091 *(message_ptr + i) = sb_chip->imc_zone0_config_vals[i];
92
93 /* EC LDN9 function 83 zone 0 - Temperature Thresholds */
94 sb_config.Pecstruct.MSGFun83zone0MSGREG0 = 0x00;
95 sb_config.Pecstruct.MSGFun83zone0MSGREG1 = IMC_ZONE0;
96 sb_config.Pecstruct.MSGFun83zone0MSGREGB = 0x00;
97 message_ptr = &sb_config.Pecstruct.MSGFun83zone0MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +020098 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -070099 *(message_ptr + i) = sb_chip->imc_zone0_thresholds[i];
100
101 /*EC LDN9 function 85 zone 0 - Fan Speeds */
102 sb_config.Pecstruct.MSGFun85zone0MSGREG0 = 0x00;
103 sb_config.Pecstruct.MSGFun85zone0MSGREG1 = IMC_ZONE0;
104 message_ptr = &sb_config.Pecstruct.MSGFun85zone0MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200105 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700106 *(message_ptr + i) = sb_chip->imc_zone0_fanspeeds[i];
Martin Rothe899e512012-12-05 16:07:11 -0700107}
108
109/*
110 ********** Zone 1 **********
111 */
112if (sb_chip->imc_fan_zone1_enabled) {
113
114 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE1;
115
116 /* EC LDN9 function 81 zone 1 */
117 sb_config.Pecstruct.MSGFun81zone1MSGREG0 = 0x00;
118 sb_config.Pecstruct.MSGFun81zone1MSGREG1 = IMC_ZONE1;
119 message_ptr = &sb_config.Pecstruct.MSGFun81zone1MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200120 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700121 *(message_ptr + i) = sb_chip->imc_zone1_config_vals[i];
122
123 /* EC LDN9 function 83 zone 1 - Temperature Thresholds */
124 sb_config.Pecstruct.MSGFun83zone1MSGREG0 = 0x00;
125 sb_config.Pecstruct.MSGFun83zone1MSGREG1 = IMC_ZONE1;
126 sb_config.Pecstruct.MSGFun83zone1MSGREGB = 0x00;
127 message_ptr = &sb_config.Pecstruct.MSGFun83zone1MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200128 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700129 *(message_ptr + i) = sb_chip->imc_zone1_thresholds[i];
130
131 /* EC LDN9 function 85 zone 1 - Fan Speeds */
132 sb_config.Pecstruct.MSGFun85zone1MSGREG0 = 0x00;
133 sb_config.Pecstruct.MSGFun85zone1MSGREG1 = IMC_ZONE1;
134 message_ptr = &sb_config.Pecstruct.MSGFun85zone1MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200135 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700136 *(message_ptr + i) = sb_chip->imc_zone1_fanspeeds[i];
Martin Rothe899e512012-12-05 16:07:11 -0700137}
138
Martin Rothe899e512012-12-05 16:07:11 -0700139/*
140 ********** Zone 2 **********
141 */
142if (sb_chip->imc_fan_zone2_enabled) {
143
144 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE2;
145
146 /* EC LDN9 function 81 zone 2 */
147 sb_config.Pecstruct.MSGFun81zone2MSGREG0 = 0x00;
148 sb_config.Pecstruct.MSGFun81zone2MSGREG1 = IMC_ZONE2;
149 message_ptr = &sb_config.Pecstruct.MSGFun81zone2MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200150 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700151 *(message_ptr + i) = sb_chip->imc_zone2_config_vals[i];
152
153 /* EC LDN9 function 83 zone 2 */
154 sb_config.Pecstruct.MSGFun83zone2MSGREG0 = 0x00;
155 sb_config.Pecstruct.MSGFun83zone2MSGREG1 = IMC_ZONE2;
156 sb_config.Pecstruct.MSGFun83zone2MSGREGB = 0x00;
157 message_ptr = &sb_config.Pecstruct.MSGFun83zone2MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200158 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700159 *(message_ptr + i) = sb_chip->imc_zone2_thresholds[i];
160
161 /* EC LDN9 function 85 zone 2 */
162 sb_config.Pecstruct.MSGFun85zone2MSGREG0 = 0x00;
163 sb_config.Pecstruct.MSGFun85zone2MSGREG1 = IMC_ZONE2;
164 message_ptr = &sb_config.Pecstruct.MSGFun85zone2MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200165 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700166 *(message_ptr + i) = sb_chip->imc_zone2_fanspeeds[i];
Martin Rothe899e512012-12-05 16:07:11 -0700167}
168
169/*
170 ********** Zone 3 **********
171 */
172
173if (sb_chip->imc_fan_zone3_enabled) {
174
175 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_ZONE3;
176
177 /* EC LDN9 function 81 zone 3 */
178 sb_config.Pecstruct.MSGFun81zone3MSGREG0 = 0x00;
179 sb_config.Pecstruct.MSGFun81zone3MSGREG1 = IMC_ZONE3;
180 message_ptr = &sb_config.Pecstruct.MSGFun81zone3MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200181 for (i = 0; i < IMC_FAN_CONFIG_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700182 *(message_ptr + i) = sb_chip->imc_zone3_config_vals[i];
183
184 /* EC LDN9 function 83 zone 3 */
185 sb_config.Pecstruct.MSGFun83zone3MSGREG0 = 0x00;
186 sb_config.Pecstruct.MSGFun83zone3MSGREG1 = IMC_ZONE3;
187 sb_config.Pecstruct.MSGFun83zone3MSGREGB = 0x00;
188 message_ptr = &sb_config.Pecstruct.MSGFun83zone3MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200189 for (i = 0; i < IMC_FAN_THRESHOLD_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700190 *(message_ptr + i) = sb_chip->imc_zone3_thresholds[i];
191
192 /* EC LDN9 function 85 zone 3 */
193 sb_config.Pecstruct.MSGFun85zone3MSGREG0 = 0x00;
194 sb_config.Pecstruct.MSGFun85zone3MSGREG1 = IMC_ZONE3;
195 message_ptr = &sb_config.Pecstruct.MSGFun85zone3MSGREG2;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200196 for (i = 0; i < IMC_FAN_SPEED_COUNT; i++)
Martin Rothe899e512012-12-05 16:07:11 -0700197 *(message_ptr + i) = sb_chip->imc_zone3_fanspeeds[i];
Martin Rothe899e512012-12-05 16:07:11 -0700198}
199
200 /*
Martin Roth3c3a50c2014-12-16 20:50:26 -0700201 * EC LDN9 function 89 - Set HWM TEMPIN Temperature Calculation Parameters
Martin Rothe899e512012-12-05 16:07:11 -0700202 * This function provides the critical parameters of the HWM TempIn
203 * sensors, IMC would not perform temperature measurement using those
204 * sensors until the parameters are provided.
205 */
206
207if (sb_chip->imc_tempin0_enabled) {
208
209 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN0;
210
Martin Roth3c3a50c2014-12-16 20:50:26 -0700211 /* EC LDN9 function 89 TEMPIN channel 0 */
Martin Rothe899e512012-12-05 16:07:11 -0700212 sb_config.Pecstruct.MSGFun89zone0MSGREG0 = 0x00;
213 sb_config.Pecstruct.MSGFun89zone0MSGREG1 = 0x00;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200214 sb_config.Pecstruct.MSGFun89zone0MSGREG2 = (sb_chip->imc_tempin0_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700215 sb_config.Pecstruct.MSGFun89zone0MSGREG3 = ((sb_chip->imc_tempin0_at >> 8) & 0xff);
216 sb_config.Pecstruct.MSGFun89zone0MSGREG4 = ((sb_chip->imc_tempin0_at >> 16) & 0xff);
217 sb_config.Pecstruct.MSGFun89zone0MSGREG5 = ((sb_chip->imc_tempin0_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200218 sb_config.Pecstruct.MSGFun89zone0MSGREG6 = (sb_chip->imc_tempin0_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700219 sb_config.Pecstruct.MSGFun89zone0MSGREG7 = ((sb_chip->imc_tempin0_ct >> 8) & 0xff);
220 sb_config.Pecstruct.MSGFun89zone0MSGREG8 = ((sb_chip->imc_tempin0_ct >> 16) & 0xff);
221 sb_config.Pecstruct.MSGFun89zone0MSGREG9 = ((sb_chip->imc_tempin0_ct >> 24) & 0xff);
222 sb_config.Pecstruct.MSGFun89zone0MSGREGA = sb_chip->imc_tempin0_tuning_param;
223}
224
225if (sb_chip->imc_tempin1_enabled) {
226
227 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN1;
228
Martin Roth3c3a50c2014-12-16 20:50:26 -0700229 /* EC LDN9 function 89 TEMPIN channel 1 */
Martin Rothe899e512012-12-05 16:07:11 -0700230 sb_config.Pecstruct.MSGFun89zone1MSGREG0 = 0x00;
231 sb_config.Pecstruct.MSGFun89zone1MSGREG1 = 0x01;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200232 sb_config.Pecstruct.MSGFun89zone1MSGREG2 = (sb_chip->imc_tempin1_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700233 sb_config.Pecstruct.MSGFun89zone1MSGREG3 = ((sb_chip->imc_tempin1_at >> 8) & 0xff);
234 sb_config.Pecstruct.MSGFun89zone1MSGREG4 = ((sb_chip->imc_tempin1_at >> 16) & 0xff);
235 sb_config.Pecstruct.MSGFun89zone1MSGREG5 = ((sb_chip->imc_tempin1_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200236 sb_config.Pecstruct.MSGFun89zone1MSGREG6 = (sb_chip->imc_tempin1_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700237 sb_config.Pecstruct.MSGFun89zone1MSGREG7 = ((sb_chip->imc_tempin1_ct >> 8) & 0xff);
238 sb_config.Pecstruct.MSGFun89zone1MSGREG8 = ((sb_chip->imc_tempin1_ct >> 16) & 0xff);
239 sb_config.Pecstruct.MSGFun89zone1MSGREG9 = ((sb_chip->imc_tempin1_ct >> 24) & 0xff);
240 sb_config.Pecstruct.MSGFun89zone1MSGREGA = sb_chip->imc_tempin1_tuning_param;
241}
242
243if (sb_chip->imc_tempin2_enabled) {
244
245 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN2;
246
Martin Roth3c3a50c2014-12-16 20:50:26 -0700247 /* EC LDN9 function 89 TEMPIN channel 2 */
Martin Rothe899e512012-12-05 16:07:11 -0700248 sb_config.Pecstruct.MSGFun89zone2MSGREG0 = 0x00;
249 sb_config.Pecstruct.MSGFun89zone2MSGREG1 = 0x02;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200250 sb_config.Pecstruct.MSGFun89zone2MSGREG2 = (sb_chip->imc_tempin2_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700251 sb_config.Pecstruct.MSGFun89zone2MSGREG3 = ((sb_chip->imc_tempin2_at >> 8) & 0xff);
252 sb_config.Pecstruct.MSGFun89zone2MSGREG4 = ((sb_chip->imc_tempin2_at >> 16) & 0xff);
253 sb_config.Pecstruct.MSGFun89zone2MSGREG5 = ((sb_chip->imc_tempin2_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200254 sb_config.Pecstruct.MSGFun89zone2MSGREG6 = (sb_chip->imc_tempin2_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700255 sb_config.Pecstruct.MSGFun89zone2MSGREG7 = ((sb_chip->imc_tempin2_ct >> 8) & 0xff);
256 sb_config.Pecstruct.MSGFun89zone2MSGREG8 = ((sb_chip->imc_tempin2_ct >> 16) & 0xff);
257 sb_config.Pecstruct.MSGFun89zone2MSGREG9 = ((sb_chip->imc_tempin2_ct >> 24) & 0xff);
258 sb_config.Pecstruct.MSGFun89zone2MSGREGA = sb_chip->imc_tempin2_tuning_param;
259}
260
261if (sb_chip->imc_tempin3_enabled) {
262
263 sb_config.Pecstruct.IMCFUNSupportBitMap |= IMC_ENABLE_TEMPIN3;
264
Martin Roth3c3a50c2014-12-16 20:50:26 -0700265 /* EC LDN9 function 89 TEMPIN channel 3 */
Martin Rothe899e512012-12-05 16:07:11 -0700266 sb_config.Pecstruct.MSGFun89zone3MSGREG0 = 0x00;
267 sb_config.Pecstruct.MSGFun89zone3MSGREG1 = 0x03;
Elyes HAOUASa342f392018-10-17 10:56:26 +0200268 sb_config.Pecstruct.MSGFun89zone3MSGREG2 = (sb_chip->imc_tempin3_at & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700269 sb_config.Pecstruct.MSGFun89zone3MSGREG3 = ((sb_chip->imc_tempin3_at >> 8) & 0xff);
270 sb_config.Pecstruct.MSGFun89zone3MSGREG4 = ((sb_chip->imc_tempin3_at >> 16) & 0xff);
271 sb_config.Pecstruct.MSGFun89zone3MSGREG5 = ((sb_chip->imc_tempin3_at >> 24) & 0xff);
Elyes HAOUASa342f392018-10-17 10:56:26 +0200272 sb_config.Pecstruct.MSGFun89zone3MSGREG6 = (sb_chip->imc_tempin3_ct & 0xff);
Martin Rothe899e512012-12-05 16:07:11 -0700273 sb_config.Pecstruct.MSGFun89zone3MSGREG7 = ((sb_chip->imc_tempin3_ct >> 8) & 0xff);
274 sb_config.Pecstruct.MSGFun89zone3MSGREG8 = ((sb_chip->imc_tempin3_ct >> 16) & 0xff);
275 sb_config.Pecstruct.MSGFun89zone3MSGREG9 = ((sb_chip->imc_tempin3_ct >> 24) & 0xff);
276 sb_config.Pecstruct.MSGFun89zone3MSGREGA = sb_chip->imc_tempin3_tuning_param;
277}
278
279 /* Set up the sb_config structure for the fan control initialization */
280 sb_config.StdHeader.Func = SB_EC_FANCONTROL;
281
282 AmdSbDispatcher(&sb_config);
Martin Rothe899e512012-12-05 16:07:11 -0700283}