summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.c89
-rw-r--r--drivers/gpu/drm/amd/display/dc/hubbub/dcn60/dcn60_hubbub.h13
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn60/dcn60_soc_and_ip_translator.c6
-rw-r--r--drivers/gpu/drm/amd/display/include/dal_asic_id.h5
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,