drm/radeon/kms/pm: add additional asic callbacks
- pm_misc() - handles voltage, pcie lanes, and other non clock related power mode settings. Currently disabled. Needs further debugging - pm_prepare() - disables crtc mem requests right now. All memory clients need to be disabled when changing memory clocks. This function can be expanded to include disabling fb access as well. - pm_finish() - enable active memory clients. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
58e21dff53
commit
49e02b7306
12 changed files with 441 additions and 0 deletions
|
@ -39,6 +39,47 @@
|
|||
static void evergreen_gpu_init(struct radeon_device *rdev);
|
||||
void evergreen_fini(struct radeon_device *rdev);
|
||||
|
||||
void evergreen_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void evergreen_pm_prepare(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *ddev = rdev->ddev;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
u32 tmp;
|
||||
|
||||
/* disable any active CRTCs */
|
||||
list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
|
||||
radeon_crtc = to_radeon_crtc(crtc);
|
||||
if (radeon_crtc->enabled) {
|
||||
tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset);
|
||||
tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void evergreen_pm_finish(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *ddev = rdev->ddev;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
u32 tmp;
|
||||
|
||||
/* enable any active CRTCs */
|
||||
list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
|
||||
radeon_crtc = to_radeon_crtc(crtc);
|
||||
if (radeon_crtc->enabled) {
|
||||
tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset);
|
||||
tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
|
||||
{
|
||||
bool connected = false;
|
||||
|
|
|
@ -166,6 +166,7 @@
|
|||
/* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */
|
||||
#define EVERGREEN_CRTC_CONTROL 0x6e70
|
||||
# define EVERGREEN_CRTC_MASTER_EN (1 << 0)
|
||||
# define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24)
|
||||
#define EVERGREEN_CRTC_STATUS 0x6e8c
|
||||
#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "rs100d.h"
|
||||
#include "rv200d.h"
|
||||
#include "rv250d.h"
|
||||
#include "atom.h"
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -200,6 +201,147 @@ void r100_set_power_state(struct radeon_device *rdev)
|
|||
DRM_INFO("GUI not idle!!!\n");
|
||||
}
|
||||
|
||||
void r100_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
#if 0
|
||||
int requested_index = rdev->pm.requested_power_state_index;
|
||||
struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
|
||||
struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
|
||||
u32 tmp, sclk_cntl, sclk_cntl2, sclk_more_cntl;
|
||||
|
||||
if ((voltage->type == VOLTAGE_GPIO) && (voltage->gpio.valid)) {
|
||||
if (ps->misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
|
||||
tmp = RREG32(voltage->gpio.reg);
|
||||
if (voltage->active_high)
|
||||
tmp |= voltage->gpio.mask;
|
||||
else
|
||||
tmp &= ~(voltage->gpio.mask);
|
||||
WREG32(voltage->gpio.reg, tmp);
|
||||
if (voltage->delay)
|
||||
udelay(voltage->delay);
|
||||
} else {
|
||||
tmp = RREG32(voltage->gpio.reg);
|
||||
if (voltage->active_high)
|
||||
tmp &= ~voltage->gpio.mask;
|
||||
else
|
||||
tmp |= voltage->gpio.mask;
|
||||
WREG32(voltage->gpio.reg, tmp);
|
||||
if (voltage->delay)
|
||||
udelay(voltage->delay);
|
||||
}
|
||||
}
|
||||
|
||||
sclk_cntl = RREG32_PLL(SCLK_CNTL);
|
||||
sclk_cntl2 = RREG32_PLL(SCLK_CNTL2);
|
||||
sclk_cntl2 &= ~REDUCED_SPEED_SCLK_SEL(3);
|
||||
sclk_more_cntl = RREG32_PLL(SCLK_MORE_CNTL);
|
||||
sclk_more_cntl &= ~VOLTAGE_DELAY_SEL(3);
|
||||
if (ps->misc & ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN) {
|
||||
sclk_more_cntl |= REDUCED_SPEED_SCLK_EN;
|
||||
if (ps->misc & ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE)
|
||||
sclk_cntl2 |= REDUCED_SPEED_SCLK_MODE;
|
||||
else
|
||||
sclk_cntl2 &= ~REDUCED_SPEED_SCLK_MODE;
|
||||
if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2)
|
||||
sclk_cntl2 |= REDUCED_SPEED_SCLK_SEL(0);
|
||||
else if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4)
|
||||
sclk_cntl2 |= REDUCED_SPEED_SCLK_SEL(2);
|
||||
} else
|
||||
sclk_more_cntl &= ~REDUCED_SPEED_SCLK_EN;
|
||||
|
||||
if (ps->misc & ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN) {
|
||||
sclk_more_cntl |= IO_CG_VOLTAGE_DROP;
|
||||
if (voltage->delay) {
|
||||
sclk_more_cntl |= VOLTAGE_DROP_SYNC;
|
||||
switch (voltage->delay) {
|
||||
case 33:
|
||||
sclk_more_cntl |= VOLTAGE_DELAY_SEL(0);
|
||||
break;
|
||||
case 66:
|
||||
sclk_more_cntl |= VOLTAGE_DELAY_SEL(1);
|
||||
break;
|
||||
case 99:
|
||||
sclk_more_cntl |= VOLTAGE_DELAY_SEL(2);
|
||||
break;
|
||||
case 132:
|
||||
sclk_more_cntl |= VOLTAGE_DELAY_SEL(3);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
sclk_more_cntl &= ~VOLTAGE_DROP_SYNC;
|
||||
} else
|
||||
sclk_more_cntl &= ~IO_CG_VOLTAGE_DROP;
|
||||
|
||||
if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN)
|
||||
sclk_cntl &= ~FORCE_HDP;
|
||||
else
|
||||
sclk_cntl |= FORCE_HDP;
|
||||
|
||||
WREG32_PLL(SCLK_CNTL, sclk_cntl);
|
||||
WREG32_PLL(SCLK_CNTL2, sclk_cntl2);
|
||||
WREG32_PLL(SCLK_MORE_CNTL, sclk_more_cntl);
|
||||
|
||||
/* set pcie lanes */
|
||||
if ((rdev->flags & RADEON_IS_PCIE) &&
|
||||
!(rdev->flags & RADEON_IS_IGP) &&
|
||||
rdev->asic->set_pcie_lanes &&
|
||||
(ps->pcie_lanes !=
|
||||
rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) {
|
||||
radeon_set_pcie_lanes(rdev,
|
||||
ps->pcie_lanes);
|
||||
DRM_INFO("Setting: p: %d\n", ps->pcie_lanes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void r100_pm_prepare(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *ddev = rdev->ddev;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
u32 tmp;
|
||||
|
||||
/* disable any active CRTCs */
|
||||
list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
|
||||
radeon_crtc = to_radeon_crtc(crtc);
|
||||
if (radeon_crtc->enabled) {
|
||||
if (radeon_crtc->crtc_id) {
|
||||
tmp = RREG32(RADEON_CRTC2_GEN_CNTL);
|
||||
tmp |= RADEON_CRTC2_DISP_REQ_EN_B;
|
||||
WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
|
||||
} else {
|
||||
tmp = RREG32(RADEON_CRTC_GEN_CNTL);
|
||||
tmp |= RADEON_CRTC_DISP_REQ_EN_B;
|
||||
WREG32(RADEON_CRTC_GEN_CNTL, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void r100_pm_finish(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *ddev = rdev->ddev;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
u32 tmp;
|
||||
|
||||
/* enable any active CRTCs */
|
||||
list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
|
||||
radeon_crtc = to_radeon_crtc(crtc);
|
||||
if (radeon_crtc->enabled) {
|
||||
if (radeon_crtc->crtc_id) {
|
||||
tmp = RREG32(RADEON_CRTC2_GEN_CNTL);
|
||||
tmp &= ~RADEON_CRTC2_DISP_REQ_EN_B;
|
||||
WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
|
||||
} else {
|
||||
tmp = RREG32(RADEON_CRTC_GEN_CNTL);
|
||||
tmp &= ~RADEON_CRTC_DISP_REQ_EN_B;
|
||||
WREG32(RADEON_CRTC_GEN_CNTL, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool r100_gui_idle(struct radeon_device *rdev)
|
||||
{
|
||||
if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)
|
||||
|
|
|
@ -838,5 +838,41 @@
|
|||
#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
|
||||
#define C_00000D_FORCE_RB 0xEFFFFFFF
|
||||
|
||||
/* PLL regs */
|
||||
#define SCLK_CNTL 0xd
|
||||
#define FORCE_HDP (1 << 17)
|
||||
#define CLK_PWRMGT_CNTL 0x14
|
||||
#define GLOBAL_PMAN_EN (1 << 10)
|
||||
#define DISP_PM (1 << 20)
|
||||
#define PLL_PWRMGT_CNTL 0x15
|
||||
#define MPLL_TURNOFF (1 << 0)
|
||||
#define SPLL_TURNOFF (1 << 1)
|
||||
#define PPLL_TURNOFF (1 << 2)
|
||||
#define P2PLL_TURNOFF (1 << 3)
|
||||
#define TVPLL_TURNOFF (1 << 4)
|
||||
#define MOBILE_SU (1 << 16)
|
||||
#define SU_SCLK_USE_BCLK (1 << 17)
|
||||
#define SCLK_CNTL2 0x1e
|
||||
#define REDUCED_SPEED_SCLK_MODE (1 << 16)
|
||||
#define REDUCED_SPEED_SCLK_SEL(x) ((x) << 17)
|
||||
#define MCLK_MISC 0x1f
|
||||
#define EN_MCLK_TRISTATE_IN_SUSPEND (1 << 18)
|
||||
#define SCLK_MORE_CNTL 0x35
|
||||
#define REDUCED_SPEED_SCLK_EN (1 << 16)
|
||||
#define IO_CG_VOLTAGE_DROP (1 << 17)
|
||||
#define VOLTAGE_DELAY_SEL(x) ((x) << 20)
|
||||
#define VOLTAGE_DROP_SYNC (1 << 19)
|
||||
|
||||
/* mmreg */
|
||||
#define DISP_PWR_MAN 0xd08
|
||||
#define DISP_D3_GRPH_RST (1 << 18)
|
||||
#define DISP_D3_SUBPIC_RST (1 << 19)
|
||||
#define DISP_D3_OV0_RST (1 << 20)
|
||||
#define DISP_D1D2_GRPH_RST (1 << 21)
|
||||
#define DISP_D1D2_SUBPIC_RST (1 << 22)
|
||||
#define DISP_D1D2_OV0_RST (1 << 23)
|
||||
#define DISP_DVO_ENABLE_RST (1 << 24)
|
||||
#define TV_ENABLE_RST (1 << 25)
|
||||
#define AUTO_PWRUP_EN (1 << 26)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -347,6 +347,7 @@
|
|||
|
||||
#define AVIVO_D1CRTC_CONTROL 0x6080
|
||||
# define AVIVO_CRTC_EN (1 << 0)
|
||||
# define AVIVO_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24)
|
||||
#define AVIVO_D1CRTC_BLANK_CONTROL 0x6084
|
||||
#define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088
|
||||
#define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c
|
||||
|
|
|
@ -304,6 +304,11 @@ void r600_set_power_state(struct radeon_device *rdev)
|
|||
DRM_INFO("GUI not idle!!!\n");
|
||||
}
|
||||
|
||||
void r600_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool r600_gui_idle(struct radeon_device *rdev)
|
||||
{
|
||||
if (RREG32(GRBM_STATUS) & GUI_ACTIVE)
|
||||
|
|
|
@ -815,6 +815,9 @@ struct radeon_asic {
|
|||
bool (*gui_idle)(struct radeon_device *rdev);
|
||||
void (*get_power_state)(struct radeon_device *rdev, enum radeon_pm_action action);
|
||||
void (*set_power_state)(struct radeon_device *rdev);
|
||||
void (*pm_misc)(struct radeon_device *rdev);
|
||||
void (*pm_prepare)(struct radeon_device *rdev);
|
||||
void (*pm_finish)(struct radeon_device *rdev);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -168,6 +168,9 @@ static struct radeon_asic r100_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &r100_pm_misc,
|
||||
.pm_prepare = &r100_pm_prepare,
|
||||
.pm_finish = &r100_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic r200_asic = {
|
||||
|
@ -209,6 +212,9 @@ static struct radeon_asic r200_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &r100_pm_misc,
|
||||
.pm_prepare = &r100_pm_prepare,
|
||||
.pm_finish = &r100_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic r300_asic = {
|
||||
|
@ -251,6 +257,9 @@ static struct radeon_asic r300_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &r100_pm_misc,
|
||||
.pm_prepare = &r100_pm_prepare,
|
||||
.pm_finish = &r100_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic r300_asic_pcie = {
|
||||
|
@ -292,6 +301,9 @@ static struct radeon_asic r300_asic_pcie = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &r100_pm_misc,
|
||||
.pm_prepare = &r100_pm_prepare,
|
||||
.pm_finish = &r100_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic r420_asic = {
|
||||
|
@ -334,6 +346,9 @@ static struct radeon_asic r420_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &r100_pm_misc,
|
||||
.pm_prepare = &r100_pm_prepare,
|
||||
.pm_finish = &r100_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic rs400_asic = {
|
||||
|
@ -376,6 +391,9 @@ static struct radeon_asic rs400_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &r100_pm_misc,
|
||||
.pm_prepare = &r100_pm_prepare,
|
||||
.pm_finish = &r100_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic rs600_asic = {
|
||||
|
@ -418,6 +436,9 @@ static struct radeon_asic rs600_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &rs600_pm_misc,
|
||||
.pm_prepare = &rs600_pm_prepare,
|
||||
.pm_finish = &rs600_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic rs690_asic = {
|
||||
|
@ -460,6 +481,9 @@ static struct radeon_asic rs690_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &rs600_pm_misc,
|
||||
.pm_prepare = &rs600_pm_prepare,
|
||||
.pm_finish = &rs600_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic rv515_asic = {
|
||||
|
@ -502,6 +526,9 @@ static struct radeon_asic rv515_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &rs600_pm_misc,
|
||||
.pm_prepare = &rs600_pm_prepare,
|
||||
.pm_finish = &rs600_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic r520_asic = {
|
||||
|
@ -544,6 +571,9 @@ static struct radeon_asic r520_asic = {
|
|||
.gui_idle = &r100_gui_idle,
|
||||
.get_power_state = &r100_get_power_state,
|
||||
.set_power_state = &r100_set_power_state,
|
||||
.pm_misc = &rs600_pm_misc,
|
||||
.pm_prepare = &rs600_pm_prepare,
|
||||
.pm_finish = &rs600_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic r600_asic = {
|
||||
|
@ -585,6 +615,9 @@ static struct radeon_asic r600_asic = {
|
|||
.gui_idle = &r600_gui_idle,
|
||||
.get_power_state = &r600_get_power_state,
|
||||
.set_power_state = &r600_set_power_state,
|
||||
.pm_misc = &r600_pm_misc,
|
||||
.pm_prepare = &rs600_pm_prepare,
|
||||
.pm_finish = &rs600_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic rs780_asic = {
|
||||
|
@ -626,6 +659,9 @@ static struct radeon_asic rs780_asic = {
|
|||
.gui_idle = &r600_gui_idle,
|
||||
.get_power_state = &r600_get_power_state,
|
||||
.set_power_state = &r600_set_power_state,
|
||||
.pm_misc = &r600_pm_misc,
|
||||
.pm_prepare = &rs600_pm_prepare,
|
||||
.pm_finish = &rs600_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic rv770_asic = {
|
||||
|
@ -667,6 +703,9 @@ static struct radeon_asic rv770_asic = {
|
|||
.gui_idle = &r600_gui_idle,
|
||||
.get_power_state = &r600_get_power_state,
|
||||
.set_power_state = &r600_set_power_state,
|
||||
.pm_misc = &rv770_pm_misc,
|
||||
.pm_prepare = &rs600_pm_prepare,
|
||||
.pm_finish = &rs600_pm_finish,
|
||||
};
|
||||
|
||||
static struct radeon_asic evergreen_asic = {
|
||||
|
@ -706,6 +745,9 @@ static struct radeon_asic evergreen_asic = {
|
|||
.gui_idle = &r600_gui_idle,
|
||||
.get_power_state = &r600_get_power_state,
|
||||
.set_power_state = &r600_set_power_state,
|
||||
.pm_misc = &evergreen_pm_misc,
|
||||
.pm_prepare = &evergreen_pm_prepare,
|
||||
.pm_finish = &evergreen_pm_finish,
|
||||
};
|
||||
|
||||
int radeon_asic_init(struct radeon_device *rdev)
|
||||
|
|
|
@ -130,6 +130,9 @@ extern bool r100_gui_idle(struct radeon_device *rdev);
|
|||
extern void r100_set_power_state(struct radeon_device *rdev);
|
||||
extern void r100_get_power_state(struct radeon_device *rdev,
|
||||
enum radeon_pm_action action);
|
||||
extern void r100_pm_misc(struct radeon_device *rdev);
|
||||
extern void r100_pm_prepare(struct radeon_device *rdev);
|
||||
extern void r100_pm_finish(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* r200,rv250,rs300,rv280
|
||||
|
@ -201,6 +204,9 @@ void rs600_hpd_fini(struct radeon_device *rdev);
|
|||
bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
|
||||
void rs600_hpd_set_polarity(struct radeon_device *rdev,
|
||||
enum radeon_hpd_id hpd);
|
||||
extern void rs600_pm_misc(struct radeon_device *rdev);
|
||||
extern void rs600_pm_prepare(struct radeon_device *rdev);
|
||||
extern void rs600_pm_finish(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* rs690,rs740
|
||||
|
@ -278,6 +284,7 @@ extern bool r600_gui_idle(struct radeon_device *rdev);
|
|||
extern void r600_set_power_state(struct radeon_device *rdev);
|
||||
extern void r600_get_power_state(struct radeon_device *rdev,
|
||||
enum radeon_pm_action action);
|
||||
extern void r600_pm_misc(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* rv770,rv730,rv710,rv740
|
||||
|
@ -286,6 +293,7 @@ int rv770_init(struct radeon_device *rdev);
|
|||
void rv770_fini(struct radeon_device *rdev);
|
||||
int rv770_suspend(struct radeon_device *rdev);
|
||||
int rv770_resume(struct radeon_device *rdev);
|
||||
extern void rv770_pm_misc(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* evergreen
|
||||
|
@ -306,5 +314,8 @@ void evergreen_hpd_set_polarity(struct radeon_device *rdev,
|
|||
u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc);
|
||||
int evergreen_irq_set(struct radeon_device *rdev);
|
||||
int evergreen_irq_process(struct radeon_device *rdev);
|
||||
extern void evergreen_pm_misc(struct radeon_device *rdev);
|
||||
extern void evergreen_pm_prepare(struct radeon_device *rdev);
|
||||
extern void evergreen_pm_finish(struct radeon_device *rdev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,129 @@
|
|||
void rs600_gpu_init(struct radeon_device *rdev);
|
||||
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
|
||||
|
||||
void rs600_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
#if 0
|
||||
int requested_index = rdev->pm.requested_power_state_index;
|
||||
struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
|
||||
struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
|
||||
u32 tmp, dyn_pwrmgt_sclk_length, dyn_sclk_vol_cntl;
|
||||
u32 hdp_dyn_cntl, mc_host_dyn_cntl;
|
||||
|
||||
if ((voltage->type == VOLTAGE_GPIO) && (voltage->gpio.valid)) {
|
||||
if (ps->misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) {
|
||||
tmp = RREG32(voltage->gpio.reg);
|
||||
if (voltage->active_high)
|
||||
tmp |= voltage->gpio.mask;
|
||||
else
|
||||
tmp &= ~(voltage->gpio.mask);
|
||||
WREG32(voltage->gpio.reg, tmp);
|
||||
if (voltage->delay)
|
||||
udelay(voltage->delay);
|
||||
} else {
|
||||
tmp = RREG32(voltage->gpio.reg);
|
||||
if (voltage->active_high)
|
||||
tmp &= ~voltage->gpio.mask;
|
||||
else
|
||||
tmp |= voltage->gpio.mask;
|
||||
WREG32(voltage->gpio.reg, tmp);
|
||||
if (voltage->delay)
|
||||
udelay(voltage->delay);
|
||||
}
|
||||
}
|
||||
|
||||
dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH);
|
||||
dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf);
|
||||
dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_LOLEN(0xf);
|
||||
if (ps->misc & ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN) {
|
||||
if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2) {
|
||||
dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(2);
|
||||
dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(2);
|
||||
} else if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4) {
|
||||
dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(4);
|
||||
dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(4);
|
||||
}
|
||||
} else {
|
||||
dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(1);
|
||||
dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(1);
|
||||
}
|
||||
WREG32_PLL(DYN_PWRMGT_SCLK_LENGTH, dyn_pwrmgt_sclk_length);
|
||||
|
||||
dyn_sclk_vol_cntl = RREG32_PLL(DYN_SCLK_VOL_CNTL);
|
||||
if (ps->misc & ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN) {
|
||||
dyn_sclk_vol_cntl |= IO_CG_VOLTAGE_DROP;
|
||||
if (voltage->delay) {
|
||||
dyn_sclk_vol_cntl |= VOLTAGE_DROP_SYNC;
|
||||
dyn_sclk_vol_cntl |= VOLTAGE_DELAY_SEL(voltage->delay);
|
||||
} else
|
||||
dyn_sclk_vol_cntl &= ~VOLTAGE_DROP_SYNC;
|
||||
} else
|
||||
dyn_sclk_vol_cntl &= ~IO_CG_VOLTAGE_DROP;
|
||||
WREG32_PLL(DYN_SCLK_VOL_CNTL, dyn_sclk_vol_cntl);
|
||||
|
||||
hdp_dyn_cntl = RREG32_PLL(HDP_DYN_CNTL);
|
||||
if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN)
|
||||
hdp_dyn_cntl &= ~HDP_FORCEON;
|
||||
else
|
||||
hdp_dyn_cntl |= HDP_FORCEON;
|
||||
WREG32_PLL(HDP_DYN_CNTL, hdp_dyn_cntl);
|
||||
|
||||
mc_host_dyn_cntl = RREG32_PLL(MC_HOST_DYN_CNTL);
|
||||
if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN)
|
||||
mc_host_dyn_cntl &= ~MC_HOST_FORCEON;
|
||||
else
|
||||
mc_host_dyn_cntl |= MC_HOST_FORCEON;
|
||||
WREG32_PLL(MC_HOST_DYN_CNTL, mc_host_dyn_cntl);
|
||||
|
||||
/* set pcie lanes */
|
||||
if ((rdev->flags & RADEON_IS_PCIE) &&
|
||||
!(rdev->flags & RADEON_IS_IGP) &&
|
||||
rdev->asic->set_pcie_lanes &&
|
||||
(ps->pcie_lanes !=
|
||||
rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) {
|
||||
radeon_set_pcie_lanes(rdev,
|
||||
ps->pcie_lanes);
|
||||
DRM_INFO("Setting: p: %d\n", ps->pcie_lanes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void rs600_pm_prepare(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *ddev = rdev->ddev;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
u32 tmp;
|
||||
|
||||
/* disable any active CRTCs */
|
||||
list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
|
||||
radeon_crtc = to_radeon_crtc(crtc);
|
||||
if (radeon_crtc->enabled) {
|
||||
tmp = RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset);
|
||||
tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE;
|
||||
WREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rs600_pm_finish(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_device *ddev = rdev->ddev;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
u32 tmp;
|
||||
|
||||
/* enable any active CRTCs */
|
||||
list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
|
||||
radeon_crtc = to_radeon_crtc(crtc);
|
||||
if (radeon_crtc->enabled) {
|
||||
tmp = RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset);
|
||||
tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE;
|
||||
WREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* hpd for digital panel detect/disconnect */
|
||||
bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
|
||||
{
|
||||
|
|
|
@ -634,4 +634,36 @@
|
|||
#define G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1)
|
||||
#define C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF
|
||||
|
||||
/* PLL regs */
|
||||
#define GENERAL_PWRMGT 0x8
|
||||
#define GLOBAL_PWRMGT_EN (1 << 0)
|
||||
#define MOBILE_SU (1 << 2)
|
||||
#define DYN_PWRMGT_SCLK_LENGTH 0xc
|
||||
#define NORMAL_POWER_SCLK_HILEN(x) ((x) << 0)
|
||||
#define NORMAL_POWER_SCLK_LOLEN(x) ((x) << 4)
|
||||
#define REDUCED_POWER_SCLK_HILEN(x) ((x) << 8)
|
||||
#define REDUCED_POWER_SCLK_LOLEN(x) ((x) << 12)
|
||||
#define POWER_D1_SCLK_HILEN(x) ((x) << 16)
|
||||
#define POWER_D1_SCLK_LOLEN(x) ((x) << 20)
|
||||
#define STATIC_SCREEN_HILEN(x) ((x) << 24)
|
||||
#define STATIC_SCREEN_LOLEN(x) ((x) << 28)
|
||||
#define DYN_SCLK_VOL_CNTL 0xe
|
||||
#define IO_CG_VOLTAGE_DROP (1 << 0)
|
||||
#define VOLTAGE_DROP_SYNC (1 << 2)
|
||||
#define VOLTAGE_DELAY_SEL(x) ((x) << 3)
|
||||
#define HDP_DYN_CNTL 0x10
|
||||
#define HDP_FORCEON (1 << 0)
|
||||
#define MC_HOST_DYN_CNTL 0x1e
|
||||
#define MC_HOST_FORCEON (1 << 0)
|
||||
|
||||
/* mmreg */
|
||||
#define DOUT_POWER_MANAGEMENT_CNTL 0x7ee0
|
||||
#define PWRDN_WAIT_BUSY_OFF (1 << 0)
|
||||
#define PWRDN_WAIT_PWRSEQ_OFF (1 << 4)
|
||||
#define PWRDN_WAIT_PPLL_OFF (1 << 8)
|
||||
#define PWRUP_WAIT_PPLL_ON (1 << 12)
|
||||
#define PWRUP_WAIT_MEM_INIT_DONE (1 << 16)
|
||||
#define PM_ASSERT_RESET (1 << 20)
|
||||
#define PM_PWRDN_PPLL (1 << 24)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
static void rv770_gpu_init(struct radeon_device *rdev);
|
||||
void rv770_fini(struct radeon_device *rdev);
|
||||
|
||||
void rv770_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* GART
|
||||
|
|
Loading…
Reference in a new issue