Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bae6b562 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms/pm: add asic specific callbacks for setting power state (v2)



(v2) Add evergreen vbl checks

Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 03214bd5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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_STATUS                           0x6e8c
#define EVERGREEN_CRTC_UPDATE_LOCK                      0x6ed4

#define EVERGREEN_DC_GPIO_HPD_MASK                      0x64b0
+37 −0
Original line number Diff line number Diff line
@@ -67,6 +67,43 @@ MODULE_FIRMWARE(FIRMWARE_R520);
 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
 */

void r100_set_power_state(struct radeon_device *rdev)
{
	/* if *_clock_mode are the same, *_power_state are as well */
	if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode)
		return;

	DRM_INFO("Setting: e: %d m: %d p: %d\n",
		 rdev->pm.requested_clock_mode->sclk,
		 rdev->pm.requested_clock_mode->mclk,
		 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);

	/* set pcie lanes */
	/* TODO */

	/* set voltage */
	/* TODO */

	/* set engine clock */
	radeon_sync_with_vblank(rdev);
	radeon_pm_debug_check_in_vbl(rdev, false);
	radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk);
	radeon_pm_debug_check_in_vbl(rdev, true);

#if 0
	/* set memory clock */
	if (rdev->asic->set_memory_clock) {
		radeon_sync_with_vblank(rdev);
		radeon_pm_debug_check_in_vbl(rdev, false);
		radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk);
		radeon_pm_debug_check_in_vbl(rdev, true);
	}
#endif

	rdev->pm.current_power_state = rdev->pm.requested_power_state;
	rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode;
}

bool r100_gui_idle(struct radeon_device *rdev)
{
	if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)
+37 −0
Original line number Diff line number Diff line
@@ -92,6 +92,43 @@ void r600_gpu_init(struct radeon_device *rdev);
void r600_fini(struct radeon_device *rdev);
void r600_irq_disable(struct radeon_device *rdev);

void r600_set_power_state(struct radeon_device *rdev)
{
	/* if *_clock_mode are the same, *_power_state are as well */
	if (rdev->pm.requested_clock_mode == rdev->pm.current_clock_mode)
		return;

	DRM_INFO("Setting: e: %d m: %d p: %d\n",
		 rdev->pm.requested_clock_mode->sclk,
		 rdev->pm.requested_clock_mode->mclk,
		 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);

	/* set pcie lanes */
	/* TODO */

	/* set voltage */
	/* TODO */

	/* set engine clock */
	radeon_sync_with_vblank(rdev);
	radeon_pm_debug_check_in_vbl(rdev, false);
	radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk);
	radeon_pm_debug_check_in_vbl(rdev, true);

#if 0
	/* set memory clock */
	if (rdev->asic->set_memory_clock) {
		radeon_sync_with_vblank(rdev);
		radeon_pm_debug_check_in_vbl(rdev, false);
		radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk);
		radeon_pm_debug_check_in_vbl(rdev, true);
	}
#endif

	rdev->pm.current_power_state = rdev->pm.requested_power_state;
	rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode;
}

bool r600_gui_idle(struct radeon_device *rdev)
{
	if (RREG32(GRBM_STATUS) & GUI_ACTIVE)
+4 −0
Original line number Diff line number Diff line
@@ -175,6 +175,8 @@ void radeon_pm_fini(struct radeon_device *rdev);
void radeon_pm_compute_clocks(struct radeon_device *rdev);
void radeon_combios_get_power_modes(struct radeon_device *rdev);
void radeon_atombios_get_power_modes(struct radeon_device *rdev);
bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
void radeon_sync_with_vblank(struct radeon_device *rdev);

/*
 * Fences.
@@ -808,6 +810,7 @@ struct radeon_asic {
	 */
	void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo);
	bool (*gui_idle)(struct radeon_device *rdev);
	void (*set_power_state)(struct radeon_device *rdev);
};

/*
@@ -1215,6 +1218,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
#define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd))
#define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd))
#define radeon_gui_idle(rdev) (rdev)->asic->gui_idle((rdev))
#define radeon_set_power_state(rdev) (rdev)->asic->set_power_state((rdev))

/* Common functions */
/* AGP */
+14 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ static struct radeon_asic r100_asic = {
	.hpd_set_polarity = &r100_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic r200_asic = {
@@ -205,6 +206,7 @@ static struct radeon_asic r200_asic = {
	.hpd_set_polarity = &r100_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic r300_asic = {
@@ -245,6 +247,7 @@ static struct radeon_asic r300_asic = {
	.hpd_set_polarity = &r100_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic r300_asic_pcie = {
@@ -284,6 +287,7 @@ static struct radeon_asic r300_asic_pcie = {
	.hpd_set_polarity = &r100_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic r420_asic = {
@@ -324,6 +328,7 @@ static struct radeon_asic r420_asic = {
	.hpd_set_polarity = &r100_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic rs400_asic = {
@@ -364,6 +369,7 @@ static struct radeon_asic rs400_asic = {
	.hpd_set_polarity = &r100_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic rs600_asic = {
@@ -404,6 +410,7 @@ static struct radeon_asic rs600_asic = {
	.hpd_set_polarity = &rs600_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic rs690_asic = {
@@ -444,6 +451,7 @@ static struct radeon_asic rs690_asic = {
	.hpd_set_polarity = &rs600_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic rv515_asic = {
@@ -484,6 +492,7 @@ static struct radeon_asic rv515_asic = {
	.hpd_set_polarity = &rs600_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic r520_asic = {
@@ -524,6 +533,7 @@ static struct radeon_asic r520_asic = {
	.hpd_set_polarity = &rs600_hpd_set_polarity,
	.ioctl_wait_idle = NULL,
	.gui_idle = &r100_gui_idle,
	.set_power_state = &r100_set_power_state,
};

static struct radeon_asic r600_asic = {
@@ -563,6 +573,7 @@ static struct radeon_asic r600_asic = {
	.hpd_set_polarity = &r600_hpd_set_polarity,
	.ioctl_wait_idle = r600_ioctl_wait_idle,
	.gui_idle = &r600_gui_idle,
	.set_power_state = &r600_set_power_state,
};

static struct radeon_asic rs780_asic = {
@@ -602,6 +613,7 @@ static struct radeon_asic rs780_asic = {
	.hpd_set_polarity = &r600_hpd_set_polarity,
	.ioctl_wait_idle = r600_ioctl_wait_idle,
	.gui_idle = &r600_gui_idle,
	.set_power_state = &r600_set_power_state,
};

static struct radeon_asic rv770_asic = {
@@ -641,6 +653,7 @@ static struct radeon_asic rv770_asic = {
	.hpd_set_polarity = &r600_hpd_set_polarity,
	.ioctl_wait_idle = r600_ioctl_wait_idle,
	.gui_idle = &r600_gui_idle,
	.set_power_state = &r600_set_power_state,
};

static struct radeon_asic evergreen_asic = {
@@ -678,6 +691,7 @@ static struct radeon_asic evergreen_asic = {
	.hpd_sense = &evergreen_hpd_sense,
	.hpd_set_polarity = &evergreen_hpd_set_polarity,
	.gui_idle = &r600_gui_idle,
	.set_power_state = &r600_set_power_state,
};

int radeon_asic_init(struct radeon_device *rdev)
Loading