1 /* 2 * Windfarm PowerMac thermal control. FCU fan control 3 * 4 * Copyright 2012 Benjamin Herrenschmidt, IBM Corp. 5 * 6 * Released under the term of the GNU GPL v2. 7 */ 8 #undef DEBUG 9 10 #include <linux/types.h> 11 #include <linux/errno.h> 12 #include <linux/kernel.h> 13 #include <linux/delay.h> 14 #include <linux/slab.h> 15 #include <linux/init.h> 16 #include <linux/wait.h> 17 #include <linux/i2c.h> 18 #include <asm/prom.h> 19 #include <asm/machdep.h> 20 #include <asm/io.h> 21 #include <asm/sections.h> 22 23 #include "windfarm.h" 24 #include "windfarm_mpu.h" 25 26 #define VERSION "1.0" 27 28 #ifdef DEBUG 29 #define DBG(args...) printk(args) 30 #else 31 #define DBG(args...) do { } while(0) 32 #endif 33 34 /* 35 * This option is "weird" :) Basically, if you define this to 1 36 * the control loop for the RPMs fans (not PWMs) will apply the 37 * correction factor obtained from the PID to the actual RPM 38 * speed read from the FCU. 39 * 40 * If you define the below constant to 0, then it will be 41 * applied to the setpoint RPM speed, that is basically the 42 * speed we proviously "asked" for. 43 * 44 * I'm using 0 for now which is what therm_pm72 used to do and 45 * what Darwin -apparently- does based on observed behaviour. 46 */ 47 #define RPM_PID_USE_ACTUAL_SPEED 0 48 49 /* Default min/max for pumps */ 50 #define CPU_PUMP_OUTPUT_MAX 3200 51 #define CPU_PUMP_OUTPUT_MIN 1250 52 53 #define FCU_FAN_RPM 0 54 #define FCU_FAN_PWM 1 55 56 struct wf_fcu_priv { 57 struct kref ref; 58 struct i2c_client *i2c; 59 struct mutex lock; 60 struct list_head fan_list; 61 int rpm_shift; 62 }; 63 64 struct wf_fcu_fan { 65 struct list_head link; 66 int id; 67 s32 min, max, target; 68 struct wf_fcu_priv *fcu_priv; 69 struct wf_control ctrl; 70 }; 71 72 static void wf_fcu_release(struct kref *ref) 73 { 74 struct wf_fcu_priv *pv = container_of(ref, struct wf_fcu_priv, ref); 75 76 kfree(pv); 77 } 78 79 static void wf_fcu_fan_release(struct wf_control *ct) 80 { 81 struct wf_fcu_fan *fan = ct->priv; 82 83 kref_put(&fan->fcu_priv->ref, wf_fcu_release); 84 kfree(fan); 85 } 86 87 static int wf_fcu_read_reg(struct wf_fcu_priv *pv, int reg, 88 unsigned char *buf, int nb) 89 { 90 int tries, nr, nw; 91 92 mutex_lock(&pv->lock); 93 94 buf[0] = reg; 95 tries = 0; 96 for (;;) { 97 nw = i2c_master_send(pv->i2c, buf, 1); 98 if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100) 99 break; 100 msleep(10); 101 ++tries; 102 } 103 if (nw <= 0) { 104 pr_err("Failure writing address to FCU: %d", nw); 105 nr = nw; 106 goto bail; 107 } 108 tries = 0; 109 for (;;) { 110 nr = i2c_master_recv(pv->i2c, buf, nb); 111 if (nr > 0 || (nr < 0 && nr != -ENODEV) || tries >= 100) 112 break; 113 msleep(10); 114 ++tries; 115 } 116 if (nr <= 0) 117 pr_err("wf_fcu: Failure reading data from FCU: %d", nw); 118 bail: 119 mutex_unlock(&pv->lock); 120 return nr; 121 } 122 123 static int wf_fcu_write_reg(struct wf_fcu_priv *pv, int reg, 124 const unsigned char *ptr, int nb) 125 { 126 int tries, nw; 127 unsigned char buf[16]; 128 129 buf[0] = reg; 130 memcpy(buf+1, ptr, nb); 131 ++nb; 132 tries = 0; 133 for (;;) { 134 nw = i2c_master_send(pv->i2c, buf, nb); 135 if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100) 136 break; 137 msleep(10); 138 ++tries; 139 } 140 if (nw < 0) 141 pr_err("wf_fcu: Failure writing to FCU: %d", nw); 142 return nw; 143 } 144 145 static int wf_fcu_fan_set_rpm(struct wf_control *ct, s32 value) 146 { 147 struct wf_fcu_fan *fan = ct->priv; 148 struct wf_fcu_priv *pv = fan->fcu_priv; 149 int rc, shift = pv->rpm_shift; 150 unsigned char buf[2]; 151 152 if (value < fan->min) 153 value = fan->min; 154 if (value > fan->max) 155 value = fan->max; 156 157 fan->target = value; 158 159 buf[0] = value >> (8 - shift); 160 buf[1] = value << shift; 161 rc = wf_fcu_write_reg(pv, 0x10 + (fan->id * 2), buf, 2); 162 if (rc < 0) 163 return -EIO; 164 return 0; 165 } 166 167 static int wf_fcu_fan_get_rpm(struct wf_control *ct, s32 *value) 168 { 169 struct wf_fcu_fan *fan = ct->priv; 170 struct wf_fcu_priv *pv = fan->fcu_priv; 171 int rc, reg_base, shift = pv->rpm_shift; 172 unsigned char failure; 173 unsigned char active; 174 unsigned char buf[2]; 175 176 rc = wf_fcu_read_reg(pv, 0xb, &failure, 1); 177 if (rc != 1) 178 return -EIO; 179 if ((failure & (1 << fan->id)) != 0) 180 return -EFAULT; 181 rc = wf_fcu_read_reg(pv, 0xd, &active, 1); 182 if (rc != 1) 183 return -EIO; 184 if ((active & (1 << fan->id)) == 0) 185 return -ENXIO; 186 187 /* Programmed value or real current speed */ 188 #if RPM_PID_USE_ACTUAL_SPEED 189 reg_base = 0x11; 190 #else 191 reg_base = 0x10; 192 #endif 193 rc = wf_fcu_read_reg(pv, reg_base + (fan->id * 2), buf, 2); 194 if (rc != 2) 195 return -EIO; 196 197 *value = (buf[0] << (8 - shift)) | buf[1] >> shift; 198 199 return 0; 200 } 201 202 static int wf_fcu_fan_set_pwm(struct wf_control *ct, s32 value) 203 { 204 struct wf_fcu_fan *fan = ct->priv; 205 struct wf_fcu_priv *pv = fan->fcu_priv; 206 unsigned char buf[2]; 207 int rc; 208 209 if (value < fan->min) 210 value = fan->min; 211 if (value > fan->max) 212 value = fan->max; 213 214 fan->target = value; 215 216 value = (value * 2559) / 1000; 217 buf[0] = value; 218 rc = wf_fcu_write_reg(pv, 0x30 + (fan->id * 2), buf, 1); 219 if (rc < 0) 220 return -EIO; 221 return 0; 222 } 223 224 static int wf_fcu_fan_get_pwm(struct wf_control *ct, s32 *value) 225 { 226 struct wf_fcu_fan *fan = ct->priv; 227 struct wf_fcu_priv *pv = fan->fcu_priv; 228 unsigned char failure; 229 unsigned char active; 230 unsigned char buf[2]; 231 int rc; 232 233 rc = wf_fcu_read_reg(pv, 0x2b, &failure, 1); 234 if (rc != 1) 235 return -EIO; 236 if ((failure & (1 << fan->id)) != 0) 237 return -EFAULT; 238 rc = wf_fcu_read_reg(pv, 0x2d, &active, 1); 239 if (rc != 1) 240 return -EIO; 241 if ((active & (1 << fan->id)) == 0) 242 return -ENXIO; 243 244 rc = wf_fcu_read_reg(pv, 0x30 + (fan->id * 2), buf, 1); 245 if (rc != 1) 246 return -EIO; 247 248 *value = (((s32)buf[0]) * 1000) / 2559; 249 250 return 0; 251 } 252 253 static s32 wf_fcu_fan_min(struct wf_control *ct) 254 { 255 struct wf_fcu_fan *fan = ct->priv; 256 257 return fan->min; 258 } 259 260 static s32 wf_fcu_fan_max(struct wf_control *ct) 261 { 262 struct wf_fcu_fan *fan = ct->priv; 263 264 return fan->max; 265 } 266 267 static const struct wf_control_ops wf_fcu_fan_rpm_ops = { 268 .set_value = wf_fcu_fan_set_rpm, 269 .get_value = wf_fcu_fan_get_rpm, 270 .get_min = wf_fcu_fan_min, 271 .get_max = wf_fcu_fan_max, 272 .release = wf_fcu_fan_release, 273 .owner = THIS_MODULE, 274 }; 275 276 static const struct wf_control_ops wf_fcu_fan_pwm_ops = { 277 .set_value = wf_fcu_fan_set_pwm, 278 .get_value = wf_fcu_fan_get_pwm, 279 .get_min = wf_fcu_fan_min, 280 .get_max = wf_fcu_fan_max, 281 .release = wf_fcu_fan_release, 282 .owner = THIS_MODULE, 283 }; 284 285 static void __devinit wf_fcu_get_pump_minmax(struct wf_fcu_fan *fan) 286 { 287 const struct mpu_data *mpu = wf_get_mpu(0); 288 u16 pump_min = 0, pump_max = 0xffff; 289 u16 tmp[4]; 290 291 /* Try to fetch pumps min/max infos from eeprom */ 292 if (mpu) { 293 memcpy(&tmp, mpu->processor_part_num, 8); 294 if (tmp[0] != 0xffff && tmp[1] != 0xffff) { 295 pump_min = max(pump_min, tmp[0]); 296 pump_max = min(pump_max, tmp[1]); 297 } 298 if (tmp[2] != 0xffff && tmp[3] != 0xffff) { 299 pump_min = max(pump_min, tmp[2]); 300 pump_max = min(pump_max, tmp[3]); 301 } 302 } 303 304 /* Double check the values, this _IS_ needed as the EEPROM on 305 * some dual 2.5Ghz G5s seem, at least, to have both min & max 306 * same to the same value ... (grrrr) 307 */ 308 if (pump_min == pump_max || pump_min == 0 || pump_max == 0xffff) { 309 pump_min = CPU_PUMP_OUTPUT_MIN; 310 pump_max = CPU_PUMP_OUTPUT_MAX; 311 } 312 313 fan->min = pump_min; 314 fan->max = pump_max; 315 316 DBG("wf_fcu: pump min/max for %s set to: [%d..%d] RPM\n", 317 fan->ctrl.name, pump_min, pump_max); 318 } 319 320 static void __devinit wf_fcu_get_rpmfan_minmax(struct wf_fcu_fan *fan) 321 { 322 struct wf_fcu_priv *pv = fan->fcu_priv; 323 const struct mpu_data *mpu0 = wf_get_mpu(0); 324 const struct mpu_data *mpu1 = wf_get_mpu(1); 325 326 /* Default */ 327 fan->min = 2400 >> pv->rpm_shift; 328 fan->max = 56000 >> pv->rpm_shift; 329 330 /* CPU fans have min/max in MPU */ 331 if (mpu0 && !strcmp(fan->ctrl.name, "cpu-front-fan-0")) { 332 fan->min = max(fan->min, (s32)mpu0->rminn_intake_fan); 333 fan->max = min(fan->max, (s32)mpu0->rmaxn_intake_fan); 334 goto bail; 335 } 336 if (mpu1 && !strcmp(fan->ctrl.name, "cpu-front-fan-1")) { 337 fan->min = max(fan->min, (s32)mpu1->rminn_intake_fan); 338 fan->max = min(fan->max, (s32)mpu1->rmaxn_intake_fan); 339 goto bail; 340 } 341 if (mpu0 && !strcmp(fan->ctrl.name, "cpu-rear-fan-0")) { 342 fan->min = max(fan->min, (s32)mpu0->rminn_exhaust_fan); 343 fan->max = min(fan->max, (s32)mpu0->rmaxn_exhaust_fan); 344 goto bail; 345 } 346 if (mpu1 && !strcmp(fan->ctrl.name, "cpu-rear-fan-1")) { 347 fan->min = max(fan->min, (s32)mpu1->rminn_exhaust_fan); 348 fan->max = min(fan->max, (s32)mpu1->rmaxn_exhaust_fan); 349 goto bail; 350 } 351 /* Rackmac variants, we just use mpu0 intake */ 352 if (!strncmp(fan->ctrl.name, "cpu-fan", 7)) { 353 fan->min = max(fan->min, (s32)mpu0->rminn_intake_fan); 354 fan->max = min(fan->max, (s32)mpu0->rmaxn_intake_fan); 355 goto bail; 356 } 357 bail: 358 DBG("wf_fcu: fan min/max for %s set to: [%d..%d] RPM\n", 359 fan->ctrl.name, fan->min, fan->max); 360 } 361 362 static void __devinit wf_fcu_add_fan(struct wf_fcu_priv *pv, 363 const char *name, 364 int type, int id) 365 { 366 struct wf_fcu_fan *fan; 367 368 fan = kzalloc(sizeof(*fan), GFP_KERNEL); 369 if (!fan) 370 return; 371 fan->fcu_priv = pv; 372 fan->id = id; 373 fan->ctrl.name = name; 374 fan->ctrl.priv = fan; 375 376 /* min/max is oddball but the code comes from 377 * therm_pm72 which seems to work so ... 378 */ 379 if (type == FCU_FAN_RPM) { 380 if (!strncmp(name, "cpu-pump", strlen("cpu-pump"))) 381 wf_fcu_get_pump_minmax(fan); 382 else 383 wf_fcu_get_rpmfan_minmax(fan); 384 fan->ctrl.type = WF_CONTROL_RPM_FAN; 385 fan->ctrl.ops = &wf_fcu_fan_rpm_ops; 386 } else { 387 fan->min = 10; 388 fan->max = 100; 389 fan->ctrl.type = WF_CONTROL_PWM_FAN; 390 fan->ctrl.ops = &wf_fcu_fan_pwm_ops; 391 } 392 393 if (wf_register_control(&fan->ctrl)) { 394 pr_err("wf_fcu: Failed to register fan %s\n", name); 395 kfree(fan); 396 return; 397 } 398 list_add(&fan->link, &pv->fan_list); 399 kref_get(&pv->ref); 400 } 401 402 static void __devinit wf_fcu_lookup_fans(struct wf_fcu_priv *pv) 403 { 404 /* Translation of device-tree location properties to 405 * windfarm fan names 406 */ 407 static const struct { 408 const char *dt_name; /* Device-tree name */ 409 const char *ct_name; /* Control name */ 410 } loc_trans[] = { 411 { "BACKSIDE", "backside-fan", }, 412 { "SYS CTRLR FAN", "backside-fan", }, 413 { "DRIVE BAY", "drive-bay-fan", }, 414 { "SLOT", "slots-fan", }, 415 { "PCI FAN", "slots-fan", }, 416 { "CPU A INTAKE", "cpu-front-fan-0", }, 417 { "CPU A EXHAUST", "cpu-rear-fan-0", }, 418 { "CPU B INTAKE", "cpu-front-fan-1", }, 419 { "CPU B EXHAUST", "cpu-rear-fan-1", }, 420 { "CPU A PUMP", "cpu-pump-0", }, 421 { "CPU B PUMP", "cpu-pump-1", }, 422 { "CPU A 1", "cpu-fan-a-0", }, 423 { "CPU A 2", "cpu-fan-b-0", }, 424 { "CPU A 3", "cpu-fan-c-0", }, 425 { "CPU B 1", "cpu-fan-a-1", }, 426 { "CPU B 2", "cpu-fan-b-1", }, 427 { "CPU B 3", "cpu-fan-c-1", }, 428 }; 429 struct device_node *np = NULL, *fcu = pv->i2c->dev.of_node; 430 int i; 431 432 DBG("Looking up FCU controls in device-tree...\n"); 433 434 while ((np = of_get_next_child(fcu, np)) != NULL) { 435 int id, type = -1; 436 const char *loc; 437 const char *name; 438 const u32 *reg; 439 440 DBG(" control: %s, type: %s\n", np->name, np->type); 441 442 /* Detect control type */ 443 if (!strcmp(np->type, "fan-rpm-control") || 444 !strcmp(np->type, "fan-rpm")) 445 type = FCU_FAN_RPM; 446 if (!strcmp(np->type, "fan-pwm-control") || 447 !strcmp(np->type, "fan-pwm")) 448 type = FCU_FAN_PWM; 449 /* Only care about fans for now */ 450 if (type == -1) 451 continue; 452 453 /* Lookup for a matching location */ 454 loc = of_get_property(np, "location", NULL); 455 reg = of_get_property(np, "reg", NULL); 456 if (loc == NULL || reg == NULL) 457 continue; 458 DBG(" matching location: %s, reg: 0x%08x\n", loc, *reg); 459 460 for (i = 0; i < ARRAY_SIZE(loc_trans); i++) { 461 if (strncmp(loc, loc_trans[i].dt_name, 462 strlen(loc_trans[i].dt_name))) 463 continue; 464 name = loc_trans[i].ct_name; 465 466 DBG(" location match, name: %s\n", name); 467 468 if (type == FCU_FAN_RPM) 469 id = ((*reg) - 0x10) / 2; 470 else 471 id = ((*reg) - 0x30) / 2; 472 if (id > 7) { 473 pr_warning("wf_fcu: Can't parse " 474 "fan ID in device-tree for %s\n", 475 np->full_name); 476 break; 477 } 478 wf_fcu_add_fan(pv, name, type, id); 479 break; 480 } 481 } 482 } 483 484 static void __devinit wf_fcu_default_fans(struct wf_fcu_priv *pv) 485 { 486 /* We only support the default fans for PowerMac7,2 */ 487 if (!of_machine_is_compatible("PowerMac7,2")) 488 return; 489 490 wf_fcu_add_fan(pv, "backside-fan", FCU_FAN_PWM, 1); 491 wf_fcu_add_fan(pv, "drive-bay-fan", FCU_FAN_RPM, 2); 492 wf_fcu_add_fan(pv, "slots-fan", FCU_FAN_PWM, 2); 493 wf_fcu_add_fan(pv, "cpu-front-fan-0", FCU_FAN_RPM, 3); 494 wf_fcu_add_fan(pv, "cpu-rear-fan-0", FCU_FAN_RPM, 4); 495 wf_fcu_add_fan(pv, "cpu-front-fan-1", FCU_FAN_RPM, 5); 496 wf_fcu_add_fan(pv, "cpu-rear-fan-1", FCU_FAN_RPM, 6); 497 } 498 499 static int __devinit wf_fcu_init_chip(struct wf_fcu_priv *pv) 500 { 501 unsigned char buf = 0xff; 502 int rc; 503 504 rc = wf_fcu_write_reg(pv, 0xe, &buf, 1); 505 if (rc < 0) 506 return -EIO; 507 rc = wf_fcu_write_reg(pv, 0x2e, &buf, 1); 508 if (rc < 0) 509 return -EIO; 510 rc = wf_fcu_read_reg(pv, 0, &buf, 1); 511 if (rc < 0) 512 return -EIO; 513 pv->rpm_shift = (buf == 1) ? 2 : 3; 514 515 pr_debug("wf_fcu: FCU Initialized, RPM fan shift is %d\n", 516 pv->rpm_shift); 517 518 return 0; 519 } 520 521 static int __devinit wf_fcu_probe(struct i2c_client *client, 522 const struct i2c_device_id *id) 523 { 524 struct wf_fcu_priv *pv; 525 526 pv = kzalloc(sizeof(*pv), GFP_KERNEL); 527 if (!pv) 528 return -ENOMEM; 529 530 kref_init(&pv->ref); 531 mutex_init(&pv->lock); 532 INIT_LIST_HEAD(&pv->fan_list); 533 pv->i2c = client; 534 535 /* 536 * First we must start the FCU which will query the 537 * shift value to apply to RPMs 538 */ 539 if (wf_fcu_init_chip(pv)) { 540 pr_err("wf_fcu: Initialization failed !\n"); 541 kfree(pv); 542 return -ENXIO; 543 } 544 545 /* First lookup fans in the device-tree */ 546 wf_fcu_lookup_fans(pv); 547 548 /* 549 * Older machines don't have the device-tree entries 550 * we are looking for, just hard code the list 551 */ 552 if (list_empty(&pv->fan_list)) 553 wf_fcu_default_fans(pv); 554 555 /* Still no fans ? FAIL */ 556 if (list_empty(&pv->fan_list)) { 557 pr_err("wf_fcu: Failed to find fans for your machine\n"); 558 kfree(pv); 559 return -ENODEV; 560 } 561 562 dev_set_drvdata(&client->dev, pv); 563 564 return 0; 565 } 566 567 static int __devexit wf_fcu_remove(struct i2c_client *client) 568 { 569 struct wf_fcu_priv *pv = dev_get_drvdata(&client->dev); 570 struct wf_fcu_fan *fan; 571 572 while (!list_empty(&pv->fan_list)) { 573 fan = list_first_entry(&pv->fan_list, struct wf_fcu_fan, link); 574 list_del(&fan->link); 575 wf_unregister_control(&fan->ctrl); 576 } 577 kref_put(&pv->ref, wf_fcu_release); 578 return 0; 579 } 580 581 static const struct i2c_device_id wf_fcu_id[] = { 582 { "MAC,fcu", 0 }, 583 { } 584 }; 585 MODULE_DEVICE_TABLE(i2c, wf_fcu_id); 586 587 static struct i2c_driver wf_fcu_driver = { 588 .driver = { 589 .name = "wf_fcu", 590 }, 591 .probe = wf_fcu_probe, 592 .remove = wf_fcu_remove, 593 .id_table = wf_fcu_id, 594 }; 595 596 static int __init wf_fcu_init(void) 597 { 598 return i2c_add_driver(&wf_fcu_driver); 599 } 600 601 static void __exit wf_fcu_exit(void) 602 { 603 i2c_del_driver(&wf_fcu_driver); 604 } 605 606 607 module_init(wf_fcu_init); 608 module_exit(wf_fcu_exit); 609 610 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); 611 MODULE_DESCRIPTION("FCU control objects for PowerMacs thermal control"); 612 MODULE_LICENSE("GPL"); 613 614