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

Commit 153549b8 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-radeon-evergreen-accel' into drm-core-next

* drm-radeon-evergreen-accel:
  drm/radeon: fix cypress firmware typo.
  drm/radeon/kms/evergreen: add hpd support
  drm/radeon/kms/evergreen: implement irq support
  drm/radeon/kms/evergreen: setup and enable the CP
  drm/radeon/kms/evergreen: implement gfx init
  drm/radeon/kms/evergreen: add soft reset function
  drm/radeon/kms/evergreen: add gart support
  drm/radeon/kms: add support for evergreen power tables
  drm/radeon/kms: update atombios.h power tables for evergreen
parents 7fff400b a7433742
Loading
Loading
Loading
Loading
+74 −2
Original line number Original line Diff line number Diff line
@@ -5742,6 +5742,9 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER
#define ATOM_PP_THERMALCONTROLLER_RV6xx     7
#define ATOM_PP_THERMALCONTROLLER_RV6xx     7
#define ATOM_PP_THERMALCONTROLLER_RV770     8
#define ATOM_PP_THERMALCONTROLLER_RV770     8
#define ATOM_PP_THERMALCONTROLLER_ADT7473   9
#define ATOM_PP_THERMALCONTROLLER_ADT7473   9
#define ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO     11
#define ATOM_PP_THERMALCONTROLLER_EVERGREEN 12
#define ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL   0x89    // ADT7473 Fan Control + Internal Thermal Controller


typedef struct _ATOM_PPLIB_STATE
typedef struct _ATOM_PPLIB_STATE
{
{
@@ -5749,6 +5752,26 @@ typedef struct _ATOM_PPLIB_STATE
    UCHAR ucClockStateIndices[1]; // variable-sized
    UCHAR ucClockStateIndices[1]; // variable-sized
} ATOM_PPLIB_STATE;
} ATOM_PPLIB_STATE;


typedef struct _ATOM_PPLIB_FANTABLE
{
    UCHAR   ucFanTableFormat;                // Change this if the table format changes or version changes so that the other fields are not the same.
    UCHAR   ucTHyst;                         // Temperature hysteresis. Integer.
    USHORT  usTMin;                          // The temperature, in 0.01 centigrades, below which we just run at a minimal PWM.
    USHORT  usTMed;                          // The middle temperature where we change slopes.
    USHORT  usTHigh;                         // The high point above TMed for adjusting the second slope.
    USHORT  usPWMMin;                        // The minimum PWM value in percent (0.01% increments).
    USHORT  usPWMMed;                        // The PWM value (in percent) at TMed.
    USHORT  usPWMHigh;                       // The PWM value at THigh.
} ATOM_PPLIB_FANTABLE;

typedef struct _ATOM_PPLIB_EXTENDEDHEADER
{
    USHORT  usSize;
    ULONG   ulMaxEngineClock;   // For Overdrive.
    ULONG   ulMaxMemoryClock;   // For Overdrive.
    // Add extra system parameters here, always adjust size to include all fields.
} ATOM_PPLIB_EXTENDEDHEADER;

//// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps
//// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps
#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1
#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1
#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2
#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2
@@ -5762,6 +5785,12 @@ typedef struct _ATOM_PPLIB_STATE
#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512
#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512
#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024
#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024
#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048
#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048
#define ATOM_PP_PLATFORM_CAP_MVDDCONTROL 4096
#define ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT 0x2000              // Go to boot state on alerts, e.g. on an AC->DC transition.
#define ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT 0x4000   // Do NOT wait for VBLANK during an alert (e.g. AC->DC transition).
#define ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL 0x8000                   // Does the driver control VDDCI independently from VDDC.
#define ATOM_PP_PLATFORM_CAP_REGULATOR_HOT 0x00010000               // Enable the 'regulator hot' feature.
#define ATOM_PP_PLATFORM_CAP_BACO          0x00020000               // Does the driver supports BACO state.


typedef struct _ATOM_PPLIB_POWERPLAYTABLE
typedef struct _ATOM_PPLIB_POWERPLAYTABLE
{
{
@@ -5797,6 +5826,21 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE


} ATOM_PPLIB_POWERPLAYTABLE;
} ATOM_PPLIB_POWERPLAYTABLE;


typedef struct _ATOM_PPLIB_POWERPLAYTABLE2
{
    ATOM_PPLIB_POWERPLAYTABLE basicTable;
    UCHAR   ucNumCustomThermalPolicy;
    USHORT  usCustomThermalPolicyArrayOffset;
}ATOM_PPLIB_POWERPLAYTABLE2, *LPATOM_PPLIB_POWERPLAYTABLE2;

typedef struct _ATOM_PPLIB_POWERPLAYTABLE3
{
    ATOM_PPLIB_POWERPLAYTABLE2 basicTable2;
    USHORT                     usFormatID;                      // To be used ONLY by PPGen.
    USHORT                     usFanTableOffset;
    USHORT                     usExtendendedHeaderOffset;
} ATOM_PPLIB_POWERPLAYTABLE3, *LPATOM_PPLIB_POWERPLAYTABLE3;

//// ATOM_PPLIB_NONCLOCK_INFO::usClassification
//// ATOM_PPLIB_NONCLOCK_INFO::usClassification
#define ATOM_PPLIB_CLASSIFICATION_UI_MASK          0x0007
#define ATOM_PPLIB_CLASSIFICATION_UI_MASK          0x0007
#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT         0
#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT         0
@@ -5816,7 +5860,9 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE
#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE               0x0400
#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE               0x0400
#define ATOM_PPLIB_CLASSIFICATION_3DLOW                  0x0800
#define ATOM_PPLIB_CLASSIFICATION_3DLOW                  0x0800
#define ATOM_PPLIB_CLASSIFICATION_ACPI                   0x1000
#define ATOM_PPLIB_CLASSIFICATION_ACPI                   0x1000
// remaining 3 bits are reserved
#define ATOM_PPLIB_CLASSIFICATION_HD2STATE               0x2000
#define ATOM_PPLIB_CLASSIFICATION_HDSTATE                0x4000
#define ATOM_PPLIB_CLASSIFICATION_SDSTATE                0x8000


//// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings
//// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings
#define ATOM_PPLIB_SINGLE_DISPLAY_ONLY           0x00000001
#define ATOM_PPLIB_SINGLE_DISPLAY_ONLY           0x00000001
@@ -5840,9 +5886,15 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE


#define ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING        0x00001000
#define ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING        0x00001000
#define ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS  0x00002000
#define ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS  0x00002000
#define ATOM_PPLIB_DISALLOW_ON_DC                        0x00004000
#define ATOM_PPLIB_ENABLE_VARIBRIGHT                     0x00008000
#define ATOM_PPLIB_ENABLE_VARIBRIGHT                     0x00008000


#define ATOM_PPLIB_DISALLOW_ON_DC                       0x00004000
//memory related flags
#define ATOM_PPLIB_SWSTATE_MEMORY_DLL_OFF               0x000010000

//M3 Arb    //2bits, current 3 sets of parameters in total
#define ATOM_PPLIB_M3ARB_MASK                       0x00060000
#define ATOM_PPLIB_M3ARB_SHIFT                      17


// Contained in an array starting at the offset
// Contained in an array starting at the offset
// in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset.
// in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset.
@@ -5860,6 +5912,9 @@ typedef struct _ATOM_PPLIB_NONCLOCK_INFO
// Contained in an array starting at the offset
// Contained in an array starting at the offset
// in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset.
// in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset.
// referenced from ATOM_PPLIB_STATE::ucClockStateIndices
// referenced from ATOM_PPLIB_STATE::ucClockStateIndices
#define ATOM_PPLIB_NONCLOCKINFO_VER1      12
#define ATOM_PPLIB_NONCLOCKINFO_VER2      24

typedef struct _ATOM_PPLIB_R600_CLOCK_INFO
typedef struct _ATOM_PPLIB_R600_CLOCK_INFO
{
{
      USHORT usEngineClockLow;
      USHORT usEngineClockLow;
@@ -5882,6 +5937,23 @@ typedef struct _ATOM_PPLIB_R600_CLOCK_INFO
#define ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE    4
#define ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE    4
#define ATOM_PPLIB_R600_FLAGS_MEMORY_ODT_OFF    8
#define ATOM_PPLIB_R600_FLAGS_MEMORY_ODT_OFF    8
#define ATOM_PPLIB_R600_FLAGS_MEMORY_DLL_OFF    16
#define ATOM_PPLIB_R600_FLAGS_MEMORY_DLL_OFF    16
#define ATOM_PPLIB_R600_FLAGS_LOWPOWER         32   // On the RV770 use 'low power' setting (sequencer S0).

typedef struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO
{
      USHORT usEngineClockLow;
      UCHAR  ucEngineClockHigh;

      USHORT usMemoryClockLow;
      UCHAR  ucMemoryClockHigh;

      USHORT usVDDC;
      USHORT usVDDCI;
      USHORT usUnused;

      ULONG ulFlags; // ATOM_PPLIB_R600_FLAGS_*

} ATOM_PPLIB_EVERGREEN_CLOCK_INFO;


typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO
typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO


+2 −6
Original line number Original line Diff line number Diff line
@@ -249,16 +249,12 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
		if (ASIC_IS_DCE3(rdev))
		if (ASIC_IS_DCE3(rdev))
			atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
			atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
		atombios_blank_crtc(crtc, ATOM_DISABLE);
		atombios_blank_crtc(crtc, ATOM_DISABLE);
		/* XXX re-enable when interrupt support is added */
		if (!ASIC_IS_DCE4(rdev))
		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
		radeon_crtc_load_lut(crtc);
		radeon_crtc_load_lut(crtc);
		break;
		break;
	case DRM_MODE_DPMS_STANDBY:
	case DRM_MODE_DPMS_STANDBY:
	case DRM_MODE_DPMS_SUSPEND:
	case DRM_MODE_DPMS_SUSPEND:
	case DRM_MODE_DPMS_OFF:
	case DRM_MODE_DPMS_OFF:
		/* XXX re-enable when interrupt support is added */
		if (!ASIC_IS_DCE4(rdev))
		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
		atombios_blank_crtc(crtc, ATOM_ENABLE);
		atombios_blank_crtc(crtc, ATOM_ENABLE);
		if (ASIC_IS_DCE3(rdev))
		if (ASIC_IS_DCE3(rdev))
+1431 −52

File changed.

Preview size limit exceeded, changes collapsed.

+556 −0

File added.

Preview size limit exceeded, changes collapsed.

+60 −11
Original line number Original line Diff line number Diff line
@@ -44,6 +44,9 @@
#define R700_PFP_UCODE_SIZE 848
#define R700_PFP_UCODE_SIZE 848
#define R700_PM4_UCODE_SIZE 1360
#define R700_PM4_UCODE_SIZE 1360
#define R700_RLC_UCODE_SIZE 1024
#define R700_RLC_UCODE_SIZE 1024
#define EVERGREEN_PFP_UCODE_SIZE 1120
#define EVERGREEN_PM4_UCODE_SIZE 1376
#define EVERGREEN_RLC_UCODE_SIZE 768


/* Firmware Names */
/* Firmware Names */
MODULE_FIRMWARE("radeon/R600_pfp.bin");
MODULE_FIRMWARE("radeon/R600_pfp.bin");
@@ -68,6 +71,18 @@ MODULE_FIRMWARE("radeon/RV710_pfp.bin");
MODULE_FIRMWARE("radeon/RV710_me.bin");
MODULE_FIRMWARE("radeon/RV710_me.bin");
MODULE_FIRMWARE("radeon/R600_rlc.bin");
MODULE_FIRMWARE("radeon/R600_rlc.bin");
MODULE_FIRMWARE("radeon/R700_rlc.bin");
MODULE_FIRMWARE("radeon/R700_rlc.bin");
MODULE_FIRMWARE("radeon/CEDAR_pfp.bin");
MODULE_FIRMWARE("radeon/CEDAR_me.bin");
MODULE_FIRMWARE("radeon/CEDAR_rlc.bin");
MODULE_FIRMWARE("radeon/REDWOOD_pfp.bin");
MODULE_FIRMWARE("radeon/REDWOOD_me.bin");
MODULE_FIRMWARE("radeon/REDWOOD_rlc.bin");
MODULE_FIRMWARE("radeon/JUNIPER_pfp.bin");
MODULE_FIRMWARE("radeon/JUNIPER_me.bin");
MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin");
MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin");
MODULE_FIRMWARE("radeon/CYPRESS_me.bin");
MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin");


int r600_debugfs_mc_info_init(struct radeon_device *rdev);
int r600_debugfs_mc_info_init(struct radeon_device *rdev);


@@ -75,6 +90,7 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev);
int r600_mc_wait_for_idle(struct radeon_device *rdev);
int r600_mc_wait_for_idle(struct radeon_device *rdev);
void r600_gpu_init(struct radeon_device *rdev);
void r600_gpu_init(struct radeon_device *rdev);
void r600_fini(struct radeon_device *rdev);
void r600_fini(struct radeon_device *rdev);
void r600_irq_disable(struct radeon_device *rdev);


/* hpd for digital panel detect/disconnect */
/* hpd for digital panel detect/disconnect */
bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
@@ -1450,10 +1466,31 @@ int r600_init_microcode(struct radeon_device *rdev)
		chip_name = "RV710";
		chip_name = "RV710";
		rlc_chip_name = "R700";
		rlc_chip_name = "R700";
		break;
		break;
	case CHIP_CEDAR:
		chip_name = "CEDAR";
		rlc_chip_name = "CEDAR";
		break;
	case CHIP_REDWOOD:
		chip_name = "REDWOOD";
		rlc_chip_name = "REDWOOD";
		break;
	case CHIP_JUNIPER:
		chip_name = "JUNIPER";
		rlc_chip_name = "JUNIPER";
		break;
	case CHIP_CYPRESS:
	case CHIP_HEMLOCK:
		chip_name = "CYPRESS";
		rlc_chip_name = "CYPRESS";
		break;
	default: BUG();
	default: BUG();
	}
	}


	if (rdev->family >= CHIP_RV770) {
	if (rdev->family >= CHIP_CEDAR) {
		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
	} else if (rdev->family >= CHIP_RV770) {
		pfp_req_size = R700_PFP_UCODE_SIZE * 4;
		pfp_req_size = R700_PFP_UCODE_SIZE * 4;
		me_req_size = R700_PM4_UCODE_SIZE * 4;
		me_req_size = R700_PM4_UCODE_SIZE * 4;
		rlc_req_size = R700_RLC_UCODE_SIZE * 4;
		rlc_req_size = R700_RLC_UCODE_SIZE * 4;
@@ -1567,12 +1604,15 @@ int r600_cp_start(struct radeon_device *rdev)
	}
	}
	radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
	radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
	radeon_ring_write(rdev, 0x1);
	radeon_ring_write(rdev, 0x1);
	if (rdev->family < CHIP_RV770) {
	if (rdev->family >= CHIP_CEDAR) {
		radeon_ring_write(rdev, 0x3);
		radeon_ring_write(rdev, 0x0);
		radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1);
		radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1);
	} else {
	} else if (rdev->family >= CHIP_RV770) {
		radeon_ring_write(rdev, 0x0);
		radeon_ring_write(rdev, 0x0);
		radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1);
		radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1);
	} else {
		radeon_ring_write(rdev, 0x3);
		radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1);
	}
	}
	radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
	radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
	radeon_ring_write(rdev, 0);
	radeon_ring_write(rdev, 0);
@@ -2273,10 +2313,11 @@ static void r600_ih_ring_fini(struct radeon_device *rdev)
	}
	}
}
}


static void r600_rlc_stop(struct radeon_device *rdev)
void r600_rlc_stop(struct radeon_device *rdev)
{
{


	if (rdev->family >= CHIP_RV770) {
	if ((rdev->family >= CHIP_RV770) &&
	    (rdev->family <= CHIP_RV740)) {
		/* r7xx asics need to soft reset RLC before halting */
		/* r7xx asics need to soft reset RLC before halting */
		WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
		WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
		RREG32(SRBM_SOFT_RESET);
		RREG32(SRBM_SOFT_RESET);
@@ -2313,7 +2354,12 @@ static int r600_rlc_init(struct radeon_device *rdev)
	WREG32(RLC_UCODE_CNTL, 0);
	WREG32(RLC_UCODE_CNTL, 0);


	fw_data = (const __be32 *)rdev->rlc_fw->data;
	fw_data = (const __be32 *)rdev->rlc_fw->data;
	if (rdev->family >= CHIP_RV770) {
	if (rdev->family >= CHIP_CEDAR) {
		for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) {
			WREG32(RLC_UCODE_ADDR, i);
			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
		}
	} else if (rdev->family >= CHIP_RV770) {
		for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
		for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
			WREG32(RLC_UCODE_ADDR, i);
			WREG32(RLC_UCODE_ADDR, i);
			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
@@ -2343,7 +2389,7 @@ static void r600_enable_interrupts(struct radeon_device *rdev)
	rdev->ih.enabled = true;
	rdev->ih.enabled = true;
}
}


static void r600_disable_interrupts(struct radeon_device *rdev)
void r600_disable_interrupts(struct radeon_device *rdev)
{
{
	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
	u32 ih_cntl = RREG32(IH_CNTL);
	u32 ih_cntl = RREG32(IH_CNTL);
@@ -2458,6 +2504,9 @@ int r600_irq_init(struct radeon_device *rdev)
	WREG32(IH_CNTL, ih_cntl);
	WREG32(IH_CNTL, ih_cntl);


	/* force the active interrupt state to all disabled */
	/* force the active interrupt state to all disabled */
	if (rdev->family >= CHIP_CEDAR)
		evergreen_disable_interrupt_state(rdev);
	else
		r600_disable_interrupt_state(rdev);
		r600_disable_interrupt_state(rdev);


	/* enable irqs */
	/* enable irqs */
@@ -2468,7 +2517,7 @@ int r600_irq_init(struct radeon_device *rdev)


void r600_irq_suspend(struct radeon_device *rdev)
void r600_irq_suspend(struct radeon_device *rdev)
{
{
	r600_disable_interrupts(rdev);
	r600_irq_disable(rdev);
	r600_rlc_stop(rdev);
	r600_rlc_stop(rdev);
}
}


Loading