diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0713-drm-amd-dal-create-dce100-resource.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0713-drm-amd-dal-create-dce100-resource.patch | 1225 |
1 files changed, 1225 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0713-drm-amd-dal-create-dce100-resource.patch b/common/recipes-kernel/linux/files/0713-drm-amd-dal-create-dce100-resource.patch new file mode 100644 index 00000000..1694c249 --- /dev/null +++ b/common/recipes-kernel/linux/files/0713-drm-amd-dal-create-dce100-resource.patch @@ -0,0 +1,1225 @@ +From 43d730fd93c53ecad452edd80ee2fa4b5ad7c1f3 Mon Sep 17 00:00:00 2001 +From: Eric Yang <eric.yang2@amd.com> +Date: Wed, 20 Jan 2016 17:43:06 -0500 +Subject: [PATCH 0713/1110] drm/amd/dal: create dce100 resource + +This has been verified by creating dce100 resouce +in dce110_hwsequencer + +Signed-off-by: Eric Yang <eric.yang2@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + drivers/gpu/drm/amd/dal/dc/Makefile | 4 + + drivers/gpu/drm/amd/dal/dc/dce100/Makefile | 23 + + .../gpu/drm/amd/dal/dc/dce100/dce100_resource.c | 1122 ++++++++++++++++++++ + .../gpu/drm/amd/dal/dc/dce100/dce100_resource.h | 24 + + 4 files changed, 1173 insertions(+) + create mode 100644 drivers/gpu/drm/amd/dal/dc/dce100/Makefile + create mode 100644 drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c + create mode 100644 drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.h + +diff --git a/drivers/gpu/drm/amd/dal/dc/Makefile b/drivers/gpu/drm/amd/dal/dc/Makefile +index fc1dd0e..05d8ce7 100644 +--- a/drivers/gpu/drm/amd/dal/dc/Makefile ++++ b/drivers/gpu/drm/amd/dal/dc/Makefile +@@ -9,6 +9,10 @@ ifdef CONFIG_DRM_AMD_DAL_DCE11_0 + DC_LIBS += dce110 + endif + ++ifdef CONFIG_DRM_AMD_DAL_DCE10_0 ++DC_LIBS += dce100 ++endif ++ + AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DAL_PATH)/dc/,$(DC_LIBS))) + + include $(AMD_DC) +diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/Makefile b/drivers/gpu/drm/amd/dal/dc/dce100/Makefile +new file mode 100644 +index 0000000..4c0b4d5 +--- /dev/null ++++ b/drivers/gpu/drm/amd/dal/dc/dce100/Makefile +@@ -0,0 +1,23 @@ ++# ++# Makefile for the 'controller' sub-component of DAL. ++# It provides the control and status of HW CRTC block. ++ ++DCE100 = dce100_resource.o ++ ++AMD_DAL_DCE100 = $(addprefix $(AMDDALPATH)/dc/dce100/,$(DCE100)) ++ ++AMD_DAL_FILES += $(AMD_DAL_DCE100) ++ ++ ++############################################################################### ++# DCE 10x ++############################################################################### ++ifdef 0#CONFIG_DRM_AMD_DAL_DCE11_0 ++TG_DCE100 = dce100_resource.o ++ ++AMD_DAL_TG_DCE100 = $(addprefix \ ++ $(AMDDALPATH)/dc/dce100/,$(TG_DCE100)) ++ ++AMD_DAL_FILES += $(AMD_DAL_TG_DCE100) ++endif ++ +diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c +new file mode 100644 +index 0000000..72493d7 +--- /dev/null ++++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c +@@ -0,0 +1,1122 @@ ++/* ++* Copyright 2012-15 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: AMD ++ * ++ */ ++#include "dc_services.h" ++ ++#include "link_encoder.h" ++#include "stream_encoder.h" ++ ++#include "resource.h" ++#include "include/irq_service_interface.h" ++#include "include/timing_generator_interface.h" ++ ++#include "dce110/dce110_timing_generator.h" ++#include "dce110/dce110_link_encoder.h" ++#include "dce110/dce110_mem_input.h" ++#include "dce110/dce110_ipp.h" ++#include "dce110/dce110_transform.h" ++#include "dce110/dce110_stream_encoder.h" ++#include "dce110/dce110_opp.h" ++ ++#include "dce/dce_10_0_d.h" ++ ++enum dce100_clk_src_array_id { ++ DCE100_CLK_SRC_PLL0 = 0, ++ DCE100_CLK_SRC_PLL1, ++ DCE100_CLK_SRC_EXT, ++ ++ DCE100_CLK_SRC_TOTAL ++}; ++ ++static const struct dce110_timing_generator_offsets dce100_tg_offsets[] = { ++ { ++ .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL), ++ .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL), ++ }, ++ { ++ .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL), ++ .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), ++ }, ++ { ++ .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL), ++ .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), ++ }, ++ { ++ .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL), ++ .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), ++ }, ++ { ++ .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL), ++ .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), ++ }, ++ { ++ .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL), ++ .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), ++ } ++}; ++ ++static const struct dce110_stream_enc_offsets dce100_str_enc_offsets[] = { ++ { ++ .dig = (mmDIG0_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP0_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG1_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP1_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG2_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP2_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG3_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP3_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG4_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP4_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG5_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP5_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG6_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP6_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ } ++}; ++ ++static const struct dce110_link_enc_offsets dce100_lnk_enc_reg_offsets[] = { ++ { ++ .dig = (mmDIG0_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP0_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG1_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP1_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG2_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP2_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG3_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP3_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG4_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP4_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG5_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP5_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ }, ++ { ++ .dig = (mmDIG6_DIG_FE_CNTL - mmDIG_FE_CNTL), ++ .dp = (mmDP6_DP_SEC_CNTL - mmDP_SEC_CNTL) ++ } ++}; ++ ++static const struct dce110_mem_input_reg_offsets dce100_mi_reg_offsets[] = { ++ { ++ .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL), ++ .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL ++ - mmDPG_WATERMARK_MASK_CONTROL), ++ .pipe = (mmPIPE0_DMIF_BUFFER_CONTROL ++ - mmPIPE0_DMIF_BUFFER_CONTROL), ++ }, ++ { ++ .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), ++ .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL ++ - mmDPG_WATERMARK_MASK_CONTROL), ++ .pipe = (mmPIPE1_DMIF_BUFFER_CONTROL ++ - mmPIPE0_DMIF_BUFFER_CONTROL), ++ }, ++ { ++ .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), ++ .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL ++ - mmDPG_WATERMARK_MASK_CONTROL), ++ .pipe = (mmPIPE2_DMIF_BUFFER_CONTROL ++ - mmPIPE0_DMIF_BUFFER_CONTROL), ++ }, ++ { ++ .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), ++ .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL ++ - mmDPG_WATERMARK_MASK_CONTROL), ++ .pipe = (mmPIPE3_DMIF_BUFFER_CONTROL ++ - mmPIPE0_DMIF_BUFFER_CONTROL), ++ }, ++ { ++ .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), ++ .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL ++ - mmDPG_WATERMARK_MASK_CONTROL), ++ .pipe = (mmPIPE4_DMIF_BUFFER_CONTROL ++ - mmPIPE0_DMIF_BUFFER_CONTROL), ++ }, ++ { ++ .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), ++ .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL ++ - mmDPG_WATERMARK_MASK_CONTROL), ++ .pipe = (mmPIPE5_DMIF_BUFFER_CONTROL ++ - mmPIPE0_DMIF_BUFFER_CONTROL), ++ } ++}; ++ ++static const struct dce110_transform_reg_offsets dce100_xfm_offsets[] = { ++{ ++ .scl_offset = (mmSCL0_SCL_CONTROL - mmSCL_CONTROL), ++ .dcfe_offset = (mmCRTC0_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL), ++ .lb_offset = (mmLB0_LB_DATA_FORMAT - mmLB_DATA_FORMAT), ++}, ++{ .scl_offset = (mmSCL1_SCL_CONTROL - mmSCL_CONTROL), ++ .dcfe_offset = (mmCRTC1_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL), ++ .lb_offset = (mmLB1_LB_DATA_FORMAT - mmLB_DATA_FORMAT), ++}, ++{ .scl_offset = (mmSCL2_SCL_CONTROL - mmSCL_CONTROL), ++ .dcfe_offset = (mmCRTC2_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL), ++ .lb_offset = (mmLB2_LB_DATA_FORMAT - mmLB_DATA_FORMAT), ++}, ++{ ++ .scl_offset = (mmSCL3_SCL_CONTROL - mmSCL_CONTROL), ++ .dcfe_offset = (mmCRTC3_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcp_offset = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL), ++ .lb_offset = (mmLB3_LB_DATA_FORMAT - mmLB_DATA_FORMAT), ++}, ++{ .scl_offset = (mmSCL4_SCL_CONTROL - mmSCL_CONTROL), ++ .dcfe_offset = (mmCRTC4_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcp_offset = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL), ++ .lb_offset = (mmLB4_LB_DATA_FORMAT - mmLB_DATA_FORMAT), ++}, ++{ .scl_offset = (mmSCL5_SCL_CONTROL - mmSCL_CONTROL), ++ .dcfe_offset = (mmCRTC5_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL), ++ .dcp_offset = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL), ++ .lb_offset = (mmLB5_LB_DATA_FORMAT - mmLB_DATA_FORMAT), ++} ++}; ++ ++static const struct dce110_ipp_reg_offsets dce100_ipp_reg_offsets[] = { ++{ ++ .dcp_offset = (mmDCP0_CUR_CONTROL - mmCUR_CONTROL), ++}, ++{ ++ .dcp_offset = (mmDCP1_CUR_CONTROL - mmCUR_CONTROL), ++}, ++{ ++ .dcp_offset = (mmDCP2_CUR_CONTROL - mmCUR_CONTROL), ++}, ++{ ++ .dcp_offset = (mmDCP3_CUR_CONTROL - mmCUR_CONTROL), ++}, ++{ ++ .dcp_offset = (mmDCP4_CUR_CONTROL - mmCUR_CONTROL), ++}, ++{ ++ .dcp_offset = (mmDCP5_CUR_CONTROL - mmCUR_CONTROL), ++} ++}; ++ ++static struct timing_generator *dce100_timing_generator_create( ++ struct adapter_service *as, ++ struct dc_context *ctx, ++ uint32_t instance, ++ const struct dce110_timing_generator_offsets *offsets) ++{ ++ struct dce110_timing_generator *tg110 = ++ dc_service_alloc(ctx, sizeof(struct dce110_timing_generator)); ++ ++ if (!tg110) ++ return NULL; ++ ++ if (dce110_timing_generator_construct(tg110, as, ctx, instance, ++ offsets)) ++ return &tg110->base; ++ ++ BREAK_TO_DEBUGGER(); ++ dc_service_free(ctx, tg110); ++ return NULL; ++} ++ ++static struct stream_encoder *dce100_stream_encoder_create( ++ enum engine_id eng_id, ++ struct dc_context *ctx, ++ struct dc_bios *bp, ++ const struct dce110_stream_enc_offsets *offsets) ++{ ++ struct dce110_stream_encoder *enc110 = ++ dc_service_alloc(ctx, sizeof(struct dce110_stream_encoder)); ++ ++ if (!enc110) ++ return NULL; ++ ++ if (dce110_stream_encoder_construct(enc110, ctx, bp, eng_id, offsets)) ++ return &enc110->base; ++ ++ BREAK_TO_DEBUGGER(); ++ dc_service_free(ctx, enc110); ++ return NULL; ++} ++ ++static struct mem_input *dce100_mem_input_create( ++ struct dc_context *ctx, ++ uint32_t inst, ++ const struct dce110_mem_input_reg_offsets *offset) ++{ ++ struct dce110_mem_input *mem_input110 = ++ dc_service_alloc(ctx, sizeof(struct dce110_mem_input)); ++ ++ if (!mem_input110) ++ return NULL; ++ ++ if (dce110_mem_input_construct(mem_input110, ++ ctx, inst, offset)) ++ return &mem_input110->base; ++ ++ BREAK_TO_DEBUGGER(); ++ dc_service_free(ctx, mem_input110); ++ return NULL; ++} ++ ++static void dce100_transform_destroy(struct transform **xfm) ++{ ++ dc_service_free((*xfm)->ctx, TO_DCE110_TRANSFORM(*xfm)); ++ *xfm = NULL; ++} ++ ++static struct transform *dce100_transform_create( ++ struct dc_context *ctx, ++ uint32_t inst, ++ const struct dce110_transform_reg_offsets *offsets) ++{ ++ struct dce110_transform *transform = ++ dc_service_alloc(ctx, sizeof(struct dce110_transform)); ++ ++ if (!transform) ++ return NULL; ++ ++ if (dce110_transform_construct(transform, ctx, inst, offsets)) ++ return &transform->base; ++ ++ BREAK_TO_DEBUGGER(); ++ dc_service_free(ctx, transform); ++ return NULL; ++} ++ ++static struct input_pixel_processor *dce100_ipp_create( ++ struct dc_context *ctx, ++ uint32_t inst, ++ const struct dce110_ipp_reg_offsets *offsets) ++{ ++ struct dce110_ipp *ipp = ++ dc_service_alloc(ctx, sizeof(struct dce110_ipp)); ++ ++ if (!ipp) ++ return NULL; ++ ++ if (dce110_ipp_construct(ipp, ctx, inst, offsets)) ++ return &ipp->base; ++ ++ BREAK_TO_DEBUGGER(); ++ dc_service_free(ctx, ipp); ++ return NULL; ++} ++ ++struct link_encoder *dce100_link_encoder_create( ++ const struct encoder_init_data *enc_init_data) ++{ ++ struct dce110_link_encoder *enc110 = ++ dc_service_alloc( ++ enc_init_data->ctx, ++ sizeof(struct dce110_link_encoder)); ++ ++ if (!enc110) ++ return NULL; ++ ++ if (dce110_link_encoder_construct( ++ enc110, ++ enc_init_data, ++ &dce100_lnk_enc_reg_offsets[enc_init_data->transmitter])) ++ return &enc110->base; ++ ++ BREAK_TO_DEBUGGER(); ++ dc_service_free(enc_init_data->ctx, enc110); ++ return NULL; ++} ++ ++bool dce100_construct_resource_pool( ++ struct adapter_service *adapter_serv, ++ struct dc *dc, ++ struct resource_pool *pool) ++{ ++ unsigned int i; ++ struct clock_source_init_data clk_src_init_data = { 0 }; ++ struct audio_init_data audio_init_data = { 0 }; ++ struct dc_context *ctx = dc->ctx; ++ ++ pool->adapter_srv = adapter_serv; ++ ++ pool->stream_engines.engine.ENGINE_ID_DIGA = 1; ++ pool->stream_engines.engine.ENGINE_ID_DIGB = 1; ++ pool->stream_engines.engine.ENGINE_ID_DIGC = 1; ++ pool->stream_engines.engine.ENGINE_ID_DIGD = 1; ++ pool->stream_engines.engine.ENGINE_ID_DIGE = 1; ++ pool->stream_engines.engine.ENGINE_ID_DIGF = 1; ++ ++ clk_src_init_data.as = adapter_serv; ++ clk_src_init_data.ctx = ctx; ++ clk_src_init_data.clk_src_id.enum_id = ENUM_ID_1; ++ clk_src_init_data.clk_src_id.type = OBJECT_TYPE_CLOCK_SOURCE; ++ pool->clk_src_count = DCE100_CLK_SRC_TOTAL; ++ ++ clk_src_init_data.clk_src_id.id = CLOCK_SOURCE_ID_PLL0; ++ pool->clock_sources[DCE100_CLK_SRC_PLL0] = dal_clock_source_create( ++ &clk_src_init_data); ++ clk_src_init_data.clk_src_id.id = CLOCK_SOURCE_ID_PLL1; ++ pool->clock_sources[DCE100_CLK_SRC_PLL1] = dal_clock_source_create( ++ &clk_src_init_data); ++ clk_src_init_data.clk_src_id.id = CLOCK_SOURCE_ID_EXTERNAL; ++ pool->clock_sources[DCE100_CLK_SRC_EXT] = dal_clock_source_create( ++ &clk_src_init_data); ++ ++ for (i = 0; i < pool->clk_src_count; i++) { ++ if (pool->clock_sources[i] == NULL) { ++ dal_error("DC: failed to create clock sources!\n"); ++ BREAK_TO_DEBUGGER(); ++ goto clk_src_create_fail; ++ } ++ } ++ ++ pool->display_clock = dal_display_clock_dce110_create(ctx, adapter_serv); ++ if (pool->display_clock == NULL) { ++ dal_error("DC: failed to create display clock!\n"); ++ BREAK_TO_DEBUGGER(); ++ goto disp_clk_create_fail; ++ } ++ ++ { ++ struct irq_service_init_data init_data; ++ ++ init_data.ctx = dc->ctx; ++ pool->irqs = dal_irq_service_create( ++ dal_adapter_service_get_dce_version( ++ dc->res_pool.adapter_srv), ++ &init_data); ++ if (!pool->irqs) ++ goto irqs_create_fail; ++ ++ } ++ ++ pool->controller_count = ++ dal_adapter_service_get_func_controllers_num(adapter_serv); ++ pool->stream_enc_count = dal_adapter_service_get_stream_engines_num( ++ adapter_serv); ++ pool->scaler_filter = dal_scaler_filter_create(ctx); ++ if (pool->scaler_filter == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error("DC: failed to create filter!\n"); ++ goto filter_create_fail; ++ } ++ ++ for (i = 0; i < pool->controller_count; i++) { ++ pool->timing_generators[i] = dce100_timing_generator_create( ++ adapter_serv, ctx, i, &dce100_tg_offsets[i]); ++ if (pool->timing_generators[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error("DC: failed to create tg!\n"); ++ goto controller_create_fail; ++ } ++ ++ pool->mis[i] = dce100_mem_input_create(ctx, i, ++ &dce100_mi_reg_offsets[i]); ++ if (pool->mis[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error( ++ "DC: failed to create memory input!\n"); ++ goto controller_create_fail; ++ } ++ ++ pool->ipps[i] = dce100_ipp_create(ctx, i, ++ &dce100_ipp_reg_offsets[i]); ++ if (pool->ipps[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error( ++ "DC: failed to create input pixel processor!\n"); ++ goto controller_create_fail; ++ } ++ ++ pool->transforms[i] = dce100_transform_create( ++ ctx, i, &dce100_xfm_offsets[i]); ++ if (pool->transforms[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error( ++ "DC: failed to create transform!\n"); ++ goto controller_create_fail; ++ } ++ pool->transforms[i]->funcs->transform_set_scaler_filter( ++ pool->transforms[i], ++ pool->scaler_filter); ++ ++ pool->opps[i] = dce110_opp_create(ctx, i); ++ if (pool->opps[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error( ++ "DC: failed to create output pixel processor!\n"); ++ goto controller_create_fail; ++ } ++ } ++ ++ audio_init_data.as = adapter_serv; ++ audio_init_data.ctx = ctx; ++ pool->audio_count = 0; ++ for (i = 0; i < pool->controller_count; i++) { ++ struct graphics_object_id obj_id; ++ ++ obj_id = dal_adapter_service_enum_audio_object(adapter_serv, i); ++ if (false == dal_graphics_object_id_is_valid(obj_id)) { ++ /* no more valid audio objects */ ++ break; ++ } ++ ++ audio_init_data.audio_stream_id = obj_id; ++ pool->audios[i] = dal_audio_create(&audio_init_data); ++ if (pool->audios[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error("DC: failed to create DPPs!\n"); ++ goto audio_create_fail; ++ } ++ pool->audio_count++; ++ } ++ ++ for (i = 0; i < pool->stream_enc_count; i++) { ++ /* TODO: rework fragile code*/ ++ if (pool->stream_engines.u_all & 1 << i) { ++ pool->stream_enc[i] = dce100_stream_encoder_create( ++ i, dc->ctx, ++ dal_adapter_service_get_bios_parser( ++ adapter_serv), ++ &dce100_str_enc_offsets[i]); ++ if (pool->stream_enc[i] == NULL) { ++ BREAK_TO_DEBUGGER(); ++ dal_error("DC: failed to create stream_encoder!\n"); ++ goto stream_enc_create_fail; ++ } ++ } ++ } ++ ++ return true; ++ ++stream_enc_create_fail: ++ for (i = 0; i < pool->stream_enc_count; i++) { ++ if (pool->stream_enc[i] != NULL) ++ dc_service_free(pool->stream_enc[i]->ctx, ++ DCE110STRENC_FROM_STRENC(pool->stream_enc[i])); ++ } ++ ++audio_create_fail: ++ for (i = 0; i < pool->controller_count; i++) { ++ if (pool->audios[i] != NULL) ++ dal_audio_destroy(&pool->audios[i]); ++ } ++ ++controller_create_fail: ++ for (i = 0; i < pool->controller_count; i++) { ++ if (pool->opps[i] != NULL) ++ dce110_opp_destroy(&pool->opps[i]); ++ ++ if (pool->transforms[i] != NULL) ++ dce100_transform_destroy(&pool->transforms[i]); ++ ++ if (pool->ipps[i] != NULL) ++ dce110_ipp_destroy(&pool->ipps[i]); ++ ++ if (pool->mis[i] != NULL) { ++ dc_service_free(pool->mis[i]->ctx, ++ TO_DCE110_MEM_INPUT(pool->mis[i])); ++ pool->mis[i] = NULL; ++ } ++ ++ if (pool->timing_generators[i] != NULL) { ++ dc_service_free(pool->timing_generators[i]->ctx, ++ DCE110TG_FROM_TG(pool->timing_generators[i])); ++ pool->timing_generators[i] = NULL; ++ } ++ } ++ ++filter_create_fail: ++ dal_irq_service_destroy(&pool->irqs); ++ ++irqs_create_fail: ++ dal_display_clock_destroy(&pool->display_clock); ++ ++disp_clk_create_fail: ++clk_src_create_fail: ++ for (i = 0; i < pool->clk_src_count; i++) { ++ if (pool->clock_sources[i] != NULL) ++ dal_clock_source_destroy(&pool->clock_sources[i]); ++ } ++ return false; ++} ++ ++void dce100_destruct_resource_pool(struct resource_pool *pool) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < pool->controller_count; i++) { ++ if (pool->opps[i] != NULL) ++ dce110_opp_destroy(&pool->opps[i]); ++ ++ if (pool->transforms[i] != NULL) ++ dce100_transform_destroy(&pool->transforms[i]); ++ ++ if (pool->ipps[i] != NULL) ++ dce110_ipp_destroy(&pool->ipps[i]); ++ ++ if (pool->mis[i] != NULL) { ++ dc_service_free(pool->mis[i]->ctx, ++ TO_DCE110_MEM_INPUT(pool->mis[i])); ++ pool->mis[i] = NULL; ++ } ++ ++ if (pool->timing_generators[i] != NULL) { ++ dc_service_free(pool->timing_generators[i]->ctx, ++ DCE110TG_FROM_TG(pool->timing_generators[i])); ++ pool->timing_generators[i] = NULL; ++ } ++ } ++ ++ for (i = 0; i < pool->stream_enc_count; i++) { ++ if (pool->stream_enc[i] != NULL) ++ dc_service_free(pool->stream_enc[i]->ctx, ++ DCE110STRENC_FROM_STRENC(pool->stream_enc[i])); ++ } ++ ++ for (i = 0; i < pool->clk_src_count; i++) { ++ if (pool->clock_sources[i] != NULL) ++ dal_clock_source_destroy(&pool->clock_sources[i]); ++ } ++ ++ for (i = 0; i < pool->audio_count; i++) { ++ if (pool->audios[i] != NULL) ++ dal_audio_destroy(&pool->audios[i]); ++ } ++ if (pool->display_clock != NULL) ++ dal_display_clock_destroy(&pool->display_clock); ++ ++ if (pool->scaler_filter != NULL) ++ dal_scaler_filter_destroy(&pool->scaler_filter); ++ ++ if (pool->irqs != NULL) ++ dal_irq_service_destroy(&pool->irqs); ++ ++ if (pool->adapter_srv != NULL) ++ dal_adapter_service_destroy(&pool->adapter_srv); ++} ++ ++static struct clock_source *find_first_free_pll( ++ struct resource_context *res_ctx) ++{ ++ if (res_ctx->clock_source_ref_count[DCE100_CLK_SRC_PLL0] == 0) ++ return res_ctx->pool.clock_sources[DCE100_CLK_SRC_PLL0]; ++ ++ if (res_ctx->clock_source_ref_count[DCE100_CLK_SRC_PLL1] == 0) ++ return res_ctx->pool.clock_sources[DCE100_CLK_SRC_PLL1]; ++ ++ return 0; ++} ++ ++static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) ++{ ++ switch (crtc_id) { ++ case CONTROLLER_ID_D0: ++ return DTO_SOURCE_ID0; ++ case CONTROLLER_ID_D1: ++ return DTO_SOURCE_ID1; ++ case CONTROLLER_ID_D2: ++ return DTO_SOURCE_ID2; ++ case CONTROLLER_ID_D3: ++ return DTO_SOURCE_ID3; ++ case CONTROLLER_ID_D4: ++ return DTO_SOURCE_ID4; ++ case CONTROLLER_ID_D5: ++ return DTO_SOURCE_ID5; ++ default: ++ return DTO_SOURCE_UNKNOWN; ++ } ++} ++ ++static void build_audio_output( ++ const struct core_stream *stream, ++ struct audio_output *audio_output) ++{ ++ audio_output->engine_id = stream->stream_enc->id; ++ ++ audio_output->signal = stream->signal; ++ ++ /* audio_crtc_info */ ++ ++ audio_output->crtc_info.h_total = ++ stream->public.timing.h_total; ++ ++ /* ++ * Audio packets are sent during actual CRTC blank physical signal, we ++ * need to specify actual active signal portion ++ */ ++ audio_output->crtc_info.h_active = ++ stream->public.timing.h_addressable ++ + stream->public.timing.h_border_left ++ + stream->public.timing.h_border_right; ++ ++ audio_output->crtc_info.v_active = ++ stream->public.timing.v_addressable ++ + stream->public.timing.v_border_top ++ + stream->public.timing.v_border_bottom; ++ ++ audio_output->crtc_info.pixel_repetition = 1; ++ ++ audio_output->crtc_info.interlaced = ++ stream->public.timing.flags.INTERLACE; ++ ++ audio_output->crtc_info.refresh_rate = ++ (stream->public.timing.pix_clk_khz*1000)/ ++ (stream->public.timing.h_total*stream->public.timing.v_total); ++ ++ audio_output->crtc_info.color_depth = ++ stream->public.timing.display_color_depth; ++ ++ audio_output->crtc_info.requested_pixel_clock = ++ stream->pix_clk_params.requested_pix_clk; ++ ++ /* ++ * TODO - Investigate why calculated pixel clk has to be ++ * requested pixel clk ++ */ ++ audio_output->crtc_info.calculated_pixel_clock = ++ stream->pix_clk_params.requested_pix_clk; ++ ++ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || ++ stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { ++ audio_output->pll_info.dp_dto_source_clock_in_khz = ++ dal_display_clock_get_dp_ref_clk_frequency( ++ stream->dis_clk); ++ } ++ ++ audio_output->pll_info.feed_back_divider = ++ stream->pll_settings.feedback_divider; ++ ++ audio_output->pll_info.dto_source = ++ translate_to_dto_source( ++ stream->controller_idx + 1); ++ ++ /* TODO hard code to enable for now. Need get from stream */ ++ audio_output->pll_info.ss_enabled = true; ++ ++ audio_output->pll_info.ss_percentage = ++ stream->pll_settings.ss_percentage; ++} ++ ++static void get_pixel_clock_parameters( ++ const struct core_stream *stream, ++ struct pixel_clk_params *pixel_clk_params) ++{ ++ pixel_clk_params->requested_pix_clk = stream->public.timing.pix_clk_khz; ++ pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id; ++ pixel_clk_params->signal_type = stream->sink->public.sink_signal; ++ pixel_clk_params->controller_id = stream->controller_idx + 1; ++ /* TODO: un-hardcode*/ ++ pixel_clk_params->requested_sym_clk = LINK_RATE_LOW * ++ LINK_RATE_REF_FREQ_IN_KHZ; ++ pixel_clk_params->flags.ENABLE_SS = 0; ++ pixel_clk_params->color_depth = ++ stream->public.timing.display_color_depth; ++ pixel_clk_params->flags.DISPLAY_BLANKED = 1; ++} ++ ++static enum dc_status build_stream_hw_param(struct core_stream *stream) ++{ ++ /*TODO: unhardcode*/ ++ stream->max_tmds_clk_from_edid_in_mhz = 0; ++ stream->max_hdmi_deep_color = COLOR_DEPTH_121212; ++ stream->max_hdmi_pixel_clock = 600000; ++ ++ get_pixel_clock_parameters(stream, &stream->pix_clk_params); ++ dal_clock_source_get_pix_clk_dividers( ++ stream->clock_source, ++ &stream->pix_clk_params, ++ &stream->pll_settings); ++ ++ build_audio_output(stream, &stream->audio_output); ++ ++ return DC_OK; ++} ++ ++static enum dc_status validate_mapped_resource( ++ const struct dc *dc, ++ struct validate_context *context) ++{ ++ enum dc_status status = DC_OK; ++ uint8_t i, j; ++ ++ for (i = 0; i < context->target_count; i++) { ++ struct core_target *target = context->targets[i]; ++ ++ if (context->target_flags[i].unchanged) ++ continue; ++ for (j = 0; j < target->public.stream_count; j++) { ++ struct core_stream *stream = ++ DC_STREAM_TO_CORE(target->public.streams[j]); ++ struct core_link *link = stream->sink->link; ++ ++ if (!stream->tg->funcs->validate_timing( ++ stream->tg, &stream->public.timing)) ++ return DC_FAIL_CONTROLLER_VALIDATE; ++ ++ if (stream->signal == SIGNAL_TYPE_VIRTUAL) ++ return status; ++ ++ status = build_stream_hw_param(stream); ++ ++ if (status != DC_OK) ++ return status; ++ ++ if (!link->link_enc->funcs->validate_output_with_stream( ++ link->link_enc, ++ stream)) ++ return DC_FAIL_ENC_VALIDATE; ++ ++ /* TODO: validate audio ASIC caps, encoder */ ++ ++ status = dc_link_validate_mode_timing(stream->sink, ++ link, ++ &stream->public.timing); ++ ++ if (status != DC_OK) ++ return status; ++ ++ build_info_frame(stream); ++ } ++ } ++ ++ return DC_OK; ++} ++ ++enum dc_status dce100_validate_bandwidth( ++ const struct dc *dc, ++ struct validate_context *context) ++{ ++ uint8_t i, j; ++ enum dc_status result = DC_ERROR_UNEXPECTED; ++ uint8_t number_of_displays = 0; ++ uint8_t max_htaps = 1; ++ uint8_t max_vtaps = 1; ++ bool all_displays_in_sync = true; ++ struct dc_crtc_timing prev_timing; ++ ++ memset(&context->bw_mode_data, 0, sizeof(context->bw_mode_data)); ++ ++ for (i = 0; i < context->target_count; i++) { ++ struct core_target *target = context->targets[i]; ++ ++ for (j = 0; j < target->public.stream_count; j++) { ++ struct core_stream *stream = ++ DC_STREAM_TO_CORE(target->public.streams[j]); ++ struct bw_calcs_input_single_display *disp = &context-> ++ bw_mode_data.displays_data[number_of_displays]; ++ ++ if (target->status.surface_count == 0) { ++ disp->graphics_scale_ratio = bw_int_to_fixed(1); ++ disp->graphics_h_taps = 2; ++ disp->graphics_v_taps = 2; ++ ++ /* TODO: remove when bw formula accepts taps per ++ * display ++ */ ++ if (max_vtaps < 2) ++ max_vtaps = 2; ++ if (max_htaps < 2) ++ max_htaps = 2; ++ ++ } else { ++ disp->graphics_scale_ratio = ++ fixed31_32_to_bw_fixed( ++ stream->ratios.vert.value); ++ disp->graphics_h_taps = stream->taps.h_taps; ++ disp->graphics_v_taps = stream->taps.v_taps; ++ ++ /* TODO: remove when bw formula accepts taps per ++ * display ++ */ ++ if (max_vtaps < stream->taps.v_taps) ++ max_vtaps = stream->taps.v_taps; ++ if (max_htaps < stream->taps.h_taps) ++ max_htaps = stream->taps.h_taps; ++ } ++ ++ disp->graphics_src_width = ++ stream->public.timing.h_addressable; ++ disp->graphics_src_height = ++ stream->public.timing.v_addressable; ++ disp->h_total = stream->public.timing.h_total; ++ disp->pixel_rate = bw_frc_to_fixed( ++ stream->public.timing.pix_clk_khz, 1000); ++ ++ /*TODO: get from surface*/ ++ disp->graphics_bytes_per_pixel = 4; ++ disp->graphics_tiling_mode = bw_def_tiled; ++ ++ /* DCE11 defaults*/ ++ disp->graphics_lb_bpc = 10; ++ disp->graphics_interlace_mode = false; ++ disp->fbc_enable = false; ++ disp->lpt_enable = false; ++ disp->graphics_stereo_mode = bw_def_mono; ++ disp->underlay_mode = bw_def_none; ++ ++ /*All displays will be synchronized if timings are all ++ * the same ++ */ ++ if (number_of_displays != 0 && all_displays_in_sync) ++ if (dal_memcmp(&prev_timing, ++ &stream->public.timing, ++ sizeof(struct dc_crtc_timing)) != 0) ++ all_displays_in_sync = false; ++ if (number_of_displays == 0) ++ prev_timing = stream->public.timing; ++ ++ number_of_displays++; ++ } ++ } ++ ++ /* TODO: remove when bw formula accepts taps per ++ * display ++ */ ++ context->bw_mode_data.displays_data[0].graphics_v_taps = max_vtaps; ++ context->bw_mode_data.displays_data[0].graphics_h_taps = max_htaps; ++ ++ context->bw_mode_data.number_of_displays = number_of_displays; ++ context->bw_mode_data.display_synchronization_enabled = ++ all_displays_in_sync; ++ ++ dal_logger_write( ++ dc->ctx->logger, ++ LOG_MAJOR_BWM, ++ LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS, ++ "%s: start\n", ++ __func__); ++ ++ if (!bw_calcs( ++ dc->ctx, ++ &dc->bw_dceip, ++ &dc->bw_vbios, ++ &context->bw_mode_data, ++ &context->bw_results)) ++ result = DC_FAIL_BANDWIDTH_VALIDATE; ++ else ++ result = DC_OK; ++ ++ if (result == DC_FAIL_BANDWIDTH_VALIDATE) ++ dal_logger_write(dc->ctx->logger, ++ LOG_MAJOR_BWM, ++ LOG_MINOR_BWM_MODE_VALIDATION, ++ "%s: Bandwidth validation failed!", ++ __func__); ++ ++ if (dal_memcmp(&dc->current_context.bw_results, ++ &context->bw_results, sizeof(context->bw_results))) { ++ struct log_entry log_entry; ++ ++ dal_logger_open( ++ dc->ctx->logger, ++ &log_entry, ++ LOG_MAJOR_BWM, ++ LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS); ++ dal_logger_append(&log_entry, "%s: finish, numDisplays: %d\n" ++ "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" ++ "stutMark_b: %d stutMark_a: %d\n", ++ __func__, number_of_displays, ++ context->bw_results.nbp_state_change_wm_ns[0].b_mark, ++ context->bw_results.nbp_state_change_wm_ns[0].a_mark, ++ context->bw_results.urgent_wm_ns[0].b_mark, ++ context->bw_results.urgent_wm_ns[0].a_mark, ++ context->bw_results.stutter_exit_wm_ns[0].b_mark, ++ context->bw_results.stutter_exit_wm_ns[0].a_mark); ++ dal_logger_append(&log_entry, ++ "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" ++ "stutMark_b: %d stutMark_a: %d\n", ++ context->bw_results.nbp_state_change_wm_ns[1].b_mark, ++ context->bw_results.nbp_state_change_wm_ns[1].a_mark, ++ context->bw_results.urgent_wm_ns[1].b_mark, ++ context->bw_results.urgent_wm_ns[1].a_mark, ++ context->bw_results.stutter_exit_wm_ns[1].b_mark, ++ context->bw_results.stutter_exit_wm_ns[1].a_mark); ++ dal_logger_append(&log_entry, ++ "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n" ++ "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n", ++ context->bw_results.nbp_state_change_wm_ns[2].b_mark, ++ context->bw_results.nbp_state_change_wm_ns[2].a_mark, ++ context->bw_results.urgent_wm_ns[2].b_mark, ++ context->bw_results.urgent_wm_ns[2].a_mark, ++ context->bw_results.stutter_exit_wm_ns[2].b_mark, ++ context->bw_results.stutter_exit_wm_ns[2].a_mark, ++ context->bw_results.stutter_mode_enable); ++ dal_logger_append(&log_entry, ++ "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n" ++ "sclk: %d sclk_sleep: %d yclk: %d blackout_duration: %d\n", ++ context->bw_results.cpuc_state_change_enable, ++ context->bw_results.cpup_state_change_enable, ++ context->bw_results.nbp_state_change_enable, ++ context->bw_results.all_displays_in_sync, ++ context->bw_results.dispclk_khz, ++ context->bw_results.required_sclk, ++ context->bw_results.required_sclk_deep_sleep, ++ context->bw_results.required_yclk, ++ context->bw_results.required_blackout_duration_us); ++ dal_logger_close(&log_entry); ++ } ++ return result; ++} ++ ++static void set_target_unchanged( ++ struct validate_context *context, ++ uint8_t target_idx) ++{ ++ uint8_t i; ++ struct core_target *target = context->targets[target_idx]; ++ ++ context->target_flags[target_idx].unchanged = true; ++ for (i = 0; i < target->public.stream_count; i++) { ++ struct core_stream *core_stream = ++ DC_STREAM_TO_CORE(target->public.streams[i]); ++ uint8_t index = core_stream->controller_idx; ++ ++ context->res_ctx.controller_ctx[index].flags.unchanged = true; ++ } ++} ++ ++static enum dc_status map_clock_resources( ++ const struct dc *dc, ++ struct validate_context *context) ++{ ++ uint8_t i, j; ++ ++ /* mark resources used for targets that are already active */ ++ for (i = 0; i < context->target_count; i++) { ++ struct core_target *target = context->targets[i]; ++ ++ if (!context->target_flags[i].unchanged) ++ continue; ++ ++ for (j = 0; j < target->public.stream_count; j++) { ++ struct core_stream *stream = ++ DC_STREAM_TO_CORE(target->public.streams[j]); ++ ++ reference_clock_source( ++ &context->res_ctx, ++ stream->clock_source); ++ } ++ } ++ ++ /* acquire new resources */ ++ for (i = 0; i < context->target_count; i++) { ++ struct core_target *target = context->targets[i]; ++ ++ if (context->target_flags[i].unchanged) ++ continue; ++ ++ for (j = 0; j < target->public.stream_count; j++) { ++ struct core_stream *stream = ++ DC_STREAM_TO_CORE(target->public.streams[j]); ++ ++ if (dc_is_dp_signal(stream->signal) ++ || stream->signal == SIGNAL_TYPE_VIRTUAL) ++ stream->clock_source = context->res_ctx. ++ pool.clock_sources[DCE100_CLK_SRC_EXT]; ++ else ++ stream->clock_source = ++ find_used_clk_src_for_sharing( ++ context, stream); ++ if (stream->clock_source == NULL) ++ stream->clock_source = ++ find_first_free_pll(&context->res_ctx); ++ ++ if (stream->clock_source == NULL) ++ return DC_NO_CLOCK_SOURCE_RESOURCE; ++ ++ reference_clock_source( ++ &context->res_ctx, ++ stream->clock_source); ++ } ++ } ++ ++ return DC_OK; ++} ++ ++enum dc_status dce100_validate_with_context( ++ const struct dc *dc, ++ const struct dc_validation_set set[], ++ uint8_t set_count, ++ struct validate_context *context) ++{ ++ enum dc_status result = DC_ERROR_UNEXPECTED; ++ uint8_t i, j; ++ struct dc_context *dc_ctx = dc->ctx; ++ ++ for (i = 0; i < set_count; i++) { ++ context->targets[i] = DC_TARGET_TO_CORE(set[i].target); ++ ++ for (j = 0; j < dc->current_context.target_count; j++) ++ if (dc->current_context.targets[j] == context->targets[i]) ++ set_target_unchanged(context, i); ++ ++ if (!context->target_flags[i].unchanged) ++ if (!logical_attach_surfaces_to_target( ++ (struct dc_surface **)set[i].surfaces, ++ set[i].surface_count, ++ &context->targets[i]->public)) { ++ DC_ERROR("Failed to attach surface to target!\n"); ++ return DC_FAIL_ATTACH_SURFACES; ++ } ++ } ++ ++ context->target_count = set_count; ++ ++ context->res_ctx.pool = dc->res_pool; ++ ++ result = map_resources(dc, context); ++ ++ if (result == DC_OK) ++ result = map_clock_resources(dc, context); ++ ++ if (result == DC_OK) ++ result = validate_mapped_resource(dc, context); ++ ++ if (result == DC_OK) ++ build_scaling_params_for_context(dc, context); ++ ++ if (result == DC_OK) ++ result = dce100_validate_bandwidth(dc, context); ++ ++ return result; ++} +diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.h b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.h +new file mode 100644 +index 0000000..1ae3ecc +--- /dev/null ++++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.h +@@ -0,0 +1,24 @@ ++/* ++ * dce100_resource.h ++ * ++ * Created on: 2016-01-20 ++ * Author: qyang ++ */ ++ ++#ifndef DCE100_RESOURCE_H_ ++#define DCE100_RESOURCE_H_ ++ ++struct adapter_service; ++struct dc; ++struct resource_pool; ++struct dc_validation_set; ++ ++ ++bool dce100_construct_resource_pool( ++ struct adapter_service *adapter_serv, ++ struct dc *dc, ++ struct resource_pool *pool); ++ ++void dce100_destruct_resource_pool(struct resource_pool *pool); ++ ++#endif /* DCE100_RESOURCE_H_ */ +-- +2.7.4 + |