diff options
Diffstat (limited to 'drivers')
7 files changed, 126 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h index 5f065b4045ee..53fac324748d 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h @@ -143,6 +143,7 @@ struct dcn_hubbub_registers { uint32_t DCHVM_CLK_CTRL; uint32_t DCHVM_RIOMMU_CTRL0; uint32_t DCHVM_RIOMMU_STAT0; + uint32_t DCHVM_PREFETCH_VFID; uint32_t DCHUBBUB_DET0_CTRL; uint32_t DCHUBBUB_DET1_CTRL; uint32_t DCHUBBUB_DET2_CTRL; @@ -398,7 +399,8 @@ struct dcn_hubbub_registers { type HOSTVM_PREFETCH_REQ; \ type HOSTVM_POWERSTATUS; \ type RIOMMU_ACTIVE; \ - type HOSTVM_PREFETCH_DONE + type HOSTVM_PREFETCH_DONE; \ + type HOSTVM_PREFETCH_VFID #define HUBBUB_RET_REG_FIELD_LIST(type) \ type DET_DEPTH;\ diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c index e2a457ab13bb..820b156474e1 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c @@ -18,6 +18,92 @@ #define FN(reg_name, field_name) \ hubbub2->shifts->field_name, hubbub2->masks->field_name +static void dcn60_control_dchvm_gating(const struct hubbub *hubbub, uint32_t disable_gating) +{ + const struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); + + if (disable_gating != 0) { + REG_UPDATE(DCHVM_MEM_CTRL, HVM_GPUVMRET_FORCE_REQ, 0); + } + + REG_UPDATE(DCHVM_MEM_CTRL, HVM_GPUVMRET_PWR_REQ_DIS, disable_gating); + + REG_UPDATE_4(DCHVM_CLK_CTRL, + HVM_DISPCLK_R_GATE_DIS, disable_gating, + HVM_DISPCLK_G_GATE_DIS, disable_gating, + HVM_DCFCLK_R_GATE_DIS, disable_gating, + HVM_DCFCLK_G_GATE_DIS, disable_gating); + + udelay(1); +} + +static void dcn60_dchvm_init(struct hubbub *hubbub) +{ + struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); + uint32_t riommu_active = 0; + uint32_t prefetch_done = 0; + unsigned int i; + + /* If already prefetched return early. */ + REG_GET(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, &prefetch_done); + + if (prefetch_done) { + hubbub->riommu_active = true; + return; + } + + /* Init DCHVM block. */ + REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); + + /* Poll until the rIOMMU and main IOMMU are active. */ + for (i = 0; i < 100u; i++) { + REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active); + if (riommu_active) + break; + + udelay(5); + } + + if (!riommu_active) { + DC_LOG_ERROR("Timed out waiting for DCHVM RIOMMU_ACTIVE\n"); + return; + } + + /* Disable gating and memory power requests. */ + dcn60_control_dchvm_gating(hubbub, 1); + + /* Select the physical function's host table for the initial prefetch. */ + REG_UPDATE(DCHVM_PREFETCH_VFID, HOSTVM_PREFETCH_VFID, 1U << 31); + + /* Reflect the power status of DCHUBBUB. */ + REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); + + /* Wait for power status to propagate to rIOMMU before prefetch req.*/ + udelay(5); + + /* Start rIOMMU prefetching. */ + REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); + + /* Poll for prefetch to be done. */ + REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); + + /* Re-enable gating and memory power requests. */ + dcn60_control_dchvm_gating(hubbub, 0); + + hubbub->riommu_active = true; +} + +static int hubbub60_init_dchub_sys_ctx(struct hubbub *hubbub, + struct dcn_hubbub_phys_addr_config *pa_config) +{ + int num_vmids = hubbub3_init_dchub_sys_ctx(hubbub, pa_config); + + if (hubbub->funcs->dchvm_init) + hubbub->funcs->dchvm_init(hubbub); + + return num_vmids; +} + static void dcn60_init_crb(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1752,7 +1838,7 @@ static void hubbub60_override_utm_client_qc_profile(struct hubbub *hubbub, uint8 static const struct hubbub_funcs hubbub60_funcs = { .update_dchub = hubbub2_update_dchub, - .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx, + .init_dchub_sys_ctx = hubbub60_init_dchub_sys_ctx, .init_vm_ctx = hubbub2_init_vm_ctx, .dcc_support_swizzle_addr3 = hubbub401_dcc_support_swizzle, .dcc_support_pixel_format_plane0_plane1 = @@ -1768,6 +1854,7 @@ static const struct hubbub_funcs hubbub60_funcs = { .force_pstate_change_control = hubbub3_force_pstate_change_control, .init_watermarks = hubbub60_init_watermarks, .init_crb = dcn60_init_crb, + .dchvm_init = dcn60_dchvm_init, .hubbub_read_state = hubbub2_read_state, .force_usr_retraining_allow = NULL, .set_request_limit = hubbub32_set_request_limit, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h index 03b5182d233c..ed47c462e8fe 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h @@ -16,6 +16,19 @@ #define DCN6_0_CRB_SEGMENT_SIZE_KB 64 #define HUBBUB_MASK_SH_LIST_DCN6_0(mask_sh)\ + HUBBUB_SF(DCHVM_CTRL0, HOSTVM_INIT_REQ, mask_sh), \ + HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_PWR_REQ_DIS, mask_sh), \ + HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_FORCE_REQ, mask_sh), \ + HUBBUB_SF(DCHVM_MEM_CTRL, HVM_GPUVMRET_POWER_STATUS, mask_sh), \ + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_R_GATE_DIS, mask_sh), \ + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DISPCLK_G_GATE_DIS, mask_sh), \ + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_R_GATE_DIS, mask_sh), \ + HUBBUB_SF(DCHVM_CLK_CTRL, HVM_DCFCLK_G_GATE_DIS, mask_sh), \ + HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, mask_sh), \ + HUBBUB_SF(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, mask_sh), \ + HUBBUB_SF(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, mask_sh), \ + HUBBUB_SF(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, mask_sh), \ + HUBBUB_SF(DCHVM_PREFETCH_VFID, HOSTVM_PREFETCH_VFID, mask_sh), \ HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ HUBBUB_SF(DCHUBBUB_SOFT_RESET, DCHUBBUB_GLOBAL_SOFT_RESET, mask_sh), \ HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \ diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c index 1cbff128789d..2dac5f7486d9 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c @@ -1962,6 +1962,8 @@ static bool dcn60_resource_construct( struct ddc_service_init_data ddc_init_data = {0}; uint32_t pipe_fuses = 0; uint32_t num_pipes = 4; + bool is_lite3 = + ASICREV_IS_DCN6_VARIANT_LITE3(ctx->asic_id.hw_internal_rev); #undef REG_STRUCT #define REG_STRUCT bios_regs @@ -2341,6 +2343,10 @@ static bool dcn60_resource_construct( dc->dml2_options.max_segments_per_hubp = 20; dc->dml2_options.det_segment_size = DCN6_0_CRB_SEGMENT_SIZE_KB; + if (is_lite3) { + dc->dml2_options.gpuvm_enable = true; + dc->dml2_options.hostvm_enable = true; + } /* SPL */ dc->caps.scl_caps.sharpener_support = true; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h index 913f049deeb3..b1a802f9f4b4 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h @@ -59,6 +59,12 @@ bool dcn50_program_mcache_pipe_config(struct dc_state *context, /* HUBBUB */ #define HUBBUB_REG_LIST_DCN60_RI(id) \ + SR(DCHVM_CTRL0), \ + SR(DCHVM_MEM_CTRL), \ + SR(DCHVM_CLK_CTRL), \ + SR(DCHVM_RIOMMU_CTRL0), \ + SR(DCHVM_RIOMMU_STAT0), \ + SR(DCHVM_PREFETCH_VFID), \ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A), \ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B), \ SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL), \ diff --git a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn60/dcn60_soc_and_ip_translator.c b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn60/dcn60_soc_and_ip_translator.c index c26ad0903975..f1ee2225e9b8 100644 --- a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn60/dcn60_soc_and_ip_translator.c +++ b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn60/dcn60_soc_and_ip_translator.c @@ -5,6 +5,7 @@ #include "dcn60_soc_and_ip_translator.h" #include "soc_and_ip_translator/dcn401/dcn401_soc_and_ip_translator.h" #include "bounding_boxes/dcn6_soc_bb.h" +#include "dal_asic_id.h" /* soc_and_ip_translator component used to get up-to-date values for bounding box. * Bounding box values are stored in several locations and locations can vary with DCN revision. @@ -94,7 +95,10 @@ static void apply_soc_bb_updates(struct dml2_soc_bb *soc_bb, const struct dc *dc static void dcn60_get_soc_bb(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config) { //get default soc_bb with static values - dcn6_test_initialize_soc_bb(soc_bb); + if (ASICREV_IS_DCN6_VARIANT_LITE3(dc->ctx->asic_id.hw_internal_rev)) + dcn6b_test_initialize_soc_bb(soc_bb); + else + dcn6_test_initialize_soc_bb(soc_bb); //get default soc_bb with static values apply_soc_bb_updates(soc_bb, dc, config); diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index 7ed785be8473..f4c6ddb6378e 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h @@ -275,6 +275,8 @@ enum { DCN6_VARIANT2_B0 = 0x11, DCN6_VARIANT3_A0 = 0x20, DCN6_VARIANT3_UPPER = 0x2F, + DCN6_VARIANT_LITE3_A0 = 0x50, + DCN6_VARIANT_LITE3_B0 = 0x51, DCN6_UNKNOWN = 0xFF }; @@ -284,6 +286,9 @@ enum { #define ASICREV_IS_DCN6_VARIANT2_A0(eChipRev) (eChipRev >= DCN6_VARIANT2_A0 && eChipRev < DCN6_VARIANT2_B0) #define ASICREV_IS_DCN6_VARIANT2_B0(eChipRev) (eChipRev >= DCN6_VARIANT2_B0 && eChipRev < DCN6_VARIANT3_A0) #define ASICREV_IS_DCN6_VARIANT3(eChipRev) (eChipRev >= DCN6_VARIANT3_A0 && eChipRev <= DCN6_VARIANT3_UPPER) +#define ASICREV_IS_DCN6_VARIANT_LITE3(eChipRev) (eChipRev >= DCN6_VARIANT_LITE3_A0 && eChipRev < DCN6_UNKNOWN) +#define ASICREV_IS_DCN6_VARIANT_LITE3_A0(eChipRev) (eChipRev >= DCN6_VARIANT_LITE3_A0 && eChipRev < DCN6_VARIANT_LITE3_B0) +#define ASICREV_IS_DCN6_VARIANT_LITE3_B0(eChipRev) (eChipRev >= DCN6_VARIANT_LITE3_B0 && eChipRev < DCN6_UNKNOWN) enum { GC_12_0_0_A0 = 0x50, |
