aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2011-05-03 12:44:54 -0400
committerDave Airlie <airlied@redhat.com>2011-05-03 23:20:53 -0400
commit63f7d9828bf55cc8ee6f460830c5285fe06bef3e (patch)
tree4e9511554d25d898a0c721ea7c6ee3b73d8dd158
parentcb3c438ea4c0e638cba08bfaa8e2b64ffb8a6ce3 (diff)
drm/radeon/kms: add support for thermal chips on combios asics
Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 8caf546c8e92..089ab92ad084 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -2504,6 +2504,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
2504 return true; 2504 return true;
2505} 2505}
2506 2506
2507static const char *thermal_controller_names[] = {
2508 "NONE",
2509 "lm63",
2510 "adm1032",
2511};
2512
2507void radeon_combios_get_power_modes(struct radeon_device *rdev) 2513void radeon_combios_get_power_modes(struct radeon_device *rdev)
2508{ 2514{
2509 struct drm_device *dev = rdev->ddev; 2515 struct drm_device *dev = rdev->ddev;
@@ -2524,6 +2530,54 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)
2524 return; 2530 return;
2525 } 2531 }
2526 2532
2533 /* check for a thermal chip */
2534 offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
2535 if (offset) {
2536 u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0;
2537 struct radeon_i2c_bus_rec i2c_bus;
2538
2539 rev = RBIOS8(offset);
2540
2541 if (rev == 0) {
2542 thermal_controller = RBIOS8(offset + 3);
2543 gpio = RBIOS8(offset + 4) & 0x3f;
2544 i2c_addr = RBIOS8(offset + 5);
2545 } else if (rev == 1) {
2546 thermal_controller = RBIOS8(offset + 4);
2547 gpio = RBIOS8(offset + 5) & 0x3f;
2548 i2c_addr = RBIOS8(offset + 6);
2549 } else if (rev == 2) {
2550 thermal_controller = RBIOS8(offset + 4);
2551 gpio = RBIOS8(offset + 5) & 0x3f;
2552 i2c_addr = RBIOS8(offset + 6);
2553 clk_bit = RBIOS8(offset + 0xa);
2554 data_bit = RBIOS8(offset + 0xb);
2555 }
2556 if ((thermal_controller > 0) && (thermal_controller < 3)) {
2557 DRM_INFO("Possible %s thermal controller at 0x%02x\n",
2558 thermal_controller_names[thermal_controller],
2559 i2c_addr >> 1);
2560 if (gpio == DDC_LCD) {
2561 /* MM i2c */
2562 i2c_bus.valid = true;
2563 i2c_bus.hw_capable = true;
2564 i2c_bus.mm_i2c = true;
2565 i2c_bus.i2c_id = 0xa0;
2566 } else if (gpio == DDC_GPIO)
2567 i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit);
2568 else
2569 i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
2570 rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
2571 if (rdev->pm.i2c_bus) {
2572 struct i2c_board_info info = { };
2573 const char *name = thermal_controller_names[thermal_controller];
2574 info.addr = i2c_addr >> 1;
2575 strlcpy(info.type, name, sizeof(info.type));
2576 i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
2577 }
2578 }
2579 }
2580
2527 if (rdev->flags & RADEON_IS_MOBILITY) { 2581 if (rdev->flags & RADEON_IS_MOBILITY) {
2528 offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); 2582 offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
2529 if (offset) { 2583 if (offset) {