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

Commit 66229b20 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon/kms: add dpm support for rv7xx (v4)



This adds dpm support for rv7xx asics.  This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching

Set radeon.dpm=1 to enable.

v2: reduce stack usage
v3: fix 64 bit div
v4: fix state enable

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4a6369e9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
	evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
	atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
	si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
	r600_dpm.o rs780_dpm.o rv6xx_dpm.o
	r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
	rv770_smc.o

radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
+78 −0
Original line number Diff line number Diff line
/*
 * Copyright 2011 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */
#ifndef PP_SMC_H
#define PP_SMC_H

#pragma pack(push, 1)

#define PPSMC_SWSTATE_FLAG_DC                           0x01

#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL             0x00
#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL             0x01
#define PPSMC_THERMAL_PROTECT_TYPE_NONE                 0xff

#define PPSMC_SYSTEMFLAG_GPIO_DC                        0x01
#define PPSMC_SYSTEMFLAG_STEPVDDC                       0x02
#define PPSMC_SYSTEMFLAG_GDDR5                          0x04
#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP               0x08
#define PPSMC_SYSTEMFLAG_REGULATOR_HOT                  0x10

#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK              0x07
#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK     0x08
#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE   0x00
#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE  0x01

#define PPSMC_DISPLAY_WATERMARK_LOW                     0
#define PPSMC_DISPLAY_WATERMARK_HIGH                    1

#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP    0x01

#define PPSMC_Result_OK             ((uint8_t)0x01)
#define PPSMC_Result_Failed         ((uint8_t)0xFF)

typedef uint8_t PPSMC_Result;

#define PPSMC_MSG_Halt                      ((uint8_t)0x10)
#define PPSMC_MSG_Resume                    ((uint8_t)0x11)
#define PPSMC_MSG_ZeroLevelsDisabled        ((uint8_t)0x13)
#define PPSMC_MSG_OneLevelsDisabled         ((uint8_t)0x14)
#define PPSMC_MSG_TwoLevelsDisabled         ((uint8_t)0x15)
#define PPSMC_MSG_EnableThermalInterrupt    ((uint8_t)0x16)
#define PPSMC_MSG_SwitchToSwState           ((uint8_t)0x20)
#define PPSMC_MSG_SwitchToInitialState      ((uint8_t)0x40)
#define PPSMC_MSG_NoForcedLevel             ((uint8_t)0x41)
#define PPSMC_MSG_SwitchToMinimumPower      ((uint8_t)0x51)
#define PPSMC_MSG_ResumeFromMinimumPower    ((uint8_t)0x52)
#define PPSMC_MSG_NoDisplay                 ((uint8_t)0x5D)
#define PPSMC_MSG_HasDisplay                ((uint8_t)0x5E)
#define PPSMC_MSG_EnableULV                 ((uint8_t)0x62)
#define PPSMC_MSG_DisableULV                ((uint8_t)0x63)
#define PPSMC_MSG_EnterULV                  ((uint8_t)0x64)
#define PPSMC_MSG_ExitULV                   ((uint8_t)0x65)
#define PPSMC_MSG_ResetToDefaults           ((uint8_t)0x84)

typedef uint8_t PPSMC_Msg;

#pragma pack(pop)

#endif
+42 −6
Original line number Diff line number Diff line
@@ -57,10 +57,14 @@ MODULE_FIRMWARE("radeon/RS780_pfp.bin");
MODULE_FIRMWARE("radeon/RS780_me.bin");
MODULE_FIRMWARE("radeon/RV770_pfp.bin");
MODULE_FIRMWARE("radeon/RV770_me.bin");
MODULE_FIRMWARE("radeon/RV770_smc.bin");
MODULE_FIRMWARE("radeon/RV730_pfp.bin");
MODULE_FIRMWARE("radeon/RV730_me.bin");
MODULE_FIRMWARE("radeon/RV730_smc.bin");
MODULE_FIRMWARE("radeon/RV740_smc.bin");
MODULE_FIRMWARE("radeon/RV710_pfp.bin");
MODULE_FIRMWARE("radeon/RV710_me.bin");
MODULE_FIRMWARE("radeon/RV710_smc.bin");
MODULE_FIRMWARE("radeon/R600_rlc.bin");
MODULE_FIRMWARE("radeon/R700_rlc.bin");
MODULE_FIRMWARE("radeon/CEDAR_pfp.bin");
@@ -2139,7 +2143,8 @@ int r600_init_microcode(struct radeon_device *rdev)
	struct platform_device *pdev;
	const char *chip_name;
	const char *rlc_chip_name;
	size_t pfp_req_size, me_req_size, rlc_req_size;
	const char *smc_chip_name = "RV770";
	size_t pfp_req_size, me_req_size, rlc_req_size, smc_req_size = 0;
	char fw_name[30];
	int err;

@@ -2185,15 +2190,26 @@ int r600_init_microcode(struct radeon_device *rdev)
	case CHIP_RV770:
		chip_name = "RV770";
		rlc_chip_name = "R700";
		smc_chip_name = "RV770";
		smc_req_size = ALIGN(RV770_SMC_UCODE_SIZE, 4);
		break;
	case CHIP_RV730:
	case CHIP_RV740:
		chip_name = "RV730";
		rlc_chip_name = "R700";
		smc_chip_name = "RV730";
		smc_req_size = ALIGN(RV730_SMC_UCODE_SIZE, 4);
		break;
	case CHIP_RV710:
		chip_name = "RV710";
		rlc_chip_name = "R700";
		smc_chip_name = "RV710";
		smc_req_size = ALIGN(RV710_SMC_UCODE_SIZE, 4);
		break;
	case CHIP_RV740:
		chip_name = "RV730";
		rlc_chip_name = "R700";
		smc_chip_name = "RV740";
		smc_req_size = ALIGN(RV740_SMC_UCODE_SIZE, 4);
		break;
	case CHIP_CEDAR:
		chip_name = "CEDAR";
@@ -2277,6 +2293,19 @@ int r600_init_microcode(struct radeon_device *rdev)
		err = -EINVAL;
	}

	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name);
		err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev);
		if (err)
			goto out;
		if (rdev->smc_fw->size != smc_req_size) {
			printk(KERN_ERR
			       "smc: Bogus length %zu in firmware \"%s\"\n",
			       rdev->smc_fw->size, fw_name);
			err = -EINVAL;
		}
	}

out:
	platform_device_unregister(pdev);

@@ -2291,6 +2320,8 @@ int r600_init_microcode(struct radeon_device *rdev)
		rdev->me_fw = NULL;
		release_firmware(rdev->rlc_fw);
		rdev->rlc_fw = NULL;
		release_firmware(rdev->smc_fw);
		rdev->smc_fw = NULL;
	}
	return err;
}
@@ -4039,11 +4070,14 @@ int r600_irq_set(struct radeon_device *rdev)
	if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
		thermal_int = RREG32(CG_THERMAL_INT) &
			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
	} else if (rdev->family >= CHIP_RV770) {
		thermal_int = RREG32(RV770_CG_THERMAL_INT) &
			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
	}
	if (rdev->irq.dpm_thermal) {
		DRM_DEBUG("dpm thermal\n");
		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
	}
	}

	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
		DRM_DEBUG("r600_irq_set: sw int\n");
@@ -4128,6 +4162,8 @@ int r600_irq_set(struct radeon_device *rdev)
	}
	if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
		WREG32(CG_THERMAL_INT, thermal_int);
	} else if (rdev->family >= CHIP_RV770) {
		WREG32(RV770_CG_THERMAL_INT, thermal_int);
	}

	return 0;
+2 −0
Original line number Diff line number Diff line
@@ -320,6 +320,8 @@
#define 	THERM_INT_MASK_HIGH			(1 << 24)
#define 	THERM_INT_MASK_LOW			(1 << 25)

#define	RV770_CG_THERMAL_INT				0x734

#define	HDP_HOST_PATH_CNTL				0x2C00
#define	HDP_NONSURFACE_BASE				0x2C04
#define	HDP_NONSURFACE_INFO				0x2C08
+1 −0
Original line number Diff line number Diff line
@@ -1913,6 +1913,7 @@ struct radeon_device {
	const struct firmware *uvd_fw;	/* UVD firmware */
	const struct firmware *mec_fw;	/* CIK MEC firmware */
	const struct firmware *sdma_fw;	/* CIK SDMA firmware */
	const struct firmware *smc_fw;	/* SMC firmware */
	struct r600_blit r600_blit;
	struct r600_vram_scratch vram_scratch;
	int msi_enabled; /* msi enabled */
Loading