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

Commit 42794b27 authored by Andres Rodriguez's avatar Andres Rodriguez Committed by Alex Deucher
Browse files

drm/amdgpu: take ownership of per-pipe configuration v3



Make amdgpu the owner of all per-pipe state of the HQDs.

This change will allow us to split the queues between kfd and amdgpu
with a queue granularity instead of pipe granularity.

This patch fixes kfd allocating an HDP_EOP region for its 3 pipes which
goes unused.

v2: support for gfx9
v3: fix gfx7 HPD intitialization

Reviewed-by: default avatarEdward O'Callaghan <funfunctor@folklore1984.net>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAndres Rodriguez <andresx7@gmail.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d59095f7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -902,9 +902,9 @@ struct amdgpu_mec {
	u64			hpd_eop_gpu_addr;
	struct amdgpu_bo	*mec_fw_obj;
	u64			mec_fw_gpu_addr;
	u32 num_pipe;
	u32 num_mec;
	u32 num_queue;
	u32 num_pipe_per_mec;
	u32 num_queue_per_pipe;
	void			*mqd_backup[AMDGPU_MAX_COMPUTE_RINGS + 1];
};

+1 −12
Original line number Diff line number Diff line
@@ -244,18 +244,7 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
				uint32_t hpd_size, uint64_t hpd_gpu_addr)
{
	struct amdgpu_device *adev = get_amdgpu_device(kgd);

	uint32_t mec = (++pipe_id / CIK_PIPE_PER_MEC) + 1;
	uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC);

	lock_srbm(kgd, mec, pipe, 0, 0);
	WREG32(mmCP_HPD_EOP_BASE_ADDR, lower_32_bits(hpd_gpu_addr >> 8));
	WREG32(mmCP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(hpd_gpu_addr >> 8));
	WREG32(mmCP_HPD_EOP_VMID, 0);
	WREG32(mmCP_HPD_EOP_CONTROL, hpd_size);
	unlock_srbm(kgd);

	/* amdgpu owns the per-pipe state */
	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
				uint32_t hpd_size, uint64_t hpd_gpu_addr)
{
	/* amdgpu owns the per-pipe state */
	return 0;
}

+26 −10
Original line number Diff line number Diff line
@@ -2827,6 +2827,7 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
{
	int r;
	u32 *hpd;
	size_t mec_hpd_size;

	/*
	 * KV:    2 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 64 Queues total
@@ -2834,13 +2835,26 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
	 * Nonetheless, we assign only 1 pipe because all other pipes will
	 * be handled by KFD
	 */
	switch (adev->asic_type) {
	case CHIP_KAVERI:
		adev->gfx.mec.num_mec = 2;
		break;
	case CHIP_BONAIRE:
	case CHIP_HAWAII:
	case CHIP_KABINI:
	case CHIP_MULLINS:
	default:
		adev->gfx.mec.num_mec = 1;
	adev->gfx.mec.num_pipe = 1;
	adev->gfx.mec.num_queue = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * 8;
		break;
	}
	adev->gfx.mec.num_pipe_per_mec = 4;
	adev->gfx.mec.num_queue_per_pipe = 8;

	mec_hpd_size = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe_per_mec
		* GFX7_MEC_HPD_SIZE * 2;
	if (adev->gfx.mec.hpd_eop_obj == NULL) {
		r = amdgpu_bo_create(adev,
				     adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * GFX7_MEC_HPD_SIZE * 2,
				     mec_hpd_size,
				     PAGE_SIZE, true,
				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
				     &adev->gfx.mec.hpd_eop_obj);
@@ -2870,7 +2884,7 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
	}

	/* clear memory.  Not sure if this is required or not */
	memset(hpd, 0, adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * GFX7_MEC_HPD_SIZE * 2);
	memset(hpd, 0, mec_hpd_size);

	amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
	amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
@@ -2917,16 +2931,18 @@ struct hqd_registers
	u32 cp_mqd_control;
};

static void gfx_v7_0_compute_pipe_init(struct amdgpu_device *adev, int me, int pipe)
static void gfx_v7_0_compute_pipe_init(struct amdgpu_device *adev,
				       int mec, int pipe)
{
	u64 eop_gpu_addr;
	u32 tmp;
	size_t eop_offset = me * pipe * GFX7_MEC_HPD_SIZE * 2;
	size_t eop_offset = (mec * adev->gfx.mec.num_pipe_per_mec + pipe)
			    * GFX7_MEC_HPD_SIZE * 2;

	mutex_lock(&adev->srbm_mutex);
	eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr + eop_offset;

	cik_srbm_select(adev, me, pipe, 0, 0);
	cik_srbm_select(adev, mec + 1, pipe, 0, 0);

	/* write the EOP addr */
	WREG32(mmCP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8);
@@ -3208,9 +3224,9 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev)
	tmp |= (1 << 23);
	WREG32(mmCP_CPF_DEBUG, tmp);

	/* init the pipes */
	/* init all pipes (even the ones we don't own) */
	for (i = 0; i < adev->gfx.mec.num_mec; i++)
		for (j = 0; j < adev->gfx.mec.num_pipe; j++)
		for (j = 0; j < adev->gfx.mec.num_pipe_per_mec; j++)
			gfx_v7_0_compute_pipe_init(adev, i, j);

	/* init the queues */
+24 −9
Original line number Diff line number Diff line
@@ -1426,18 +1426,33 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev)
{
	int r;
	u32 *hpd;
	size_t mec_hpd_size;

	/*
	 * we assign only 1 pipe because all other pipes will
	 * be handled by KFD
	 */
	switch (adev->asic_type) {
	case CHIP_FIJI:
	case CHIP_TONGA:
	case CHIP_POLARIS11:
	case CHIP_POLARIS12:
	case CHIP_POLARIS10:
	case CHIP_CARRIZO:
		adev->gfx.mec.num_mec = 2;
		break;
	case CHIP_TOPAZ:
	case CHIP_STONEY:
	default:
		adev->gfx.mec.num_mec = 1;
	adev->gfx.mec.num_pipe = 1;
	adev->gfx.mec.num_queue = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * 8;
		break;
	}

	adev->gfx.mec.num_pipe_per_mec = 4;
	adev->gfx.mec.num_queue_per_pipe = 8;

	/* only 1 pipe of the first MEC is owned by amdgpu */
	mec_hpd_size = 1 * 1 * adev->gfx.mec.num_queue_per_pipe * GFX8_MEC_HPD_SIZE;

	if (adev->gfx.mec.hpd_eop_obj == NULL) {
		r = amdgpu_bo_create(adev,
				     adev->gfx.mec.num_queue * GFX8_MEC_HPD_SIZE,
				     mec_hpd_size,
				     PAGE_SIZE, true,
				     AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
				     &adev->gfx.mec.hpd_eop_obj);
@@ -1466,7 +1481,7 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev)
		return r;
	}

	memset(hpd, 0, adev->gfx.mec.num_queue * GFX8_MEC_HPD_SIZE);
	memset(hpd, 0, mec_hpd_size);

	amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
	amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
Loading