Commit 7fd36c0b authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next-3.19' of git://people.freedesktop.org/~agd5f/linux into drm-next

Radeon patches for 3.19.  Christian has a number of GPUVM improvements
slated as well, but I'd like to wait until he gets back to work next week
to pull those in. Highlights of this pull:
- ttm performance improvements
- CI dpm fixes

* 'drm-next-3.19' of git://people.freedesktop.org/~agd5f/linux: (26 commits)
  drm/radeon/si/ci: make u8 static arrays constant
  drm/radeon: set power control in ci dpm enable
  drm/radeon: powertune fixes for hawaii
  drm/radeon: fix dpm mc init for certain hawaii boards
  drm/radeon: set bootup pcie level to max for ci dpm
  drm/radeon: fix default dpm state setup
  drm/radeon: workaround a hw bug in bonaire pcie dpm
  drm/radeon: fix mclk vddc configuration for cards for hawaii
  drm/radeon: fix sclk DS enablement
  drm/radeon: fix activity settings for sclk and mclk for CI
  drm/radeon: improve mclk param calcuations for ci dpm
  drm/radeon: fix dram timing for certain hawaii boards
  drm/radeon: switch force state commands for CI
  drm/radeon: fix for memory training on bonaire 0x6649
  drm/radeon/ci: handle gpio controlled dpm features properly
  drm/radeon: store the gpio shift as well
  drm/radeon: export radeon_atombios_lookup_gpio
  drm/radeon: fix typo in CI dpm disable
  drm/radeon: rework CI dpm thermal setup
  drm/radeon: rework SI dpm thermal setup
  ...
parents fcf93f69 c81b9942
This diff is collapsed.
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define CISLANDS_MAX_HARDWARE_POWERLEVELS 2 #define CISLANDS_MAX_HARDWARE_POWERLEVELS 2
#define CISLANDS_UNUSED_GPIO_PIN 0x7F
struct ci_pl { struct ci_pl {
u32 mclk; u32 mclk;
u32 sclk; u32 sclk;
......
...@@ -129,7 +129,7 @@ void ci_reset_smc(struct radeon_device *rdev) ...@@ -129,7 +129,7 @@ void ci_reset_smc(struct radeon_device *rdev)
int ci_program_jump_on_start(struct radeon_device *rdev) int ci_program_jump_on_start(struct radeon_device *rdev)
{ {
static u8 data[] = { 0xE0, 0x00, 0x80, 0x40 }; static const u8 data[] = { 0xE0, 0x00, 0x80, 0x40 };
return ci_copy_bytes_to_smc(rdev, 0x0, data, 4, sizeof(data)+1); return ci_copy_bytes_to_smc(rdev, 0x0, data, 4, sizeof(data)+1);
} }
......
...@@ -1806,7 +1806,7 @@ int ci_mc_load_microcode(struct radeon_device *rdev) ...@@ -1806,7 +1806,7 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
{ {
const __be32 *fw_data = NULL; const __be32 *fw_data = NULL;
const __le32 *new_fw_data = NULL; const __le32 *new_fw_data = NULL;
u32 running, blackout = 0; u32 running, blackout = 0, tmp;
u32 *io_mc_regs = NULL; u32 *io_mc_regs = NULL;
const __le32 *new_io_mc_regs = NULL; const __le32 *new_io_mc_regs = NULL;
int i, regs_size, ucode_size; int i, regs_size, ucode_size;
...@@ -1866,6 +1866,15 @@ int ci_mc_load_microcode(struct radeon_device *rdev) ...@@ -1866,6 +1866,15 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
} }
} }
tmp = RREG32(MC_SEQ_MISC0);
if ((rdev->pdev->device == 0x6649) && ((tmp & 0xff00) == 0x5600)) {
WREG32(MC_SEQ_IO_DEBUG_INDEX, 5);
WREG32(MC_SEQ_IO_DEBUG_DATA, 0x00000023);
WREG32(MC_SEQ_IO_DEBUG_INDEX, 9);
WREG32(MC_SEQ_IO_DEBUG_DATA, 0x000001f0);
}
/* load the MC ucode */ /* load the MC ucode */
for (i = 0; i < ucode_size; i++) { for (i = 0; i < ucode_size; i++) {
if (rdev->new_fw) if (rdev->new_fw)
......
...@@ -106,6 +106,7 @@ typedef uint8_t PPSMC_Result; ...@@ -106,6 +106,7 @@ typedef uint8_t PPSMC_Result;
#define PPSMC_MSG_SAMUDPM_SetEnabledMask ((uint16_t) 0x130) #define PPSMC_MSG_SAMUDPM_SetEnabledMask ((uint16_t) 0x130)
#define PPSMC_MSG_MCLKDPM_ForceState ((uint16_t) 0x131) #define PPSMC_MSG_MCLKDPM_ForceState ((uint16_t) 0x131)
#define PPSMC_MSG_MCLKDPM_NoForcedLevel ((uint16_t) 0x132) #define PPSMC_MSG_MCLKDPM_NoForcedLevel ((uint16_t) 0x132)
#define PPSMC_MSG_Thermal_Cntl_Disable ((uint16_t) 0x133)
#define PPSMC_MSG_Voltage_Cntl_Disable ((uint16_t) 0x135) #define PPSMC_MSG_Voltage_Cntl_Disable ((uint16_t) 0x135)
#define PPSMC_MSG_PCIeDPM_Enable ((uint16_t) 0x136) #define PPSMC_MSG_PCIeDPM_Enable ((uint16_t) 0x136)
#define PPSMC_MSG_PCIeDPM_Disable ((uint16_t) 0x13d) #define PPSMC_MSG_PCIeDPM_Disable ((uint16_t) 0x13d)
...@@ -157,10 +158,11 @@ typedef uint8_t PPSMC_Result; ...@@ -157,10 +158,11 @@ typedef uint8_t PPSMC_Result;
#define PPSMC_MSG_DPM_Config ((uint32_t) 0x102) #define PPSMC_MSG_DPM_Config ((uint32_t) 0x102)
#define PPSMC_MSG_DPM_ForceState ((uint32_t) 0x104) #define PPSMC_MSG_DPM_ForceState ((uint32_t) 0x104)
#define PPSMC_MSG_PG_SIMD_Config ((uint32_t) 0x108) #define PPSMC_MSG_PG_SIMD_Config ((uint32_t) 0x108)
#define PPSMC_MSG_DPM_N_LevelsDisabled ((uint32_t) 0x112) #define PPSMC_MSG_Thermal_Cntl_Enable ((uint32_t) 0x10a)
#define PPSMC_MSG_Voltage_Cntl_Enable ((uint32_t) 0x109) #define PPSMC_MSG_Voltage_Cntl_Enable ((uint32_t) 0x109)
#define PPSMC_MSG_VCEPowerOFF ((uint32_t) 0x10e) #define PPSMC_MSG_VCEPowerOFF ((uint32_t) 0x10e)
#define PPSMC_MSG_VCEPowerON ((uint32_t) 0x10f) #define PPSMC_MSG_VCEPowerON ((uint32_t) 0x10f)
#define PPSMC_MSG_DPM_N_LevelsDisabled ((uint32_t) 0x112)
#define PPSMC_MSG_DCE_RemoveVoltageAdjustment ((uint32_t) 0x11d) #define PPSMC_MSG_DCE_RemoveVoltageAdjustment ((uint32_t) 0x11d)
#define PPSMC_MSG_DCE_AllowVoltageAdjustment ((uint32_t) 0x11e) #define PPSMC_MSG_DCE_AllowVoltageAdjustment ((uint32_t) 0x11e)
#define PPSMC_MSG_EnableBAPM ((uint32_t) 0x120) #define PPSMC_MSG_EnableBAPM ((uint32_t) 0x120)
......
...@@ -474,7 +474,7 @@ struct radeon_bo { ...@@ -474,7 +474,7 @@ struct radeon_bo {
struct list_head list; struct list_head list;
/* Protected by tbo.reserved */ /* Protected by tbo.reserved */
u32 initial_domain; u32 initial_domain;
struct ttm_place placements[3]; struct ttm_place placements[4];
struct ttm_placement placement; struct ttm_placement placement;
struct ttm_buffer_object tbo; struct ttm_buffer_object tbo;
struct ttm_bo_kmap_obj kmap; struct ttm_bo_kmap_obj kmap;
...@@ -1623,6 +1623,11 @@ struct radeon_pm { ...@@ -1623,6 +1623,11 @@ struct radeon_pm {
/* internal thermal controller on rv6xx+ */ /* internal thermal controller on rv6xx+ */
enum radeon_int_thermal_type int_thermal_type; enum radeon_int_thermal_type int_thermal_type;
struct device *int_hwmon_dev; struct device *int_hwmon_dev;
/* fan control parameters */
bool no_fan;
u8 fan_pulses_per_revolution;
u8 fan_min_rpm;
u8 fan_max_rpm;
/* dpm */ /* dpm */
bool dpm_enabled; bool dpm_enabled;
struct radeon_dpm dpm; struct radeon_dpm dpm;
......
...@@ -196,8 +196,8 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) ...@@ -196,8 +196,8 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
} }
} }
static struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, struct radeon_gpio_rec radeon_atombios_lookup_gpio(struct radeon_device *rdev,
u8 id) u8 id)
{ {
struct atom_context *ctx = rdev->mode_info.atom_context; struct atom_context *ctx = rdev->mode_info.atom_context;
struct radeon_gpio_rec gpio; struct radeon_gpio_rec gpio;
...@@ -221,6 +221,7 @@ static struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, ...@@ -221,6 +221,7 @@ static struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev,
if (id == pin->ucGPIO_ID) { if (id == pin->ucGPIO_ID) {
gpio.id = pin->ucGPIO_ID; gpio.id = pin->ucGPIO_ID;
gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4; gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4;
gpio.shift = pin->ucGpioPinBitShift;
gpio.mask = (1 << pin->ucGpioPinBitShift); gpio.mask = (1 << pin->ucGpioPinBitShift);
gpio.valid = true; gpio.valid = true;
break; break;
...@@ -801,7 +802,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ...@@ -801,7 +802,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
hpd_record = hpd_record =
(ATOM_HPD_INT_RECORD *) (ATOM_HPD_INT_RECORD *)
record; record;
gpio = radeon_lookup_gpio(rdev, gpio = radeon_atombios_lookup_gpio(rdev,
hpd_record->ucHPDIntGPIOID); hpd_record->ucHPDIntGPIOID);
hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
hpd.plugged_state = hpd_record->ucPlugged_PinState; hpd.plugged_state = hpd_record->ucPlugged_PinState;
...@@ -2128,7 +2129,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) ...@@ -2128,7 +2129,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
rdev->pm.power_state[state_index].clock_info[0].voltage.type = rdev->pm.power_state[state_index].clock_info[0].voltage.type =
VOLTAGE_GPIO; VOLTAGE_GPIO;
rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
radeon_lookup_gpio(rdev, radeon_atombios_lookup_gpio(rdev,
power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex);
if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
...@@ -2164,7 +2165,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) ...@@ -2164,7 +2165,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
rdev->pm.power_state[state_index].clock_info[0].voltage.type = rdev->pm.power_state[state_index].clock_info[0].voltage.type =
VOLTAGE_GPIO; VOLTAGE_GPIO;
rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
radeon_lookup_gpio(rdev, radeon_atombios_lookup_gpio(rdev,
power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex);
if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
...@@ -2200,7 +2201,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) ...@@ -2200,7 +2201,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
rdev->pm.power_state[state_index].clock_info[0].voltage.type = rdev->pm.power_state[state_index].clock_info[0].voltage.type =
VOLTAGE_GPIO; VOLTAGE_GPIO;
rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = rdev->pm.power_state[state_index].clock_info[0].voltage.gpio =
radeon_lookup_gpio(rdev, radeon_atombios_lookup_gpio(rdev,
power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex);
if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)
rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
...@@ -2248,6 +2249,14 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r ...@@ -2248,6 +2249,14 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
/* add the i2c bus for thermal/fan chip */ /* add the i2c bus for thermal/fan chip */
if (controller->ucType > 0) { if (controller->ucType > 0) {
if (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN)
rdev->pm.no_fan = true;
rdev->pm.fan_pulses_per_revolution =
controller->ucFanParameters & ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
if (rdev->pm.fan_pulses_per_revolution) {
rdev->pm.fan_min_rpm = controller->ucFanMinRPM;
rdev->pm.fan_max_rpm = controller->ucFanMaxRPM;
}
if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
DRM_INFO("Internal thermal controller %s fan control\n", DRM_INFO("Internal thermal controller %s fan control\n",
(controller->ucFanParameters & (controller->ucFanParameters &
......
...@@ -462,6 +462,7 @@ struct radeon_gpio_rec { ...@@ -462,6 +462,7 @@ struct radeon_gpio_rec {
u8 id; u8 id;
u32 reg; u32 reg;
u32 mask; u32 mask;
u32 shift;
}; };
struct radeon_hpd { struct radeon_hpd {
...@@ -748,6 +749,8 @@ extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, ...@@ -748,6 +749,8 @@ extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev,
extern bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, extern bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
struct radeon_atom_ss *ss, struct radeon_atom_ss *ss,
int id, u32 clock); int id, u32 clock);
extern struct radeon_gpio_rec radeon_atombios_lookup_gpio(struct radeon_device *rdev,
u8 id);
extern void radeon_compute_pll_legacy(struct radeon_pll *pll, extern void radeon_compute_pll_legacy(struct radeon_pll *pll,
uint64_t freq, uint64_t freq,
......
...@@ -99,22 +99,39 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) ...@@ -99,22 +99,39 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
rbo->placement.placement = rbo->placements; rbo->placement.placement = rbo->placements;
rbo->placement.busy_placement = rbo->placements; rbo->placement.busy_placement = rbo->placements;
if (domain & RADEON_GEM_DOMAIN_VRAM) if (domain & RADEON_GEM_DOMAIN_VRAM) {
/* Try placing BOs which don't need CPU access outside of the
* CPU accessible part of VRAM
*/
if ((rbo->flags & RADEON_GEM_NO_CPU_ACCESS) &&
rbo->rdev->mc.visible_vram_size < rbo->rdev->mc.real_vram_size) {
rbo->placements[c].fpfn =
rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
rbo->placements[c++].flags = TTM_PL_FLAG_WC |
TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_VRAM;
}
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_FLAG_WC | rbo->placements[c++].flags = TTM_PL_FLAG_WC |
TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_VRAM; TTM_PL_FLAG_VRAM;
}
if (domain & RADEON_GEM_DOMAIN_GTT) { if (domain & RADEON_GEM_DOMAIN_GTT) {
if (rbo->flags & RADEON_GEM_GTT_UC) { if (rbo->flags & RADEON_GEM_GTT_UC) {
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_TT; TTM_PL_FLAG_TT;
} else if ((rbo->flags & RADEON_GEM_GTT_WC) || } else if ((rbo->flags & RADEON_GEM_GTT_WC) ||
(rbo->rdev->flags & RADEON_IS_AGP)) { (rbo->rdev->flags & RADEON_IS_AGP)) {
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_FLAG_WC | rbo->placements[c++].flags = TTM_PL_FLAG_WC |
TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_TT; TTM_PL_FLAG_TT;
} else { } else {
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_FLAG_CACHED | rbo->placements[c++].flags = TTM_PL_FLAG_CACHED |
TTM_PL_FLAG_TT; TTM_PL_FLAG_TT;
} }
...@@ -122,30 +139,35 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) ...@@ -122,30 +139,35 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
if (domain & RADEON_GEM_DOMAIN_CPU) { if (domain & RADEON_GEM_DOMAIN_CPU) {
if (rbo->flags & RADEON_GEM_GTT_UC) { if (rbo->flags & RADEON_GEM_GTT_UC) {
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED | rbo->placements[c++].flags = TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_SYSTEM; TTM_PL_FLAG_SYSTEM;
} else if ((rbo->flags & RADEON_GEM_GTT_WC) || } else if ((rbo->flags & RADEON_GEM_GTT_WC) ||
rbo->rdev->flags & RADEON_IS_AGP) { rbo->rdev->flags & RADEON_IS_AGP) {
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_FLAG_WC | rbo->placements[c++].flags = TTM_PL_FLAG_WC |
TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_SYSTEM; TTM_PL_FLAG_SYSTEM;
} else { } else {
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_FLAG_CACHED | rbo->placements[c++].flags = TTM_PL_FLAG_CACHED |
TTM_PL_FLAG_SYSTEM; TTM_PL_FLAG_SYSTEM;
} }
} }
if (!c) if (!c) {
rbo->placements[c].fpfn = 0;
rbo->placements[c++].flags = TTM_PL_MASK_CACHING | rbo->placements[c++].flags = TTM_PL_MASK_CACHING |
TTM_PL_FLAG_SYSTEM; TTM_PL_FLAG_SYSTEM;
}
rbo->placement.num_placement = c; rbo->placement.num_placement = c;
rbo->placement.num_busy_placement = c; rbo->placement.num_busy_placement = c;
for (i = 0; i < c; ++i) { for (i = 0; i < c; ++i) {
rbo->placements[i].fpfn = 0;
if ((rbo->flags & RADEON_GEM_CPU_ACCESS) && if ((rbo->flags & RADEON_GEM_CPU_ACCESS) &&
(rbo->placements[i].flags & TTM_PL_FLAG_VRAM)) (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
!rbo->placements[i].fpfn)
rbo->placements[i].lpfn = rbo->placements[i].lpfn =
rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT; rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
else else
...@@ -157,9 +179,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) ...@@ -157,9 +179,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
* improve fragmentation quality. * improve fragmentation quality.
* 512kb was measured as the most optimal number. * 512kb was measured as the most optimal number.
*/ */
if (!((rbo->flags & RADEON_GEM_CPU_ACCESS) && if (rbo->tbo.mem.size > 512 * 1024) {
(rbo->placements[i].flags & TTM_PL_FLAG_VRAM)) &&
rbo->tbo.mem.size > 512 * 1024) {
for (i = 0; i < c; i++) { for (i = 0; i < c; i++) {
rbo->placements[i].flags |= TTM_PL_FLAG_TOPDOWN; rbo->placements[i].flags |= TTM_PL_FLAG_TOPDOWN;
} }
...@@ -743,8 +763,8 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) ...@@ -743,8 +763,8 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
{ {
struct radeon_device *rdev; struct radeon_device *rdev;
struct radeon_bo *rbo; struct radeon_bo *rbo;
unsigned long offset, size; unsigned long offset, size, lpfn;
int r; int i, r;
if (!radeon_ttm_bo_is_radeon_bo(bo)) if (!radeon_ttm_bo_is_radeon_bo(bo))
return 0; return 0;
...@@ -761,7 +781,13 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) ...@@ -761,7 +781,13 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
/* hurrah the memory is not visible ! */ /* hurrah the memory is not visible ! */
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM); radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM);
rbo->placements[0].lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT; lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT;
for (i = 0; i < rbo->placement.num_placement; i++) {
/* Force into visible VRAM */
if ((rbo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
(!rbo->placements[i].lpfn || rbo->placements[i].lpfn > lpfn))
rbo->placements[i].lpfn = lpfn;
}
r = ttm_bo_validate(bo, &rbo->placement, false, false); r = ttm_bo_validate(bo, &rbo->placement, false, false);
if (unlikely(r == -ENOMEM)) { if (unlikely(r == -ENOMEM)) {
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
......
...@@ -198,7 +198,30 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, ...@@ -198,7 +198,30 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo,
case TTM_PL_VRAM: case TTM_PL_VRAM:
if (rbo->rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready == false) if (rbo->rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready == false)
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
else else if (rbo->rdev->mc.visible_vram_size < rbo->rdev->mc.real_vram_size &&
bo->mem.start < (rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT)) {
unsigned fpfn = rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT;
int i;
/* Try evicting to the CPU inaccessible part of VRAM
* first, but only set GTT as busy placement, so this
* BO will be evicted to GTT rather than causing other
* BOs to be evicted from VRAM
*/
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM |
RADEON_GEM_DOMAIN_GTT);
rbo->placement.num_busy_placement = 0;
for (i = 0; i < rbo->placement.num_placement; i++) {
if (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) {
if (rbo->placements[0].fpfn < fpfn)
rbo->placements[0].fpfn = fpfn;
} else {
rbo->placement.busy_placement =
&rbo->placements[i];
rbo->placement.num_busy_placement = 1;
}
}
} else
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
break; break;
case TTM_PL_TT: case TTM_PL_TT:
......
...@@ -5817,8 +5817,33 @@ void si_dpm_setup_asic(struct radeon_device *rdev) ...@@ -5817,8 +5817,33 @@ void si_dpm_setup_asic(struct radeon_device *rdev)
si_enable_acpi_power_management(rdev); si_enable_acpi_power_management(rdev);
} }
static int si_set_thermal_temperature_range(struct radeon_device *rdev, static int si_thermal_enable_alert(struct radeon_device *rdev,
int min_temp, int max_temp) bool enable)
{
u32 thermal_int = RREG32(CG_THERMAL_INT);
if (enable) {
PPSMC_Result result;
thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
rdev->irq.dpm_thermal = true;
result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
if (result != PPSMC_Result_OK) {
DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
return -EINVAL;
}
} else {
thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
rdev->irq.dpm_thermal = false;
}
WREG32(CG_THERMAL_INT, thermal_int);
return 0;
}
static int si_thermal_set_temperature_range(struct radeon_device *rdev,
int min_temp, int max_temp)
{ {
int low_temp = 0 * 1000; int low_temp = 0 * 1000;
int high_temp = 255 * 1000; int high_temp = 255 * 1000;
...@@ -5959,26 +5984,32 @@ int si_dpm_enable(struct radeon_device *rdev) ...@@ -5959,26 +5984,32 @@ int si_dpm_enable(struct radeon_device *rdev)
return 0; return 0;
} }
int si_dpm_late_enable(struct radeon_device *rdev) static int si_set_temperature_range(struct radeon_device *rdev)
{ {
int ret; int ret;
if (rdev->irq.installed && ret = si_thermal_enable_alert(rdev, false);
r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { if (ret)
PPSMC_Result result; return ret;
ret = si_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
if (ret)
return ret;
ret = si_thermal_enable_alert(rdev, true);
if (ret)
return ret;
ret = si_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); return ret;
if (ret) }
return ret;
rdev->irq.dpm_thermal = true;
radeon_irq_set(rdev);
result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
if (result != PPSMC_Result_OK) int si_dpm_late_enable(struct radeon_device *rdev)
DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); {
} int ret;
return 0; ret = si_set_temperature_range(rdev);
if (ret)
return ret;
return ret;
} }
void si_dpm_disable(struct radeon_device *rdev) void si_dpm_disable(struct radeon_device *rdev)
......
...@@ -135,7 +135,7 @@ void si_reset_smc(struct radeon_device *rdev) ...@@ -135,7 +135,7 @@ void si_reset_smc(struct radeon_device *rdev)
int si_program_jump_on_start(struct radeon_device *rdev) int si_program_jump_on_start(struct radeon_device *rdev)
{ {
static u8 data[] = { 0x0E, 0x00, 0x40, 0x40 }; static const u8 data[] = { 0x0E, 0x00, 0x40, 0x40 };
return si_copy_bytes_to_smc(rdev, 0x0, data, 4, sizeof(data)+1); return si_copy_bytes_to_smc(rdev, 0x0, data, 4, sizeof(data)+1);
} }
......
...@@ -55,6 +55,7 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, ...@@ -55,6 +55,7 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
struct drm_mm *mm = &rman->mm; struct drm_mm *mm = &rman->mm;
struct drm_mm_node *node = NULL; struct drm_mm_node *node = NULL;
enum drm_mm_search_flags sflags = DRM_MM_SEARCH_BEST;
enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT; enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT;
unsigned long lpfn; unsigned long lpfn;
int ret; int ret;
...@@ -67,15 +68,16 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, ...@@ -67,15 +68,16 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
if (!node) if (!node)
return -ENOMEM; return -ENOMEM;
if (place->flags & TTM_PL_FLAG_TOPDOWN) if (place->flags & TTM_PL_FLAG_TOPDOWN) {
sflags = DRM_MM_SEARCH_BELOW;
aflags = DRM_MM_CREATE_TOP; aflags = DRM_MM_CREATE_TOP;
}
spin_lock(&rman->lock); spin_lock(&rman->lock);
ret = drm_mm_insert_node_in_range_generic(mm, node, mem->num_pages, ret = drm_mm_insert_node_in_range_generic(mm, node, mem->num_pages,
mem->page_alignment, 0, mem->page_alignment, 0,
place->fpfn, lpfn, place->fpfn, lpfn,
DRM_MM_SEARCH_BEST, sflags, aflags);
aflags);
spin_unlock(&rman->lock); spin_unlock(&rman->lock);
if (unlikely(ret)) { if (unlikely(ret)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment