14562236bSHarry Wentland /* 24562236bSHarry Wentland * Copyright 2015 Advanced Micro Devices, Inc. 34562236bSHarry Wentland * 44562236bSHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a 54562236bSHarry Wentland * copy of this software and associated documentation files (the "Software"), 64562236bSHarry Wentland * to deal in the Software without restriction, including without limitation 74562236bSHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 84562236bSHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the 94562236bSHarry Wentland * Software is furnished to do so, subject to the following conditions: 104562236bSHarry Wentland * 114562236bSHarry Wentland * The above copyright notice and this permission notice shall be included in 124562236bSHarry Wentland * all copies or substantial portions of the Software. 134562236bSHarry Wentland * 144562236bSHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 154562236bSHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 164562236bSHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 174562236bSHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 184562236bSHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 194562236bSHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 204562236bSHarry Wentland * OTHER DEALINGS IN THE SOFTWARE. 214562236bSHarry Wentland * 224562236bSHarry Wentland * Authors: AMD 234562236bSHarry Wentland * 244562236bSHarry Wentland */ 254562236bSHarry Wentland #include "dm_services.h" 264562236bSHarry Wentland #include "dc.h" 274562236bSHarry Wentland #include "dc_bios_types.h" 284562236bSHarry Wentland #include "core_types.h" 294562236bSHarry Wentland #include "core_status.h" 304562236bSHarry Wentland #include "resource.h" 314562236bSHarry Wentland #include "hw_sequencer.h" 324562236bSHarry Wentland #include "dm_helpers.h" 334562236bSHarry Wentland #include "dce110_hw_sequencer.h" 344562236bSHarry Wentland #include "dce110_timing_generator.h" 354562236bSHarry Wentland 364562236bSHarry Wentland #include "bios/bios_parser_helper.h" 374562236bSHarry Wentland #include "timing_generator.h" 384562236bSHarry Wentland #include "mem_input.h" 394562236bSHarry Wentland #include "opp.h" 404562236bSHarry Wentland #include "ipp.h" 414562236bSHarry Wentland #include "transform.h" 424562236bSHarry Wentland #include "stream_encoder.h" 434562236bSHarry Wentland #include "link_encoder.h" 444562236bSHarry Wentland #include "clock_source.h" 454562236bSHarry Wentland #include "gamma_calcs.h" 464562236bSHarry Wentland #include "audio.h" 474562236bSHarry Wentland #include "dce/dce_hwseq.h" 484562236bSHarry Wentland 494562236bSHarry Wentland /* include DCE11 register header files */ 504562236bSHarry Wentland #include "dce/dce_11_0_d.h" 514562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 524562236bSHarry Wentland 534562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 544562236bSHarry Wentland uint32_t crtc; 554562236bSHarry Wentland }; 564562236bSHarry Wentland 574562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 584562236bSHarry Wentland { 594562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 604562236bSHarry Wentland }, 614562236bSHarry Wentland { 624562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 634562236bSHarry Wentland }, 644562236bSHarry Wentland { 654562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 664562236bSHarry Wentland }, 674562236bSHarry Wentland { 684562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 694562236bSHarry Wentland } 704562236bSHarry Wentland }; 714562236bSHarry Wentland 724562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 734562236bSHarry Wentland (reg + reg_offsets[id].blnd) 744562236bSHarry Wentland 754562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 764562236bSHarry Wentland (reg + reg_offsets[id].crtc) 774562236bSHarry Wentland 784562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 794562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 804562236bSHarry Wentland 814562236bSHarry Wentland /******************************************************************************* 824562236bSHarry Wentland * Private definitions 834562236bSHarry Wentland ******************************************************************************/ 844562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 854562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 864562236bSHarry Wentland { 874562236bSHarry Wentland uint32_t addr; 884562236bSHarry Wentland uint32_t value = 0; 894562236bSHarry Wentland uint32_t chunk_int = 0; 904562236bSHarry Wentland uint32_t chunk_mul = 0; 914562236bSHarry Wentland 924562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 934562236bSHarry Wentland value = dm_read_reg(ctx, addr); 944562236bSHarry Wentland 954562236bSHarry Wentland set_reg_field_value( 964562236bSHarry Wentland value, 974562236bSHarry Wentland 0, 984562236bSHarry Wentland DVMM_PTE_CONTROL, 994562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1004562236bSHarry Wentland 1014562236bSHarry Wentland set_reg_field_value( 1024562236bSHarry Wentland value, 1034562236bSHarry Wentland 1, 1044562236bSHarry Wentland DVMM_PTE_CONTROL, 1054562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1064562236bSHarry Wentland 1074562236bSHarry Wentland set_reg_field_value( 1084562236bSHarry Wentland value, 1094562236bSHarry Wentland 1, 1104562236bSHarry Wentland DVMM_PTE_CONTROL, 1114562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1124562236bSHarry Wentland 1134562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1144562236bSHarry Wentland 1154562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1164562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1174562236bSHarry Wentland 1184562236bSHarry Wentland chunk_int = get_reg_field_value( 1194562236bSHarry Wentland value, 1204562236bSHarry Wentland DVMM_PTE_REQ, 1214562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1224562236bSHarry Wentland 1234562236bSHarry Wentland chunk_mul = get_reg_field_value( 1244562236bSHarry Wentland value, 1254562236bSHarry Wentland DVMM_PTE_REQ, 1264562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1274562236bSHarry Wentland 1284562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1294562236bSHarry Wentland 1304562236bSHarry Wentland set_reg_field_value( 1314562236bSHarry Wentland value, 1324562236bSHarry Wentland 255, 1334562236bSHarry Wentland DVMM_PTE_REQ, 1344562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1354562236bSHarry Wentland 1364562236bSHarry Wentland set_reg_field_value( 1374562236bSHarry Wentland value, 1384562236bSHarry Wentland 4, 1394562236bSHarry Wentland DVMM_PTE_REQ, 1404562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1414562236bSHarry Wentland 1424562236bSHarry Wentland set_reg_field_value( 1434562236bSHarry Wentland value, 1444562236bSHarry Wentland 4, 1454562236bSHarry Wentland DVMM_PTE_REQ, 1464562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1474562236bSHarry Wentland 1484562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1494562236bSHarry Wentland } 1504562236bSHarry Wentland } 1514562236bSHarry Wentland /**************************************************************************/ 1524562236bSHarry Wentland 1534562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1544562236bSHarry Wentland struct dc_context *ctx, 1554562236bSHarry Wentland bool clock_gating) 1564562236bSHarry Wentland { 1574562236bSHarry Wentland /*TODO*/ 1584562236bSHarry Wentland } 1594562236bSHarry Wentland 1604562236bSHarry Wentland static bool dce110_enable_display_power_gating( 1614562236bSHarry Wentland struct core_dc *dc, 1624562236bSHarry Wentland uint8_t controller_id, 1634562236bSHarry Wentland struct dc_bios *dcb, 1644562236bSHarry Wentland enum pipe_gating_control power_gating) 1654562236bSHarry Wentland { 1664562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 1674562236bSHarry Wentland enum bp_pipe_control_action cntl; 1684562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 1694562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 1704562236bSHarry Wentland 1714562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 1724562236bSHarry Wentland return true; 1734562236bSHarry Wentland 1744562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 1754562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 1764562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 1774562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 1784562236bSHarry Wentland else 1794562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 1804562236bSHarry Wentland 1814562236bSHarry Wentland if (controller_id == underlay_idx) 1824562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 1834562236bSHarry Wentland 1844562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){ 1854562236bSHarry Wentland 1864562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 1874562236bSHarry Wentland dcb, controller_id + 1, cntl); 1884562236bSHarry Wentland 1894562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 1904562236bSHarry Wentland * by default when command table is called 1914562236bSHarry Wentland * 1924562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 1934562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 1944562236bSHarry Wentland * than 3. 1954562236bSHarry Wentland */ 1964562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 1974562236bSHarry Wentland dm_write_reg(ctx, 1984562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 1994562236bSHarry Wentland 0); 2004562236bSHarry Wentland } 2014562236bSHarry Wentland 2024562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2034562236bSHarry Wentland dce110_init_pte(ctx); 2044562236bSHarry Wentland 2054562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2064562236bSHarry Wentland return true; 2074562236bSHarry Wentland else 2084562236bSHarry Wentland return false; 2094562236bSHarry Wentland } 2104562236bSHarry Wentland 2114562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2124562236bSHarry Wentland const struct core_surface *surface) 2134562236bSHarry Wentland { 2144562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2154562236bSHarry Wentland 2164562236bSHarry Wentland switch (surface->public.format) { 2174562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2184562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_BGRA8888: 2194562236bSHarry Wentland prescale_params->scale = 0x2020; 2204562236bSHarry Wentland break; 2214562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2224562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2234562236bSHarry Wentland prescale_params->scale = 0x2008; 2244562236bSHarry Wentland break; 2254562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 2264562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2274562236bSHarry Wentland prescale_params->scale = 0x2000; 2284562236bSHarry Wentland break; 2294562236bSHarry Wentland default: 2304562236bSHarry Wentland ASSERT(false); 231d7194cf6SAric Cyr break; 2324562236bSHarry Wentland } 2334562236bSHarry Wentland } 2344562236bSHarry Wentland 235d7194cf6SAric Cyr static bool dce110_set_input_transfer_func( 236fb735a9fSAnthony Koo struct pipe_ctx *pipe_ctx, 2374562236bSHarry Wentland const struct core_surface *surface) 2384562236bSHarry Wentland { 239fb735a9fSAnthony Koo struct input_pixel_processor *ipp = pipe_ctx->ipp; 24090e508baSAnthony Koo const struct core_transfer_func *tf = NULL; 24190e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 24290e508baSAnthony Koo bool result = true; 24390e508baSAnthony Koo 24490e508baSAnthony Koo if (ipp == NULL) 24590e508baSAnthony Koo return false; 24690e508baSAnthony Koo 24790e508baSAnthony Koo if (surface->public.in_transfer_func) 24890e508baSAnthony Koo tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func); 24990e508baSAnthony Koo 25090e508baSAnthony Koo build_prescale_params(&prescale_params, surface); 25190e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 25290e508baSAnthony Koo 253d7194cf6SAric Cyr if (surface->public.gamma_correction) 254d7194cf6SAric Cyr ipp->funcs->ipp_program_input_lut(ipp, surface->public.gamma_correction); 255d7194cf6SAric Cyr 25690e508baSAnthony Koo if (tf == NULL) { 25790e508baSAnthony Koo /* Default case if no input transfer function specified */ 25890e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 25990e508baSAnthony Koo IPP_DEGAMMA_MODE_BYPASS); 26090e508baSAnthony Koo } else if (tf->public.type == TF_TYPE_PREDEFINED) { 26190e508baSAnthony Koo switch (tf->public.tf) { 26290e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 26390e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 26490e508baSAnthony Koo IPP_DEGAMMA_MODE_HW_sRGB); 26590e508baSAnthony Koo break; 26690e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 26790e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 26890e508baSAnthony Koo IPP_DEGAMMA_MODE_HW_xvYCC); 26990e508baSAnthony Koo break; 27090e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 27190e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 27290e508baSAnthony Koo IPP_DEGAMMA_MODE_BYPASS); 27390e508baSAnthony Koo break; 27490e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 27590e508baSAnthony Koo result = false; 27690e508baSAnthony Koo break; 27790e508baSAnthony Koo default: 27890e508baSAnthony Koo result = false; 279d7194cf6SAric Cyr break; 28090e508baSAnthony Koo } 28190e508baSAnthony Koo } else { 28290e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 28390e508baSAnthony Koo result = false; 28490e508baSAnthony Koo } 28590e508baSAnthony Koo 28690e508baSAnthony Koo return result; 28790e508baSAnthony Koo } 28890e508baSAnthony Koo 28990e508baSAnthony Koo static bool dce110_set_output_transfer_func( 29090e508baSAnthony Koo struct pipe_ctx *pipe_ctx, 29190e508baSAnthony Koo const struct core_surface *surface, /* Surface - To be removed */ 29290e508baSAnthony Koo const struct core_stream *stream) 29390e508baSAnthony Koo { 294fb735a9fSAnthony Koo struct output_pixel_processor *opp = pipe_ctx->opp; 295fb735a9fSAnthony Koo const struct core_gamma *ramp = NULL; 2964562236bSHarry Wentland struct ipp_prescale_params prescale_params = { 0 }; 2974562236bSHarry Wentland struct pwl_params *regamma_params; 2984562236bSHarry Wentland bool result = false; 2994562236bSHarry Wentland 300fb735a9fSAnthony Koo if (surface->public.gamma_correction) 301fb735a9fSAnthony Koo ramp = DC_GAMMA_TO_CORE(surface->public.gamma_correction); 302fb735a9fSAnthony Koo 3034562236bSHarry Wentland regamma_params = dm_alloc(sizeof(struct pwl_params)); 3044562236bSHarry Wentland if (regamma_params == NULL) 3054562236bSHarry Wentland goto regamma_alloc_fail; 3064562236bSHarry Wentland 3074562236bSHarry Wentland regamma_params->hw_points_num = GAMMA_HW_POINTS_NUM; 3084562236bSHarry Wentland 3094562236bSHarry Wentland opp->funcs->opp_power_on_regamma_lut(opp, true); 3104562236bSHarry Wentland 311d7194cf6SAric Cyr if (stream->public.out_transfer_func && 312d7194cf6SAric Cyr stream->public.out_transfer_func->type == TF_TYPE_PREDEFINED && 313d7194cf6SAric Cyr stream->public.out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) { 314d7194cf6SAric Cyr opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB); 315d7194cf6SAric Cyr } else if (ramp && calculate_regamma_params(regamma_params, ramp, surface, stream)) { 3164562236bSHarry Wentland opp->funcs->opp_program_regamma_pwl(opp, regamma_params); 3174562236bSHarry Wentland opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER); 3184562236bSHarry Wentland } else { 3194562236bSHarry Wentland opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS); 3204562236bSHarry Wentland } 3214562236bSHarry Wentland 3224562236bSHarry Wentland opp->funcs->opp_power_on_regamma_lut(opp, false); 3234562236bSHarry Wentland 3244562236bSHarry Wentland result = true; 3254562236bSHarry Wentland 3264562236bSHarry Wentland dm_free(regamma_params); 3274562236bSHarry Wentland 3284562236bSHarry Wentland regamma_alloc_fail: 3294562236bSHarry Wentland return result; 3304562236bSHarry Wentland } 3314562236bSHarry Wentland 3324562236bSHarry Wentland static enum dc_status bios_parser_crtc_source_select( 3334562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 3344562236bSHarry Wentland { 3354562236bSHarry Wentland struct dc_bios *dcb; 3364562236bSHarry Wentland /* call VBIOS table to set CRTC source for the HW 3374562236bSHarry Wentland * encoder block 3384562236bSHarry Wentland * note: video bios clears all FMT setting here. */ 3394562236bSHarry Wentland struct bp_crtc_source_select crtc_source_select = {0}; 3404562236bSHarry Wentland const struct core_sink *sink = pipe_ctx->stream->sink; 3414562236bSHarry Wentland 3424562236bSHarry Wentland crtc_source_select.engine_id = pipe_ctx->stream_enc->id; 3434562236bSHarry Wentland crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1; 3444562236bSHarry Wentland /*TODO: Need to un-hardcode color depth, dp_audio and account for 3454562236bSHarry Wentland * the case where signal and sink signal is different (translator 3464562236bSHarry Wentland * encoder)*/ 3474562236bSHarry Wentland crtc_source_select.signal = pipe_ctx->stream->signal; 3484562236bSHarry Wentland crtc_source_select.enable_dp_audio = false; 3494562236bSHarry Wentland crtc_source_select.sink_signal = pipe_ctx->stream->signal; 3504562236bSHarry Wentland crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 3514562236bSHarry Wentland 3524562236bSHarry Wentland dcb = sink->ctx->dc_bios; 3534562236bSHarry Wentland 3544562236bSHarry Wentland if (BP_RESULT_OK != dcb->funcs->crtc_source_select( 3554562236bSHarry Wentland dcb, 3564562236bSHarry Wentland &crtc_source_select)) { 3574562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 3584562236bSHarry Wentland } 3594562236bSHarry Wentland 3604562236bSHarry Wentland return DC_OK; 3614562236bSHarry Wentland } 3624562236bSHarry Wentland 3634562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 3644562236bSHarry Wentland { 3654562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 3664562236bSHarry Wentland pipe_ctx->stream_enc->funcs->update_hdmi_info_packets( 3674562236bSHarry Wentland pipe_ctx->stream_enc, 3684562236bSHarry Wentland &pipe_ctx->encoder_info_frame); 3694562236bSHarry Wentland else if (dc_is_dp_signal(pipe_ctx->stream->signal)) 3704562236bSHarry Wentland pipe_ctx->stream_enc->funcs->update_dp_info_packets( 3714562236bSHarry Wentland pipe_ctx->stream_enc, 3724562236bSHarry Wentland &pipe_ctx->encoder_info_frame); 3734562236bSHarry Wentland } 3744562236bSHarry Wentland 3754562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 3764562236bSHarry Wentland { 3774562236bSHarry Wentland enum dc_lane_count lane_count = 3784562236bSHarry Wentland pipe_ctx->stream->sink->link->public.cur_link_settings.lane_count; 3794562236bSHarry Wentland 3804562236bSHarry Wentland struct dc_crtc_timing *timing = &pipe_ctx->stream->public.timing; 3814562236bSHarry Wentland struct core_link *link = pipe_ctx->stream->sink->link; 3824562236bSHarry Wentland 3834562236bSHarry Wentland /* 1. update AVI info frame (HDMI, DP) 3844562236bSHarry Wentland * we always need to update info frame 3854562236bSHarry Wentland */ 3864562236bSHarry Wentland uint32_t active_total_with_borders; 3874562236bSHarry Wentland uint32_t early_control = 0; 3884562236bSHarry Wentland struct timing_generator *tg = pipe_ctx->tg; 3894562236bSHarry Wentland 3904562236bSHarry Wentland /* TODOFPGA may change to hwss.update_info_frame */ 3914562236bSHarry Wentland dce110_update_info_frame(pipe_ctx); 3924562236bSHarry Wentland /* enable early control to avoid corruption on DP monitor*/ 3934562236bSHarry Wentland active_total_with_borders = 3944562236bSHarry Wentland timing->h_addressable 3954562236bSHarry Wentland + timing->h_border_left 3964562236bSHarry Wentland + timing->h_border_right; 3974562236bSHarry Wentland 3984562236bSHarry Wentland if (lane_count != 0) 3994562236bSHarry Wentland early_control = active_total_with_borders % lane_count; 4004562236bSHarry Wentland 4014562236bSHarry Wentland if (early_control == 0) 4024562236bSHarry Wentland early_control = lane_count; 4034562236bSHarry Wentland 4044562236bSHarry Wentland tg->funcs->set_early_control(tg, early_control); 4054562236bSHarry Wentland 4064562236bSHarry Wentland /* enable audio only within mode set */ 4074562236bSHarry Wentland if (pipe_ctx->audio != NULL) { 4084562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 4094562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_enc); 4104562236bSHarry Wentland } 4114562236bSHarry Wentland 4124562236bSHarry Wentland /* For MST, there are multiply stream go to only one link. 4134562236bSHarry Wentland * connect DIG back_end to front_end while enable_stream and 4144562236bSHarry Wentland * disconnect them during disable_stream 4154562236bSHarry Wentland * BY this, it is logic clean to separate stream and link */ 4164562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 4174562236bSHarry Wentland pipe_ctx->stream_enc->id, true); 4184562236bSHarry Wentland 4194562236bSHarry Wentland } 4204562236bSHarry Wentland 4214562236bSHarry Wentland void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 4224562236bSHarry Wentland { 4234562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 4244562236bSHarry Wentland struct core_link *link = stream->sink->link; 4254562236bSHarry Wentland 4264562236bSHarry Wentland if (pipe_ctx->audio) { 4274562236bSHarry Wentland pipe_ctx->audio->funcs->az_disable(pipe_ctx->audio); 4284562236bSHarry Wentland 4294562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 4304562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_audio_disable( 4314562236bSHarry Wentland pipe_ctx->stream_enc); 4324562236bSHarry Wentland else 4334562236bSHarry Wentland pipe_ctx->stream_enc->funcs->hdmi_audio_disable( 4344562236bSHarry Wentland pipe_ctx->stream_enc); 4354562236bSHarry Wentland 4364562236bSHarry Wentland pipe_ctx->audio = NULL; 4374562236bSHarry Wentland 4384562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 4394562236bSHarry Wentland * add audio mode list change flag */ 4404562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 4414562236bSHarry Wentland * stream->stream_engine_id); 4424562236bSHarry Wentland */ 4434562236bSHarry Wentland } 4444562236bSHarry Wentland 4454562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 4464562236bSHarry Wentland pipe_ctx->stream_enc->funcs->stop_hdmi_info_packets( 4474562236bSHarry Wentland pipe_ctx->stream_enc); 4484562236bSHarry Wentland 4494562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 4504562236bSHarry Wentland pipe_ctx->stream_enc->funcs->stop_dp_info_packets( 4514562236bSHarry Wentland pipe_ctx->stream_enc); 4524562236bSHarry Wentland 4534562236bSHarry Wentland pipe_ctx->stream_enc->funcs->audio_mute_control( 4544562236bSHarry Wentland pipe_ctx->stream_enc, true); 4554562236bSHarry Wentland 4564562236bSHarry Wentland 4574562236bSHarry Wentland /* blank at encoder level */ 4584562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 4594562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_blank(pipe_ctx->stream_enc); 4604562236bSHarry Wentland 4614562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe( 4624562236bSHarry Wentland link->link_enc, 4634562236bSHarry Wentland pipe_ctx->stream_enc->id, 4644562236bSHarry Wentland false); 4654562236bSHarry Wentland 4664562236bSHarry Wentland } 4674562236bSHarry Wentland 4684562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 4694562236bSHarry Wentland struct dc_link_settings *link_settings) 4704562236bSHarry Wentland { 4714562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 4724562236bSHarry Wentland 4734562236bSHarry Wentland /* only 3 items below are used by unblank */ 4744562236bSHarry Wentland params.crtc_timing.pixel_clock = 4754562236bSHarry Wentland pipe_ctx->stream->public.timing.pix_clk_khz; 4764562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 4774562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_unblank(pipe_ctx->stream_enc, ¶ms); 4784562236bSHarry Wentland } 4794562236bSHarry Wentland 4804562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 4814562236bSHarry Wentland { 4824562236bSHarry Wentland switch (crtc_id) { 4834562236bSHarry Wentland case CONTROLLER_ID_D0: 4844562236bSHarry Wentland return DTO_SOURCE_ID0; 4854562236bSHarry Wentland case CONTROLLER_ID_D1: 4864562236bSHarry Wentland return DTO_SOURCE_ID1; 4874562236bSHarry Wentland case CONTROLLER_ID_D2: 4884562236bSHarry Wentland return DTO_SOURCE_ID2; 4894562236bSHarry Wentland case CONTROLLER_ID_D3: 4904562236bSHarry Wentland return DTO_SOURCE_ID3; 4914562236bSHarry Wentland case CONTROLLER_ID_D4: 4924562236bSHarry Wentland return DTO_SOURCE_ID4; 4934562236bSHarry Wentland case CONTROLLER_ID_D5: 4944562236bSHarry Wentland return DTO_SOURCE_ID5; 4954562236bSHarry Wentland default: 4964562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 4974562236bSHarry Wentland } 4984562236bSHarry Wentland } 4994562236bSHarry Wentland 5004562236bSHarry Wentland static void build_audio_output( 5014562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 5024562236bSHarry Wentland struct audio_output *audio_output) 5034562236bSHarry Wentland { 5044562236bSHarry Wentland const struct core_stream *stream = pipe_ctx->stream; 5054562236bSHarry Wentland audio_output->engine_id = pipe_ctx->stream_enc->id; 5064562236bSHarry Wentland 5074562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 5084562236bSHarry Wentland 5094562236bSHarry Wentland /* audio_crtc_info */ 5104562236bSHarry Wentland 5114562236bSHarry Wentland audio_output->crtc_info.h_total = 5124562236bSHarry Wentland stream->public.timing.h_total; 5134562236bSHarry Wentland 5144562236bSHarry Wentland /* 5154562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 5164562236bSHarry Wentland * need to specify actual active signal portion 5174562236bSHarry Wentland */ 5184562236bSHarry Wentland audio_output->crtc_info.h_active = 5194562236bSHarry Wentland stream->public.timing.h_addressable 5204562236bSHarry Wentland + stream->public.timing.h_border_left 5214562236bSHarry Wentland + stream->public.timing.h_border_right; 5224562236bSHarry Wentland 5234562236bSHarry Wentland audio_output->crtc_info.v_active = 5244562236bSHarry Wentland stream->public.timing.v_addressable 5254562236bSHarry Wentland + stream->public.timing.v_border_top 5264562236bSHarry Wentland + stream->public.timing.v_border_bottom; 5274562236bSHarry Wentland 5284562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 5294562236bSHarry Wentland 5304562236bSHarry Wentland audio_output->crtc_info.interlaced = 5314562236bSHarry Wentland stream->public.timing.flags.INTERLACE; 5324562236bSHarry Wentland 5334562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 5344562236bSHarry Wentland (stream->public.timing.pix_clk_khz*1000)/ 5354562236bSHarry Wentland (stream->public.timing.h_total*stream->public.timing.v_total); 5364562236bSHarry Wentland 5374562236bSHarry Wentland audio_output->crtc_info.color_depth = 5384562236bSHarry Wentland stream->public.timing.display_color_depth; 5394562236bSHarry Wentland 5404562236bSHarry Wentland audio_output->crtc_info.requested_pixel_clock = 5414562236bSHarry Wentland pipe_ctx->pix_clk_params.requested_pix_clk; 5424562236bSHarry Wentland 5434562236bSHarry Wentland /* 5444562236bSHarry Wentland * TODO - Investigate why calculated pixel clk has to be 5454562236bSHarry Wentland * requested pixel clk 5464562236bSHarry Wentland */ 5474562236bSHarry Wentland audio_output->crtc_info.calculated_pixel_clock = 5484562236bSHarry Wentland pipe_ctx->pix_clk_params.requested_pix_clk; 5494562236bSHarry Wentland 5504562236bSHarry Wentland if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 5514562236bSHarry Wentland pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { 5524562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 5531a687574SDmytro Laktyushkin pipe_ctx->dis_clk->funcs->get_dp_ref_clk_frequency( 5544562236bSHarry Wentland pipe_ctx->dis_clk); 5554562236bSHarry Wentland } 5564562236bSHarry Wentland 5574562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 5584562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 5594562236bSHarry Wentland 5604562236bSHarry Wentland audio_output->pll_info.dto_source = 5614562236bSHarry Wentland translate_to_dto_source( 5624562236bSHarry Wentland pipe_ctx->pipe_idx + 1); 5634562236bSHarry Wentland 5644562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 5654562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 5664562236bSHarry Wentland 5674562236bSHarry Wentland audio_output->pll_info.ss_percentage = 5684562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 5694562236bSHarry Wentland } 5704562236bSHarry Wentland 5714562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 5724562236bSHarry Wentland struct tg_color *color) 5734562236bSHarry Wentland { 5744562236bSHarry Wentland uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->pipe_idx) / 4; 5754562236bSHarry Wentland 5764562236bSHarry Wentland switch (pipe_ctx->scl_data.format) { 5774562236bSHarry Wentland case PIXEL_FORMAT_ARGB8888: 5784562236bSHarry Wentland /* set boarder color to red */ 5794562236bSHarry Wentland color->color_r_cr = color_value; 5804562236bSHarry Wentland break; 5814562236bSHarry Wentland 5824562236bSHarry Wentland case PIXEL_FORMAT_ARGB2101010: 5834562236bSHarry Wentland /* set boarder color to blue */ 5844562236bSHarry Wentland color->color_b_cb = color_value; 5854562236bSHarry Wentland break; 5864562236bSHarry Wentland case PIXEL_FORMAT_420BPP12: 5874562236bSHarry Wentland /* set boarder color to green */ 5884562236bSHarry Wentland color->color_g_y = color_value; 5894562236bSHarry Wentland break; 5904562236bSHarry Wentland case PIXEL_FORMAT_FP16: 5914562236bSHarry Wentland /* set boarder color to white */ 5924562236bSHarry Wentland color->color_r_cr = color_value; 5934562236bSHarry Wentland color->color_b_cb = color_value; 5944562236bSHarry Wentland color->color_g_y = color_value; 5954562236bSHarry Wentland break; 5964562236bSHarry Wentland default: 5974562236bSHarry Wentland break; 5984562236bSHarry Wentland } 5994562236bSHarry Wentland } 6004562236bSHarry Wentland 6014562236bSHarry Wentland static void program_scaler(const struct core_dc *dc, 6024562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 6034562236bSHarry Wentland { 6044562236bSHarry Wentland struct tg_color color = {0}; 6054562236bSHarry Wentland 6064562236bSHarry Wentland if (dc->public.debug.surface_visual_confirm) 6074562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 6084562236bSHarry Wentland else 6094562236bSHarry Wentland color_space_to_black_color(dc, 6104562236bSHarry Wentland pipe_ctx->stream->public.output_color_space, 6114562236bSHarry Wentland &color); 6124562236bSHarry Wentland 6134562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_pixel_storage_depth( 6144562236bSHarry Wentland pipe_ctx->xfm, 6154562236bSHarry Wentland pipe_ctx->scl_data.lb_params.depth, 6164562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 6174562236bSHarry Wentland 6184562236bSHarry Wentland if (pipe_ctx->tg->funcs->set_overscan_blank_color) 6194562236bSHarry Wentland pipe_ctx->tg->funcs->set_overscan_blank_color( 6204562236bSHarry Wentland pipe_ctx->tg, 6214562236bSHarry Wentland &color); 6224562236bSHarry Wentland 6234562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_scaler(pipe_ctx->xfm, 6244562236bSHarry Wentland &pipe_ctx->scl_data); 6254562236bSHarry Wentland } 6264562236bSHarry Wentland 6274562236bSHarry Wentland static enum dc_status prog_pixclk_crtc_otg( 6284562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 6294562236bSHarry Wentland struct validate_context *context, 6304562236bSHarry Wentland struct core_dc *dc) 6314562236bSHarry Wentland { 6324562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 6334562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = &dc->current_context->res_ctx. 6344562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 6354562236bSHarry Wentland struct tg_color black_color = {0}; 6364562236bSHarry Wentland 6374562236bSHarry Wentland if (!pipe_ctx_old->stream) { 6384562236bSHarry Wentland 6394562236bSHarry Wentland /* program blank color */ 6404562236bSHarry Wentland color_space_to_black_color(dc, 6414562236bSHarry Wentland stream->public.output_color_space, &black_color); 6424562236bSHarry Wentland pipe_ctx->tg->funcs->set_blank_color( 6434562236bSHarry Wentland pipe_ctx->tg, 6444562236bSHarry Wentland &black_color); 6454562236bSHarry Wentland /* 6464562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 6474562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 6484562236bSHarry Wentland */ 6494562236bSHarry Wentland pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); 6504562236bSHarry Wentland 6514562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 6524562236bSHarry Wentland pipe_ctx->clock_source, 6534562236bSHarry Wentland &pipe_ctx->pix_clk_params, 6544562236bSHarry Wentland &pipe_ctx->pll_settings)) { 6554562236bSHarry Wentland BREAK_TO_DEBUGGER(); 6564562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 6574562236bSHarry Wentland } 6584562236bSHarry Wentland 6594562236bSHarry Wentland pipe_ctx->tg->funcs->program_timing( 6604562236bSHarry Wentland pipe_ctx->tg, 6614562236bSHarry Wentland &stream->public.timing, 6624562236bSHarry Wentland true); 6634562236bSHarry Wentland } 6644562236bSHarry Wentland 6654562236bSHarry Wentland if (!pipe_ctx_old->stream) { 6664562236bSHarry Wentland if (false == pipe_ctx->tg->funcs->enable_crtc( 6674562236bSHarry Wentland pipe_ctx->tg)) { 6684562236bSHarry Wentland BREAK_TO_DEBUGGER(); 6694562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 6704562236bSHarry Wentland } 6714562236bSHarry Wentland } 6724562236bSHarry Wentland 6734562236bSHarry Wentland return DC_OK; 6744562236bSHarry Wentland } 6754562236bSHarry Wentland 6764562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 6774562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 6784562236bSHarry Wentland struct validate_context *context, 6794562236bSHarry Wentland struct core_dc *dc) 6804562236bSHarry Wentland { 6814562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 6824562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = &dc->current_context->res_ctx. 6834562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 6844562236bSHarry Wentland 6854562236bSHarry Wentland /* */ 6864562236bSHarry Wentland dc->hwss.prog_pixclk_crtc_otg(pipe_ctx, context, dc); 6874562236bSHarry Wentland 6884562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_dyn_expansion( 6894562236bSHarry Wentland pipe_ctx->opp, 6904562236bSHarry Wentland COLOR_SPACE_YCBCR601, 6914562236bSHarry Wentland stream->public.timing.display_color_depth, 6924562236bSHarry Wentland pipe_ctx->stream->signal); 6934562236bSHarry Wentland 6944562236bSHarry Wentland pipe_ctx->opp->funcs->opp_program_fmt( 6954562236bSHarry Wentland pipe_ctx->opp, 6964562236bSHarry Wentland &stream->bit_depth_params, 6974562236bSHarry Wentland &stream->clamping); 6984562236bSHarry Wentland 6994562236bSHarry Wentland /* FPGA does not program backend */ 7004562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) 7014562236bSHarry Wentland return DC_OK; 7024562236bSHarry Wentland 7034562236bSHarry Wentland /* TODO: move to stream encoder */ 7044562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 7054562236bSHarry Wentland if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) { 7064562236bSHarry Wentland BREAK_TO_DEBUGGER(); 7074562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 7084562236bSHarry Wentland } 7094562236bSHarry Wentland 7104562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 7114562236bSHarry Wentland stream->sink->link->link_enc->funcs->setup( 7124562236bSHarry Wentland stream->sink->link->link_enc, 7134562236bSHarry Wentland pipe_ctx->stream->signal); 7144562236bSHarry Wentland 7154562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7164562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_set_stream_attribute( 7174562236bSHarry Wentland pipe_ctx->stream_enc, 7184562236bSHarry Wentland &stream->public.timing, 7194562236bSHarry Wentland stream->public.output_color_space); 7204562236bSHarry Wentland 7214562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 7224562236bSHarry Wentland pipe_ctx->stream_enc->funcs->hdmi_set_stream_attribute( 7234562236bSHarry Wentland pipe_ctx->stream_enc, 7244562236bSHarry Wentland &stream->public.timing, 7254562236bSHarry Wentland stream->phy_pix_clk, 7264562236bSHarry Wentland pipe_ctx->audio != NULL); 7274562236bSHarry Wentland 7284562236bSHarry Wentland if (dc_is_dvi_signal(pipe_ctx->stream->signal)) 7294562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dvi_set_stream_attribute( 7304562236bSHarry Wentland pipe_ctx->stream_enc, 7314562236bSHarry Wentland &stream->public.timing, 7324562236bSHarry Wentland (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? 7334562236bSHarry Wentland true : false); 7344562236bSHarry Wentland 7354562236bSHarry Wentland if (!pipe_ctx_old->stream) { 7364562236bSHarry Wentland core_link_enable_stream(pipe_ctx); 7374562236bSHarry Wentland 7384562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7394562236bSHarry Wentland dce110_unblank_stream(pipe_ctx, 7404562236bSHarry Wentland &stream->sink->link->public.cur_link_settings); 7414562236bSHarry Wentland } 7424562236bSHarry Wentland 7434562236bSHarry Wentland pipe_ctx->scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 7444562236bSHarry Wentland /* program_scaler and allocate_mem_input are not new asic */ 7454562236bSHarry Wentland if (!pipe_ctx_old || memcmp(&pipe_ctx_old->scl_data, 7464562236bSHarry Wentland &pipe_ctx->scl_data, 7474562236bSHarry Wentland sizeof(struct scaler_data)) != 0) 7484562236bSHarry Wentland program_scaler(dc, pipe_ctx); 7494562236bSHarry Wentland 7504562236bSHarry Wentland /* mst support - use total stream count */ 7514562236bSHarry Wentland pipe_ctx->mi->funcs->allocate_mem_input( 7524562236bSHarry Wentland pipe_ctx->mi, 7534562236bSHarry Wentland stream->public.timing.h_total, 7544562236bSHarry Wentland stream->public.timing.v_total, 7554562236bSHarry Wentland stream->public.timing.pix_clk_khz, 7564562236bSHarry Wentland context->target_count); 7574562236bSHarry Wentland 7584562236bSHarry Wentland return DC_OK; 7594562236bSHarry Wentland } 7604562236bSHarry Wentland 7614562236bSHarry Wentland /******************************************************************************/ 7624562236bSHarry Wentland 7634562236bSHarry Wentland static void power_down_encoders(struct core_dc *dc) 7644562236bSHarry Wentland { 7654562236bSHarry Wentland int i; 7664562236bSHarry Wentland 7674562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 7684562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 7694562236bSHarry Wentland dc->links[i]->link_enc, SIGNAL_TYPE_NONE); 7704562236bSHarry Wentland } 7714562236bSHarry Wentland } 7724562236bSHarry Wentland 7734562236bSHarry Wentland static void power_down_controllers(struct core_dc *dc) 7744562236bSHarry Wentland { 7754562236bSHarry Wentland int i; 7764562236bSHarry Wentland 7774562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 7784562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 7794562236bSHarry Wentland dc->res_pool->timing_generators[i]); 7804562236bSHarry Wentland } 7814562236bSHarry Wentland } 7824562236bSHarry Wentland 7834562236bSHarry Wentland static void power_down_clock_sources(struct core_dc *dc) 7844562236bSHarry Wentland { 7854562236bSHarry Wentland int i; 7864562236bSHarry Wentland 7874562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 7884562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 7894562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 7904562236bSHarry Wentland 7914562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 7924562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 7934562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 7944562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 7954562236bSHarry Wentland } 7964562236bSHarry Wentland } 7974562236bSHarry Wentland 7984562236bSHarry Wentland static void power_down_all_hw_blocks(struct core_dc *dc) 7994562236bSHarry Wentland { 8004562236bSHarry Wentland power_down_encoders(dc); 8014562236bSHarry Wentland 8024562236bSHarry Wentland power_down_controllers(dc); 8034562236bSHarry Wentland 8044562236bSHarry Wentland power_down_clock_sources(dc); 8054562236bSHarry Wentland } 8064562236bSHarry Wentland 8074562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 8084562236bSHarry Wentland struct core_dc *dc) 8094562236bSHarry Wentland { 8104562236bSHarry Wentland int i; 8114562236bSHarry Wentland struct timing_generator *tg; 8124562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 8134562236bSHarry Wentland 8144562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 8154562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 8164562236bSHarry Wentland 8174562236bSHarry Wentland tg->funcs->disable_vga(tg); 8184562236bSHarry Wentland 8194562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 8204562236bSHarry Wentland * powergating. */ 8214562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 8224562236bSHarry Wentland true); 8234562236bSHarry Wentland 8244562236bSHarry Wentland dc->hwss.power_down_front_end( 8254562236bSHarry Wentland dc, &dc->current_context->res_ctx.pipe_ctx[i]); 8264562236bSHarry Wentland } 8274562236bSHarry Wentland } 8284562236bSHarry Wentland 8294562236bSHarry Wentland /** 8304562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 8314562236bSHarry Wentland * 1. Power down all DC HW blocks 8324562236bSHarry Wentland * 2. Disable VGA engine on all controllers 8334562236bSHarry Wentland * 3. Enable power gating for controller 8344562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 8354562236bSHarry Wentland */ 8364562236bSHarry Wentland void dce110_enable_accelerated_mode(struct core_dc *dc) 8374562236bSHarry Wentland { 8384562236bSHarry Wentland power_down_all_hw_blocks(dc); 8394562236bSHarry Wentland 8404562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 8414562236bSHarry Wentland bios_set_scratch_acc_mode_change(dc->ctx->dc_bios); 8424562236bSHarry Wentland } 8434562236bSHarry Wentland 8444562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 8454562236bSHarry Wentland struct bw_fixed blackout_duration, 8464562236bSHarry Wentland const struct core_stream *stream) 8474562236bSHarry Wentland { 8484562236bSHarry Wentland uint32_t total_dest_line_time_ns; 8494562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 8504562236bSHarry Wentland 8514562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 8524562236bSHarry Wentland 8534562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 8544562236bSHarry Wentland stream->public.timing.h_total / 8554562236bSHarry Wentland stream->public.timing.pix_clk_khz + 8564562236bSHarry Wentland pstate_blackout_duration_ns; 8574562236bSHarry Wentland 8584562236bSHarry Wentland return total_dest_line_time_ns; 8594562236bSHarry Wentland } 8604562236bSHarry Wentland 8614562236bSHarry Wentland /* get the index of the pipe_ctx if there were no gaps in the pipe_ctx array*/ 8624562236bSHarry Wentland int get_bw_result_idx( 8634562236bSHarry Wentland struct resource_context *res_ctx, 8644562236bSHarry Wentland int pipe_idx) 8654562236bSHarry Wentland { 8664562236bSHarry Wentland int i, collapsed_idx; 8674562236bSHarry Wentland 8684562236bSHarry Wentland if (res_ctx->pipe_ctx[pipe_idx].top_pipe) 8694562236bSHarry Wentland return 3; 8704562236bSHarry Wentland 8714562236bSHarry Wentland collapsed_idx = 0; 8724562236bSHarry Wentland for (i = 0; i < pipe_idx; i++) { 8734562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream) 8744562236bSHarry Wentland collapsed_idx++; 8754562236bSHarry Wentland } 8764562236bSHarry Wentland 8774562236bSHarry Wentland return collapsed_idx; 8784562236bSHarry Wentland } 8794562236bSHarry Wentland 8804562236bSHarry Wentland static bool is_watermark_set_a_greater( 8814562236bSHarry Wentland const struct bw_watermarks *set_a, 8824562236bSHarry Wentland const struct bw_watermarks *set_b) 8834562236bSHarry Wentland { 8844562236bSHarry Wentland if (set_a->a_mark > set_b->a_mark 8854562236bSHarry Wentland || set_a->b_mark > set_b->b_mark 8864562236bSHarry Wentland || set_a->c_mark > set_b->c_mark 8874562236bSHarry Wentland || set_a->d_mark > set_b->d_mark) 8884562236bSHarry Wentland return true; 8894562236bSHarry Wentland return false; 8904562236bSHarry Wentland } 8914562236bSHarry Wentland 8924562236bSHarry Wentland static bool did_watermarks_increase( 8934562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 8944562236bSHarry Wentland struct validate_context *context, 8954562236bSHarry Wentland struct validate_context *old_context) 8964562236bSHarry Wentland { 8974562236bSHarry Wentland int collapsed_pipe_idx = get_bw_result_idx(&context->res_ctx, 8984562236bSHarry Wentland pipe_ctx->pipe_idx); 8994562236bSHarry Wentland int old_collapsed_pipe_idx = get_bw_result_idx(&old_context->res_ctx, 9004562236bSHarry Wentland pipe_ctx->pipe_idx); 9014562236bSHarry Wentland struct pipe_ctx *old_pipe_ctx = &old_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; 9024562236bSHarry Wentland 9034562236bSHarry Wentland if (!old_pipe_ctx->stream) 9044562236bSHarry Wentland return true; 9054562236bSHarry Wentland 9064562236bSHarry Wentland if (is_watermark_set_a_greater( 9074562236bSHarry Wentland &context->bw_results.nbp_state_change_wm_ns[collapsed_pipe_idx], 9084562236bSHarry Wentland &old_context->bw_results.nbp_state_change_wm_ns[old_collapsed_pipe_idx])) 9094562236bSHarry Wentland return true; 9104562236bSHarry Wentland if (is_watermark_set_a_greater( 9114562236bSHarry Wentland &context->bw_results.stutter_exit_wm_ns[collapsed_pipe_idx], 9124562236bSHarry Wentland &old_context->bw_results.stutter_exit_wm_ns[old_collapsed_pipe_idx])) 9134562236bSHarry Wentland return true; 9144562236bSHarry Wentland if (is_watermark_set_a_greater( 9154562236bSHarry Wentland &context->bw_results.urgent_wm_ns[collapsed_pipe_idx], 9164562236bSHarry Wentland &old_context->bw_results.urgent_wm_ns[old_collapsed_pipe_idx])) 9174562236bSHarry Wentland return true; 9184562236bSHarry Wentland 9194562236bSHarry Wentland return false; 9204562236bSHarry Wentland } 9214562236bSHarry Wentland 9224562236bSHarry Wentland static void program_wm_for_pipe(struct core_dc *dc, 9234562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 9244562236bSHarry Wentland struct validate_context *context) 9254562236bSHarry Wentland { 9264562236bSHarry Wentland int total_dest_line_time_ns = compute_pstate_blackout_duration( 9274562236bSHarry Wentland dc->bw_vbios.blackout_duration, 9284562236bSHarry Wentland pipe_ctx->stream); 9294562236bSHarry Wentland int bw_result_idx = get_bw_result_idx(&context->res_ctx, 9304562236bSHarry Wentland pipe_ctx->pipe_idx); 9314562236bSHarry Wentland 9324562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_display_marks( 9334562236bSHarry Wentland pipe_ctx->mi, 9344562236bSHarry Wentland context->bw_results.nbp_state_change_wm_ns[bw_result_idx], 9354562236bSHarry Wentland context->bw_results.stutter_exit_wm_ns[bw_result_idx], 9364562236bSHarry Wentland context->bw_results.urgent_wm_ns[bw_result_idx], 9374562236bSHarry Wentland total_dest_line_time_ns); 9384562236bSHarry Wentland 9394562236bSHarry Wentland if (pipe_ctx->top_pipe) 9404562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_chroma_display_marks( 9414562236bSHarry Wentland pipe_ctx->mi, 9424562236bSHarry Wentland context->bw_results.nbp_state_change_wm_ns[bw_result_idx + 1], 9434562236bSHarry Wentland context->bw_results.stutter_exit_wm_ns[bw_result_idx + 1], 9444562236bSHarry Wentland context->bw_results.urgent_wm_ns[bw_result_idx + 1], 9454562236bSHarry Wentland total_dest_line_time_ns); 9464562236bSHarry Wentland } 9474562236bSHarry Wentland 9484562236bSHarry Wentland void dce110_set_displaymarks( 9494562236bSHarry Wentland const struct core_dc *dc, 9504562236bSHarry Wentland struct validate_context *context) 9514562236bSHarry Wentland { 9524562236bSHarry Wentland uint8_t i, num_pipes; 9534562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 9544562236bSHarry Wentland 9554562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 9564562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 9574562236bSHarry Wentland uint32_t total_dest_line_time_ns; 9584562236bSHarry Wentland 9594562236bSHarry Wentland if (pipe_ctx->stream == NULL) 9604562236bSHarry Wentland continue; 9614562236bSHarry Wentland 9624562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 9634562236bSHarry Wentland dc->bw_vbios.blackout_duration, pipe_ctx->stream); 9644562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_display_marks( 9654562236bSHarry Wentland pipe_ctx->mi, 9664562236bSHarry Wentland context->bw_results.nbp_state_change_wm_ns[num_pipes], 9674562236bSHarry Wentland context->bw_results.stutter_exit_wm_ns[num_pipes], 9684562236bSHarry Wentland context->bw_results.urgent_wm_ns[num_pipes], 9694562236bSHarry Wentland total_dest_line_time_ns); 9704562236bSHarry Wentland if (i == underlay_idx) { 9714562236bSHarry Wentland num_pipes++; 9724562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_chroma_display_marks( 9734562236bSHarry Wentland pipe_ctx->mi, 9744562236bSHarry Wentland context->bw_results.nbp_state_change_wm_ns[num_pipes], 9754562236bSHarry Wentland context->bw_results.stutter_exit_wm_ns[num_pipes], 9764562236bSHarry Wentland context->bw_results.urgent_wm_ns[num_pipes], 9774562236bSHarry Wentland total_dest_line_time_ns); 9784562236bSHarry Wentland } 9794562236bSHarry Wentland num_pipes++; 9804562236bSHarry Wentland } 9814562236bSHarry Wentland } 9824562236bSHarry Wentland 9834562236bSHarry Wentland static void set_safe_displaymarks(struct resource_context *res_ctx) 9844562236bSHarry Wentland { 9854562236bSHarry Wentland int i; 9864562236bSHarry Wentland int underlay_idx = res_ctx->pool->underlay_pipe_index; 9874562236bSHarry Wentland struct bw_watermarks max_marks = { 9884562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 9894562236bSHarry Wentland struct bw_watermarks nbp_marks = { 9904562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 9914562236bSHarry Wentland 9924562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 9934562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream == NULL) 9944562236bSHarry Wentland continue; 9954562236bSHarry Wentland 9964562236bSHarry Wentland res_ctx->pipe_ctx[i].mi->funcs->mem_input_program_display_marks( 9974562236bSHarry Wentland res_ctx->pipe_ctx[i].mi, 9984562236bSHarry Wentland nbp_marks, 9994562236bSHarry Wentland max_marks, 10004562236bSHarry Wentland max_marks, 10014562236bSHarry Wentland MAX_WATERMARK); 10024562236bSHarry Wentland if (i == underlay_idx) 10034562236bSHarry Wentland res_ctx->pipe_ctx[i].mi->funcs->mem_input_program_chroma_display_marks( 10044562236bSHarry Wentland res_ctx->pipe_ctx[i].mi, 10054562236bSHarry Wentland nbp_marks, 10064562236bSHarry Wentland max_marks, 10074562236bSHarry Wentland max_marks, 10084562236bSHarry Wentland MAX_WATERMARK); 10094562236bSHarry Wentland } 10104562236bSHarry Wentland } 10114562236bSHarry Wentland 10124562236bSHarry Wentland static void switch_dp_clock_sources( 10134562236bSHarry Wentland const struct core_dc *dc, 10144562236bSHarry Wentland struct resource_context *res_ctx) 10154562236bSHarry Wentland { 10164562236bSHarry Wentland uint8_t i; 10174562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 10184562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; 10194562236bSHarry Wentland 10204562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 10214562236bSHarry Wentland continue; 10224562236bSHarry Wentland 10234562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 10244562236bSHarry Wentland struct clock_source *clk_src = 10254562236bSHarry Wentland resource_find_used_clk_src_for_sharing( 10264562236bSHarry Wentland res_ctx, pipe_ctx); 10274562236bSHarry Wentland 10284562236bSHarry Wentland if (clk_src && 10294562236bSHarry Wentland clk_src != pipe_ctx->clock_source) { 10304562236bSHarry Wentland resource_unreference_clock_source( 10318c737fccSYongqiang Sun res_ctx, &pipe_ctx->clock_source); 10324562236bSHarry Wentland pipe_ctx->clock_source = clk_src; 10334562236bSHarry Wentland resource_reference_clock_source(res_ctx, clk_src); 10344562236bSHarry Wentland 10354562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, clk_src, i); 10364562236bSHarry Wentland } 10374562236bSHarry Wentland } 10384562236bSHarry Wentland } 10394562236bSHarry Wentland } 10404562236bSHarry Wentland 10414562236bSHarry Wentland /******************************************************************************* 10424562236bSHarry Wentland * Public functions 10434562236bSHarry Wentland ******************************************************************************/ 10444562236bSHarry Wentland 10454562236bSHarry Wentland static void reset_single_pipe_hw_ctx( 10464562236bSHarry Wentland const struct core_dc *dc, 10474562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 10484562236bSHarry Wentland struct validate_context *context) 10494562236bSHarry Wentland { 10504562236bSHarry Wentland core_link_disable_stream(pipe_ctx); 10514562236bSHarry Wentland if (!pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true)) { 10524562236bSHarry Wentland dm_error("DC: failed to blank crtc!\n"); 10534562236bSHarry Wentland BREAK_TO_DEBUGGER(); 10544562236bSHarry Wentland } 10554562236bSHarry Wentland pipe_ctx->tg->funcs->disable_crtc(pipe_ctx->tg); 10564562236bSHarry Wentland pipe_ctx->mi->funcs->free_mem_input( 10574562236bSHarry Wentland pipe_ctx->mi, context->target_count); 10584562236bSHarry Wentland resource_unreference_clock_source( 10598c737fccSYongqiang Sun &context->res_ctx, &pipe_ctx->clock_source); 10604562236bSHarry Wentland 10614562236bSHarry Wentland dc->hwss.power_down_front_end((struct core_dc *)dc, pipe_ctx); 10624562236bSHarry Wentland 10634562236bSHarry Wentland pipe_ctx->stream = NULL; 10644562236bSHarry Wentland } 10654562236bSHarry Wentland 10664562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 10674562236bSHarry Wentland int num_pipes, int vmin, int vmax) 10684562236bSHarry Wentland { 10694562236bSHarry Wentland int i = 0; 10704562236bSHarry Wentland struct drr_params params = {0}; 10714562236bSHarry Wentland 10724562236bSHarry Wentland params.vertical_total_max = vmax; 10734562236bSHarry Wentland params.vertical_total_min = vmin; 10744562236bSHarry Wentland 10754562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 10764562236bSHarry Wentland * some GSL stuff 10774562236bSHarry Wentland */ 10784562236bSHarry Wentland 10794562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 10804562236bSHarry Wentland pipe_ctx[i]->tg->funcs->set_drr(pipe_ctx[i]->tg, ¶ms); 10814562236bSHarry Wentland } 10824562236bSHarry Wentland } 10834562236bSHarry Wentland 10844562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 10854562236bSHarry Wentland int num_pipes, int value) 10864562236bSHarry Wentland { 10874562236bSHarry Wentland unsigned int i; 10884562236bSHarry Wentland 10894562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 10904562236bSHarry Wentland pipe_ctx[i]->tg->funcs-> 10914562236bSHarry Wentland set_static_screen_control(pipe_ctx[i]->tg, value); 10924562236bSHarry Wentland } 10934562236bSHarry Wentland 10944562236bSHarry Wentland /* unit: in_khz before mode set, get pixel clock from context. ASIC register 10954562236bSHarry Wentland * may not be programmed yet. 10964562236bSHarry Wentland * TODO: after mode set, pre_mode_set = false, 10974562236bSHarry Wentland * may read PLL register to get pixel clock 10984562236bSHarry Wentland */ 10994562236bSHarry Wentland static uint32_t get_max_pixel_clock_for_all_paths( 11004562236bSHarry Wentland struct core_dc *dc, 11014562236bSHarry Wentland struct validate_context *context, 11024562236bSHarry Wentland bool pre_mode_set) 11034562236bSHarry Wentland { 11044562236bSHarry Wentland uint32_t max_pix_clk = 0; 11054562236bSHarry Wentland int i; 11064562236bSHarry Wentland 11074562236bSHarry Wentland if (!pre_mode_set) { 11084562236bSHarry Wentland /* TODO: read ASIC register to get pixel clock */ 11094562236bSHarry Wentland ASSERT(0); 11104562236bSHarry Wentland } 11114562236bSHarry Wentland 11124562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 11134562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 11144562236bSHarry Wentland 11154562236bSHarry Wentland if (pipe_ctx->stream == NULL) 11164562236bSHarry Wentland continue; 11174562236bSHarry Wentland 11184562236bSHarry Wentland /* do not check under lay */ 11194562236bSHarry Wentland if (pipe_ctx->top_pipe) 11204562236bSHarry Wentland continue; 11214562236bSHarry Wentland 11224562236bSHarry Wentland if (pipe_ctx->pix_clk_params.requested_pix_clk > max_pix_clk) 11234562236bSHarry Wentland max_pix_clk = 11244562236bSHarry Wentland pipe_ctx->pix_clk_params.requested_pix_clk; 11254562236bSHarry Wentland } 11264562236bSHarry Wentland 11274562236bSHarry Wentland if (max_pix_clk == 0) 11284562236bSHarry Wentland ASSERT(0); 11294562236bSHarry Wentland 11304562236bSHarry Wentland return max_pix_clk; 11314562236bSHarry Wentland } 11324562236bSHarry Wentland 11334562236bSHarry Wentland /* 11344562236bSHarry Wentland * Find clock state based on clock requested. if clock value is 0, simply 11354562236bSHarry Wentland * set clock state as requested without finding clock state by clock value 11364562236bSHarry Wentland */ 11374562236bSHarry Wentland static void apply_min_clocks( 11384562236bSHarry Wentland struct core_dc *dc, 11394562236bSHarry Wentland struct validate_context *context, 1140e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state *clocks_state, 11414562236bSHarry Wentland bool pre_mode_set) 11424562236bSHarry Wentland { 11434562236bSHarry Wentland struct state_dependent_clocks req_clocks = {0}; 11444562236bSHarry Wentland struct pipe_ctx *pipe_ctx; 11454562236bSHarry Wentland int i; 11464562236bSHarry Wentland 11474562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 11484562236bSHarry Wentland pipe_ctx = &context->res_ctx.pipe_ctx[i]; 11494562236bSHarry Wentland if (pipe_ctx->dis_clk != NULL) 11504562236bSHarry Wentland break; 11514562236bSHarry Wentland } 11524562236bSHarry Wentland 11534562236bSHarry Wentland if (!pre_mode_set) { 11544562236bSHarry Wentland /* set clock_state without verification */ 11555d6d185fSDmytro Laktyushkin if (pipe_ctx->dis_clk->funcs->set_min_clocks_state) { 11565d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk->funcs->set_min_clocks_state( 11575d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk, *clocks_state); 11584562236bSHarry Wentland return; 11595d6d185fSDmytro Laktyushkin } 11604562236bSHarry Wentland 11614562236bSHarry Wentland /* TODOFPGA */ 11624562236bSHarry Wentland } 11634562236bSHarry Wentland 11644562236bSHarry Wentland /* get the required state based on state dependent clocks: 11654562236bSHarry Wentland * display clock and pixel clock 11664562236bSHarry Wentland */ 11674562236bSHarry Wentland req_clocks.display_clk_khz = context->bw_results.dispclk_khz; 11684562236bSHarry Wentland 11694562236bSHarry Wentland req_clocks.pixel_clk_khz = get_max_pixel_clock_for_all_paths( 11704562236bSHarry Wentland dc, context, true); 11714562236bSHarry Wentland 11725d6d185fSDmytro Laktyushkin if (pipe_ctx->dis_clk->funcs->get_required_clocks_state) { 11735d6d185fSDmytro Laktyushkin *clocks_state = pipe_ctx->dis_clk->funcs->get_required_clocks_state( 11745d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk, &req_clocks); 11755d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk->funcs->set_min_clocks_state( 11764562236bSHarry Wentland pipe_ctx->dis_clk, *clocks_state); 11774562236bSHarry Wentland } else { 11784562236bSHarry Wentland } 11794562236bSHarry Wentland } 11804562236bSHarry Wentland 11814562236bSHarry Wentland static enum dc_status apply_ctx_to_hw_fpga( 11824562236bSHarry Wentland struct core_dc *dc, 11834562236bSHarry Wentland struct validate_context *context) 11844562236bSHarry Wentland { 11854562236bSHarry Wentland enum dc_status status = DC_ERROR_UNEXPECTED; 11864562236bSHarry Wentland int i; 11874562236bSHarry Wentland 11884562236bSHarry Wentland for (i = 0; i < context->res_ctx.pool->pipe_count; i++) { 11894562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 11904562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[i]; 11914562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 11924562236bSHarry Wentland 11934562236bSHarry Wentland if (pipe_ctx->stream == NULL) 11944562236bSHarry Wentland continue; 11954562236bSHarry Wentland 11964562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) 11974562236bSHarry Wentland continue; 11984562236bSHarry Wentland 11994562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 12004562236bSHarry Wentland pipe_ctx, 12014562236bSHarry Wentland context, 12024562236bSHarry Wentland dc); 12034562236bSHarry Wentland 12044562236bSHarry Wentland if (status != DC_OK) 12054562236bSHarry Wentland return status; 12064562236bSHarry Wentland } 12074562236bSHarry Wentland 12084562236bSHarry Wentland return DC_OK; 12094562236bSHarry Wentland } 12104562236bSHarry Wentland 12114562236bSHarry Wentland static void reset_hw_ctx_wrap( 12124562236bSHarry Wentland struct core_dc *dc, 12134562236bSHarry Wentland struct validate_context *context) 12144562236bSHarry Wentland { 12154562236bSHarry Wentland int i; 12164562236bSHarry Wentland 12174562236bSHarry Wentland /* Reset old context */ 12184562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 12194562236bSHarry Wentland for (i = 0; i < context->res_ctx.pool->pipe_count; i++) { 12204562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 12214562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[i]; 12224562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 12234562236bSHarry Wentland 12244562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 12254562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 12264562236bSHarry Wentland * PHY when not already disabled. 12274562236bSHarry Wentland */ 12284562236bSHarry Wentland 12294562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 12304562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 12314562236bSHarry Wentland continue; 12324562236bSHarry Wentland 12334562236bSHarry Wentland if (!pipe_ctx->stream || 12344562236bSHarry Wentland pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 12354562236bSHarry Wentland reset_single_pipe_hw_ctx( 12364562236bSHarry Wentland dc, pipe_ctx_old, dc->current_context); 12374562236bSHarry Wentland } 12384562236bSHarry Wentland } 12394562236bSHarry Wentland 12404562236bSHarry Wentland /*TODO: const validate_context*/ 12414562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 12424562236bSHarry Wentland struct core_dc *dc, 12434562236bSHarry Wentland struct validate_context *context) 12444562236bSHarry Wentland { 12454562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 12464562236bSHarry Wentland enum dc_status status; 12474562236bSHarry Wentland int i; 12484562236bSHarry Wentland bool programmed_audio_dto = false; 1249e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID; 12504562236bSHarry Wentland 12514562236bSHarry Wentland /* Reset old context */ 12524562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 12534562236bSHarry Wentland dc->hwss.reset_hw_ctx_wrap(dc, context); 12544562236bSHarry Wentland 12554562236bSHarry Wentland /* Skip applying if no targets */ 12564562236bSHarry Wentland if (context->target_count <= 0) 12574562236bSHarry Wentland return DC_OK; 12584562236bSHarry Wentland 12594562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 12604562236bSHarry Wentland apply_ctx_to_hw_fpga(dc, context); 12614562236bSHarry Wentland return DC_OK; 12624562236bSHarry Wentland } 12634562236bSHarry Wentland 12644562236bSHarry Wentland /* Apply new context */ 12654562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 12664562236bSHarry Wentland 12674562236bSHarry Wentland /* below is for real asic only */ 12684562236bSHarry Wentland for (i = 0; i < context->res_ctx.pool->pipe_count; i++) { 12694562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 12704562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[i]; 12714562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 12724562236bSHarry Wentland 12734562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 12744562236bSHarry Wentland continue; 12754562236bSHarry Wentland 12764562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 12774562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 12784562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 12794562236bSHarry Wentland pipe_ctx->clock_source, i); 12804562236bSHarry Wentland continue; 12814562236bSHarry Wentland } 12824562236bSHarry Wentland 12834562236bSHarry Wentland dc->hwss.enable_display_power_gating( 12844562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 12854562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 12864562236bSHarry Wentland } 12874562236bSHarry Wentland 12884562236bSHarry Wentland set_safe_displaymarks(&context->res_ctx); 12894562236bSHarry Wentland /*TODO: when pplib works*/ 12904562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, true); 12914562236bSHarry Wentland 12924562236bSHarry Wentland if (context->bw_results.dispclk_khz 12934562236bSHarry Wentland > dc->current_context->bw_results.dispclk_khz) 12941a687574SDmytro Laktyushkin context->res_ctx.pool->display_clock->funcs->set_clock( 12951a687574SDmytro Laktyushkin context->res_ctx.pool->display_clock, 12961a687574SDmytro Laktyushkin context->bw_results.dispclk_khz * 115 / 100); 12974562236bSHarry Wentland 12984562236bSHarry Wentland for (i = 0; i < context->res_ctx.pool->pipe_count; i++) { 12994562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 13004562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[i]; 13014562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 13024562236bSHarry Wentland 13034562236bSHarry Wentland if (pipe_ctx->stream == NULL) 13044562236bSHarry Wentland continue; 13054562236bSHarry Wentland 13064562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) 13074562236bSHarry Wentland continue; 13084562236bSHarry Wentland 13094562236bSHarry Wentland if (pipe_ctx->top_pipe) 13104562236bSHarry Wentland continue; 13114562236bSHarry Wentland 13124562236bSHarry Wentland if (context->res_ctx.pipe_ctx[i].audio != NULL) { 13134562236bSHarry Wentland /* Setup audio rate clock source */ 13144562236bSHarry Wentland /* Issue: 13154562236bSHarry Wentland * Audio lag happened on DP monitor when unplug a HDMI monitor 13164562236bSHarry Wentland * 13174562236bSHarry Wentland * Cause: 13184562236bSHarry Wentland * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 13194562236bSHarry Wentland * is set to either dto0 or dto1, audio should work fine. 13204562236bSHarry Wentland * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 13214562236bSHarry Wentland * set to dto0 will cause audio lag. 13224562236bSHarry Wentland * 13234562236bSHarry Wentland * Solution: 13244562236bSHarry Wentland * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 13254562236bSHarry Wentland * find first available pipe with audio, setup audio wall DTO per topology 13264562236bSHarry Wentland * instead of per pipe. 13274562236bSHarry Wentland */ 13284562236bSHarry Wentland struct audio_output audio_output; 13294562236bSHarry Wentland 13304562236bSHarry Wentland build_audio_output(pipe_ctx, &audio_output); 13314562236bSHarry Wentland 13324562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 13334562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_audio_setup( 13344562236bSHarry Wentland pipe_ctx->stream_enc, 13354562236bSHarry Wentland pipe_ctx->audio->inst, 13364562236bSHarry Wentland &pipe_ctx->stream->public.audio_info); 13374562236bSHarry Wentland else 13384562236bSHarry Wentland pipe_ctx->stream_enc->funcs->hdmi_audio_setup( 13394562236bSHarry Wentland pipe_ctx->stream_enc, 13404562236bSHarry Wentland pipe_ctx->audio->inst, 13414562236bSHarry Wentland &pipe_ctx->stream->public.audio_info, 13424562236bSHarry Wentland &audio_output.crtc_info); 13434562236bSHarry Wentland 13444562236bSHarry Wentland pipe_ctx->audio->funcs->az_configure( 13454562236bSHarry Wentland pipe_ctx->audio, 13464562236bSHarry Wentland pipe_ctx->stream->signal, 13474562236bSHarry Wentland &audio_output.crtc_info, 13484562236bSHarry Wentland &pipe_ctx->stream->public.audio_info); 13494562236bSHarry Wentland 13504562236bSHarry Wentland if (!programmed_audio_dto) { 13514562236bSHarry Wentland pipe_ctx->audio->funcs->wall_dto_setup( 13524562236bSHarry Wentland pipe_ctx->audio, 13534562236bSHarry Wentland pipe_ctx->stream->signal, 13544562236bSHarry Wentland &audio_output.crtc_info, 13554562236bSHarry Wentland &audio_output.pll_info); 13564562236bSHarry Wentland programmed_audio_dto = true; 13574562236bSHarry Wentland } 13584562236bSHarry Wentland } 13594562236bSHarry Wentland 13604562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 13614562236bSHarry Wentland pipe_ctx, 13624562236bSHarry Wentland context, 13634562236bSHarry Wentland dc); 13644562236bSHarry Wentland 13654562236bSHarry Wentland if (DC_OK != status) 13664562236bSHarry Wentland return status; 13674562236bSHarry Wentland } 13684562236bSHarry Wentland 13694562236bSHarry Wentland dc->hwss.set_displaymarks(dc, context); 13704562236bSHarry Wentland 13714562236bSHarry Wentland /* to save power */ 13724562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, false); 13734562236bSHarry Wentland 13744562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, false); 13754562236bSHarry Wentland 13764562236bSHarry Wentland switch_dp_clock_sources(dc, &context->res_ctx); 13774562236bSHarry Wentland 13784562236bSHarry Wentland return DC_OK; 13794562236bSHarry Wentland } 13804562236bSHarry Wentland 13814562236bSHarry Wentland /******************************************************************************* 13824562236bSHarry Wentland * Front End programming 13834562236bSHarry Wentland ******************************************************************************/ 13844562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 13854562236bSHarry Wentland { 13864562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 13874562236bSHarry Wentland 13884562236bSHarry Wentland default_adjust.force_hw_default = false; 13894562236bSHarry Wentland if (pipe_ctx->surface == NULL) 13904562236bSHarry Wentland default_adjust.in_color_space = COLOR_SPACE_SRGB; 13914562236bSHarry Wentland else 13924562236bSHarry Wentland default_adjust.in_color_space = 13934562236bSHarry Wentland pipe_ctx->surface->public.color_space; 13944562236bSHarry Wentland if (pipe_ctx->stream == NULL) 13954562236bSHarry Wentland default_adjust.out_color_space = COLOR_SPACE_SRGB; 13964562236bSHarry Wentland else 13974562236bSHarry Wentland default_adjust.out_color_space = 13984562236bSHarry Wentland pipe_ctx->stream->public.output_color_space; 13994562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 14004562236bSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->scl_data.format; 14014562236bSHarry Wentland 14024562236bSHarry Wentland /* display color depth */ 14034562236bSHarry Wentland default_adjust.color_depth = 14044562236bSHarry Wentland pipe_ctx->stream->public.timing.display_color_depth; 14054562236bSHarry Wentland 14064562236bSHarry Wentland /* Lb color depth */ 14074562236bSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->scl_data.lb_params.depth; 14084562236bSHarry Wentland 14094562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_csc_default( 14104562236bSHarry Wentland pipe_ctx->opp, &default_adjust); 14114562236bSHarry Wentland } 14124562236bSHarry Wentland 14134562236bSHarry Wentland static void program_blender(const struct core_dc *dc, 14144562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 14154562236bSHarry Wentland { 14164562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 14174562236bSHarry Wentland 14184562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 14194562236bSHarry Wentland if (pipe_ctx->bottom_pipe->surface->public.visible) { 14204562236bSHarry Wentland if (pipe_ctx->surface->public.visible) 14214562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 14224562236bSHarry Wentland else 14234562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 14244562236bSHarry Wentland } 14254562236bSHarry Wentland } 14264562236bSHarry Wentland dce_set_blender_mode(dc->hwseq, pipe_ctx->pipe_idx, blender_mode); 14274562236bSHarry Wentland } 14284562236bSHarry Wentland 14294562236bSHarry Wentland /** 14304562236bSHarry Wentland * TODO REMOVE, USE UPDATE INSTEAD 14314562236bSHarry Wentland */ 14324562236bSHarry Wentland static void set_plane_config( 14334562236bSHarry Wentland const struct core_dc *dc, 14344562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 14354562236bSHarry Wentland struct resource_context *res_ctx) 14364562236bSHarry Wentland { 14374562236bSHarry Wentland struct mem_input *mi = pipe_ctx->mi; 14384562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 14394562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 14404562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 14414562236bSHarry Wentland unsigned int i; 14424562236bSHarry Wentland 14434562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 14444562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 14454562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 14464562236bSHarry Wentland 14474562236bSHarry Wentland dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true); 14484562236bSHarry Wentland 14494562236bSHarry Wentland set_default_colors(pipe_ctx); 14504562236bSHarry Wentland if (pipe_ctx->stream->public.csc_color_matrix.enable_adjustment 14514562236bSHarry Wentland == true) { 14524562236bSHarry Wentland tbl_entry.color_space = 14534562236bSHarry Wentland pipe_ctx->stream->public.output_color_space; 14544562236bSHarry Wentland 14554562236bSHarry Wentland for (i = 0; i < 12; i++) 14564562236bSHarry Wentland tbl_entry.regval[i] = 14574562236bSHarry Wentland pipe_ctx->stream->public.csc_color_matrix.matrix[i]; 14584562236bSHarry Wentland 14594562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_csc_adjustment 14604562236bSHarry Wentland (pipe_ctx->opp, &tbl_entry); 14614562236bSHarry Wentland } 14624562236bSHarry Wentland 14634562236bSHarry Wentland if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) { 14644562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 14654562236bSHarry Wentland adjust.temperature_matrix[0] = 14664562236bSHarry Wentland pipe_ctx->stream-> 14674562236bSHarry Wentland public.gamut_remap_matrix.matrix[0]; 14684562236bSHarry Wentland adjust.temperature_matrix[1] = 14694562236bSHarry Wentland pipe_ctx->stream-> 14704562236bSHarry Wentland public.gamut_remap_matrix.matrix[1]; 14714562236bSHarry Wentland adjust.temperature_matrix[2] = 14724562236bSHarry Wentland pipe_ctx->stream-> 14734562236bSHarry Wentland public.gamut_remap_matrix.matrix[2]; 14744562236bSHarry Wentland adjust.temperature_matrix[3] = 14754562236bSHarry Wentland pipe_ctx->stream-> 14764562236bSHarry Wentland public.gamut_remap_matrix.matrix[4]; 14774562236bSHarry Wentland adjust.temperature_matrix[4] = 14784562236bSHarry Wentland pipe_ctx->stream-> 14794562236bSHarry Wentland public.gamut_remap_matrix.matrix[5]; 14804562236bSHarry Wentland adjust.temperature_matrix[5] = 14814562236bSHarry Wentland pipe_ctx->stream-> 14824562236bSHarry Wentland public.gamut_remap_matrix.matrix[6]; 14834562236bSHarry Wentland adjust.temperature_matrix[6] = 14844562236bSHarry Wentland pipe_ctx->stream-> 14854562236bSHarry Wentland public.gamut_remap_matrix.matrix[8]; 14864562236bSHarry Wentland adjust.temperature_matrix[7] = 14874562236bSHarry Wentland pipe_ctx->stream-> 14884562236bSHarry Wentland public.gamut_remap_matrix.matrix[9]; 14894562236bSHarry Wentland adjust.temperature_matrix[8] = 14904562236bSHarry Wentland pipe_ctx->stream-> 14914562236bSHarry Wentland public.gamut_remap_matrix.matrix[10]; 14924562236bSHarry Wentland } 14934562236bSHarry Wentland 14944562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust); 14954562236bSHarry Wentland 14964562236bSHarry Wentland pipe_ctx->scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 14974562236bSHarry Wentland program_scaler(dc, pipe_ctx); 14984562236bSHarry Wentland 14994562236bSHarry Wentland program_blender(dc, pipe_ctx); 15004562236bSHarry Wentland 15014562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 15024562236bSHarry Wentland mi, 15034562236bSHarry Wentland surface->public.format, 15044562236bSHarry Wentland &surface->public.tiling_info, 15054562236bSHarry Wentland &surface->public.plane_size, 15064562236bSHarry Wentland surface->public.rotation, 15074562236bSHarry Wentland NULL, 15084562236bSHarry Wentland false); 15094562236bSHarry Wentland 15104562236bSHarry Wentland if (dc->public.config.gpu_vm_support) 15114562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 15124562236bSHarry Wentland pipe_ctx->mi, 15134562236bSHarry Wentland surface->public.format, 15144562236bSHarry Wentland &surface->public.tiling_info, 15154562236bSHarry Wentland surface->public.rotation); 15164562236bSHarry Wentland } 15174562236bSHarry Wentland 15184562236bSHarry Wentland static void update_plane_addr(const struct core_dc *dc, 15194562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 15204562236bSHarry Wentland { 15214562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 15224562236bSHarry Wentland 15234562236bSHarry Wentland if (surface == NULL) 15244562236bSHarry Wentland return; 15254562236bSHarry Wentland 15264562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_surface_flip_and_addr( 15274562236bSHarry Wentland pipe_ctx->mi, 15284562236bSHarry Wentland &surface->public.address, 15294562236bSHarry Wentland surface->public.flip_immediate); 15304562236bSHarry Wentland 15314562236bSHarry Wentland surface->status.requested_address = surface->public.address; 15324562236bSHarry Wentland 15334562236bSHarry Wentland if (surface->public.visible) 15344562236bSHarry Wentland pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, false); 15354562236bSHarry Wentland } 15364562236bSHarry Wentland 15374562236bSHarry Wentland void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 15384562236bSHarry Wentland { 15394562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 15404562236bSHarry Wentland 15414562236bSHarry Wentland if (surface == NULL) 15424562236bSHarry Wentland return; 15434562236bSHarry Wentland 15444562236bSHarry Wentland surface->status.is_flip_pending = 15454562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_is_flip_pending( 15464562236bSHarry Wentland pipe_ctx->mi); 15474562236bSHarry Wentland 15484562236bSHarry Wentland if (surface->status.is_flip_pending && !surface->public.visible) 15494562236bSHarry Wentland pipe_ctx->mi->current_address = pipe_ctx->mi->request_address; 15504562236bSHarry Wentland 15514562236bSHarry Wentland surface->status.current_address = pipe_ctx->mi->current_address; 15524562236bSHarry Wentland } 15534562236bSHarry Wentland 15544562236bSHarry Wentland void dce110_power_down(struct core_dc *dc) 15554562236bSHarry Wentland { 15564562236bSHarry Wentland power_down_all_hw_blocks(dc); 15574562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 15584562236bSHarry Wentland } 15594562236bSHarry Wentland 15604562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 15614562236bSHarry Wentland struct dc_context *dc_ctx, 15624562236bSHarry Wentland struct timing_generator *tg) 15634562236bSHarry Wentland { 15644562236bSHarry Wentland bool rc = false; 15654562236bSHarry Wentland 15664562236bSHarry Wentland /* To avoid endless loop we wait at most 15674562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 15684562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 15694562236bSHarry Wentland uint32_t i; 15704562236bSHarry Wentland 15714562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 15724562236bSHarry Wentland 15734562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 15744562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 15754562236bSHarry Wentland break; 15764562236bSHarry Wentland } 15774562236bSHarry Wentland 15784562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 15794562236bSHarry Wentland rc = true; 15804562236bSHarry Wentland /* usually occurs at i=1 */ 15814562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 15824562236bSHarry Wentland i); 15834562236bSHarry Wentland break; 15844562236bSHarry Wentland } 15854562236bSHarry Wentland 15864562236bSHarry Wentland /* Wait for one frame. */ 15874562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 15884562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 15894562236bSHarry Wentland } 15904562236bSHarry Wentland 15914562236bSHarry Wentland if (false == rc) 15924562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 15934562236bSHarry Wentland 15944562236bSHarry Wentland return rc; 15954562236bSHarry Wentland } 15964562236bSHarry Wentland 15974562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 15984562236bSHarry Wentland static void dce110_enable_timing_synchronization( 15994562236bSHarry Wentland struct core_dc *dc, 16004562236bSHarry Wentland int group_index, 16014562236bSHarry Wentland int group_size, 16024562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 16034562236bSHarry Wentland { 16044562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 16054562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 16064562236bSHarry Wentland int i; 16074562236bSHarry Wentland 16084562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 16094562236bSHarry Wentland 16104562236bSHarry Wentland /* Designate a single TG in the group as a master. 16114562236bSHarry Wentland * Since HW doesn't care which one, we always assign 16124562236bSHarry Wentland * the 1st one in the group. */ 16134562236bSHarry Wentland gsl_params.gsl_group = 0; 16144562236bSHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->tg->inst; 16154562236bSHarry Wentland 16164562236bSHarry Wentland for (i = 0; i < group_size; i++) 16174562236bSHarry Wentland grouped_pipes[i]->tg->funcs->setup_global_swap_lock( 16184562236bSHarry Wentland grouped_pipes[i]->tg, &gsl_params); 16194562236bSHarry Wentland 16204562236bSHarry Wentland /* Reset slave controllers on master VSync */ 16214562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 16224562236bSHarry Wentland 16234562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 16244562236bSHarry Wentland grouped_pipes[i]->tg->funcs->enable_reset_trigger( 16254562236bSHarry Wentland grouped_pipes[i]->tg, gsl_params.gsl_group); 16264562236bSHarry Wentland 16274562236bSHarry Wentland 16284562236bSHarry Wentland 16294562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 16304562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 16314562236bSHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->tg); 16324562236bSHarry Wentland /* Regardless of success of the wait above, remove the reset or 16334562236bSHarry Wentland * the driver will start timing out on Display requests. */ 16344562236bSHarry Wentland DC_SYNC_INFO("GSL: disabling trigger-reset.\n"); 16354562236bSHarry Wentland grouped_pipes[i]->tg->funcs->disable_reset_trigger(grouped_pipes[i]->tg); 16364562236bSHarry Wentland } 16374562236bSHarry Wentland 16384562236bSHarry Wentland 16394562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 16404562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 16414562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 16424562236bSHarry Wentland for (i = 0; i < group_size; i++) 16434562236bSHarry Wentland grouped_pipes[i]->tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->tg); 16444562236bSHarry Wentland 16454562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 16464562236bSHarry Wentland } 16474562236bSHarry Wentland 16484562236bSHarry Wentland static void init_hw(struct core_dc *dc) 16494562236bSHarry Wentland { 16504562236bSHarry Wentland int i; 16514562236bSHarry Wentland struct dc_bios *bp; 16524562236bSHarry Wentland struct transform *xfm; 16534562236bSHarry Wentland 16544562236bSHarry Wentland bp = dc->ctx->dc_bios; 16554562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 16564562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 16574562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 16584562236bSHarry Wentland 16594562236bSHarry Wentland dc->hwss.enable_display_power_gating( 16604562236bSHarry Wentland dc, i, bp, 16614562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 16624562236bSHarry Wentland dc->hwss.enable_display_power_gating( 16634562236bSHarry Wentland dc, i, bp, 16644562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 16654562236bSHarry Wentland dc->hwss.enable_display_pipe_clock_gating( 16664562236bSHarry Wentland dc->ctx, 16674562236bSHarry Wentland true); 16684562236bSHarry Wentland } 16694562236bSHarry Wentland 16704562236bSHarry Wentland dce_clock_gating_power_up(dc->hwseq, false);; 16714562236bSHarry Wentland /***************************************/ 16724562236bSHarry Wentland 16734562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 16744562236bSHarry Wentland /****************************************/ 16754562236bSHarry Wentland /* Power up AND update implementation according to the 16764562236bSHarry Wentland * required signal (which may be different from the 16774562236bSHarry Wentland * default signal on connector). */ 16784562236bSHarry Wentland struct core_link *link = dc->links[i]; 16794562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 16804562236bSHarry Wentland } 16814562236bSHarry Wentland 16824562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 16834562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 16844562236bSHarry Wentland 16854562236bSHarry Wentland tg->funcs->disable_vga(tg); 16864562236bSHarry Wentland 16874562236bSHarry Wentland /* Blank controller using driver code instead of 16884562236bSHarry Wentland * command table. */ 16894562236bSHarry Wentland tg->funcs->set_blank(tg, true); 16904562236bSHarry Wentland } 16914562236bSHarry Wentland 16924562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 16934562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 16944562236bSHarry Wentland audio->funcs->hw_init(audio); 16954562236bSHarry Wentland } 16964562236bSHarry Wentland } 16974562236bSHarry Wentland 16984562236bSHarry Wentland /* TODO: move this to apply_ctx_tohw some how?*/ 16994562236bSHarry Wentland static void dce110_power_on_pipe_if_needed( 17004562236bSHarry Wentland struct core_dc *dc, 17014562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 17024562236bSHarry Wentland struct validate_context *context) 17034562236bSHarry Wentland { 17044562236bSHarry Wentland struct pipe_ctx *old_pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; 17054562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 17064562236bSHarry Wentland struct tg_color black_color = {0}; 17074562236bSHarry Wentland 17084562236bSHarry Wentland if (!old_pipe_ctx->stream && pipe_ctx->stream) { 17094562236bSHarry Wentland dc->hwss.enable_display_power_gating( 17104562236bSHarry Wentland dc, 17114562236bSHarry Wentland pipe_ctx->pipe_idx, 17124562236bSHarry Wentland dcb, PIPE_GATING_CONTROL_DISABLE); 17134562236bSHarry Wentland 17144562236bSHarry Wentland /* 17154562236bSHarry Wentland * This is for powering on underlay, so crtc does not 17164562236bSHarry Wentland * need to be enabled 17174562236bSHarry Wentland */ 17184562236bSHarry Wentland 17194562236bSHarry Wentland pipe_ctx->tg->funcs->program_timing(pipe_ctx->tg, 17204562236bSHarry Wentland &pipe_ctx->stream->public.timing, 17214562236bSHarry Wentland false); 17224562236bSHarry Wentland 17234562236bSHarry Wentland pipe_ctx->tg->funcs->enable_advanced_request( 17244562236bSHarry Wentland pipe_ctx->tg, 17254562236bSHarry Wentland true, 17264562236bSHarry Wentland &pipe_ctx->stream->public.timing); 17274562236bSHarry Wentland 17284562236bSHarry Wentland pipe_ctx->mi->funcs->allocate_mem_input(pipe_ctx->mi, 17294562236bSHarry Wentland pipe_ctx->stream->public.timing.h_total, 17304562236bSHarry Wentland pipe_ctx->stream->public.timing.v_total, 17314562236bSHarry Wentland pipe_ctx->stream->public.timing.pix_clk_khz, 17324562236bSHarry Wentland context->target_count); 17334562236bSHarry Wentland 17344562236bSHarry Wentland /* TODO unhardcode*/ 17354562236bSHarry Wentland color_space_to_black_color(dc, 17364562236bSHarry Wentland COLOR_SPACE_YCBCR601, &black_color); 17374562236bSHarry Wentland pipe_ctx->tg->funcs->set_blank_color( 17384562236bSHarry Wentland pipe_ctx->tg, 17394562236bSHarry Wentland &black_color); 17404562236bSHarry Wentland } 17414562236bSHarry Wentland } 17424562236bSHarry Wentland 17434562236bSHarry Wentland static void dce110_increase_watermarks_for_pipe( 17444562236bSHarry Wentland struct core_dc *dc, 17454562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 17464562236bSHarry Wentland struct validate_context *context) 17474562236bSHarry Wentland { 17484562236bSHarry Wentland if (did_watermarks_increase(pipe_ctx, context, dc->current_context)) 17494562236bSHarry Wentland program_wm_for_pipe(dc, pipe_ctx, context); 17504562236bSHarry Wentland } 17514562236bSHarry Wentland 17524562236bSHarry Wentland static void dce110_set_bandwidth(struct core_dc *dc) 17534562236bSHarry Wentland { 17544562236bSHarry Wentland int i; 17554562236bSHarry Wentland 17564562236bSHarry Wentland for (i = 0; i < dc->current_context->res_ctx.pool->pipe_count; i++) { 17574562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &dc->current_context->res_ctx.pipe_ctx[i]; 17584562236bSHarry Wentland 17594562236bSHarry Wentland if (!pipe_ctx->stream) 17604562236bSHarry Wentland continue; 17614562236bSHarry Wentland 17624562236bSHarry Wentland program_wm_for_pipe(dc, pipe_ctx, dc->current_context); 17634562236bSHarry Wentland } 17644562236bSHarry Wentland 17651a687574SDmytro Laktyushkin dc->current_context->res_ctx.pool->display_clock->funcs->set_clock( 17661a687574SDmytro Laktyushkin dc->current_context->res_ctx.pool->display_clock, 17671a687574SDmytro Laktyushkin dc->current_context->bw_results.dispclk_khz * 115 / 100); 17684562236bSHarry Wentland } 17694562236bSHarry Wentland 17704562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 17714562236bSHarry Wentland struct core_dc *dc, struct pipe_ctx *pipe_ctx) 17724562236bSHarry Wentland { 17734562236bSHarry Wentland struct mem_input *mi = pipe_ctx->mi; 17744562236bSHarry Wentland struct pipe_ctx *old_pipe = NULL; 17754562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 17764562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 17774562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 17784562236bSHarry Wentland unsigned int i; 17794562236bSHarry Wentland 17804562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 17814562236bSHarry Wentland 17824562236bSHarry Wentland if (dc->current_context) 17834562236bSHarry Wentland old_pipe = &dc->current_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; 17844562236bSHarry Wentland 17854562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 17864562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 17874562236bSHarry Wentland 17884562236bSHarry Wentland dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true); 17894562236bSHarry Wentland 17904562236bSHarry Wentland set_default_colors(pipe_ctx); 17914562236bSHarry Wentland if (pipe_ctx->stream->public.csc_color_matrix.enable_adjustment 17924562236bSHarry Wentland == true) { 17934562236bSHarry Wentland tbl_entry.color_space = 17944562236bSHarry Wentland pipe_ctx->stream->public.output_color_space; 17954562236bSHarry Wentland 17964562236bSHarry Wentland for (i = 0; i < 12; i++) 17974562236bSHarry Wentland tbl_entry.regval[i] = 17984562236bSHarry Wentland pipe_ctx->stream->public.csc_color_matrix.matrix[i]; 17994562236bSHarry Wentland 18004562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_csc_adjustment 18014562236bSHarry Wentland (pipe_ctx->opp, &tbl_entry); 18024562236bSHarry Wentland } 18034562236bSHarry Wentland 18044562236bSHarry Wentland if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) { 18054562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 18064562236bSHarry Wentland adjust.temperature_matrix[0] = 18074562236bSHarry Wentland pipe_ctx->stream-> 18084562236bSHarry Wentland public.gamut_remap_matrix.matrix[0]; 18094562236bSHarry Wentland adjust.temperature_matrix[1] = 18104562236bSHarry Wentland pipe_ctx->stream-> 18114562236bSHarry Wentland public.gamut_remap_matrix.matrix[1]; 18124562236bSHarry Wentland adjust.temperature_matrix[2] = 18134562236bSHarry Wentland pipe_ctx->stream-> 18144562236bSHarry Wentland public.gamut_remap_matrix.matrix[2]; 18154562236bSHarry Wentland adjust.temperature_matrix[3] = 18164562236bSHarry Wentland pipe_ctx->stream-> 18174562236bSHarry Wentland public.gamut_remap_matrix.matrix[4]; 18184562236bSHarry Wentland adjust.temperature_matrix[4] = 18194562236bSHarry Wentland pipe_ctx->stream-> 18204562236bSHarry Wentland public.gamut_remap_matrix.matrix[5]; 18214562236bSHarry Wentland adjust.temperature_matrix[5] = 18224562236bSHarry Wentland pipe_ctx->stream-> 18234562236bSHarry Wentland public.gamut_remap_matrix.matrix[6]; 18244562236bSHarry Wentland adjust.temperature_matrix[6] = 18254562236bSHarry Wentland pipe_ctx->stream-> 18264562236bSHarry Wentland public.gamut_remap_matrix.matrix[8]; 18274562236bSHarry Wentland adjust.temperature_matrix[7] = 18284562236bSHarry Wentland pipe_ctx->stream-> 18294562236bSHarry Wentland public.gamut_remap_matrix.matrix[9]; 18304562236bSHarry Wentland adjust.temperature_matrix[8] = 18314562236bSHarry Wentland pipe_ctx->stream-> 18324562236bSHarry Wentland public.gamut_remap_matrix.matrix[10]; 18334562236bSHarry Wentland } 18344562236bSHarry Wentland 18354562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust); 18364562236bSHarry Wentland 18374562236bSHarry Wentland pipe_ctx->scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 18384562236bSHarry Wentland if (old_pipe && memcmp(&old_pipe->scl_data, 18394562236bSHarry Wentland &pipe_ctx->scl_data, 18404562236bSHarry Wentland sizeof(struct scaler_data)) != 0) 18414562236bSHarry Wentland program_scaler(dc, pipe_ctx); 18424562236bSHarry Wentland 18434562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 18444562236bSHarry Wentland mi, 18454562236bSHarry Wentland surface->public.format, 18464562236bSHarry Wentland &surface->public.tiling_info, 18474562236bSHarry Wentland &surface->public.plane_size, 18484562236bSHarry Wentland surface->public.rotation, 18494562236bSHarry Wentland false, 18504562236bSHarry Wentland false); 18514562236bSHarry Wentland 18524562236bSHarry Wentland if (dc->public.config.gpu_vm_support) 18534562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 18544562236bSHarry Wentland pipe_ctx->mi, 18554562236bSHarry Wentland surface->public.format, 18564562236bSHarry Wentland &surface->public.tiling_info, 18574562236bSHarry Wentland surface->public.rotation); 18584562236bSHarry Wentland 18594562236bSHarry Wentland dm_logger_write(dc->ctx->logger, LOG_SURFACE, 18604562236bSHarry Wentland "Pipe:%d 0x%x: addr hi:0x%x, " 18614562236bSHarry Wentland "addr low:0x%x, " 18624562236bSHarry Wentland "src: %d, %d, %d," 18634562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 18644562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 18654562236bSHarry Wentland pipe_ctx->pipe_idx, 18664562236bSHarry Wentland pipe_ctx->surface, 18674562236bSHarry Wentland pipe_ctx->surface->public.address.grph.addr.high_part, 18684562236bSHarry Wentland pipe_ctx->surface->public.address.grph.addr.low_part, 18694562236bSHarry Wentland pipe_ctx->surface->public.src_rect.x, 18704562236bSHarry Wentland pipe_ctx->surface->public.src_rect.y, 18714562236bSHarry Wentland pipe_ctx->surface->public.src_rect.width, 18724562236bSHarry Wentland pipe_ctx->surface->public.src_rect.height, 18734562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.x, 18744562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.y, 18754562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.width, 18764562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.height, 18774562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.x, 18784562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.y, 18794562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.width, 18804562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.height); 18814562236bSHarry Wentland 18824562236bSHarry Wentland dm_logger_write(dc->ctx->logger, LOG_SURFACE, 18834562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 18844562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 18854562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 18864562236bSHarry Wentland pipe_ctx->pipe_idx, 18874562236bSHarry Wentland pipe_ctx->scl_data.viewport.width, 18884562236bSHarry Wentland pipe_ctx->scl_data.viewport.height, 18894562236bSHarry Wentland pipe_ctx->scl_data.viewport.x, 18904562236bSHarry Wentland pipe_ctx->scl_data.viewport.y, 18914562236bSHarry Wentland pipe_ctx->scl_data.recout.width, 18924562236bSHarry Wentland pipe_ctx->scl_data.recout.height, 18934562236bSHarry Wentland pipe_ctx->scl_data.recout.x, 18944562236bSHarry Wentland pipe_ctx->scl_data.recout.y); 18954562236bSHarry Wentland } 18964562236bSHarry Wentland 18974562236bSHarry Wentland static void dce110_prepare_pipe_for_context( 18984562236bSHarry Wentland struct core_dc *dc, 18994562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 19004562236bSHarry Wentland struct validate_context *context) 19014562236bSHarry Wentland { 19024562236bSHarry Wentland dce110_power_on_pipe_if_needed(dc, pipe_ctx, context); 1903fb735a9fSAnthony Koo dc->hwss.increase_watermarks_for_pipe(dc, pipe_ctx, context); 19044562236bSHarry Wentland } 19054562236bSHarry Wentland 19064562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 19074562236bSHarry Wentland struct core_dc *dc, 19084562236bSHarry Wentland struct core_surface *surface, 19094562236bSHarry Wentland struct validate_context *context) 19104562236bSHarry Wentland { 19114562236bSHarry Wentland int i; 19124562236bSHarry Wentland 19134562236bSHarry Wentland /* TODO remove when removing the surface reset workaroud*/ 19144562236bSHarry Wentland if (!surface) 19154562236bSHarry Wentland return; 19164562236bSHarry Wentland 19174562236bSHarry Wentland for (i = 0; i < context->res_ctx.pool->pipe_count; i++) { 19184562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 19194562236bSHarry Wentland 19204562236bSHarry Wentland if (pipe_ctx->surface != surface) 19214562236bSHarry Wentland continue; 19224562236bSHarry Wentland 19234562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 19244562236bSHarry Wentland program_blender(dc, pipe_ctx); 19254562236bSHarry Wentland 19264562236bSHarry Wentland } 19274562236bSHarry Wentland } 19284562236bSHarry Wentland 19294562236bSHarry Wentland static void dce110_power_down_fe(struct core_dc *dc, struct pipe_ctx *pipe) 19304562236bSHarry Wentland { 19314562236bSHarry Wentland int i; 19324562236bSHarry Wentland 19334562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) 19344562236bSHarry Wentland if (&dc->current_context->res_ctx.pipe_ctx[i] == pipe) 19354562236bSHarry Wentland break; 19364562236bSHarry Wentland 19374562236bSHarry Wentland if (i == dc->res_pool->pipe_count) 19384562236bSHarry Wentland return; 19394562236bSHarry Wentland 19404562236bSHarry Wentland dc->hwss.enable_display_power_gating( 19414562236bSHarry Wentland dc, i, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 19424562236bSHarry Wentland if (pipe->xfm) 19434562236bSHarry Wentland pipe->xfm->funcs->transform_reset(pipe->xfm); 19444562236bSHarry Wentland memset(&pipe->scl_data, 0, sizeof(struct scaler_data)); 19454562236bSHarry Wentland } 19464562236bSHarry Wentland 19474562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 19484562236bSHarry Wentland .init_hw = init_hw, 19494562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 19504562236bSHarry Wentland .prepare_pipe_for_context = dce110_prepare_pipe_for_context, 19514562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 19524562236bSHarry Wentland .set_plane_config = set_plane_config, 19534562236bSHarry Wentland .update_plane_addr = update_plane_addr, 19544562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 1955d7194cf6SAric Cyr .set_input_transfer_func = dce110_set_input_transfer_func, 195690e508baSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 19574562236bSHarry Wentland .power_down = dce110_power_down, 19584562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 19594562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 19604562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 19614562236bSHarry Wentland .enable_stream = dce110_enable_stream, 19624562236bSHarry Wentland .disable_stream = dce110_disable_stream, 19634562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 19644562236bSHarry Wentland .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 19654562236bSHarry Wentland .enable_display_power_gating = dce110_enable_display_power_gating, 19664562236bSHarry Wentland .power_down_front_end = dce110_power_down_fe, 19674562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 19684562236bSHarry Wentland .set_displaymarks = dce110_set_displaymarks, 19694562236bSHarry Wentland .increase_watermarks_for_pipe = dce110_increase_watermarks_for_pipe, 19704562236bSHarry Wentland .set_bandwidth = dce110_set_bandwidth, 19714562236bSHarry Wentland .set_drr = set_drr, 19724562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 19734562236bSHarry Wentland .reset_hw_ctx_wrap = reset_hw_ctx_wrap, 19744562236bSHarry Wentland .prog_pixclk_crtc_otg = prog_pixclk_crtc_otg, 19754562236bSHarry Wentland }; 19764562236bSHarry Wentland 19774562236bSHarry Wentland bool dce110_hw_sequencer_construct(struct core_dc *dc) 19784562236bSHarry Wentland { 19794562236bSHarry Wentland dc->hwss = dce110_funcs; 19804562236bSHarry Wentland 19814562236bSHarry Wentland return true; 19824562236bSHarry Wentland } 19834562236bSHarry Wentland 1984