diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 3 |
6 files changed, 77 insertions, 23 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 7e3d96e7ac04..12d2fdc52414 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -140,11 +140,17 @@ void evergreen_pm_misc(struct radeon_device *rdev) | |||
140 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | 140 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; |
141 | 141 | ||
142 | if (voltage->type == VOLTAGE_SW) { | 142 | if (voltage->type == VOLTAGE_SW) { |
143 | /* 0xff01 is a flag rather then an actual voltage */ | ||
144 | if (voltage->voltage == 0xff01) | ||
145 | return; | ||
143 | if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { | 146 | if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { |
144 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); | 147 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
145 | rdev->pm.current_vddc = voltage->voltage; | 148 | rdev->pm.current_vddc = voltage->voltage; |
146 | DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); | 149 | DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); |
147 | } | 150 | } |
151 | /* 0xff01 is a flag rather then an actual voltage */ | ||
152 | if (voltage->vddci == 0xff01) | ||
153 | return; | ||
148 | if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { | 154 | if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { |
149 | radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); | 155 | radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); |
150 | rdev->pm.current_vddci = voltage->vddci; | 156 | rdev->pm.current_vddci = voltage->vddci; |
@@ -2007,9 +2013,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
2007 | rdev->config.evergreen.tile_config |= (3 << 0); | 2013 | rdev->config.evergreen.tile_config |= (3 << 0); |
2008 | break; | 2014 | break; |
2009 | } | 2015 | } |
2010 | /* num banks is 8 on all fusion asics */ | 2016 | /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ |
2011 | if (rdev->flags & RADEON_IS_IGP) | 2017 | if (rdev->flags & RADEON_IS_IGP) |
2012 | rdev->config.evergreen.tile_config |= 8 << 4; | 2018 | rdev->config.evergreen.tile_config |= 1 << 4; |
2013 | else | 2019 | else |
2014 | rdev->config.evergreen.tile_config |= | 2020 | rdev->config.evergreen.tile_config |= |
2015 | ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; | 2021 | ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; |
@@ -2695,28 +2701,25 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) | |||
2695 | 2701 | ||
2696 | int evergreen_irq_process(struct radeon_device *rdev) | 2702 | int evergreen_irq_process(struct radeon_device *rdev) |
2697 | { | 2703 | { |
2698 | u32 wptr = evergreen_get_ih_wptr(rdev); | 2704 | u32 wptr; |
2699 | u32 rptr = rdev->ih.rptr; | 2705 | u32 rptr; |
2700 | u32 src_id, src_data; | 2706 | u32 src_id, src_data; |
2701 | u32 ring_index; | 2707 | u32 ring_index; |
2702 | unsigned long flags; | 2708 | unsigned long flags; |
2703 | bool queue_hotplug = false; | 2709 | bool queue_hotplug = false; |
2704 | 2710 | ||
2705 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 2711 | if (!rdev->ih.enabled || rdev->shutdown) |
2706 | if (!rdev->ih.enabled) | ||
2707 | return IRQ_NONE; | 2712 | return IRQ_NONE; |
2708 | 2713 | ||
2709 | spin_lock_irqsave(&rdev->ih.lock, flags); | 2714 | wptr = evergreen_get_ih_wptr(rdev); |
2715 | rptr = rdev->ih.rptr; | ||
2716 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
2710 | 2717 | ||
2718 | spin_lock_irqsave(&rdev->ih.lock, flags); | ||
2711 | if (rptr == wptr) { | 2719 | if (rptr == wptr) { |
2712 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 2720 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
2713 | return IRQ_NONE; | 2721 | return IRQ_NONE; |
2714 | } | 2722 | } |
2715 | if (rdev->shutdown) { | ||
2716 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2717 | return IRQ_NONE; | ||
2718 | } | ||
2719 | |||
2720 | restart_ih: | 2723 | restart_ih: |
2721 | /* display interrupts */ | 2724 | /* display interrupts */ |
2722 | evergreen_irq_ack(rdev); | 2725 | evergreen_irq_ack(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 7dd45ca64e29..f79d2ccb6755 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -590,6 +590,9 @@ void r600_pm_misc(struct radeon_device *rdev) | |||
590 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | 590 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; |
591 | 591 | ||
592 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 592 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { |
593 | /* 0xff01 is a flag rather then an actual voltage */ | ||
594 | if (voltage->voltage == 0xff01) | ||
595 | return; | ||
593 | if (voltage->voltage != rdev->pm.current_vddc) { | 596 | if (voltage->voltage != rdev->pm.current_vddc) { |
594 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); | 597 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
595 | rdev->pm.current_vddc = voltage->voltage; | 598 | rdev->pm.current_vddc = voltage->voltage; |
@@ -3294,27 +3297,26 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
3294 | 3297 | ||
3295 | int r600_irq_process(struct radeon_device *rdev) | 3298 | int r600_irq_process(struct radeon_device *rdev) |
3296 | { | 3299 | { |
3297 | u32 wptr = r600_get_ih_wptr(rdev); | 3300 | u32 wptr; |
3298 | u32 rptr = rdev->ih.rptr; | 3301 | u32 rptr; |
3299 | u32 src_id, src_data; | 3302 | u32 src_id, src_data; |
3300 | u32 ring_index; | 3303 | u32 ring_index; |
3301 | unsigned long flags; | 3304 | unsigned long flags; |
3302 | bool queue_hotplug = false; | 3305 | bool queue_hotplug = false; |
3303 | 3306 | ||
3304 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | 3307 | if (!rdev->ih.enabled || rdev->shutdown) |
3305 | if (!rdev->ih.enabled) | ||
3306 | return IRQ_NONE; | 3308 | return IRQ_NONE; |
3307 | 3309 | ||
3310 | wptr = r600_get_ih_wptr(rdev); | ||
3311 | rptr = rdev->ih.rptr; | ||
3312 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
3313 | |||
3308 | spin_lock_irqsave(&rdev->ih.lock, flags); | 3314 | spin_lock_irqsave(&rdev->ih.lock, flags); |
3309 | 3315 | ||
3310 | if (rptr == wptr) { | 3316 | if (rptr == wptr) { |
3311 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3317 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
3312 | return IRQ_NONE; | 3318 | return IRQ_NONE; |
3313 | } | 3319 | } |
3314 | if (rdev->shutdown) { | ||
3315 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
3316 | return IRQ_NONE; | ||
3317 | } | ||
3318 | 3320 | ||
3319 | restart_ih: | 3321 | restart_ih: |
3320 | /* display interrupts */ | 3322 | /* display interrupts */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 27f45579e64b..ef0e0e016914 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -179,6 +179,7 @@ void radeon_pm_resume(struct radeon_device *rdev); | |||
179 | void radeon_combios_get_power_modes(struct radeon_device *rdev); | 179 | void radeon_combios_get_power_modes(struct radeon_device *rdev); |
180 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); | 180 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); |
181 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); | 181 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); |
182 | int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage); | ||
182 | void rs690_pm_info(struct radeon_device *rdev); | 183 | void rs690_pm_info(struct radeon_device *rdev); |
183 | extern int rv6xx_get_temp(struct radeon_device *rdev); | 184 | extern int rv6xx_get_temp(struct radeon_device *rdev); |
184 | extern int rv770_get_temp(struct radeon_device *rdev); | 185 | extern int rv770_get_temp(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index fa62a503ae70..bf2b61584cdb 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -2320,6 +2320,14 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2320 | le16_to_cpu(clock_info->r600.usVDDC); | 2320 | le16_to_cpu(clock_info->r600.usVDDC); |
2321 | } | 2321 | } |
2322 | 2322 | ||
2323 | /* patch up vddc if necessary */ | ||
2324 | if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) { | ||
2325 | u16 vddc; | ||
2326 | |||
2327 | if (radeon_atom_get_max_vddc(rdev, &vddc) == 0) | ||
2328 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; | ||
2329 | } | ||
2330 | |||
2323 | if (rdev->flags & RADEON_IS_IGP) { | 2331 | if (rdev->flags & RADEON_IS_IGP) { |
2324 | /* skip invalid modes */ | 2332 | /* skip invalid modes */ |
2325 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | 2333 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) |
@@ -2607,6 +2615,10 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v | |||
2607 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 2615 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
2608 | return; | 2616 | return; |
2609 | 2617 | ||
2618 | /* 0xff01 is a flag rather then an actual voltage */ | ||
2619 | if (voltage_level == 0xff01) | ||
2620 | return; | ||
2621 | |||
2610 | switch (crev) { | 2622 | switch (crev) { |
2611 | case 1: | 2623 | case 1: |
2612 | args.v1.ucVoltageType = voltage_type; | 2624 | args.v1.ucVoltageType = voltage_type; |
@@ -2626,7 +2638,35 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v | |||
2626 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 2638 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
2627 | } | 2639 | } |
2628 | 2640 | ||
2641 | int radeon_atom_get_max_vddc(struct radeon_device *rdev, | ||
2642 | u16 *voltage) | ||
2643 | { | ||
2644 | union set_voltage args; | ||
2645 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); | ||
2646 | u8 frev, crev; | ||
2647 | |||
2648 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
2649 | return -EINVAL; | ||
2650 | |||
2651 | switch (crev) { | ||
2652 | case 1: | ||
2653 | return -EINVAL; | ||
2654 | case 2: | ||
2655 | args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE; | ||
2656 | args.v2.ucVoltageMode = 0; | ||
2657 | args.v2.usVoltageLevel = 0; | ||
2658 | |||
2659 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
2629 | 2660 | ||
2661 | *voltage = le16_to_cpu(args.v2.usVoltageLevel); | ||
2662 | break; | ||
2663 | default: | ||
2664 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
2665 | return -EINVAL; | ||
2666 | } | ||
2667 | |||
2668 | return 0; | ||
2669 | } | ||
2630 | 2670 | ||
2631 | void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) | 2671 | void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) |
2632 | { | 2672 | { |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index f55b64cb59d1..b293487e5aa3 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -1090,9 +1090,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
1090 | break; | 1090 | break; |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | if (is_dp) | 1093 | if (is_dp) { |
1094 | args.v2.acConfig.fCoherentMode = 1; | 1094 | args.v2.acConfig.fCoherentMode = 1; |
1095 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 1095 | args.v2.acConfig.fDPConnector = 1; |
1096 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
1096 | if (dig->coherent_mode) | 1097 | if (dig->coherent_mode) |
1097 | args.v2.acConfig.fCoherentMode = 1; | 1098 | args.v2.acConfig.fCoherentMode = 1; |
1098 | if (radeon_encoder->pixel_clock > 165000) | 1099 | if (radeon_encoder->pixel_clock > 165000) |
@@ -1431,7 +1432,11 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1431 | if (is_dig) { | 1432 | if (is_dig) { |
1432 | switch (mode) { | 1433 | switch (mode) { |
1433 | case DRM_MODE_DPMS_ON: | 1434 | case DRM_MODE_DPMS_ON: |
1434 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1435 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
1436 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) | ||
1437 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1438 | else | ||
1439 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1435 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1440 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1436 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1441 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1437 | 1442 | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index ef8a5babe9f7..6f508ffd1035 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -105,6 +105,9 @@ void rv770_pm_misc(struct radeon_device *rdev) | |||
105 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | 105 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; |
106 | 106 | ||
107 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 107 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { |
108 | /* 0xff01 is a flag rather then an actual voltage */ | ||
109 | if (voltage->voltage == 0xff01) | ||
110 | return; | ||
108 | if (voltage->voltage != rdev->pm.current_vddc) { | 111 | if (voltage->voltage != rdev->pm.current_vddc) { |
109 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); | 112 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
110 | rdev->pm.current_vddc = voltage->voltage; | 113 | rdev->pm.current_vddc = voltage->voltage; |