aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3443-drm-amd-display-Load-NV12-SOC-BB-from-firmware.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3443-drm-amd-display-Load-NV12-SOC-BB-from-firmware.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3443-drm-amd-display-Load-NV12-SOC-BB-from-firmware.patch311
1 files changed, 311 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3443-drm-amd-display-Load-NV12-SOC-BB-from-firmware.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3443-drm-amd-display-Load-NV12-SOC-BB-from-firmware.patch
new file mode 100644
index 00000000..c9d65b9e
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3443-drm-amd-display-Load-NV12-SOC-BB-from-firmware.patch
@@ -0,0 +1,311 @@
+From e3cde02f51794051497381012ddf9353a865c19d Mon Sep 17 00:00:00 2001
+From: Leo Li <sunpeng.li@amd.com>
+Date: Tue, 6 Aug 2019 13:50:28 -0400
+Subject: [PATCH 3443/4256] drm/amd/display: Load NV12 SOC BB from firmware
+
+[Why]
+
+Previous SOC bounding box firmware loading logic was for NV10, when we
+still had it in firmware. Now that it's brought into driver code, and
+NV12 BB is in firmware, this logic needs to be repurposed for NV12.
+
+[How]
+
+Set SOC_BOUNDING_BOX_VALID to false, and add the dcn_2_0_nv12_soc BB
+struct. In init_soc_bounding_box, load firmware to nv12 BB instead.
+
+In addition, conditionally update and patch the BB, depending on ASIC
+REV.
+
+Signed-off-by: Leo Li <sunpeng.li@amd.com>
+Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
+---
+ .../drm/amd/display/dc/dcn20/dcn20_resource.c | 156 +++++++++++-------
+ 1 file changed, 96 insertions(+), 60 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+index 000b2bfe54fb..c59f31dcdc0d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+@@ -80,7 +80,8 @@
+
+ #include "amdgpu_socbb.h"
+
+-#define SOC_BOUNDING_BOX_VALID true
++/* NV12 SOC BB is currently in FW, mark SW bounding box invalid. */
++#define SOC_BOUNDING_BOX_VALID false
+ #define DC_LOGGER_INIT(logger)
+
+ struct _vcs_dpi_ip_params_st dcn2_0_ip = {
+@@ -266,6 +267,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = {
+ .use_urgent_burst_bw = 0
+ };
+
++struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 };
+
+ #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
+ #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
+@@ -3042,6 +3044,27 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s
+ kernel_fpu_end();
+ }
+
++static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb(
++ uint32_t hw_internal_rev)
++{
++ if (ASICREV_IS_NAVI12_P(hw_internal_rev))
++ return &dcn2_0_nv12_soc;
++
++ return &dcn2_0_soc;
++}
++
++static struct _vcs_dpi_ip_params_st *get_asic_rev_ip_params(
++ uint32_t hw_internal_rev)
++{
++ /* NV12 and NV10 */
++ return &dcn2_0_ip;
++}
++
++static enum dml_project get_dml_project_version(uint32_t hw_internal_rev)
++{
++ return DML_PROJECT_NAVI10v2;
++}
++
+ #define fixed16_to_double(x) (((double) x) / ((double) (1 << 16)))
+ #define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
+
+@@ -3049,6 +3072,11 @@ static bool init_soc_bounding_box(struct dc *dc,
+ struct dcn20_resource_pool *pool)
+ {
+ const struct gpu_info_soc_bounding_box_v1_0 *bb = dc->soc_bounding_box;
++ struct _vcs_dpi_soc_bounding_box_st *loaded_bb =
++ get_asic_rev_soc_bb(dc->ctx->asic_id.hw_internal_rev);
++ struct _vcs_dpi_ip_params_st *loaded_ip =
++ get_asic_rev_ip_params(dc->ctx->asic_id.hw_internal_rev);
++
+ DC_LOGGER_INIT(dc->ctx->logger);
+
+ if (!bb && !SOC_BOUNDING_BOX_VALID) {
+@@ -3059,101 +3087,103 @@ static bool init_soc_bounding_box(struct dc *dc,
+ if (bb && !SOC_BOUNDING_BOX_VALID) {
+ int i;
+
+- dcn2_0_soc.sr_exit_time_us =
++ dcn2_0_nv12_soc.sr_exit_time_us =
+ fixed16_to_double_to_cpu(bb->sr_exit_time_us);
+- dcn2_0_soc.sr_enter_plus_exit_time_us =
++ dcn2_0_nv12_soc.sr_enter_plus_exit_time_us =
+ fixed16_to_double_to_cpu(bb->sr_enter_plus_exit_time_us);
+- dcn2_0_soc.urgent_latency_us =
++ dcn2_0_nv12_soc.urgent_latency_us =
+ fixed16_to_double_to_cpu(bb->urgent_latency_us);
+- dcn2_0_soc.urgent_latency_pixel_data_only_us =
++ dcn2_0_nv12_soc.urgent_latency_pixel_data_only_us =
+ fixed16_to_double_to_cpu(bb->urgent_latency_pixel_data_only_us);
+- dcn2_0_soc.urgent_latency_pixel_mixed_with_vm_data_us =
++ dcn2_0_nv12_soc.urgent_latency_pixel_mixed_with_vm_data_us =
+ fixed16_to_double_to_cpu(bb->urgent_latency_pixel_mixed_with_vm_data_us);
+- dcn2_0_soc.urgent_latency_vm_data_only_us =
++ dcn2_0_nv12_soc.urgent_latency_vm_data_only_us =
+ fixed16_to_double_to_cpu(bb->urgent_latency_vm_data_only_us);
+- dcn2_0_soc.urgent_out_of_order_return_per_channel_pixel_only_bytes =
++ dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_pixel_only_bytes =
+ le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_only_bytes);
+- dcn2_0_soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes =
++ dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes =
+ le32_to_cpu(bb->urgent_out_of_order_return_per_channel_pixel_and_vm_bytes);
+- dcn2_0_soc.urgent_out_of_order_return_per_channel_vm_only_bytes =
++ dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_vm_only_bytes =
+ le32_to_cpu(bb->urgent_out_of_order_return_per_channel_vm_only_bytes);
+- dcn2_0_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only =
++ dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_only =
+ fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_only);
+- dcn2_0_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm =
++ dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm =
+ fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm);
+- dcn2_0_soc.pct_ideal_dram_sdp_bw_after_urgent_vm_only =
++ dcn2_0_nv12_soc.pct_ideal_dram_sdp_bw_after_urgent_vm_only =
+ fixed16_to_double_to_cpu(bb->pct_ideal_dram_sdp_bw_after_urgent_vm_only);
+- dcn2_0_soc.max_avg_sdp_bw_use_normal_percent =
++ dcn2_0_nv12_soc.max_avg_sdp_bw_use_normal_percent =
+ fixed16_to_double_to_cpu(bb->max_avg_sdp_bw_use_normal_percent);
+- dcn2_0_soc.max_avg_dram_bw_use_normal_percent =
++ dcn2_0_nv12_soc.max_avg_dram_bw_use_normal_percent =
+ fixed16_to_double_to_cpu(bb->max_avg_dram_bw_use_normal_percent);
+- dcn2_0_soc.writeback_latency_us =
++ dcn2_0_nv12_soc.writeback_latency_us =
+ fixed16_to_double_to_cpu(bb->writeback_latency_us);
+- dcn2_0_soc.ideal_dram_bw_after_urgent_percent =
++ dcn2_0_nv12_soc.ideal_dram_bw_after_urgent_percent =
+ fixed16_to_double_to_cpu(bb->ideal_dram_bw_after_urgent_percent);
+- dcn2_0_soc.max_request_size_bytes =
++ dcn2_0_nv12_soc.max_request_size_bytes =
+ le32_to_cpu(bb->max_request_size_bytes);
+- dcn2_0_soc.dram_channel_width_bytes =
++ dcn2_0_nv12_soc.dram_channel_width_bytes =
+ le32_to_cpu(bb->dram_channel_width_bytes);
+- dcn2_0_soc.fabric_datapath_to_dcn_data_return_bytes =
++ dcn2_0_nv12_soc.fabric_datapath_to_dcn_data_return_bytes =
+ le32_to_cpu(bb->fabric_datapath_to_dcn_data_return_bytes);
+- dcn2_0_soc.dcn_downspread_percent =
++ dcn2_0_nv12_soc.dcn_downspread_percent =
+ fixed16_to_double_to_cpu(bb->dcn_downspread_percent);
+- dcn2_0_soc.downspread_percent =
++ dcn2_0_nv12_soc.downspread_percent =
+ fixed16_to_double_to_cpu(bb->downspread_percent);
+- dcn2_0_soc.dram_page_open_time_ns =
++ dcn2_0_nv12_soc.dram_page_open_time_ns =
+ fixed16_to_double_to_cpu(bb->dram_page_open_time_ns);
+- dcn2_0_soc.dram_rw_turnaround_time_ns =
++ dcn2_0_nv12_soc.dram_rw_turnaround_time_ns =
+ fixed16_to_double_to_cpu(bb->dram_rw_turnaround_time_ns);
+- dcn2_0_soc.dram_return_buffer_per_channel_bytes =
++ dcn2_0_nv12_soc.dram_return_buffer_per_channel_bytes =
+ le32_to_cpu(bb->dram_return_buffer_per_channel_bytes);
+- dcn2_0_soc.round_trip_ping_latency_dcfclk_cycles =
++ dcn2_0_nv12_soc.round_trip_ping_latency_dcfclk_cycles =
+ le32_to_cpu(bb->round_trip_ping_latency_dcfclk_cycles);
+- dcn2_0_soc.urgent_out_of_order_return_per_channel_bytes =
++ dcn2_0_nv12_soc.urgent_out_of_order_return_per_channel_bytes =
+ le32_to_cpu(bb->urgent_out_of_order_return_per_channel_bytes);
+- dcn2_0_soc.channel_interleave_bytes =
++ dcn2_0_nv12_soc.channel_interleave_bytes =
+ le32_to_cpu(bb->channel_interleave_bytes);
+- dcn2_0_soc.num_banks =
++ dcn2_0_nv12_soc.num_banks =
+ le32_to_cpu(bb->num_banks);
+- dcn2_0_soc.num_chans =
++ dcn2_0_nv12_soc.num_chans =
+ le32_to_cpu(bb->num_chans);
+- dcn2_0_soc.vmm_page_size_bytes =
++ dcn2_0_nv12_soc.vmm_page_size_bytes =
+ le32_to_cpu(bb->vmm_page_size_bytes);
+- dcn2_0_soc.dram_clock_change_latency_us =
++ dcn2_0_nv12_soc.dram_clock_change_latency_us =
+ fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us);
+- dcn2_0_soc.writeback_dram_clock_change_latency_us =
++ // HACK!! Lower uclock latency switch time so we don't switch
++ dcn2_0_nv12_soc.dram_clock_change_latency_us = 10;
++ dcn2_0_nv12_soc.writeback_dram_clock_change_latency_us =
+ fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us);
+- dcn2_0_soc.return_bus_width_bytes =
++ dcn2_0_nv12_soc.return_bus_width_bytes =
+ le32_to_cpu(bb->return_bus_width_bytes);
+- dcn2_0_soc.dispclk_dppclk_vco_speed_mhz =
++ dcn2_0_nv12_soc.dispclk_dppclk_vco_speed_mhz =
+ le32_to_cpu(bb->dispclk_dppclk_vco_speed_mhz);
+- dcn2_0_soc.xfc_bus_transport_time_us =
++ dcn2_0_nv12_soc.xfc_bus_transport_time_us =
+ le32_to_cpu(bb->xfc_bus_transport_time_us);
+- dcn2_0_soc.xfc_xbuf_latency_tolerance_us =
++ dcn2_0_nv12_soc.xfc_xbuf_latency_tolerance_us =
+ le32_to_cpu(bb->xfc_xbuf_latency_tolerance_us);
+- dcn2_0_soc.use_urgent_burst_bw =
++ dcn2_0_nv12_soc.use_urgent_burst_bw =
+ le32_to_cpu(bb->use_urgent_burst_bw);
+- dcn2_0_soc.num_states =
++ dcn2_0_nv12_soc.num_states =
+ le32_to_cpu(bb->num_states);
+
+- for (i = 0; i < dcn2_0_soc.num_states; i++) {
+- dcn2_0_soc.clock_limits[i].state =
++ for (i = 0; i < dcn2_0_nv12_soc.num_states; i++) {
++ dcn2_0_nv12_soc.clock_limits[i].state =
+ le32_to_cpu(bb->clock_limits[i].state);
+- dcn2_0_soc.clock_limits[i].dcfclk_mhz =
++ dcn2_0_nv12_soc.clock_limits[i].dcfclk_mhz =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].dcfclk_mhz);
+- dcn2_0_soc.clock_limits[i].fabricclk_mhz =
++ dcn2_0_nv12_soc.clock_limits[i].fabricclk_mhz =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].fabricclk_mhz);
+- dcn2_0_soc.clock_limits[i].dispclk_mhz =
++ dcn2_0_nv12_soc.clock_limits[i].dispclk_mhz =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].dispclk_mhz);
+- dcn2_0_soc.clock_limits[i].dppclk_mhz =
++ dcn2_0_nv12_soc.clock_limits[i].dppclk_mhz =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].dppclk_mhz);
+- dcn2_0_soc.clock_limits[i].phyclk_mhz =
++ dcn2_0_nv12_soc.clock_limits[i].phyclk_mhz =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].phyclk_mhz);
+- dcn2_0_soc.clock_limits[i].socclk_mhz =
++ dcn2_0_nv12_soc.clock_limits[i].socclk_mhz =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].socclk_mhz);
+- dcn2_0_soc.clock_limits[i].dscclk_mhz =
++ dcn2_0_nv12_soc.clock_limits[i].dscclk_mhz =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].dscclk_mhz);
+- dcn2_0_soc.clock_limits[i].dram_speed_mts =
++ dcn2_0_nv12_soc.clock_limits[i].dram_speed_mts =
+ fixed16_to_double_to_cpu(bb->clock_limits[i].dram_speed_mts);
+ }
+ }
+@@ -3184,14 +3214,14 @@ static bool init_soc_bounding_box(struct dc *dc,
+ }
+
+ if (clock_limits_available && uclk_states_available && num_states)
+- update_bounding_box(dc, &dcn2_0_soc, &max_clocks, uclk_states, num_states);
++ update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
+ else if (clock_limits_available)
+- cap_soc_clocks(&dcn2_0_soc, max_clocks);
++ cap_soc_clocks(loaded_bb, max_clocks);
+ }
+
+- dcn2_0_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
+- dcn2_0_ip.max_num_dpp = pool->base.pipe_count;
+- patch_bounding_box(dc, &dcn2_0_soc);
++ loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
++ loaded_ip->max_num_dpp = pool->base.pipe_count;
++ patch_bounding_box(dc, loaded_bb);
+
+ return true;
+ }
+@@ -3204,6 +3234,12 @@ static bool construct(
+ int i;
+ struct dc_context *ctx = dc->ctx;
+ struct irq_service_init_data init_data;
++ struct _vcs_dpi_soc_bounding_box_st *loaded_bb =
++ get_asic_rev_soc_bb(ctx->asic_id.hw_internal_rev);
++ struct _vcs_dpi_ip_params_st *loaded_ip =
++ get_asic_rev_ip_params(ctx->asic_id.hw_internal_rev);
++ enum dml_project dml_project_version =
++ get_dml_project_version(ctx->asic_id.hw_internal_rev);
+
+ ctx->dc_bios->regs = &bios_regs;
+ pool->base.funcs = &dcn20_res_pool_funcs;
+@@ -3327,7 +3363,7 @@ static bool construct(
+ goto create_fail;
+ }
+
+- dml_init_instance(&dc->dml, &dcn2_0_soc, &dcn2_0_ip, DML_PROJECT_NAVI10v2);
++ dml_init_instance(&dc->dml, loaded_bb, loaded_ip, dml_project_version);
+
+ if (!dc->debug.disable_pplib_wm_range) {
+ struct pp_smu_wm_range_sets ranges = {0};
+@@ -3335,7 +3371,7 @@ static bool construct(
+
+ ranges.num_reader_wm_sets = 0;
+
+- if (dcn2_0_soc.num_states == 1) {
++ if (loaded_bb->num_states == 1) {
+ ranges.reader_wm_sets[0].wm_inst = i;
+ ranges.reader_wm_sets[0].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
+ ranges.reader_wm_sets[0].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
+@@ -3343,13 +3379,13 @@ static bool construct(
+ ranges.reader_wm_sets[0].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
+
+ ranges.num_reader_wm_sets = 1;
+- } else if (dcn2_0_soc.num_states > 1) {
+- for (i = 0; i < 4 && i < dcn2_0_soc.num_states; i++) {
++ } else if (loaded_bb->num_states > 1) {
++ for (i = 0; i < 4 && i < loaded_bb->num_states; i++) {
+ ranges.reader_wm_sets[i].wm_inst = i;
+ ranges.reader_wm_sets[i].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
+ ranges.reader_wm_sets[i].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
+- ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (dcn2_0_soc.clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
+- ranges.reader_wm_sets[i].max_fill_clk_mhz = dcn2_0_soc.clock_limits[i].dram_speed_mts / 16;
++ ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
++ ranges.reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
+
+ ranges.num_reader_wm_sets = i + 1;
+ }
+--
+2.17.1
+