diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce80')
| -rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | 163 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c | 7 |
2 files changed, 104 insertions, 66 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index c109ace96be9..3e8d4b49f279 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -23,6 +23,8 @@ * */ +#include <linux/slab.h> + #include "dce/dce_8_0_d.h" #include "dce/dce_8_0_sh_mask.h" @@ -37,7 +39,6 @@ #include "dce110/dce110_timing_generator.h" #include "dce110/dce110_resource.h" #include "dce80/dce80_timing_generator.h" -#include "dce/dce_clk_mgr.h" #include "dce/dce_mem_input.h" #include "dce/dce_link_encoder.h" #include "dce/dce_stream_encoder.h" @@ -154,19 +155,6 @@ static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = { #define SRI(reg_name, block, id)\ .reg_name = mm ## block ## id ## _ ## reg_name - -static const struct clk_mgr_registers disp_clk_regs = { - CLK_COMMON_REG_LIST_DCE_BASE() -}; - -static const struct clk_mgr_shift disp_clk_shift = { - CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT) -}; - -static const struct clk_mgr_mask disp_clk_mask = { - CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK) -}; - #define ipp_regs(id)\ [id] = {\ IPP_COMMON_REG_LIST_DCE_BASE(id)\ @@ -300,6 +288,14 @@ static const struct dce_opp_mask opp_mask = { OPP_COMMON_MASK_SH_LIST_DCE_80(_MASK) }; +static const struct dce110_aux_registers_shift aux_shift = { + DCE10_AUX_MASK_SH_LIST(__SHIFT) +}; + +static const struct dce110_aux_registers_mask aux_mask = { + DCE10_AUX_MASK_SH_LIST(_MASK) +}; + #define aux_engine_regs(id)\ [id] = {\ AUX_COMMON_REG_LIST(id), \ @@ -334,7 +330,7 @@ static const struct dce_audio_shift audio_shift = { AUD_COMMON_MASK_SH_LIST(__SHIFT) }; -static const struct dce_aduio_mask audio_mask = { +static const struct dce_audio_mask audio_mask = { AUD_COMMON_MASK_SH_LIST(_MASK) }; @@ -387,6 +383,28 @@ static const struct resource_caps res_cap_83 = { .num_ddc = 2, }; +static const struct dc_plane_cap plane_cap = { + .type = DC_PLANE_TYPE_DCE_RGB, + + .pixel_format_support = { + .argb8888 = true, + .nv12 = false, + .fp16 = false + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 1, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 1, + .fp16 = 1 + } +}; + static const struct dce_dmcu_registers dmcu_regs = { DMCU_DCE80_REG_LIST() }; @@ -421,6 +439,37 @@ static const struct dce_abm_mask abm_mask = { #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8 #endif +static int map_transmitter_id_to_phy_instance( + enum transmitter transmitter) +{ + switch (transmitter) { + case TRANSMITTER_UNIPHY_A: + return 0; + break; + case TRANSMITTER_UNIPHY_B: + return 1; + break; + case TRANSMITTER_UNIPHY_C: + return 2; + break; + case TRANSMITTER_UNIPHY_D: + return 3; + break; + case TRANSMITTER_UNIPHY_E: + return 4; + break; + case TRANSMITTER_UNIPHY_F: + return 5; + break; + case TRANSMITTER_UNIPHY_G: + return 6; + break; + default: + ASSERT(0); + return 0; + } +} + static void read_dce_straps( struct dc_context *ctx, struct resource_straps *straps) @@ -481,7 +530,10 @@ struct dce_aux *dce80_aux_engine_create( dce110_aux_engine_construct(aux_engine, ctx, inst, SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD, - &aux_engine_regs[inst]); + &aux_engine_regs[inst], + &aux_mask, + &aux_shift, + ctx->dc->caps.extended_aux_timeout_support); return &aux_engine->base; } @@ -659,14 +711,18 @@ struct link_encoder *dce80_link_encoder_create( { struct dce110_link_encoder *enc110 = kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + int link_regs_id; if (!enc110) return NULL; + link_regs_id = + map_transmitter_id_to_phy_instance(enc_init_data->transmitter); + dce110_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, - &link_enc_regs[enc_init_data->transmitter], + &link_enc_regs[link_regs_id], &link_enc_aux_regs[enc_init_data->channel - 1], &link_enc_hpd_regs[enc_init_data->hpd_source]); return &enc110->base; @@ -691,6 +747,7 @@ struct clock_source *dce80_clock_source_create( return &clk_src->base; } + kfree(clk_src); BREAK_TO_DEBUGGER(); return NULL; } @@ -780,9 +837,6 @@ static void destruct(struct dce110_resource_pool *pool) } } - if (pool->base.clk_mgr != NULL) - dce_clk_mgr_destroy(&pool->base.clk_mgr); - if (pool->base.irqs != NULL) { dal_irq_service_destroy(&pool->base.irqs); } @@ -790,7 +844,8 @@ static void destruct(struct dce110_resource_pool *pool) bool dce80_validate_bandwidth( struct dc *dc, - struct dc_state *context) + struct dc_state *context, + bool fast_validate) { int i; bool at_least_one_pipe = false; @@ -802,11 +857,11 @@ bool dce80_validate_bandwidth( if (at_least_one_pipe) { /* TODO implement when needed but for now hardcode max value*/ - context->bw.dce.dispclk_khz = 681000; - context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; + context->bw_ctx.bw.dce.dispclk_khz = 681000; + context->bw_ctx.bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; } else { - context->bw.dce.dispclk_khz = 0; - context->bw.dce.yclk_khz = 0; + context->bw_ctx.bw.dce.dispclk_khz = 0; + context->bw_ctx.bw.dce.yclk_khz = 0; } return true; @@ -857,7 +912,8 @@ static const struct resource_funcs dce80_res_pool_funcs = { .validate_bandwidth = dce80_validate_bandwidth, .validate_plane = dce100_validate_plane, .add_stream_to_ctx = dce100_add_stream_to_ctx, - .validate_global = dce80_validate_global + .validate_global = dce80_validate_global, + .find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link }; static bool dce80_construct( @@ -867,7 +923,6 @@ static bool dce80_construct( { unsigned int i; struct dc_context *ctx = dc->ctx; - struct dc_firmware_info info; struct dc_bios *bp; ctx->dc_bios->regs = &bios_regs; @@ -886,6 +941,7 @@ static bool dce80_construct( dc->caps.i2c_speed_in_khz = 40; dc->caps.max_cursor_size = 128; dc->caps.dual_link_dvi = true; + dc->caps.extended_aux_timeout_support = false; /************************************************* * Create resources * @@ -893,8 +949,7 @@ static bool dce80_construct( bp = ctx->dc_bios; - if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && - info.external_clock_source_frequency_for_dp != 0) { + if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { pool->base.dp_clock_source = dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); @@ -931,16 +986,6 @@ static bool dce80_construct( } } - pool->base.clk_mgr = dce_clk_mgr_create(ctx, - &disp_clk_regs, - &disp_clk_shift, - &disp_clk_mask); - if (pool->base.clk_mgr == NULL) { - dm_error("DC: failed to create display clock!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - pool->base.dmcu = dce_dmcu_create(ctx, &dmcu_regs, &dmcu_shift, @@ -1032,6 +1077,10 @@ static bool dce80_construct( } dc->caps.max_planes = pool->base.pipe_count; + + for (i = 0; i < dc->caps.max_planes; ++i) + dc->caps.planes[i] = plane_cap; + dc->caps.disable_dp_clk_share = true; if (!resource_construct(num_virtual_links, dc, &pool->base, @@ -1072,7 +1121,6 @@ static bool dce81_construct( { unsigned int i; struct dc_context *ctx = dc->ctx; - struct dc_firmware_info info; struct dc_bios *bp; ctx->dc_bios->regs = &bios_regs; @@ -1098,8 +1146,7 @@ static bool dce81_construct( bp = ctx->dc_bios; - if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && - info.external_clock_source_frequency_for_dp != 0) { + if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { pool->base.dp_clock_source = dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); @@ -1136,16 +1183,6 @@ static bool dce81_construct( } } - pool->base.clk_mgr = dce_clk_mgr_create(ctx, - &disp_clk_regs, - &disp_clk_shift, - &disp_clk_mask); - if (pool->base.clk_mgr == NULL) { - dm_error("DC: failed to create display clock!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - pool->base.dmcu = dce_dmcu_create(ctx, &dmcu_regs, &dmcu_shift, @@ -1237,6 +1274,10 @@ static bool dce81_construct( } dc->caps.max_planes = pool->base.pipe_count; + + for (i = 0; i < dc->caps.max_planes; ++i) + dc->caps.planes[i] = plane_cap; + dc->caps.disable_dp_clk_share = true; if (!resource_construct(num_virtual_links, dc, &pool->base, @@ -1277,7 +1318,6 @@ static bool dce83_construct( { unsigned int i; struct dc_context *ctx = dc->ctx; - struct dc_firmware_info info; struct dc_bios *bp; ctx->dc_bios->regs = &bios_regs; @@ -1303,8 +1343,7 @@ static bool dce83_construct( bp = ctx->dc_bios; - if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) && - info.external_clock_source_frequency_for_dp != 0) { + if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { pool->base.dp_clock_source = dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); @@ -1337,16 +1376,6 @@ static bool dce83_construct( } } - pool->base.clk_mgr = dce_clk_mgr_create(ctx, - &disp_clk_regs, - &disp_clk_shift, - &disp_clk_mask); - if (pool->base.clk_mgr == NULL) { - dm_error("DC: failed to create display clock!\n"); - BREAK_TO_DEBUGGER(); - goto res_create_fail; - } - pool->base.dmcu = dce_dmcu_create(ctx, &dmcu_regs, &dmcu_shift, @@ -1438,6 +1467,10 @@ static bool dce83_construct( } dc->caps.max_planes = pool->base.pipe_count; + + for (i = 0; i < dc->caps.max_planes; ++i) + dc->caps.planes[i] = plane_cap; + dc->caps.disable_dp_clk_share = true; if (!resource_construct(num_virtual_links, dc, &pool->base, diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c index 8b5ce557ee71..397e7f94e1e8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c @@ -107,12 +107,17 @@ static void program_pix_dur(struct timing_generator *tg, uint32_t pix_clk_100hz) static void program_timing(struct timing_generator *tg, const struct dc_crtc_timing *timing, + int vready_offset, + int vstartup_start, + int vupdate_offset, + int vupdate_width, + const enum signal_type signal, bool use_vbios) { if (!use_vbios) program_pix_dur(tg, timing->pix_clk_100hz); - dce110_tg_program_timing(tg, timing, use_vbios); + dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios); } static void dce80_timing_generator_enable_advanced_request( |