drivers/gpu/drm/amd/display/dc/hubbub/dcn21/dcn21_hubbub.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/hubbub/dcn21/dcn21_hubbub.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/hubbub/dcn21/dcn21_hubbub.c
Extension
.c
Size
29315 bytes
Lines
724
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/delay.h>
#include "dm_services.h"
#include "dcn20/dcn20_hubbub.h"
#include "dcn21_hubbub.h"
#include "reg_helper.h"

#define REG(reg)\
	hubbub1->regs->reg
#define DC_LOGGER \
	hubbub1->base.ctx->logger
#define CTX \
	hubbub1->base.ctx

#undef FN
#define FN(reg_name, field_name) \
	hubbub1->shifts->field_name, hubbub1->masks->field_name

#define REG(reg)\
	hubbub1->regs->reg

#define CTX \
	hubbub1->base.ctx

#undef FN
#define FN(reg_name, field_name) \
	hubbub1->shifts->field_name, hubbub1->masks->field_name

static uint32_t convert_and_clamp(
	uint32_t wm_ns,
	uint32_t refclk_mhz,
	uint32_t clamp_value)
{
	uint32_t ret_val = 0;
	ret_val = wm_ns * refclk_mhz;
	ret_val /= 1000;

	if (ret_val > clamp_value)
		ret_val = clamp_value;

	return ret_val;
}

void dcn21_dchvm_init(struct hubbub *hubbub)
{
	struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
	uint32_t riommu_active;
	int i;

	//Init DCHVM block
	REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1);

	//Poll until RIOMMU_ACTIVE = 1
	for (i = 0; i < 100; i++) {
		REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active);

		if (riommu_active)
			break;
		else
			udelay(5);
	}

	if (riommu_active) {
		//Reflect the power status of DCHUBBUB
		REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);

		//Start rIOMMU prefetching
		REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);

		// Enable dynamic clock gating
		REG_UPDATE_4(DCHVM_CLK_CTRL,
						HVM_DISPCLK_R_GATE_DIS, 0,
						HVM_DISPCLK_G_GATE_DIS, 0,
						HVM_DCFCLK_R_GATE_DIS, 0,
						HVM_DCFCLK_G_GATE_DIS, 0);

		//Poll until HOSTVM_PREFETCH_DONE = 1
		REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100);

		hubbub->riommu_active = true;
	}
}

int hubbub21_init_dchub(struct hubbub *hubbub,
		struct dcn_hubbub_phys_addr_config *pa_config)
{
	struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
	struct dcn_vmid_page_table_config phys_config;

	REG_SET(DCN_VM_FB_LOCATION_BASE, 0,
			FB_BASE, ADDR_HI24(pa_config->system_aperture.fb_base));

Annotation

Implementation Notes