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 "dm_helpers.h" 324562236bSHarry Wentland #include "dce110_hw_sequencer.h" 334562236bSHarry Wentland #include "dce110_timing_generator.h" 3498489c02SLeo (Sunpeng) Li #include "dce/dce_hwseq.h" 354562236bSHarry Wentland 361663ae1cSBhawanpreet Lakha #ifdef ENABLE_FBC 371663ae1cSBhawanpreet Lakha #include "dce110_compressor.h" 381663ae1cSBhawanpreet Lakha #endif 391663ae1cSBhawanpreet Lakha 404562236bSHarry Wentland #include "bios/bios_parser_helper.h" 414562236bSHarry Wentland #include "timing_generator.h" 424562236bSHarry Wentland #include "mem_input.h" 434562236bSHarry Wentland #include "opp.h" 444562236bSHarry Wentland #include "ipp.h" 454562236bSHarry Wentland #include "transform.h" 464562236bSHarry Wentland #include "stream_encoder.h" 474562236bSHarry Wentland #include "link_encoder.h" 484562236bSHarry Wentland #include "clock_source.h" 495e7773a2SAnthony Koo #include "abm.h" 504562236bSHarry Wentland #include "audio.h" 514562236bSHarry Wentland #include "dce/dce_hwseq.h" 524562236bSHarry Wentland 534562236bSHarry Wentland /* include DCE11 register header files */ 544562236bSHarry Wentland #include "dce/dce_11_0_d.h" 554562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 56e266fdf6SVitaly Prosyak #include "custom_float.h" 574562236bSHarry Wentland 584562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 594562236bSHarry Wentland uint32_t crtc; 604562236bSHarry Wentland }; 614562236bSHarry Wentland 624562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 634562236bSHarry Wentland { 644562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 654562236bSHarry Wentland }, 664562236bSHarry Wentland { 674562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 684562236bSHarry Wentland }, 694562236bSHarry Wentland { 704562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 714562236bSHarry Wentland }, 724562236bSHarry Wentland { 734562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 744562236bSHarry Wentland } 754562236bSHarry Wentland }; 764562236bSHarry Wentland 774562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 784562236bSHarry Wentland (reg + reg_offsets[id].blnd) 794562236bSHarry Wentland 804562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 814562236bSHarry Wentland (reg + reg_offsets[id].crtc) 824562236bSHarry Wentland 834562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 844562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 854562236bSHarry Wentland 864562236bSHarry Wentland /******************************************************************************* 874562236bSHarry Wentland * Private definitions 884562236bSHarry Wentland ******************************************************************************/ 894562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 904562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 914562236bSHarry Wentland { 924562236bSHarry Wentland uint32_t addr; 934562236bSHarry Wentland uint32_t value = 0; 944562236bSHarry Wentland uint32_t chunk_int = 0; 954562236bSHarry Wentland uint32_t chunk_mul = 0; 964562236bSHarry Wentland 974562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 984562236bSHarry Wentland value = dm_read_reg(ctx, addr); 994562236bSHarry Wentland 1004562236bSHarry Wentland set_reg_field_value( 1014562236bSHarry Wentland value, 1024562236bSHarry Wentland 0, 1034562236bSHarry Wentland DVMM_PTE_CONTROL, 1044562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1054562236bSHarry Wentland 1064562236bSHarry Wentland set_reg_field_value( 1074562236bSHarry Wentland value, 1084562236bSHarry Wentland 1, 1094562236bSHarry Wentland DVMM_PTE_CONTROL, 1104562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1114562236bSHarry Wentland 1124562236bSHarry Wentland set_reg_field_value( 1134562236bSHarry Wentland value, 1144562236bSHarry Wentland 1, 1154562236bSHarry Wentland DVMM_PTE_CONTROL, 1164562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1174562236bSHarry Wentland 1184562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1194562236bSHarry Wentland 1204562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1214562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1224562236bSHarry Wentland 1234562236bSHarry Wentland chunk_int = get_reg_field_value( 1244562236bSHarry Wentland value, 1254562236bSHarry Wentland DVMM_PTE_REQ, 1264562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1274562236bSHarry Wentland 1284562236bSHarry Wentland chunk_mul = get_reg_field_value( 1294562236bSHarry Wentland value, 1304562236bSHarry Wentland DVMM_PTE_REQ, 1314562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1324562236bSHarry Wentland 1334562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1344562236bSHarry Wentland 1354562236bSHarry Wentland set_reg_field_value( 1364562236bSHarry Wentland value, 1374562236bSHarry Wentland 255, 1384562236bSHarry Wentland DVMM_PTE_REQ, 1394562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1404562236bSHarry Wentland 1414562236bSHarry Wentland set_reg_field_value( 1424562236bSHarry Wentland value, 1434562236bSHarry Wentland 4, 1444562236bSHarry Wentland DVMM_PTE_REQ, 1454562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1464562236bSHarry Wentland 1474562236bSHarry Wentland set_reg_field_value( 1484562236bSHarry Wentland value, 1494562236bSHarry Wentland 4, 1504562236bSHarry Wentland DVMM_PTE_REQ, 1514562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1524562236bSHarry Wentland 1534562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1544562236bSHarry Wentland } 1554562236bSHarry Wentland } 1564562236bSHarry Wentland /**************************************************************************/ 1574562236bSHarry Wentland 1584562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1594562236bSHarry Wentland struct dc_context *ctx, 1604562236bSHarry Wentland bool clock_gating) 1614562236bSHarry Wentland { 1624562236bSHarry Wentland /*TODO*/ 1634562236bSHarry Wentland } 1644562236bSHarry Wentland 1654562236bSHarry Wentland static bool dce110_enable_display_power_gating( 1664562236bSHarry Wentland struct core_dc *dc, 1674562236bSHarry Wentland uint8_t controller_id, 1684562236bSHarry Wentland struct dc_bios *dcb, 1694562236bSHarry Wentland enum pipe_gating_control power_gating) 1704562236bSHarry Wentland { 1714562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 1724562236bSHarry Wentland enum bp_pipe_control_action cntl; 1734562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 1744562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 1754562236bSHarry Wentland 1764562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 1774562236bSHarry Wentland return true; 1784562236bSHarry Wentland 1794562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 1804562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 1814562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 1824562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 1834562236bSHarry Wentland else 1844562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 1854562236bSHarry Wentland 1864562236bSHarry Wentland if (controller_id == underlay_idx) 1874562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 1884562236bSHarry Wentland 1894562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){ 1904562236bSHarry Wentland 1914562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 1924562236bSHarry Wentland dcb, controller_id + 1, cntl); 1934562236bSHarry Wentland 1944562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 1954562236bSHarry Wentland * by default when command table is called 1964562236bSHarry Wentland * 1974562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 1984562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 1994562236bSHarry Wentland * than 3. 2004562236bSHarry Wentland */ 2014562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 2024562236bSHarry Wentland dm_write_reg(ctx, 2034562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 2044562236bSHarry Wentland 0); 2054562236bSHarry Wentland } 2064562236bSHarry Wentland 2074562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2084562236bSHarry Wentland dce110_init_pte(ctx); 2094562236bSHarry Wentland 2104562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2114562236bSHarry Wentland return true; 2124562236bSHarry Wentland else 2134562236bSHarry Wentland return false; 2144562236bSHarry Wentland } 2154562236bSHarry Wentland 2164562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2174562236bSHarry Wentland const struct core_surface *surface) 2184562236bSHarry Wentland { 2194562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2204562236bSHarry Wentland 2214562236bSHarry Wentland switch (surface->public.format) { 2224562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2238693049aSTony Cheng case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 2244562236bSHarry Wentland prescale_params->scale = 0x2020; 2254562236bSHarry Wentland break; 2264562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2274562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2284562236bSHarry Wentland prescale_params->scale = 0x2008; 2294562236bSHarry Wentland break; 2304562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 2314562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2324562236bSHarry Wentland prescale_params->scale = 0x2000; 2334562236bSHarry Wentland break; 2344562236bSHarry Wentland default: 2354562236bSHarry Wentland ASSERT(false); 236d7194cf6SAric Cyr break; 2374562236bSHarry Wentland } 2384562236bSHarry Wentland } 2394562236bSHarry Wentland 240d7194cf6SAric Cyr static bool dce110_set_input_transfer_func( 241fb735a9fSAnthony Koo struct pipe_ctx *pipe_ctx, 2424562236bSHarry Wentland const struct core_surface *surface) 2434562236bSHarry Wentland { 244fb735a9fSAnthony Koo struct input_pixel_processor *ipp = pipe_ctx->ipp; 24590e508baSAnthony Koo const struct core_transfer_func *tf = NULL; 24690e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 24790e508baSAnthony Koo bool result = true; 24890e508baSAnthony Koo 24990e508baSAnthony Koo if (ipp == NULL) 25090e508baSAnthony Koo return false; 25190e508baSAnthony Koo 25290e508baSAnthony Koo if (surface->public.in_transfer_func) 25390e508baSAnthony Koo tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func); 25490e508baSAnthony Koo 25590e508baSAnthony Koo build_prescale_params(&prescale_params, surface); 25690e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 25790e508baSAnthony Koo 25898489c02SLeo (Sunpeng) Li if (surface->public.gamma_correction && dce_use_lut(surface)) 259d7194cf6SAric Cyr ipp->funcs->ipp_program_input_lut(ipp, surface->public.gamma_correction); 260d7194cf6SAric Cyr 26190e508baSAnthony Koo if (tf == NULL) { 26290e508baSAnthony Koo /* Default case if no input transfer function specified */ 26390e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 264306dadf0SAmy Zhang IPP_DEGAMMA_MODE_HW_sRGB); 26590e508baSAnthony Koo } else if (tf->public.type == TF_TYPE_PREDEFINED) { 26690e508baSAnthony Koo switch (tf->public.tf) { 26790e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 26890e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 26990e508baSAnthony Koo IPP_DEGAMMA_MODE_HW_sRGB); 27090e508baSAnthony Koo break; 27190e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 27290e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 27390e508baSAnthony Koo IPP_DEGAMMA_MODE_HW_xvYCC); 27490e508baSAnthony Koo break; 27590e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 27690e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 27790e508baSAnthony Koo IPP_DEGAMMA_MODE_BYPASS); 27890e508baSAnthony Koo break; 27990e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 28090e508baSAnthony Koo result = false; 28190e508baSAnthony Koo break; 28290e508baSAnthony Koo default: 28390e508baSAnthony Koo result = false; 284d7194cf6SAric Cyr break; 28590e508baSAnthony Koo } 28670063a59SAmy Zhang } else if (tf->public.type == TF_TYPE_BYPASS) { 28770063a59SAmy Zhang ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 28890e508baSAnthony Koo } else { 28990e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 29090e508baSAnthony Koo result = false; 29190e508baSAnthony Koo } 29290e508baSAnthony Koo 29390e508baSAnthony Koo return result; 29490e508baSAnthony Koo } 29590e508baSAnthony Koo 296fcd2f4bfSAmy Zhang static bool convert_to_custom_float( 297fcd2f4bfSAmy Zhang struct pwl_result_data *rgb_resulted, 298fcd2f4bfSAmy Zhang struct curve_points *arr_points, 299fcd2f4bfSAmy Zhang uint32_t hw_points_num) 300fcd2f4bfSAmy Zhang { 301fcd2f4bfSAmy Zhang struct custom_float_format fmt; 302fcd2f4bfSAmy Zhang 303fcd2f4bfSAmy Zhang struct pwl_result_data *rgb = rgb_resulted; 304fcd2f4bfSAmy Zhang 305fcd2f4bfSAmy Zhang uint32_t i = 0; 306fcd2f4bfSAmy Zhang 307fcd2f4bfSAmy Zhang fmt.exponenta_bits = 6; 308fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 309fcd2f4bfSAmy Zhang fmt.sign = true; 310fcd2f4bfSAmy Zhang 311fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 312fcd2f4bfSAmy Zhang arr_points[0].x, 313fcd2f4bfSAmy Zhang &fmt, 314fcd2f4bfSAmy Zhang &arr_points[0].custom_float_x)) { 315fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 316fcd2f4bfSAmy Zhang return false; 317fcd2f4bfSAmy Zhang } 318fcd2f4bfSAmy Zhang 319fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 320fcd2f4bfSAmy Zhang arr_points[0].offset, 321fcd2f4bfSAmy Zhang &fmt, 322fcd2f4bfSAmy Zhang &arr_points[0].custom_float_offset)) { 323fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 324fcd2f4bfSAmy Zhang return false; 325fcd2f4bfSAmy Zhang } 326fcd2f4bfSAmy Zhang 327fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 328fcd2f4bfSAmy Zhang arr_points[0].slope, 329fcd2f4bfSAmy Zhang &fmt, 330fcd2f4bfSAmy Zhang &arr_points[0].custom_float_slope)) { 331fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 332fcd2f4bfSAmy Zhang return false; 333fcd2f4bfSAmy Zhang } 334fcd2f4bfSAmy Zhang 335fcd2f4bfSAmy Zhang fmt.mantissa_bits = 10; 336fcd2f4bfSAmy Zhang fmt.sign = false; 337fcd2f4bfSAmy Zhang 338fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 339fcd2f4bfSAmy Zhang arr_points[1].x, 340fcd2f4bfSAmy Zhang &fmt, 341fcd2f4bfSAmy Zhang &arr_points[1].custom_float_x)) { 342fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 343fcd2f4bfSAmy Zhang return false; 344fcd2f4bfSAmy Zhang } 345fcd2f4bfSAmy Zhang 346fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 347fcd2f4bfSAmy Zhang arr_points[1].y, 348fcd2f4bfSAmy Zhang &fmt, 349fcd2f4bfSAmy Zhang &arr_points[1].custom_float_y)) { 350fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 351fcd2f4bfSAmy Zhang return false; 352fcd2f4bfSAmy Zhang } 353fcd2f4bfSAmy Zhang 354fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 355fcd2f4bfSAmy Zhang arr_points[2].slope, 356fcd2f4bfSAmy Zhang &fmt, 357fcd2f4bfSAmy Zhang &arr_points[2].custom_float_slope)) { 358fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 359fcd2f4bfSAmy Zhang return false; 360fcd2f4bfSAmy Zhang } 361fcd2f4bfSAmy Zhang 362fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 363fcd2f4bfSAmy Zhang fmt.sign = true; 364fcd2f4bfSAmy Zhang 365fcd2f4bfSAmy Zhang while (i != hw_points_num) { 366fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 367fcd2f4bfSAmy Zhang rgb->red, 368fcd2f4bfSAmy Zhang &fmt, 369fcd2f4bfSAmy Zhang &rgb->red_reg)) { 370fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 371fcd2f4bfSAmy Zhang return false; 372fcd2f4bfSAmy Zhang } 373fcd2f4bfSAmy Zhang 374fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 375fcd2f4bfSAmy Zhang rgb->green, 376fcd2f4bfSAmy Zhang &fmt, 377fcd2f4bfSAmy Zhang &rgb->green_reg)) { 378fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 379fcd2f4bfSAmy Zhang return false; 380fcd2f4bfSAmy Zhang } 381fcd2f4bfSAmy Zhang 382fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 383fcd2f4bfSAmy Zhang rgb->blue, 384fcd2f4bfSAmy Zhang &fmt, 385fcd2f4bfSAmy Zhang &rgb->blue_reg)) { 386fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 387fcd2f4bfSAmy Zhang return false; 388fcd2f4bfSAmy Zhang } 389fcd2f4bfSAmy Zhang 390fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 391fcd2f4bfSAmy Zhang rgb->delta_red, 392fcd2f4bfSAmy Zhang &fmt, 393fcd2f4bfSAmy Zhang &rgb->delta_red_reg)) { 394fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 395fcd2f4bfSAmy Zhang return false; 396fcd2f4bfSAmy Zhang } 397fcd2f4bfSAmy Zhang 398fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 399fcd2f4bfSAmy Zhang rgb->delta_green, 400fcd2f4bfSAmy Zhang &fmt, 401fcd2f4bfSAmy Zhang &rgb->delta_green_reg)) { 402fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 403fcd2f4bfSAmy Zhang return false; 404fcd2f4bfSAmy Zhang } 405fcd2f4bfSAmy Zhang 406fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 407fcd2f4bfSAmy Zhang rgb->delta_blue, 408fcd2f4bfSAmy Zhang &fmt, 409fcd2f4bfSAmy Zhang &rgb->delta_blue_reg)) { 410fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 411fcd2f4bfSAmy Zhang return false; 412fcd2f4bfSAmy Zhang } 413fcd2f4bfSAmy Zhang 414fcd2f4bfSAmy Zhang ++rgb; 415fcd2f4bfSAmy Zhang ++i; 416fcd2f4bfSAmy Zhang } 417fcd2f4bfSAmy Zhang 418fcd2f4bfSAmy Zhang return true; 419fcd2f4bfSAmy Zhang } 420fcd2f4bfSAmy Zhang 421e266fdf6SVitaly Prosyak static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func 422fcd2f4bfSAmy Zhang *output_tf, struct pwl_params *regamma_params) 423fcd2f4bfSAmy Zhang { 42423ae4f8eSAmy Zhang struct curve_points *arr_points; 42523ae4f8eSAmy Zhang struct pwl_result_data *rgb_resulted; 42623ae4f8eSAmy Zhang struct pwl_result_data *rgb; 42723ae4f8eSAmy Zhang struct pwl_result_data *rgb_plus_1; 428fcd2f4bfSAmy Zhang struct fixed31_32 y_r; 429fcd2f4bfSAmy Zhang struct fixed31_32 y_g; 430fcd2f4bfSAmy Zhang struct fixed31_32 y_b; 431fcd2f4bfSAmy Zhang struct fixed31_32 y1_min; 432fcd2f4bfSAmy Zhang struct fixed31_32 y3_max; 433fcd2f4bfSAmy Zhang 434fcd2f4bfSAmy Zhang int32_t segment_start, segment_end; 43523ae4f8eSAmy Zhang uint32_t i, j, k, seg_distr[16], increment, start_index, hw_points; 43623ae4f8eSAmy Zhang 43770063a59SAmy Zhang if (output_tf == NULL || regamma_params == NULL || 43870063a59SAmy Zhang output_tf->type == TF_TYPE_BYPASS) 43923ae4f8eSAmy Zhang return false; 44023ae4f8eSAmy Zhang 44123ae4f8eSAmy Zhang arr_points = regamma_params->arr_points; 44223ae4f8eSAmy Zhang rgb_resulted = regamma_params->rgb_resulted; 44323ae4f8eSAmy Zhang hw_points = 0; 444fcd2f4bfSAmy Zhang 445fcd2f4bfSAmy Zhang memset(regamma_params, 0, sizeof(struct pwl_params)); 446fcd2f4bfSAmy Zhang 447fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 448534db198SAmy Zhang /* 16 segments 449fcd2f4bfSAmy Zhang * segments are from 2^-11 to 2^5 450fcd2f4bfSAmy Zhang */ 451fcd2f4bfSAmy Zhang segment_start = -11; 452fcd2f4bfSAmy Zhang segment_end = 5; 453fcd2f4bfSAmy Zhang 454534db198SAmy Zhang seg_distr[0] = 2; 455534db198SAmy Zhang seg_distr[1] = 2; 456534db198SAmy Zhang seg_distr[2] = 2; 457534db198SAmy Zhang seg_distr[3] = 2; 458534db198SAmy Zhang seg_distr[4] = 2; 459534db198SAmy Zhang seg_distr[5] = 2; 460534db198SAmy Zhang seg_distr[6] = 3; 461534db198SAmy Zhang seg_distr[7] = 4; 462534db198SAmy Zhang seg_distr[8] = 4; 463534db198SAmy Zhang seg_distr[9] = 4; 464534db198SAmy Zhang seg_distr[10] = 4; 465534db198SAmy Zhang seg_distr[11] = 5; 466534db198SAmy Zhang seg_distr[12] = 5; 467534db198SAmy Zhang seg_distr[13] = 5; 468534db198SAmy Zhang seg_distr[14] = 5; 469534db198SAmy Zhang seg_distr[15] = 5; 470534db198SAmy Zhang 471fcd2f4bfSAmy Zhang } else { 472534db198SAmy Zhang /* 10 segments 473fcd2f4bfSAmy Zhang * segment is from 2^-10 to 2^0 474fcd2f4bfSAmy Zhang */ 475fcd2f4bfSAmy Zhang segment_start = -10; 476fcd2f4bfSAmy Zhang segment_end = 0; 477534db198SAmy Zhang 478534db198SAmy Zhang seg_distr[0] = 3; 479534db198SAmy Zhang seg_distr[1] = 4; 480534db198SAmy Zhang seg_distr[2] = 4; 481534db198SAmy Zhang seg_distr[3] = 4; 482534db198SAmy Zhang seg_distr[4] = 4; 483534db198SAmy Zhang seg_distr[5] = 4; 484534db198SAmy Zhang seg_distr[6] = 4; 485534db198SAmy Zhang seg_distr[7] = 4; 486534db198SAmy Zhang seg_distr[8] = 5; 487534db198SAmy Zhang seg_distr[9] = 5; 488534db198SAmy Zhang seg_distr[10] = -1; 489534db198SAmy Zhang seg_distr[11] = -1; 490534db198SAmy Zhang seg_distr[12] = -1; 491534db198SAmy Zhang seg_distr[13] = -1; 492534db198SAmy Zhang seg_distr[14] = -1; 493534db198SAmy Zhang seg_distr[15] = -1; 494fcd2f4bfSAmy Zhang } 495fcd2f4bfSAmy Zhang 496534db198SAmy Zhang for (k = 0; k < 16; k++) { 497534db198SAmy Zhang if (seg_distr[k] != -1) 498534db198SAmy Zhang hw_points += (1 << seg_distr[k]); 499534db198SAmy Zhang } 500534db198SAmy Zhang 501fcd2f4bfSAmy Zhang j = 0; 502534db198SAmy Zhang for (k = 0; k < (segment_end - segment_start); k++) { 503534db198SAmy Zhang increment = 32 / (1 << seg_distr[k]); 504534db198SAmy Zhang start_index = (segment_start + k + 25) * 32; 505534db198SAmy Zhang for (i = start_index; i < start_index + 32; i += increment) { 506534db198SAmy Zhang if (j == hw_points - 1) 507fcd2f4bfSAmy Zhang break; 508fcd2f4bfSAmy Zhang rgb_resulted[j].red = output_tf->tf_pts.red[i]; 509fcd2f4bfSAmy Zhang rgb_resulted[j].green = output_tf->tf_pts.green[i]; 510fcd2f4bfSAmy Zhang rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 511fcd2f4bfSAmy Zhang j++; 512fcd2f4bfSAmy Zhang } 513534db198SAmy Zhang } 514534db198SAmy Zhang 515534db198SAmy Zhang /* last point */ 516534db198SAmy Zhang start_index = (segment_end + 25) * 32; 517534db198SAmy Zhang rgb_resulted[hw_points - 1].red = 518534db198SAmy Zhang output_tf->tf_pts.red[start_index]; 519534db198SAmy Zhang rgb_resulted[hw_points - 1].green = 520534db198SAmy Zhang output_tf->tf_pts.green[start_index]; 521534db198SAmy Zhang rgb_resulted[hw_points - 1].blue = 522534db198SAmy Zhang output_tf->tf_pts.blue[start_index]; 523fcd2f4bfSAmy Zhang 524fcd2f4bfSAmy Zhang arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 525fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(segment_start)); 526fcd2f4bfSAmy Zhang arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 527fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(segment_end)); 528fcd2f4bfSAmy Zhang arr_points[2].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 529fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(segment_end)); 530fcd2f4bfSAmy Zhang 531fcd2f4bfSAmy Zhang y_r = rgb_resulted[0].red; 532fcd2f4bfSAmy Zhang y_g = rgb_resulted[0].green; 533fcd2f4bfSAmy Zhang y_b = rgb_resulted[0].blue; 534fcd2f4bfSAmy Zhang 535fcd2f4bfSAmy Zhang y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); 536fcd2f4bfSAmy Zhang 537fcd2f4bfSAmy Zhang arr_points[0].y = y1_min; 538fcd2f4bfSAmy Zhang arr_points[0].slope = dal_fixed31_32_div( 539fcd2f4bfSAmy Zhang arr_points[0].y, 540fcd2f4bfSAmy Zhang arr_points[0].x); 541fcd2f4bfSAmy Zhang 542fcd2f4bfSAmy Zhang y_r = rgb_resulted[hw_points - 1].red; 543fcd2f4bfSAmy Zhang y_g = rgb_resulted[hw_points - 1].green; 544fcd2f4bfSAmy Zhang y_b = rgb_resulted[hw_points - 1].blue; 545fcd2f4bfSAmy Zhang 546fcd2f4bfSAmy Zhang /* see comment above, m_arrPoints[1].y should be the Y value for the 547fcd2f4bfSAmy Zhang * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 548fcd2f4bfSAmy Zhang */ 549fcd2f4bfSAmy Zhang y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); 550fcd2f4bfSAmy Zhang 551fcd2f4bfSAmy Zhang arr_points[1].y = y3_max; 552fcd2f4bfSAmy Zhang arr_points[2].y = y3_max; 553fcd2f4bfSAmy Zhang 554fcd2f4bfSAmy Zhang arr_points[1].slope = dal_fixed31_32_zero; 555fcd2f4bfSAmy Zhang arr_points[2].slope = dal_fixed31_32_zero; 556fcd2f4bfSAmy Zhang 557fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 558fcd2f4bfSAmy Zhang /* for PQ, we want to have a straight line from last HW X point, 559fcd2f4bfSAmy Zhang * and the slope to be such that we hit 1.0 at 10000 nits. 560fcd2f4bfSAmy Zhang */ 561fcd2f4bfSAmy Zhang const struct fixed31_32 end_value = 562fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(125); 563fcd2f4bfSAmy Zhang 564fcd2f4bfSAmy Zhang arr_points[1].slope = dal_fixed31_32_div( 565fcd2f4bfSAmy Zhang dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 566fcd2f4bfSAmy Zhang dal_fixed31_32_sub(end_value, arr_points[1].x)); 567fcd2f4bfSAmy Zhang arr_points[2].slope = dal_fixed31_32_div( 568fcd2f4bfSAmy Zhang dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 569fcd2f4bfSAmy Zhang dal_fixed31_32_sub(end_value, arr_points[1].x)); 570fcd2f4bfSAmy Zhang } 571fcd2f4bfSAmy Zhang 572fcd2f4bfSAmy Zhang regamma_params->hw_points_num = hw_points; 573fcd2f4bfSAmy Zhang 574534db198SAmy Zhang i = 1; 575534db198SAmy Zhang for (k = 0; k < 16 && i < 16; k++) { 576534db198SAmy Zhang if (seg_distr[k] != -1) { 577534db198SAmy Zhang regamma_params->arr_curve_points[k].segments_num = 578534db198SAmy Zhang seg_distr[k]; 579534db198SAmy Zhang regamma_params->arr_curve_points[i].offset = 580534db198SAmy Zhang regamma_params->arr_curve_points[k]. 581534db198SAmy Zhang offset + (1 << seg_distr[k]); 582fcd2f4bfSAmy Zhang } 583534db198SAmy Zhang i++; 584534db198SAmy Zhang } 585534db198SAmy Zhang 586534db198SAmy Zhang if (seg_distr[k] != -1) 587534db198SAmy Zhang regamma_params->arr_curve_points[k].segments_num = 588534db198SAmy Zhang seg_distr[k]; 589fcd2f4bfSAmy Zhang 59023ae4f8eSAmy Zhang rgb = rgb_resulted; 59123ae4f8eSAmy Zhang rgb_plus_1 = rgb_resulted + 1; 592fcd2f4bfSAmy Zhang 593fcd2f4bfSAmy Zhang i = 1; 594fcd2f4bfSAmy Zhang 595fcd2f4bfSAmy Zhang while (i != hw_points + 1) { 596fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) 597fcd2f4bfSAmy Zhang rgb_plus_1->red = rgb->red; 598fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) 599fcd2f4bfSAmy Zhang rgb_plus_1->green = rgb->green; 600fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) 601fcd2f4bfSAmy Zhang rgb_plus_1->blue = rgb->blue; 602fcd2f4bfSAmy Zhang 603fcd2f4bfSAmy Zhang rgb->delta_red = dal_fixed31_32_sub( 604fcd2f4bfSAmy Zhang rgb_plus_1->red, 605fcd2f4bfSAmy Zhang rgb->red); 606fcd2f4bfSAmy Zhang rgb->delta_green = dal_fixed31_32_sub( 607fcd2f4bfSAmy Zhang rgb_plus_1->green, 608fcd2f4bfSAmy Zhang rgb->green); 609fcd2f4bfSAmy Zhang rgb->delta_blue = dal_fixed31_32_sub( 610fcd2f4bfSAmy Zhang rgb_plus_1->blue, 611fcd2f4bfSAmy Zhang rgb->blue); 612fcd2f4bfSAmy Zhang 613fcd2f4bfSAmy Zhang ++rgb_plus_1; 614fcd2f4bfSAmy Zhang ++rgb; 615fcd2f4bfSAmy Zhang ++i; 616fcd2f4bfSAmy Zhang } 617fcd2f4bfSAmy Zhang 618fcd2f4bfSAmy Zhang convert_to_custom_float(rgb_resulted, arr_points, hw_points); 619fcd2f4bfSAmy Zhang 620fcd2f4bfSAmy Zhang return true; 621fcd2f4bfSAmy Zhang } 622fcd2f4bfSAmy Zhang 62390e508baSAnthony Koo static bool dce110_set_output_transfer_func( 62490e508baSAnthony Koo struct pipe_ctx *pipe_ctx, 62590e508baSAnthony Koo const struct core_stream *stream) 62690e508baSAnthony Koo { 627fb735a9fSAnthony Koo struct output_pixel_processor *opp = pipe_ctx->opp; 6284562236bSHarry Wentland 6294562236bSHarry Wentland opp->funcs->opp_power_on_regamma_lut(opp, true); 630974db151SDmytro Laktyushkin opp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 6314562236bSHarry Wentland 632d7194cf6SAric Cyr if (stream->public.out_transfer_func && 633fcd2f4bfSAmy Zhang stream->public.out_transfer_func->type == 634fcd2f4bfSAmy Zhang TF_TYPE_PREDEFINED && 635fcd2f4bfSAmy Zhang stream->public.out_transfer_func->tf == 636fcd2f4bfSAmy Zhang TRANSFER_FUNCTION_SRGB) { 637d7194cf6SAric Cyr opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB); 638fcd2f4bfSAmy Zhang } else if (dce110_translate_regamma_to_hw_format( 639974db151SDmytro Laktyushkin stream->public.out_transfer_func, &opp->regamma_params)) { 640974db151SDmytro Laktyushkin opp->funcs->opp_program_regamma_pwl(opp, &opp->regamma_params); 6414562236bSHarry Wentland opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER); 6424562236bSHarry Wentland } else { 6434562236bSHarry Wentland opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS); 6444562236bSHarry Wentland } 6454562236bSHarry Wentland 6464562236bSHarry Wentland opp->funcs->opp_power_on_regamma_lut(opp, false); 6474562236bSHarry Wentland 648cc0cb445SLeon Elazar return true; 6494562236bSHarry Wentland } 6504562236bSHarry Wentland 6514562236bSHarry Wentland static enum dc_status bios_parser_crtc_source_select( 6524562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 6534562236bSHarry Wentland { 6544562236bSHarry Wentland struct dc_bios *dcb; 6554562236bSHarry Wentland /* call VBIOS table to set CRTC source for the HW 6564562236bSHarry Wentland * encoder block 6574562236bSHarry Wentland * note: video bios clears all FMT setting here. */ 6584562236bSHarry Wentland struct bp_crtc_source_select crtc_source_select = {0}; 6594562236bSHarry Wentland const struct core_sink *sink = pipe_ctx->stream->sink; 6604562236bSHarry Wentland 6614562236bSHarry Wentland crtc_source_select.engine_id = pipe_ctx->stream_enc->id; 6624562236bSHarry Wentland crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1; 6634562236bSHarry Wentland /*TODO: Need to un-hardcode color depth, dp_audio and account for 6644562236bSHarry Wentland * the case where signal and sink signal is different (translator 6654562236bSHarry Wentland * encoder)*/ 6664562236bSHarry Wentland crtc_source_select.signal = pipe_ctx->stream->signal; 6674562236bSHarry Wentland crtc_source_select.enable_dp_audio = false; 6684562236bSHarry Wentland crtc_source_select.sink_signal = pipe_ctx->stream->signal; 6694562236bSHarry Wentland crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 6704562236bSHarry Wentland 6714562236bSHarry Wentland dcb = sink->ctx->dc_bios; 6724562236bSHarry Wentland 6734562236bSHarry Wentland if (BP_RESULT_OK != dcb->funcs->crtc_source_select( 6744562236bSHarry Wentland dcb, 6754562236bSHarry Wentland &crtc_source_select)) { 6764562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 6774562236bSHarry Wentland } 6784562236bSHarry Wentland 6794562236bSHarry Wentland return DC_OK; 6804562236bSHarry Wentland } 6814562236bSHarry Wentland 6824562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 6834562236bSHarry Wentland { 68486e2e1beSHersen Wu ASSERT(pipe_ctx->stream); 68586e2e1beSHersen Wu 68686e2e1beSHersen Wu if (pipe_ctx->stream_enc == NULL) 68786e2e1beSHersen Wu return; /* this is not root pipe */ 68886e2e1beSHersen Wu 6894562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 6904562236bSHarry Wentland pipe_ctx->stream_enc->funcs->update_hdmi_info_packets( 6914562236bSHarry Wentland pipe_ctx->stream_enc, 6924562236bSHarry Wentland &pipe_ctx->encoder_info_frame); 6934562236bSHarry Wentland else if (dc_is_dp_signal(pipe_ctx->stream->signal)) 6944562236bSHarry Wentland pipe_ctx->stream_enc->funcs->update_dp_info_packets( 6954562236bSHarry Wentland pipe_ctx->stream_enc, 6964562236bSHarry Wentland &pipe_ctx->encoder_info_frame); 6974562236bSHarry Wentland } 6984562236bSHarry Wentland 6994562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 7004562236bSHarry Wentland { 7014562236bSHarry Wentland enum dc_lane_count lane_count = 7024562236bSHarry Wentland pipe_ctx->stream->sink->link->public.cur_link_settings.lane_count; 7034562236bSHarry Wentland 7044562236bSHarry Wentland struct dc_crtc_timing *timing = &pipe_ctx->stream->public.timing; 7054562236bSHarry Wentland struct core_link *link = pipe_ctx->stream->sink->link; 7064562236bSHarry Wentland 7074562236bSHarry Wentland /* 1. update AVI info frame (HDMI, DP) 7084562236bSHarry Wentland * we always need to update info frame 7094562236bSHarry Wentland */ 7104562236bSHarry Wentland uint32_t active_total_with_borders; 7114562236bSHarry Wentland uint32_t early_control = 0; 7124562236bSHarry Wentland struct timing_generator *tg = pipe_ctx->tg; 7134562236bSHarry Wentland 7144562236bSHarry Wentland /* TODOFPGA may change to hwss.update_info_frame */ 7154562236bSHarry Wentland dce110_update_info_frame(pipe_ctx); 7164562236bSHarry Wentland /* enable early control to avoid corruption on DP monitor*/ 7174562236bSHarry Wentland active_total_with_borders = 7184562236bSHarry Wentland timing->h_addressable 7194562236bSHarry Wentland + timing->h_border_left 7204562236bSHarry Wentland + timing->h_border_right; 7214562236bSHarry Wentland 7224562236bSHarry Wentland if (lane_count != 0) 7234562236bSHarry Wentland early_control = active_total_with_borders % lane_count; 7244562236bSHarry Wentland 7254562236bSHarry Wentland if (early_control == 0) 7264562236bSHarry Wentland early_control = lane_count; 7274562236bSHarry Wentland 7284562236bSHarry Wentland tg->funcs->set_early_control(tg, early_control); 7294562236bSHarry Wentland 7304562236bSHarry Wentland /* enable audio only within mode set */ 7314562236bSHarry Wentland if (pipe_ctx->audio != NULL) { 7324562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7334562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_enc); 7344562236bSHarry Wentland } 7354562236bSHarry Wentland 7364562236bSHarry Wentland /* For MST, there are multiply stream go to only one link. 7374562236bSHarry Wentland * connect DIG back_end to front_end while enable_stream and 7384562236bSHarry Wentland * disconnect them during disable_stream 7394562236bSHarry Wentland * BY this, it is logic clean to separate stream and link */ 7404562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 7414562236bSHarry Wentland pipe_ctx->stream_enc->id, true); 7424562236bSHarry Wentland 7434562236bSHarry Wentland } 7444562236bSHarry Wentland 7454562236bSHarry Wentland void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 7464562236bSHarry Wentland { 7474562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 7484562236bSHarry Wentland struct core_link *link = stream->sink->link; 7494562236bSHarry Wentland 7504562236bSHarry Wentland if (pipe_ctx->audio) { 7514562236bSHarry Wentland pipe_ctx->audio->funcs->az_disable(pipe_ctx->audio); 7524562236bSHarry Wentland 7534562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7544562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_audio_disable( 7554562236bSHarry Wentland pipe_ctx->stream_enc); 7564562236bSHarry Wentland else 7574562236bSHarry Wentland pipe_ctx->stream_enc->funcs->hdmi_audio_disable( 7584562236bSHarry Wentland pipe_ctx->stream_enc); 7594562236bSHarry Wentland 7604562236bSHarry Wentland pipe_ctx->audio = NULL; 7614562236bSHarry Wentland 7624562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 7634562236bSHarry Wentland * add audio mode list change flag */ 7644562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 7654562236bSHarry Wentland * stream->stream_engine_id); 7664562236bSHarry Wentland */ 7674562236bSHarry Wentland } 7684562236bSHarry Wentland 7694562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 7704562236bSHarry Wentland pipe_ctx->stream_enc->funcs->stop_hdmi_info_packets( 7714562236bSHarry Wentland pipe_ctx->stream_enc); 7724562236bSHarry Wentland 7734562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7744562236bSHarry Wentland pipe_ctx->stream_enc->funcs->stop_dp_info_packets( 7754562236bSHarry Wentland pipe_ctx->stream_enc); 7764562236bSHarry Wentland 7774562236bSHarry Wentland pipe_ctx->stream_enc->funcs->audio_mute_control( 7784562236bSHarry Wentland pipe_ctx->stream_enc, true); 7794562236bSHarry Wentland 7804562236bSHarry Wentland 7814562236bSHarry Wentland /* blank at encoder level */ 7824562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7834562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_blank(pipe_ctx->stream_enc); 7844562236bSHarry Wentland 7854562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe( 7864562236bSHarry Wentland link->link_enc, 7874562236bSHarry Wentland pipe_ctx->stream_enc->id, 7884562236bSHarry Wentland false); 7894562236bSHarry Wentland 7904562236bSHarry Wentland } 7914562236bSHarry Wentland 7924562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 7934562236bSHarry Wentland struct dc_link_settings *link_settings) 7944562236bSHarry Wentland { 7954562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 7964562236bSHarry Wentland 7974562236bSHarry Wentland /* only 3 items below are used by unblank */ 7986235b23cSTony Cheng params.pixel_clk_khz = 7994562236bSHarry Wentland pipe_ctx->stream->public.timing.pix_clk_khz; 8004562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 8014562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_unblank(pipe_ctx->stream_enc, ¶ms); 8024562236bSHarry Wentland } 8034562236bSHarry Wentland 8044562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 8054562236bSHarry Wentland { 8064562236bSHarry Wentland switch (crtc_id) { 8074562236bSHarry Wentland case CONTROLLER_ID_D0: 8084562236bSHarry Wentland return DTO_SOURCE_ID0; 8094562236bSHarry Wentland case CONTROLLER_ID_D1: 8104562236bSHarry Wentland return DTO_SOURCE_ID1; 8114562236bSHarry Wentland case CONTROLLER_ID_D2: 8124562236bSHarry Wentland return DTO_SOURCE_ID2; 8134562236bSHarry Wentland case CONTROLLER_ID_D3: 8144562236bSHarry Wentland return DTO_SOURCE_ID3; 8154562236bSHarry Wentland case CONTROLLER_ID_D4: 8164562236bSHarry Wentland return DTO_SOURCE_ID4; 8174562236bSHarry Wentland case CONTROLLER_ID_D5: 8184562236bSHarry Wentland return DTO_SOURCE_ID5; 8194562236bSHarry Wentland default: 8204562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 8214562236bSHarry Wentland } 8224562236bSHarry Wentland } 8234562236bSHarry Wentland 8244562236bSHarry Wentland static void build_audio_output( 8254562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 8264562236bSHarry Wentland struct audio_output *audio_output) 8274562236bSHarry Wentland { 8284562236bSHarry Wentland const struct core_stream *stream = pipe_ctx->stream; 8294562236bSHarry Wentland audio_output->engine_id = pipe_ctx->stream_enc->id; 8304562236bSHarry Wentland 8314562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 8324562236bSHarry Wentland 8334562236bSHarry Wentland /* audio_crtc_info */ 8344562236bSHarry Wentland 8354562236bSHarry Wentland audio_output->crtc_info.h_total = 8364562236bSHarry Wentland stream->public.timing.h_total; 8374562236bSHarry Wentland 8384562236bSHarry Wentland /* 8394562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 8404562236bSHarry Wentland * need to specify actual active signal portion 8414562236bSHarry Wentland */ 8424562236bSHarry Wentland audio_output->crtc_info.h_active = 8434562236bSHarry Wentland stream->public.timing.h_addressable 8444562236bSHarry Wentland + stream->public.timing.h_border_left 8454562236bSHarry Wentland + stream->public.timing.h_border_right; 8464562236bSHarry Wentland 8474562236bSHarry Wentland audio_output->crtc_info.v_active = 8484562236bSHarry Wentland stream->public.timing.v_addressable 8494562236bSHarry Wentland + stream->public.timing.v_border_top 8504562236bSHarry Wentland + stream->public.timing.v_border_bottom; 8514562236bSHarry Wentland 8524562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 8534562236bSHarry Wentland 8544562236bSHarry Wentland audio_output->crtc_info.interlaced = 8554562236bSHarry Wentland stream->public.timing.flags.INTERLACE; 8564562236bSHarry Wentland 8574562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 8584562236bSHarry Wentland (stream->public.timing.pix_clk_khz*1000)/ 8594562236bSHarry Wentland (stream->public.timing.h_total*stream->public.timing.v_total); 8604562236bSHarry Wentland 8614562236bSHarry Wentland audio_output->crtc_info.color_depth = 8624562236bSHarry Wentland stream->public.timing.display_color_depth; 8634562236bSHarry Wentland 8644562236bSHarry Wentland audio_output->crtc_info.requested_pixel_clock = 8654562236bSHarry Wentland pipe_ctx->pix_clk_params.requested_pix_clk; 8664562236bSHarry Wentland 8674562236bSHarry Wentland audio_output->crtc_info.calculated_pixel_clock = 8684562236bSHarry Wentland pipe_ctx->pix_clk_params.requested_pix_clk; 8694562236bSHarry Wentland 87087b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/ 87187b58768SCharlene Liu if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && 87287b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock == 87387b58768SCharlene Liu stream->public.timing.pix_clk_khz) { 87487b58768SCharlene Liu if (pipe_ctx->pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 87587b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock = 87687b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock/2; 87787b58768SCharlene Liu audio_output->crtc_info.calculated_pixel_clock = 87887b58768SCharlene Liu pipe_ctx->pix_clk_params.requested_pix_clk/2; 87987b58768SCharlene Liu 88087b58768SCharlene Liu } 88187b58768SCharlene Liu } 88287b58768SCharlene Liu 8834562236bSHarry Wentland if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 8844562236bSHarry Wentland pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { 8854562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 8861a687574SDmytro Laktyushkin pipe_ctx->dis_clk->funcs->get_dp_ref_clk_frequency( 8874562236bSHarry Wentland pipe_ctx->dis_clk); 8884562236bSHarry Wentland } 8894562236bSHarry Wentland 8904562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 8914562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 8924562236bSHarry Wentland 8934562236bSHarry Wentland audio_output->pll_info.dto_source = 8944562236bSHarry Wentland translate_to_dto_source( 8954562236bSHarry Wentland pipe_ctx->pipe_idx + 1); 8964562236bSHarry Wentland 8974562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 8984562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 8994562236bSHarry Wentland 9004562236bSHarry Wentland audio_output->pll_info.ss_percentage = 9014562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 9024562236bSHarry Wentland } 9034562236bSHarry Wentland 9044562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 9054562236bSHarry Wentland struct tg_color *color) 9064562236bSHarry Wentland { 9074562236bSHarry Wentland uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->pipe_idx) / 4; 9084562236bSHarry Wentland 9094562236bSHarry Wentland switch (pipe_ctx->scl_data.format) { 9104562236bSHarry Wentland case PIXEL_FORMAT_ARGB8888: 9114562236bSHarry Wentland /* set boarder color to red */ 9124562236bSHarry Wentland color->color_r_cr = color_value; 9134562236bSHarry Wentland break; 9144562236bSHarry Wentland 9154562236bSHarry Wentland case PIXEL_FORMAT_ARGB2101010: 9164562236bSHarry Wentland /* set boarder color to blue */ 9174562236bSHarry Wentland color->color_b_cb = color_value; 9184562236bSHarry Wentland break; 91987449a90SAnthony Koo case PIXEL_FORMAT_420BPP8: 9204562236bSHarry Wentland /* set boarder color to green */ 9214562236bSHarry Wentland color->color_g_y = color_value; 9224562236bSHarry Wentland break; 92387449a90SAnthony Koo case PIXEL_FORMAT_420BPP10: 92487449a90SAnthony Koo /* set boarder color to yellow */ 92587449a90SAnthony Koo color->color_g_y = color_value; 92687449a90SAnthony Koo color->color_r_cr = color_value; 92787449a90SAnthony Koo break; 9284562236bSHarry Wentland case PIXEL_FORMAT_FP16: 9294562236bSHarry Wentland /* set boarder color to white */ 9304562236bSHarry Wentland color->color_r_cr = color_value; 9314562236bSHarry Wentland color->color_b_cb = color_value; 9324562236bSHarry Wentland color->color_g_y = color_value; 9334562236bSHarry Wentland break; 9344562236bSHarry Wentland default: 9354562236bSHarry Wentland break; 9364562236bSHarry Wentland } 9374562236bSHarry Wentland } 9384562236bSHarry Wentland 9394562236bSHarry Wentland static void program_scaler(const struct core_dc *dc, 9404562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 9414562236bSHarry Wentland { 9424562236bSHarry Wentland struct tg_color color = {0}; 9434562236bSHarry Wentland 944ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 945ff5ef992SAlex Deucher /* TOFPGA */ 946ff5ef992SAlex Deucher if (pipe_ctx->xfm->funcs->transform_set_pixel_storage_depth == NULL) 947ff5ef992SAlex Deucher return; 948ff5ef992SAlex Deucher #endif 949ff5ef992SAlex Deucher 9504562236bSHarry Wentland if (dc->public.debug.surface_visual_confirm) 9514562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 9524562236bSHarry Wentland else 9534562236bSHarry Wentland color_space_to_black_color(dc, 9544562236bSHarry Wentland pipe_ctx->stream->public.output_color_space, 9554562236bSHarry Wentland &color); 9564562236bSHarry Wentland 9574562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_pixel_storage_depth( 9584562236bSHarry Wentland pipe_ctx->xfm, 9594562236bSHarry Wentland pipe_ctx->scl_data.lb_params.depth, 9604562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 9614562236bSHarry Wentland 9624562236bSHarry Wentland if (pipe_ctx->tg->funcs->set_overscan_blank_color) 9634562236bSHarry Wentland pipe_ctx->tg->funcs->set_overscan_blank_color( 9644562236bSHarry Wentland pipe_ctx->tg, 9654562236bSHarry Wentland &color); 9664562236bSHarry Wentland 9674562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_scaler(pipe_ctx->xfm, 9684562236bSHarry Wentland &pipe_ctx->scl_data); 9694562236bSHarry Wentland } 9704562236bSHarry Wentland 9714b5e7d62SHersen Wu static enum dc_status dce110_prog_pixclk_crtc_otg( 9724562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 9734562236bSHarry Wentland struct validate_context *context, 9744562236bSHarry Wentland struct core_dc *dc) 9754562236bSHarry Wentland { 9764562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 9774562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = &dc->current_context->res_ctx. 9784562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 9794562236bSHarry Wentland struct tg_color black_color = {0}; 9804562236bSHarry Wentland 9814562236bSHarry Wentland if (!pipe_ctx_old->stream) { 9824562236bSHarry Wentland 9834562236bSHarry Wentland /* program blank color */ 9844562236bSHarry Wentland color_space_to_black_color(dc, 9854562236bSHarry Wentland stream->public.output_color_space, &black_color); 9864562236bSHarry Wentland pipe_ctx->tg->funcs->set_blank_color( 9874562236bSHarry Wentland pipe_ctx->tg, 9884562236bSHarry Wentland &black_color); 9894b5e7d62SHersen Wu 9904562236bSHarry Wentland /* 9914562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 9924562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 9934562236bSHarry Wentland */ 9944562236bSHarry Wentland pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); 9954562236bSHarry Wentland 9964562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 9974562236bSHarry Wentland pipe_ctx->clock_source, 9984562236bSHarry Wentland &pipe_ctx->pix_clk_params, 9994562236bSHarry Wentland &pipe_ctx->pll_settings)) { 10004562236bSHarry Wentland BREAK_TO_DEBUGGER(); 10014562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 10024562236bSHarry Wentland } 10034562236bSHarry Wentland 10044562236bSHarry Wentland pipe_ctx->tg->funcs->program_timing( 10054562236bSHarry Wentland pipe_ctx->tg, 10064562236bSHarry Wentland &stream->public.timing, 10074562236bSHarry Wentland true); 100894267b3dSSylvia Tsai 100994267b3dSSylvia Tsai pipe_ctx->tg->funcs->set_static_screen_control( 101094267b3dSSylvia Tsai pipe_ctx->tg, 101194267b3dSSylvia Tsai 0x182); 10124562236bSHarry Wentland } 10134562236bSHarry Wentland 10144562236bSHarry Wentland if (!pipe_ctx_old->stream) { 10154562236bSHarry Wentland if (false == pipe_ctx->tg->funcs->enable_crtc( 10164562236bSHarry Wentland pipe_ctx->tg)) { 10174562236bSHarry Wentland BREAK_TO_DEBUGGER(); 10184562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 10194562236bSHarry Wentland } 10204562236bSHarry Wentland } 10214562236bSHarry Wentland 102294267b3dSSylvia Tsai 102394267b3dSSylvia Tsai 10244562236bSHarry Wentland return DC_OK; 10254562236bSHarry Wentland } 10264562236bSHarry Wentland 10274562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 10284562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 10294562236bSHarry Wentland struct validate_context *context, 10304562236bSHarry Wentland struct core_dc *dc) 10314562236bSHarry Wentland { 10324562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 10334562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = &dc->current_context->res_ctx. 10344562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 10354562236bSHarry Wentland 10364562236bSHarry Wentland /* */ 10374562236bSHarry Wentland dc->hwss.prog_pixclk_crtc_otg(pipe_ctx, context, dc); 10384562236bSHarry Wentland 10394562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_dyn_expansion( 10404562236bSHarry Wentland pipe_ctx->opp, 10414562236bSHarry Wentland COLOR_SPACE_YCBCR601, 10424562236bSHarry Wentland stream->public.timing.display_color_depth, 10434562236bSHarry Wentland pipe_ctx->stream->signal); 10444562236bSHarry Wentland 1045181a888fSCharlene Liu /* FPGA does not program backend */ 1046181a888fSCharlene Liu if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 10474562236bSHarry Wentland pipe_ctx->opp->funcs->opp_program_fmt( 10484562236bSHarry Wentland pipe_ctx->opp, 10494562236bSHarry Wentland &stream->bit_depth_params, 10504562236bSHarry Wentland &stream->clamping); 10514562236bSHarry Wentland return DC_OK; 1052181a888fSCharlene Liu } 10534562236bSHarry Wentland /* TODO: move to stream encoder */ 10544562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 10554562236bSHarry Wentland if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) { 10564562236bSHarry Wentland BREAK_TO_DEBUGGER(); 10574562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 10584562236bSHarry Wentland } 10594562236bSHarry Wentland 10604562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 10614562236bSHarry Wentland stream->sink->link->link_enc->funcs->setup( 10624562236bSHarry Wentland stream->sink->link->link_enc, 10634562236bSHarry Wentland pipe_ctx->stream->signal); 10644562236bSHarry Wentland 1065ab3c1798SVitaly Prosyak if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 1066ab3c1798SVitaly Prosyak pipe_ctx->stream_enc->funcs->setup_stereo_sync( 1067ab3c1798SVitaly Prosyak pipe_ctx->stream_enc, 1068ab3c1798SVitaly Prosyak pipe_ctx->tg->inst, 1069ab3c1798SVitaly Prosyak stream->public.timing.timing_3d_format != TIMING_3D_FORMAT_NONE); 1070ab3c1798SVitaly Prosyak 1071ab3c1798SVitaly Prosyak 1072181a888fSCharlene Liu /*vbios crtc_source_selection and encoder_setup will override fmt_C*/ 1073181a888fSCharlene Liu pipe_ctx->opp->funcs->opp_program_fmt( 1074181a888fSCharlene Liu pipe_ctx->opp, 1075181a888fSCharlene Liu &stream->bit_depth_params, 1076181a888fSCharlene Liu &stream->clamping); 1077181a888fSCharlene Liu 10784562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10794562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_set_stream_attribute( 10804562236bSHarry Wentland pipe_ctx->stream_enc, 10814562236bSHarry Wentland &stream->public.timing, 10824562236bSHarry Wentland stream->public.output_color_space); 10834562236bSHarry Wentland 10844562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 10854562236bSHarry Wentland pipe_ctx->stream_enc->funcs->hdmi_set_stream_attribute( 10864562236bSHarry Wentland pipe_ctx->stream_enc, 10874562236bSHarry Wentland &stream->public.timing, 10884562236bSHarry Wentland stream->phy_pix_clk, 10894562236bSHarry Wentland pipe_ctx->audio != NULL); 10904562236bSHarry Wentland 10914562236bSHarry Wentland if (dc_is_dvi_signal(pipe_ctx->stream->signal)) 10924562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dvi_set_stream_attribute( 10934562236bSHarry Wentland pipe_ctx->stream_enc, 10944562236bSHarry Wentland &stream->public.timing, 10954562236bSHarry Wentland (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? 10964562236bSHarry Wentland true : false); 10974562236bSHarry Wentland 10984562236bSHarry Wentland if (!pipe_ctx_old->stream) { 10994562236bSHarry Wentland core_link_enable_stream(pipe_ctx); 11004562236bSHarry Wentland 1101b3c64dffSCharlene Liu resource_build_info_frame(pipe_ctx); 1102b3c64dffSCharlene Liu dce110_update_info_frame(pipe_ctx); 11034562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 11044562236bSHarry Wentland dce110_unblank_stream(pipe_ctx, 11054562236bSHarry Wentland &stream->sink->link->public.cur_link_settings); 11064562236bSHarry Wentland } 11074562236bSHarry Wentland 11084562236bSHarry Wentland pipe_ctx->scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 11094562236bSHarry Wentland /* program_scaler and allocate_mem_input are not new asic */ 1110866294f8SHarry Wentland if ((!pipe_ctx_old || 1111866294f8SHarry Wentland memcmp(&pipe_ctx_old->scl_data, &pipe_ctx->scl_data, 1112866294f8SHarry Wentland sizeof(struct scaler_data)) != 0) && 1113866294f8SHarry Wentland pipe_ctx->surface) { 11144562236bSHarry Wentland program_scaler(dc, pipe_ctx); 1115866294f8SHarry Wentland } 11164562236bSHarry Wentland 11174562236bSHarry Wentland /* mst support - use total stream count */ 1118ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1119ff5ef992SAlex Deucher if (pipe_ctx->mi->funcs->allocate_mem_input != NULL) 1120ff5ef992SAlex Deucher #endif 11214562236bSHarry Wentland pipe_ctx->mi->funcs->allocate_mem_input( 11224562236bSHarry Wentland pipe_ctx->mi, 11234562236bSHarry Wentland stream->public.timing.h_total, 11244562236bSHarry Wentland stream->public.timing.v_total, 11254562236bSHarry Wentland stream->public.timing.pix_clk_khz, 1126ab2541b6SAric Cyr context->stream_count); 11274562236bSHarry Wentland 112894267b3dSSylvia Tsai pipe_ctx->stream->sink->link->psr_enabled = false; 112994267b3dSSylvia Tsai 11304562236bSHarry Wentland return DC_OK; 11314562236bSHarry Wentland } 11324562236bSHarry Wentland 11334562236bSHarry Wentland /******************************************************************************/ 11344562236bSHarry Wentland 11354562236bSHarry Wentland static void power_down_encoders(struct core_dc *dc) 11364562236bSHarry Wentland { 11374562236bSHarry Wentland int i; 11384562236bSHarry Wentland 11394562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 11404562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 11414562236bSHarry Wentland dc->links[i]->link_enc, SIGNAL_TYPE_NONE); 11424562236bSHarry Wentland } 11434562236bSHarry Wentland } 11444562236bSHarry Wentland 11454562236bSHarry Wentland static void power_down_controllers(struct core_dc *dc) 11464562236bSHarry Wentland { 11474562236bSHarry Wentland int i; 11484562236bSHarry Wentland 11494562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 11504562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 11514562236bSHarry Wentland dc->res_pool->timing_generators[i]); 11524562236bSHarry Wentland } 11534562236bSHarry Wentland } 11544562236bSHarry Wentland 11554562236bSHarry Wentland static void power_down_clock_sources(struct core_dc *dc) 11564562236bSHarry Wentland { 11574562236bSHarry Wentland int i; 11584562236bSHarry Wentland 11594562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 11604562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 11614562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 11624562236bSHarry Wentland 11634562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 11644562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 11654562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 11664562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 11674562236bSHarry Wentland } 11684562236bSHarry Wentland } 11694562236bSHarry Wentland 11704562236bSHarry Wentland static void power_down_all_hw_blocks(struct core_dc *dc) 11714562236bSHarry Wentland { 11724562236bSHarry Wentland power_down_encoders(dc); 11734562236bSHarry Wentland 11744562236bSHarry Wentland power_down_controllers(dc); 11754562236bSHarry Wentland 11764562236bSHarry Wentland power_down_clock_sources(dc); 11771663ae1cSBhawanpreet Lakha 11781663ae1cSBhawanpreet Lakha #ifdef ENABLE_FBC 11791663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 11801663ae1cSBhawanpreet Lakha #endif 11814562236bSHarry Wentland } 11824562236bSHarry Wentland 11834562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 11844562236bSHarry Wentland struct core_dc *dc) 11854562236bSHarry Wentland { 11864562236bSHarry Wentland int i; 11874562236bSHarry Wentland struct timing_generator *tg; 11884562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 11894562236bSHarry Wentland 11904562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 11914562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 11924562236bSHarry Wentland 11934562236bSHarry Wentland tg->funcs->disable_vga(tg); 11944562236bSHarry Wentland 11954562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 11964562236bSHarry Wentland * powergating. */ 11974562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 11984562236bSHarry Wentland true); 11994562236bSHarry Wentland 1200cfe4645eSDmytro Laktyushkin dc->hwss.power_down_front_end(dc, i); 12014562236bSHarry Wentland } 12024562236bSHarry Wentland } 12034562236bSHarry Wentland 12044562236bSHarry Wentland /** 12054562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 12064562236bSHarry Wentland * 1. Power down all DC HW blocks 12074562236bSHarry Wentland * 2. Disable VGA engine on all controllers 12084562236bSHarry Wentland * 3. Enable power gating for controller 12094562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 12104562236bSHarry Wentland */ 12114562236bSHarry Wentland void dce110_enable_accelerated_mode(struct core_dc *dc) 12124562236bSHarry Wentland { 12134562236bSHarry Wentland power_down_all_hw_blocks(dc); 12144562236bSHarry Wentland 12154562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 12164562236bSHarry Wentland bios_set_scratch_acc_mode_change(dc->ctx->dc_bios); 12174562236bSHarry Wentland } 12184562236bSHarry Wentland 12194562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 12204562236bSHarry Wentland struct bw_fixed blackout_duration, 12214562236bSHarry Wentland const struct core_stream *stream) 12224562236bSHarry Wentland { 12234562236bSHarry Wentland uint32_t total_dest_line_time_ns; 12244562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 12254562236bSHarry Wentland 12264562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 12274562236bSHarry Wentland 12284562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 12294562236bSHarry Wentland stream->public.timing.h_total / 12304562236bSHarry Wentland stream->public.timing.pix_clk_khz + 12314562236bSHarry Wentland pstate_blackout_duration_ns; 12324562236bSHarry Wentland 12334562236bSHarry Wentland return total_dest_line_time_ns; 12344562236bSHarry Wentland } 12354562236bSHarry Wentland 12364562236bSHarry Wentland void dce110_set_displaymarks( 12374562236bSHarry Wentland const struct core_dc *dc, 12384562236bSHarry Wentland struct validate_context *context) 12394562236bSHarry Wentland { 12404562236bSHarry Wentland uint8_t i, num_pipes; 12414562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 12424562236bSHarry Wentland 12434562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 12444562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 12454562236bSHarry Wentland uint32_t total_dest_line_time_ns; 12464562236bSHarry Wentland 12474562236bSHarry Wentland if (pipe_ctx->stream == NULL) 12484562236bSHarry Wentland continue; 12494562236bSHarry Wentland 12504562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 12514562236bSHarry Wentland dc->bw_vbios.blackout_duration, pipe_ctx->stream); 12524562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_display_marks( 12534562236bSHarry Wentland pipe_ctx->mi, 12549037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 12559037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 12569037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 12574562236bSHarry Wentland total_dest_line_time_ns); 12584562236bSHarry Wentland if (i == underlay_idx) { 12594562236bSHarry Wentland num_pipes++; 12604562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_chroma_display_marks( 12614562236bSHarry Wentland pipe_ctx->mi, 12629037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 12639037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 12649037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 12654562236bSHarry Wentland total_dest_line_time_ns); 12664562236bSHarry Wentland } 12674562236bSHarry Wentland num_pipes++; 12684562236bSHarry Wentland } 12694562236bSHarry Wentland } 12704562236bSHarry Wentland 1271a2b8659dSTony Cheng static void set_safe_displaymarks( 1272a2b8659dSTony Cheng struct resource_context *res_ctx, 1273a2b8659dSTony Cheng const struct resource_pool *pool) 12744562236bSHarry Wentland { 12754562236bSHarry Wentland int i; 1276a2b8659dSTony Cheng int underlay_idx = pool->underlay_pipe_index; 12779037d802SDmytro Laktyushkin struct dce_watermarks max_marks = { 12784562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 12799037d802SDmytro Laktyushkin struct dce_watermarks nbp_marks = { 12804562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 12814562236bSHarry Wentland 12824562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 12834562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream == NULL) 12844562236bSHarry Wentland continue; 12854562236bSHarry Wentland 12864562236bSHarry Wentland res_ctx->pipe_ctx[i].mi->funcs->mem_input_program_display_marks( 12874562236bSHarry Wentland res_ctx->pipe_ctx[i].mi, 12884562236bSHarry Wentland nbp_marks, 12894562236bSHarry Wentland max_marks, 12904562236bSHarry Wentland max_marks, 12914562236bSHarry Wentland MAX_WATERMARK); 12924562236bSHarry Wentland if (i == underlay_idx) 12934562236bSHarry Wentland res_ctx->pipe_ctx[i].mi->funcs->mem_input_program_chroma_display_marks( 12944562236bSHarry Wentland res_ctx->pipe_ctx[i].mi, 12954562236bSHarry Wentland nbp_marks, 12964562236bSHarry Wentland max_marks, 12974562236bSHarry Wentland max_marks, 12984562236bSHarry Wentland MAX_WATERMARK); 12994562236bSHarry Wentland } 13004562236bSHarry Wentland } 13014562236bSHarry Wentland 13024562236bSHarry Wentland static void switch_dp_clock_sources( 13034562236bSHarry Wentland const struct core_dc *dc, 13044562236bSHarry Wentland struct resource_context *res_ctx) 13054562236bSHarry Wentland { 13064562236bSHarry Wentland uint8_t i; 13074562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 13084562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; 13094562236bSHarry Wentland 13104562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 13114562236bSHarry Wentland continue; 13124562236bSHarry Wentland 13134562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 13144562236bSHarry Wentland struct clock_source *clk_src = 13154562236bSHarry Wentland resource_find_used_clk_src_for_sharing( 13164562236bSHarry Wentland res_ctx, pipe_ctx); 13174562236bSHarry Wentland 13184562236bSHarry Wentland if (clk_src && 13194562236bSHarry Wentland clk_src != pipe_ctx->clock_source) { 13204562236bSHarry Wentland resource_unreference_clock_source( 1321a2b8659dSTony Cheng res_ctx, dc->res_pool, 1322a2b8659dSTony Cheng &pipe_ctx->clock_source); 13234562236bSHarry Wentland pipe_ctx->clock_source = clk_src; 1324a2b8659dSTony Cheng resource_reference_clock_source( 1325a2b8659dSTony Cheng res_ctx, dc->res_pool, clk_src); 13264562236bSHarry Wentland 13274562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, clk_src, i); 13284562236bSHarry Wentland } 13294562236bSHarry Wentland } 13304562236bSHarry Wentland } 13314562236bSHarry Wentland } 13324562236bSHarry Wentland 13334562236bSHarry Wentland /******************************************************************************* 13344562236bSHarry Wentland * Public functions 13354562236bSHarry Wentland ******************************************************************************/ 13364562236bSHarry Wentland 13374562236bSHarry Wentland static void reset_single_pipe_hw_ctx( 13384562236bSHarry Wentland const struct core_dc *dc, 13394562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 13404562236bSHarry Wentland struct validate_context *context) 13414562236bSHarry Wentland { 13424562236bSHarry Wentland core_link_disable_stream(pipe_ctx); 13434b5e7d62SHersen Wu pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); 13444b5e7d62SHersen Wu if (!hwss_wait_for_blank_complete(pipe_ctx->tg)) { 13454562236bSHarry Wentland dm_error("DC: failed to blank crtc!\n"); 13464562236bSHarry Wentland BREAK_TO_DEBUGGER(); 13474562236bSHarry Wentland } 13484562236bSHarry Wentland pipe_ctx->tg->funcs->disable_crtc(pipe_ctx->tg); 13494562236bSHarry Wentland pipe_ctx->mi->funcs->free_mem_input( 1350ab2541b6SAric Cyr pipe_ctx->mi, context->stream_count); 1351a2b8659dSTony Cheng resource_unreference_clock_source(&context->res_ctx, dc->res_pool, 1352a2b8659dSTony Cheng &pipe_ctx->clock_source); 13534562236bSHarry Wentland 1354cfe4645eSDmytro Laktyushkin dc->hwss.power_down_front_end((struct core_dc *)dc, pipe_ctx->pipe_idx); 13554562236bSHarry Wentland 13564562236bSHarry Wentland pipe_ctx->stream = NULL; 13574562236bSHarry Wentland } 13584562236bSHarry Wentland 13594562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 13604562236bSHarry Wentland int num_pipes, int vmin, int vmax) 13614562236bSHarry Wentland { 13624562236bSHarry Wentland int i = 0; 13634562236bSHarry Wentland struct drr_params params = {0}; 13644562236bSHarry Wentland 13654562236bSHarry Wentland params.vertical_total_max = vmax; 13664562236bSHarry Wentland params.vertical_total_min = vmin; 13674562236bSHarry Wentland 13684562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 13694562236bSHarry Wentland * some GSL stuff 13704562236bSHarry Wentland */ 13714562236bSHarry Wentland 13724562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 13734562236bSHarry Wentland pipe_ctx[i]->tg->funcs->set_drr(pipe_ctx[i]->tg, ¶ms); 13744562236bSHarry Wentland } 13754562236bSHarry Wentland } 13764562236bSHarry Wentland 137772ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx, 137872ada5f7SEric Cook int num_pipes, 137972ada5f7SEric Cook struct crtc_position *position) 138072ada5f7SEric Cook { 138172ada5f7SEric Cook int i = 0; 138272ada5f7SEric Cook 138372ada5f7SEric Cook /* TODO: handle pipes > 1 138472ada5f7SEric Cook */ 138572ada5f7SEric Cook for (i = 0; i < num_pipes; i++) 138672ada5f7SEric Cook pipe_ctx[i]->tg->funcs->get_position(pipe_ctx[i]->tg, position); 138772ada5f7SEric Cook } 138872ada5f7SEric Cook 13894562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 139094267b3dSSylvia Tsai int num_pipes, const struct dc_static_screen_events *events) 13914562236bSHarry Wentland { 13924562236bSHarry Wentland unsigned int i; 139394267b3dSSylvia Tsai unsigned int value = 0; 139494267b3dSSylvia Tsai 139594267b3dSSylvia Tsai if (events->overlay_update) 139694267b3dSSylvia Tsai value |= 0x100; 139794267b3dSSylvia Tsai if (events->surface_update) 139894267b3dSSylvia Tsai value |= 0x80; 139994267b3dSSylvia Tsai if (events->cursor_update) 140094267b3dSSylvia Tsai value |= 0x2; 14014562236bSHarry Wentland 1402c3aa1d67SBhawanpreet Lakha #ifdef ENABLE_FBC 1403c3aa1d67SBhawanpreet Lakha value |= 0x84; 1404c3aa1d67SBhawanpreet Lakha #endif 1405c3aa1d67SBhawanpreet Lakha 14064562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 14074562236bSHarry Wentland pipe_ctx[i]->tg->funcs-> 14084562236bSHarry Wentland set_static_screen_control(pipe_ctx[i]->tg, value); 14094562236bSHarry Wentland } 14104562236bSHarry Wentland 14114562236bSHarry Wentland /* unit: in_khz before mode set, get pixel clock from context. ASIC register 14124562236bSHarry Wentland * may not be programmed yet. 14134562236bSHarry Wentland * TODO: after mode set, pre_mode_set = false, 14144562236bSHarry Wentland * may read PLL register to get pixel clock 14154562236bSHarry Wentland */ 14164562236bSHarry Wentland static uint32_t get_max_pixel_clock_for_all_paths( 14174562236bSHarry Wentland struct core_dc *dc, 14184562236bSHarry Wentland struct validate_context *context, 14194562236bSHarry Wentland bool pre_mode_set) 14204562236bSHarry Wentland { 14214562236bSHarry Wentland uint32_t max_pix_clk = 0; 14224562236bSHarry Wentland int i; 14234562236bSHarry Wentland 14244562236bSHarry Wentland if (!pre_mode_set) { 14254562236bSHarry Wentland /* TODO: read ASIC register to get pixel clock */ 14264562236bSHarry Wentland ASSERT(0); 14274562236bSHarry Wentland } 14284562236bSHarry Wentland 14294562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 14304562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 14314562236bSHarry Wentland 14324562236bSHarry Wentland if (pipe_ctx->stream == NULL) 14334562236bSHarry Wentland continue; 14344562236bSHarry Wentland 14354562236bSHarry Wentland /* do not check under lay */ 14364562236bSHarry Wentland if (pipe_ctx->top_pipe) 14374562236bSHarry Wentland continue; 14384562236bSHarry Wentland 14394562236bSHarry Wentland if (pipe_ctx->pix_clk_params.requested_pix_clk > max_pix_clk) 14404562236bSHarry Wentland max_pix_clk = 14414562236bSHarry Wentland pipe_ctx->pix_clk_params.requested_pix_clk; 14424562236bSHarry Wentland } 14434562236bSHarry Wentland 14444562236bSHarry Wentland if (max_pix_clk == 0) 14454562236bSHarry Wentland ASSERT(0); 14464562236bSHarry Wentland 14474562236bSHarry Wentland return max_pix_clk; 14484562236bSHarry Wentland } 14494562236bSHarry Wentland 14502c8ad2d5SAlex Deucher /* Find clock state based on clock requested. if clock value is 0, simply 14514562236bSHarry Wentland * set clock state as requested without finding clock state by clock value 14522c8ad2d5SAlex Deucher *TODO: when dce120_hw_sequencer.c is created, override apply_min_clock. 14532c8ad2d5SAlex Deucher * 14542c8ad2d5SAlex Deucher * TODOFPGA remove TODO after implement dal_display_clock_get_cur_clocks_value 14552c8ad2d5SAlex Deucher * etc support for dcn1.0 14564562236bSHarry Wentland */ 14574562236bSHarry Wentland static void apply_min_clocks( 14584562236bSHarry Wentland struct core_dc *dc, 14594562236bSHarry Wentland struct validate_context *context, 1460e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state *clocks_state, 14614562236bSHarry Wentland bool pre_mode_set) 14624562236bSHarry Wentland { 14634562236bSHarry Wentland struct state_dependent_clocks req_clocks = {0}; 14644562236bSHarry Wentland struct pipe_ctx *pipe_ctx; 14654562236bSHarry Wentland int i; 14664562236bSHarry Wentland 14674562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 14684562236bSHarry Wentland pipe_ctx = &context->res_ctx.pipe_ctx[i]; 14694562236bSHarry Wentland if (pipe_ctx->dis_clk != NULL) 14704562236bSHarry Wentland break; 14714562236bSHarry Wentland } 14724562236bSHarry Wentland 14734562236bSHarry Wentland if (!pre_mode_set) { 14744562236bSHarry Wentland /* set clock_state without verification */ 14755d6d185fSDmytro Laktyushkin if (pipe_ctx->dis_clk->funcs->set_min_clocks_state) { 14765d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk->funcs->set_min_clocks_state( 14775d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk, *clocks_state); 14784562236bSHarry Wentland return; 14795d6d185fSDmytro Laktyushkin } 14804562236bSHarry Wentland 14812c8ad2d5SAlex Deucher /* TODO: This is incorrect. Figure out how to fix. */ 14822c8ad2d5SAlex Deucher pipe_ctx->dis_clk->funcs->apply_clock_voltage_request( 14832c8ad2d5SAlex Deucher pipe_ctx->dis_clk, 14842c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAY_CLK, 14852c8ad2d5SAlex Deucher pipe_ctx->dis_clk->cur_clocks_value.dispclk_in_khz, 14862c8ad2d5SAlex Deucher pre_mode_set, 14872c8ad2d5SAlex Deucher false); 14882c8ad2d5SAlex Deucher 14892c8ad2d5SAlex Deucher pipe_ctx->dis_clk->funcs->apply_clock_voltage_request( 14902c8ad2d5SAlex Deucher pipe_ctx->dis_clk, 14912c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_PIXELCLK, 14922c8ad2d5SAlex Deucher pipe_ctx->dis_clk->cur_clocks_value.max_pixelclk_in_khz, 14932c8ad2d5SAlex Deucher pre_mode_set, 14942c8ad2d5SAlex Deucher false); 14952c8ad2d5SAlex Deucher 14962c8ad2d5SAlex Deucher pipe_ctx->dis_clk->funcs->apply_clock_voltage_request( 14972c8ad2d5SAlex Deucher pipe_ctx->dis_clk, 14982c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, 14992c8ad2d5SAlex Deucher pipe_ctx->dis_clk->cur_clocks_value.max_non_dp_phyclk_in_khz, 15002c8ad2d5SAlex Deucher pre_mode_set, 15012c8ad2d5SAlex Deucher false); 15022c8ad2d5SAlex Deucher return; 15034562236bSHarry Wentland } 15044562236bSHarry Wentland 15054562236bSHarry Wentland /* get the required state based on state dependent clocks: 15064562236bSHarry Wentland * display clock and pixel clock 15074562236bSHarry Wentland */ 15089037d802SDmytro Laktyushkin req_clocks.display_clk_khz = context->bw.dce.dispclk_khz; 15094562236bSHarry Wentland 15104562236bSHarry Wentland req_clocks.pixel_clk_khz = get_max_pixel_clock_for_all_paths( 15114562236bSHarry Wentland dc, context, true); 15124562236bSHarry Wentland 15135d6d185fSDmytro Laktyushkin if (pipe_ctx->dis_clk->funcs->get_required_clocks_state) { 15145d6d185fSDmytro Laktyushkin *clocks_state = pipe_ctx->dis_clk->funcs->get_required_clocks_state( 15155d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk, &req_clocks); 15165d6d185fSDmytro Laktyushkin pipe_ctx->dis_clk->funcs->set_min_clocks_state( 15174562236bSHarry Wentland pipe_ctx->dis_clk, *clocks_state); 15184562236bSHarry Wentland } else { 15192c8ad2d5SAlex Deucher pipe_ctx->dis_clk->funcs->apply_clock_voltage_request( 15202c8ad2d5SAlex Deucher pipe_ctx->dis_clk, 15212c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAY_CLK, 15222c8ad2d5SAlex Deucher req_clocks.display_clk_khz, 15232c8ad2d5SAlex Deucher pre_mode_set, 15242c8ad2d5SAlex Deucher false); 15252c8ad2d5SAlex Deucher 15262c8ad2d5SAlex Deucher pipe_ctx->dis_clk->funcs->apply_clock_voltage_request( 15272c8ad2d5SAlex Deucher pipe_ctx->dis_clk, 15282c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_PIXELCLK, 15292c8ad2d5SAlex Deucher req_clocks.pixel_clk_khz, 15302c8ad2d5SAlex Deucher pre_mode_set, 15312c8ad2d5SAlex Deucher false); 15322c8ad2d5SAlex Deucher 15332c8ad2d5SAlex Deucher pipe_ctx->dis_clk->funcs->apply_clock_voltage_request( 15342c8ad2d5SAlex Deucher pipe_ctx->dis_clk, 15352c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, 15362c8ad2d5SAlex Deucher req_clocks.pixel_clk_khz, 15372c8ad2d5SAlex Deucher pre_mode_set, 15382c8ad2d5SAlex Deucher false); 15394562236bSHarry Wentland } 15404562236bSHarry Wentland } 15414562236bSHarry Wentland 15424562236bSHarry Wentland static enum dc_status apply_ctx_to_hw_fpga( 15434562236bSHarry Wentland struct core_dc *dc, 15444562236bSHarry Wentland struct validate_context *context) 15454562236bSHarry Wentland { 15464562236bSHarry Wentland enum dc_status status = DC_ERROR_UNEXPECTED; 15474562236bSHarry Wentland int i; 15484562236bSHarry Wentland 1549a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 15504562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 15514562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[i]; 15524562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 15534562236bSHarry Wentland 15544562236bSHarry Wentland if (pipe_ctx->stream == NULL) 15554562236bSHarry Wentland continue; 15564562236bSHarry Wentland 15574562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) 15584562236bSHarry Wentland continue; 15594562236bSHarry Wentland 15604562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 15614562236bSHarry Wentland pipe_ctx, 15624562236bSHarry Wentland context, 15634562236bSHarry Wentland dc); 15644562236bSHarry Wentland 15654562236bSHarry Wentland if (status != DC_OK) 15664562236bSHarry Wentland return status; 15674562236bSHarry Wentland } 15684562236bSHarry Wentland 15694562236bSHarry Wentland return DC_OK; 15704562236bSHarry Wentland } 15714562236bSHarry Wentland 15724562236bSHarry Wentland static void reset_hw_ctx_wrap( 15734562236bSHarry Wentland struct core_dc *dc, 15744562236bSHarry Wentland struct validate_context *context) 15754562236bSHarry Wentland { 15764562236bSHarry Wentland int i; 15774562236bSHarry Wentland 15784562236bSHarry Wentland /* Reset old context */ 15794562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 1580a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 15814562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 15824562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[i]; 15834562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 15844562236bSHarry Wentland 15854562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 15864562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 15874562236bSHarry Wentland * PHY when not already disabled. 15884562236bSHarry Wentland */ 15894562236bSHarry Wentland 15904562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 15914562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 15924562236bSHarry Wentland continue; 15934562236bSHarry Wentland 15944562236bSHarry Wentland if (!pipe_ctx->stream || 15954562236bSHarry Wentland pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 15964562236bSHarry Wentland reset_single_pipe_hw_ctx( 15974562236bSHarry Wentland dc, pipe_ctx_old, dc->current_context); 15984562236bSHarry Wentland } 15994562236bSHarry Wentland } 16004562236bSHarry Wentland 1601cf437593SDmytro Laktyushkin 16024562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 16034562236bSHarry Wentland struct core_dc *dc, 16044562236bSHarry Wentland struct validate_context *context) 16054562236bSHarry Wentland { 16064562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 16074562236bSHarry Wentland enum dc_status status; 16084562236bSHarry Wentland int i; 1609e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID; 16104562236bSHarry Wentland 16114562236bSHarry Wentland /* Reset old context */ 16124562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 16134562236bSHarry Wentland dc->hwss.reset_hw_ctx_wrap(dc, context); 16144562236bSHarry Wentland 16154562236bSHarry Wentland /* Skip applying if no targets */ 1616ab2541b6SAric Cyr if (context->stream_count <= 0) 16174562236bSHarry Wentland return DC_OK; 16184562236bSHarry Wentland 16194562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 16204562236bSHarry Wentland apply_ctx_to_hw_fpga(dc, context); 16214562236bSHarry Wentland return DC_OK; 16224562236bSHarry Wentland } 16234562236bSHarry Wentland 16244562236bSHarry Wentland /* Apply new context */ 16254562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 16264562236bSHarry Wentland 16274562236bSHarry Wentland /* below is for real asic only */ 1628a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 16294562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 16304562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[i]; 16314562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 16324562236bSHarry Wentland 16334562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 16344562236bSHarry Wentland continue; 16354562236bSHarry Wentland 16364562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 16374562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 16384562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 16394562236bSHarry Wentland pipe_ctx->clock_source, i); 16404562236bSHarry Wentland continue; 16414562236bSHarry Wentland } 16424562236bSHarry Wentland 16434562236bSHarry Wentland dc->hwss.enable_display_power_gating( 16444562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 16454562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 16464562236bSHarry Wentland } 16474562236bSHarry Wentland 1648a2b8659dSTony Cheng set_safe_displaymarks(&context->res_ctx, dc->res_pool); 16491663ae1cSBhawanpreet Lakha 16501663ae1cSBhawanpreet Lakha #ifdef ENABLE_FBC 16511663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 16521663ae1cSBhawanpreet Lakha #endif 16534562236bSHarry Wentland /*TODO: when pplib works*/ 16544562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, true); 16554562236bSHarry Wentland 1656ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1657c8210d5aSHarry Wentland if (dc->ctx->dce_version == DCN_VERSION_1_0) { 16589037d802SDmytro Laktyushkin if (context->bw.dcn.calc_clk.fclk_khz 1659c66a54dcSDmytro Laktyushkin > dc->current_context->bw.dcn.cur_clk.fclk_khz) { 1660ff5ef992SAlex Deucher struct dm_pp_clock_for_voltage_req clock; 1661ff5ef992SAlex Deucher 1662ff5ef992SAlex Deucher clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; 16639037d802SDmytro Laktyushkin clock.clocks_in_khz = context->bw.dcn.calc_clk.fclk_khz; 1664ff5ef992SAlex Deucher dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 1665c66a54dcSDmytro Laktyushkin dc->current_context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 1666c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 1667ff5ef992SAlex Deucher } 16689037d802SDmytro Laktyushkin if (context->bw.dcn.calc_clk.dcfclk_khz 1669c66a54dcSDmytro Laktyushkin > dc->current_context->bw.dcn.cur_clk.dcfclk_khz) { 1670ff5ef992SAlex Deucher struct dm_pp_clock_for_voltage_req clock; 1671ff5ef992SAlex Deucher 1672ff5ef992SAlex Deucher clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; 16739037d802SDmytro Laktyushkin clock.clocks_in_khz = context->bw.dcn.calc_clk.dcfclk_khz; 1674ff5ef992SAlex Deucher dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 1675c66a54dcSDmytro Laktyushkin dc->current_context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 1676c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 1677ff5ef992SAlex Deucher } 1678c66a54dcSDmytro Laktyushkin if (context->bw.dcn.calc_clk.dispclk_khz 1679c66a54dcSDmytro Laktyushkin > dc->current_context->bw.dcn.cur_clk.dispclk_khz) { 1680c66a54dcSDmytro Laktyushkin dc->res_pool->display_clock->funcs->set_clock( 1681c66a54dcSDmytro Laktyushkin dc->res_pool->display_clock, 1682c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz); 1683c66a54dcSDmytro Laktyushkin dc->current_context->bw.dcn.cur_clk.dispclk_khz = 1684c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz; 1685c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.dispclk_khz = 1686c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz; 1687c66a54dcSDmytro Laktyushkin } 1688c66a54dcSDmytro Laktyushkin } else 1689ff5ef992SAlex Deucher #endif 16909037d802SDmytro Laktyushkin if (context->bw.dce.dispclk_khz 16919037d802SDmytro Laktyushkin > dc->current_context->bw.dce.dispclk_khz) { 1692a2b8659dSTony Cheng dc->res_pool->display_clock->funcs->set_clock( 1693a2b8659dSTony Cheng dc->res_pool->display_clock, 16949037d802SDmytro Laktyushkin context->bw.dce.dispclk_khz * 115 / 100); 16951ce71fcdSCharlene Liu } 1696ab8812a3SHersen Wu /* program audio wall clock. use HDMI as clock source if HDMI 1697ab8812a3SHersen Wu * audio active. Otherwise, use DP as clock source 1698ab8812a3SHersen Wu * first, loop to find any HDMI audio, if not, loop find DP audio 1699ab8812a3SHersen Wu */ 17004562236bSHarry Wentland /* Setup audio rate clock source */ 17014562236bSHarry Wentland /* Issue: 17024562236bSHarry Wentland * Audio lag happened on DP monitor when unplug a HDMI monitor 17034562236bSHarry Wentland * 17044562236bSHarry Wentland * Cause: 17054562236bSHarry Wentland * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 17064562236bSHarry Wentland * is set to either dto0 or dto1, audio should work fine. 17074562236bSHarry Wentland * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 17084562236bSHarry Wentland * set to dto0 will cause audio lag. 17094562236bSHarry Wentland * 17104562236bSHarry Wentland * Solution: 17114562236bSHarry Wentland * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 17124562236bSHarry Wentland * find first available pipe with audio, setup audio wall DTO per topology 17134562236bSHarry Wentland * instead of per pipe. 17144562236bSHarry Wentland */ 1715a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 1716ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1717ab8812a3SHersen Wu 1718ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 1719ab8812a3SHersen Wu continue; 1720ab8812a3SHersen Wu 1721ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 1722ab8812a3SHersen Wu continue; 1723ab8812a3SHersen Wu 1724ab8812a3SHersen Wu if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 1725ab8812a3SHersen Wu continue; 1726ab8812a3SHersen Wu 1727ab8812a3SHersen Wu if (pipe_ctx->audio != NULL) { 1728ab8812a3SHersen Wu struct audio_output audio_output; 1729ab8812a3SHersen Wu 1730ab8812a3SHersen Wu build_audio_output(pipe_ctx, &audio_output); 1731ab8812a3SHersen Wu 1732ab8812a3SHersen Wu pipe_ctx->audio->funcs->wall_dto_setup( 1733ab8812a3SHersen Wu pipe_ctx->audio, 1734ab8812a3SHersen Wu pipe_ctx->stream->signal, 1735ab8812a3SHersen Wu &audio_output.crtc_info, 1736ab8812a3SHersen Wu &audio_output.pll_info); 1737ab8812a3SHersen Wu break; 1738ab8812a3SHersen Wu } 1739ab8812a3SHersen Wu } 1740ab8812a3SHersen Wu 1741ab8812a3SHersen Wu /* no HDMI audio is found, try DP audio */ 1742a2b8659dSTony Cheng if (i == dc->res_pool->pipe_count) { 1743a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 1744ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1745ab8812a3SHersen Wu 1746ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 1747ab8812a3SHersen Wu continue; 1748ab8812a3SHersen Wu 1749ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 1750ab8812a3SHersen Wu continue; 1751ab8812a3SHersen Wu 1752ab8812a3SHersen Wu if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 1753ab8812a3SHersen Wu continue; 1754ab8812a3SHersen Wu 1755ab8812a3SHersen Wu if (pipe_ctx->audio != NULL) { 1756ab8812a3SHersen Wu struct audio_output audio_output; 1757ab8812a3SHersen Wu 1758ab8812a3SHersen Wu build_audio_output(pipe_ctx, &audio_output); 1759ab8812a3SHersen Wu 1760ab8812a3SHersen Wu pipe_ctx->audio->funcs->wall_dto_setup( 1761ab8812a3SHersen Wu pipe_ctx->audio, 1762ab8812a3SHersen Wu pipe_ctx->stream->signal, 1763ab8812a3SHersen Wu &audio_output.crtc_info, 1764ab8812a3SHersen Wu &audio_output.pll_info); 1765ab8812a3SHersen Wu break; 1766ab8812a3SHersen Wu } 1767ab8812a3SHersen Wu } 1768ab8812a3SHersen Wu } 1769ab8812a3SHersen Wu 1770a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 1771ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx_old = 1772ab8812a3SHersen Wu &dc->current_context->res_ctx.pipe_ctx[i]; 1773ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1774ab8812a3SHersen Wu 1775ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 1776ab8812a3SHersen Wu continue; 1777ab8812a3SHersen Wu 1778ab8812a3SHersen Wu if (pipe_ctx->stream == pipe_ctx_old->stream) 1779ab8812a3SHersen Wu continue; 1780ab8812a3SHersen Wu 1781313bf4ffSYongqiang Sun if (pipe_ctx->stream && pipe_ctx_old->stream 1782313bf4ffSYongqiang Sun && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 1783313bf4ffSYongqiang Sun continue; 1784313bf4ffSYongqiang Sun 1785ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 1786ab8812a3SHersen Wu continue; 1787ab8812a3SHersen Wu 1788ab8812a3SHersen Wu if (context->res_ctx.pipe_ctx[i].audio != NULL) { 1789ab8812a3SHersen Wu 17904562236bSHarry Wentland struct audio_output audio_output; 17914562236bSHarry Wentland 17924562236bSHarry Wentland build_audio_output(pipe_ctx, &audio_output); 17934562236bSHarry Wentland 17944562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 17954562236bSHarry Wentland pipe_ctx->stream_enc->funcs->dp_audio_setup( 17964562236bSHarry Wentland pipe_ctx->stream_enc, 17974562236bSHarry Wentland pipe_ctx->audio->inst, 17984562236bSHarry Wentland &pipe_ctx->stream->public.audio_info); 17994562236bSHarry Wentland else 18004562236bSHarry Wentland pipe_ctx->stream_enc->funcs->hdmi_audio_setup( 18014562236bSHarry Wentland pipe_ctx->stream_enc, 18024562236bSHarry Wentland pipe_ctx->audio->inst, 18034562236bSHarry Wentland &pipe_ctx->stream->public.audio_info, 18044562236bSHarry Wentland &audio_output.crtc_info); 18054562236bSHarry Wentland 18064562236bSHarry Wentland pipe_ctx->audio->funcs->az_configure( 18074562236bSHarry Wentland pipe_ctx->audio, 18084562236bSHarry Wentland pipe_ctx->stream->signal, 18094562236bSHarry Wentland &audio_output.crtc_info, 18104562236bSHarry Wentland &pipe_ctx->stream->public.audio_info); 18114562236bSHarry Wentland } 18124562236bSHarry Wentland 18134562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 18144562236bSHarry Wentland pipe_ctx, 18154562236bSHarry Wentland context, 18164562236bSHarry Wentland dc); 18174562236bSHarry Wentland 181818f7a1e4SYongqiang Sun if (dc->hwss.power_on_front_end) 181918f7a1e4SYongqiang Sun dc->hwss.power_on_front_end(dc, pipe_ctx, context); 182018f7a1e4SYongqiang Sun 18214562236bSHarry Wentland if (DC_OK != status) 18224562236bSHarry Wentland return status; 18234562236bSHarry Wentland } 18244562236bSHarry Wentland 1825cf437593SDmytro Laktyushkin dc->hwss.set_bandwidth(dc, context, true); 18264562236bSHarry Wentland 18274562236bSHarry Wentland /* to save power */ 18284562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, false); 18294562236bSHarry Wentland 18304562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, false); 18314562236bSHarry Wentland 18324562236bSHarry Wentland switch_dp_clock_sources(dc, &context->res_ctx); 18334562236bSHarry Wentland 1834cf437593SDmytro Laktyushkin 18354562236bSHarry Wentland return DC_OK; 18364562236bSHarry Wentland } 18374562236bSHarry Wentland 18384562236bSHarry Wentland /******************************************************************************* 18394562236bSHarry Wentland * Front End programming 18404562236bSHarry Wentland ******************************************************************************/ 18414562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 18424562236bSHarry Wentland { 18434562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 18444562236bSHarry Wentland 18454562236bSHarry Wentland default_adjust.force_hw_default = false; 18464562236bSHarry Wentland if (pipe_ctx->surface == NULL) 18474562236bSHarry Wentland default_adjust.in_color_space = COLOR_SPACE_SRGB; 18484562236bSHarry Wentland else 18494562236bSHarry Wentland default_adjust.in_color_space = 18504562236bSHarry Wentland pipe_ctx->surface->public.color_space; 18514562236bSHarry Wentland if (pipe_ctx->stream == NULL) 18524562236bSHarry Wentland default_adjust.out_color_space = COLOR_SPACE_SRGB; 18534562236bSHarry Wentland else 18544562236bSHarry Wentland default_adjust.out_color_space = 18554562236bSHarry Wentland pipe_ctx->stream->public.output_color_space; 18564562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 18574562236bSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->scl_data.format; 18584562236bSHarry Wentland 18594562236bSHarry Wentland /* display color depth */ 18604562236bSHarry Wentland default_adjust.color_depth = 18614562236bSHarry Wentland pipe_ctx->stream->public.timing.display_color_depth; 18624562236bSHarry Wentland 18634562236bSHarry Wentland /* Lb color depth */ 18644562236bSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->scl_data.lb_params.depth; 18654562236bSHarry Wentland 18664562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_csc_default( 18674562236bSHarry Wentland pipe_ctx->opp, &default_adjust); 18684562236bSHarry Wentland } 18694562236bSHarry Wentland 1870b06b7680SLeon Elazar 1871b06b7680SLeon Elazar /******************************************************************************* 1872b06b7680SLeon Elazar * In order to turn on/off specific surface we will program 1873b06b7680SLeon Elazar * Blender + CRTC 1874b06b7680SLeon Elazar * 1875b06b7680SLeon Elazar * In case that we have two surfaces and they have a different visibility 1876b06b7680SLeon Elazar * we can't turn off the CRTC since it will turn off the entire display 1877b06b7680SLeon Elazar * 1878b06b7680SLeon Elazar * |----------------------------------------------- | 1879b06b7680SLeon Elazar * |bottom pipe|curr pipe | | | 1880b06b7680SLeon Elazar * |Surface |Surface | Blender | CRCT | 1881b06b7680SLeon Elazar * |visibility |visibility | Configuration| | 1882b06b7680SLeon Elazar * |------------------------------------------------| 1883b06b7680SLeon Elazar * | off | off | CURRENT_PIPE | blank | 1884b06b7680SLeon Elazar * | off | on | CURRENT_PIPE | unblank | 1885b06b7680SLeon Elazar * | on | off | OTHER_PIPE | unblank | 1886b06b7680SLeon Elazar * | on | on | BLENDING | unblank | 1887b06b7680SLeon Elazar * -------------------------------------------------| 1888b06b7680SLeon Elazar * 1889b06b7680SLeon Elazar ******************************************************************************/ 1890b06b7680SLeon Elazar static void program_surface_visibility(const struct core_dc *dc, 18914562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 18924562236bSHarry Wentland { 18934562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 1894b06b7680SLeon Elazar bool blank_target = false; 18954562236bSHarry Wentland 18964562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 1897b06b7680SLeon Elazar 1898b06b7680SLeon Elazar /* For now we are supporting only two pipes */ 1899b06b7680SLeon Elazar ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 1900b06b7680SLeon Elazar 19014562236bSHarry Wentland if (pipe_ctx->bottom_pipe->surface->public.visible) { 19024562236bSHarry Wentland if (pipe_ctx->surface->public.visible) 19034562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 19044562236bSHarry Wentland else 19054562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 1906b06b7680SLeon Elazar 1907b06b7680SLeon Elazar } else if (!pipe_ctx->surface->public.visible) 1908b06b7680SLeon Elazar blank_target = true; 1909b06b7680SLeon Elazar 1910b06b7680SLeon Elazar } else if (!pipe_ctx->surface->public.visible) 1911b06b7680SLeon Elazar blank_target = true; 1912b06b7680SLeon Elazar 19134562236bSHarry Wentland dce_set_blender_mode(dc->hwseq, pipe_ctx->pipe_idx, blender_mode); 1914b06b7680SLeon Elazar pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, blank_target); 1915b06b7680SLeon Elazar 19164562236bSHarry Wentland } 19174562236bSHarry Wentland 19181bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 19191bf56e62SZeyu Fan { 19201bf56e62SZeyu Fan struct xfm_grph_csc_adjustment adjust; 19211bf56e62SZeyu Fan memset(&adjust, 0, sizeof(adjust)); 19221bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 19231bf56e62SZeyu Fan 19241bf56e62SZeyu Fan 19251bf56e62SZeyu Fan if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) { 19261bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 19271bf56e62SZeyu Fan adjust.temperature_matrix[0] = 19281bf56e62SZeyu Fan pipe_ctx->stream-> 19291bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[0]; 19301bf56e62SZeyu Fan adjust.temperature_matrix[1] = 19311bf56e62SZeyu Fan pipe_ctx->stream-> 19321bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[1]; 19331bf56e62SZeyu Fan adjust.temperature_matrix[2] = 19341bf56e62SZeyu Fan pipe_ctx->stream-> 19351bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[2]; 19361bf56e62SZeyu Fan adjust.temperature_matrix[3] = 19371bf56e62SZeyu Fan pipe_ctx->stream-> 19381bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[4]; 19391bf56e62SZeyu Fan adjust.temperature_matrix[4] = 19401bf56e62SZeyu Fan pipe_ctx->stream-> 19411bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[5]; 19421bf56e62SZeyu Fan adjust.temperature_matrix[5] = 19431bf56e62SZeyu Fan pipe_ctx->stream-> 19441bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[6]; 19451bf56e62SZeyu Fan adjust.temperature_matrix[6] = 19461bf56e62SZeyu Fan pipe_ctx->stream-> 19471bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[8]; 19481bf56e62SZeyu Fan adjust.temperature_matrix[7] = 19491bf56e62SZeyu Fan pipe_ctx->stream-> 19501bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[9]; 19511bf56e62SZeyu Fan adjust.temperature_matrix[8] = 19521bf56e62SZeyu Fan pipe_ctx->stream-> 19531bf56e62SZeyu Fan public.gamut_remap_matrix.matrix[10]; 19541bf56e62SZeyu Fan } 19551bf56e62SZeyu Fan 19561bf56e62SZeyu Fan pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust); 19571bf56e62SZeyu Fan } 19581bf56e62SZeyu Fan 19594562236bSHarry Wentland /** 19604562236bSHarry Wentland * TODO REMOVE, USE UPDATE INSTEAD 19614562236bSHarry Wentland */ 19624562236bSHarry Wentland static void set_plane_config( 19634562236bSHarry Wentland const struct core_dc *dc, 19644562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 19654562236bSHarry Wentland struct resource_context *res_ctx) 19664562236bSHarry Wentland { 19674562236bSHarry Wentland struct mem_input *mi = pipe_ctx->mi; 19684562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 19694562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 19704562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 19714562236bSHarry Wentland unsigned int i; 19724562236bSHarry Wentland 19734562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 19744562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 19754562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 19764562236bSHarry Wentland 19774562236bSHarry Wentland dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true); 19784562236bSHarry Wentland 19794562236bSHarry Wentland set_default_colors(pipe_ctx); 19804562236bSHarry Wentland if (pipe_ctx->stream->public.csc_color_matrix.enable_adjustment 19814562236bSHarry Wentland == true) { 19824562236bSHarry Wentland tbl_entry.color_space = 19834562236bSHarry Wentland pipe_ctx->stream->public.output_color_space; 19844562236bSHarry Wentland 19854562236bSHarry Wentland for (i = 0; i < 12; i++) 19864562236bSHarry Wentland tbl_entry.regval[i] = 19874562236bSHarry Wentland pipe_ctx->stream->public.csc_color_matrix.matrix[i]; 19884562236bSHarry Wentland 19894562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_csc_adjustment 19904562236bSHarry Wentland (pipe_ctx->opp, &tbl_entry); 19914562236bSHarry Wentland } 19924562236bSHarry Wentland 19934562236bSHarry Wentland if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) { 19944562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 19954562236bSHarry Wentland adjust.temperature_matrix[0] = 19964562236bSHarry Wentland pipe_ctx->stream-> 19974562236bSHarry Wentland public.gamut_remap_matrix.matrix[0]; 19984562236bSHarry Wentland adjust.temperature_matrix[1] = 19994562236bSHarry Wentland pipe_ctx->stream-> 20004562236bSHarry Wentland public.gamut_remap_matrix.matrix[1]; 20014562236bSHarry Wentland adjust.temperature_matrix[2] = 20024562236bSHarry Wentland pipe_ctx->stream-> 20034562236bSHarry Wentland public.gamut_remap_matrix.matrix[2]; 20044562236bSHarry Wentland adjust.temperature_matrix[3] = 20054562236bSHarry Wentland pipe_ctx->stream-> 20064562236bSHarry Wentland public.gamut_remap_matrix.matrix[4]; 20074562236bSHarry Wentland adjust.temperature_matrix[4] = 20084562236bSHarry Wentland pipe_ctx->stream-> 20094562236bSHarry Wentland public.gamut_remap_matrix.matrix[5]; 20104562236bSHarry Wentland adjust.temperature_matrix[5] = 20114562236bSHarry Wentland pipe_ctx->stream-> 20124562236bSHarry Wentland public.gamut_remap_matrix.matrix[6]; 20134562236bSHarry Wentland adjust.temperature_matrix[6] = 20144562236bSHarry Wentland pipe_ctx->stream-> 20154562236bSHarry Wentland public.gamut_remap_matrix.matrix[8]; 20164562236bSHarry Wentland adjust.temperature_matrix[7] = 20174562236bSHarry Wentland pipe_ctx->stream-> 20184562236bSHarry Wentland public.gamut_remap_matrix.matrix[9]; 20194562236bSHarry Wentland adjust.temperature_matrix[8] = 20204562236bSHarry Wentland pipe_ctx->stream-> 20214562236bSHarry Wentland public.gamut_remap_matrix.matrix[10]; 20224562236bSHarry Wentland } 20234562236bSHarry Wentland 20244562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust); 20254562236bSHarry Wentland 20264562236bSHarry Wentland pipe_ctx->scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 20274562236bSHarry Wentland program_scaler(dc, pipe_ctx); 20284562236bSHarry Wentland 2029b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 20304562236bSHarry Wentland 20314562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 20324562236bSHarry Wentland mi, 20334562236bSHarry Wentland surface->public.format, 20344562236bSHarry Wentland &surface->public.tiling_info, 20354562236bSHarry Wentland &surface->public.plane_size, 20364562236bSHarry Wentland surface->public.rotation, 20374562236bSHarry Wentland NULL, 20384b28b76bSDmytro Laktyushkin false); 20394b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 20404b28b76bSDmytro Laktyushkin mi->funcs->set_blank(mi, pipe_ctx->surface->public.visible); 20414562236bSHarry Wentland 20424562236bSHarry Wentland if (dc->public.config.gpu_vm_support) 20434562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 20444562236bSHarry Wentland pipe_ctx->mi, 20454562236bSHarry Wentland surface->public.format, 20464562236bSHarry Wentland &surface->public.tiling_info, 20474562236bSHarry Wentland surface->public.rotation); 20484562236bSHarry Wentland } 20494562236bSHarry Wentland 20504562236bSHarry Wentland static void update_plane_addr(const struct core_dc *dc, 20514562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 20524562236bSHarry Wentland { 20534562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 20544562236bSHarry Wentland 20554562236bSHarry Wentland if (surface == NULL) 20564562236bSHarry Wentland return; 20574562236bSHarry Wentland 20584562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_program_surface_flip_and_addr( 20594562236bSHarry Wentland pipe_ctx->mi, 20604562236bSHarry Wentland &surface->public.address, 20614562236bSHarry Wentland surface->public.flip_immediate); 20624562236bSHarry Wentland 20634562236bSHarry Wentland surface->status.requested_address = surface->public.address; 20644562236bSHarry Wentland } 20654562236bSHarry Wentland 20664562236bSHarry Wentland void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 20674562236bSHarry Wentland { 20684562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 20694562236bSHarry Wentland 20704562236bSHarry Wentland if (surface == NULL) 20714562236bSHarry Wentland return; 20724562236bSHarry Wentland 20734562236bSHarry Wentland surface->status.is_flip_pending = 20744562236bSHarry Wentland pipe_ctx->mi->funcs->mem_input_is_flip_pending( 20754562236bSHarry Wentland pipe_ctx->mi); 20764562236bSHarry Wentland 20774562236bSHarry Wentland if (surface->status.is_flip_pending && !surface->public.visible) 20784562236bSHarry Wentland pipe_ctx->mi->current_address = pipe_ctx->mi->request_address; 20794562236bSHarry Wentland 20804562236bSHarry Wentland surface->status.current_address = pipe_ctx->mi->current_address; 20817f5c22d1SVitaly Prosyak if (pipe_ctx->mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 20827f5c22d1SVitaly Prosyak pipe_ctx->tg->funcs->is_stereo_left_eye) { 20837f5c22d1SVitaly Prosyak surface->status.is_right_eye =\ 20847f5c22d1SVitaly Prosyak !pipe_ctx->tg->funcs->is_stereo_left_eye(pipe_ctx->tg); 20857f5c22d1SVitaly Prosyak } 20864562236bSHarry Wentland } 20874562236bSHarry Wentland 20884562236bSHarry Wentland void dce110_power_down(struct core_dc *dc) 20894562236bSHarry Wentland { 20904562236bSHarry Wentland power_down_all_hw_blocks(dc); 20914562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 20924562236bSHarry Wentland } 20934562236bSHarry Wentland 20944562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 20954562236bSHarry Wentland struct dc_context *dc_ctx, 20964562236bSHarry Wentland struct timing_generator *tg) 20974562236bSHarry Wentland { 20984562236bSHarry Wentland bool rc = false; 20994562236bSHarry Wentland 21004562236bSHarry Wentland /* To avoid endless loop we wait at most 21014562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 21024562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 21034562236bSHarry Wentland uint32_t i; 21044562236bSHarry Wentland 21054562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 21064562236bSHarry Wentland 21074562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 21084562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 21094562236bSHarry Wentland break; 21104562236bSHarry Wentland } 21114562236bSHarry Wentland 21124562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 21134562236bSHarry Wentland rc = true; 21144562236bSHarry Wentland /* usually occurs at i=1 */ 21154562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 21164562236bSHarry Wentland i); 21174562236bSHarry Wentland break; 21184562236bSHarry Wentland } 21194562236bSHarry Wentland 21204562236bSHarry Wentland /* Wait for one frame. */ 21214562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 21224562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 21234562236bSHarry Wentland } 21244562236bSHarry Wentland 21254562236bSHarry Wentland if (false == rc) 21264562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 21274562236bSHarry Wentland 21284562236bSHarry Wentland return rc; 21294562236bSHarry Wentland } 21304562236bSHarry Wentland 21314562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 21324562236bSHarry Wentland static void dce110_enable_timing_synchronization( 21334562236bSHarry Wentland struct core_dc *dc, 21344562236bSHarry Wentland int group_index, 21354562236bSHarry Wentland int group_size, 21364562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 21374562236bSHarry Wentland { 21384562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 21394562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 21404562236bSHarry Wentland int i; 21414562236bSHarry Wentland 21424562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 21434562236bSHarry Wentland 21444562236bSHarry Wentland /* Designate a single TG in the group as a master. 21454562236bSHarry Wentland * Since HW doesn't care which one, we always assign 21464562236bSHarry Wentland * the 1st one in the group. */ 21474562236bSHarry Wentland gsl_params.gsl_group = 0; 21484562236bSHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->tg->inst; 21494562236bSHarry Wentland 21504562236bSHarry Wentland for (i = 0; i < group_size; i++) 21514562236bSHarry Wentland grouped_pipes[i]->tg->funcs->setup_global_swap_lock( 21524562236bSHarry Wentland grouped_pipes[i]->tg, &gsl_params); 21534562236bSHarry Wentland 21544562236bSHarry Wentland /* Reset slave controllers on master VSync */ 21554562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 21564562236bSHarry Wentland 21574562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 21584562236bSHarry Wentland grouped_pipes[i]->tg->funcs->enable_reset_trigger( 21594562236bSHarry Wentland grouped_pipes[i]->tg, gsl_params.gsl_group); 21604562236bSHarry Wentland 21614562236bSHarry Wentland 21624562236bSHarry Wentland 21634562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 21644562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 21654562236bSHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->tg); 21664562236bSHarry Wentland /* Regardless of success of the wait above, remove the reset or 21674562236bSHarry Wentland * the driver will start timing out on Display requests. */ 21684562236bSHarry Wentland DC_SYNC_INFO("GSL: disabling trigger-reset.\n"); 21694562236bSHarry Wentland grouped_pipes[i]->tg->funcs->disable_reset_trigger(grouped_pipes[i]->tg); 21704562236bSHarry Wentland } 21714562236bSHarry Wentland 21724562236bSHarry Wentland 21734562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 21744562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 21754562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 21764562236bSHarry Wentland for (i = 0; i < group_size; i++) 21774562236bSHarry Wentland grouped_pipes[i]->tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->tg); 21784562236bSHarry Wentland 21794562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 21804562236bSHarry Wentland } 21814562236bSHarry Wentland 21824562236bSHarry Wentland static void init_hw(struct core_dc *dc) 21834562236bSHarry Wentland { 21844562236bSHarry Wentland int i; 21854562236bSHarry Wentland struct dc_bios *bp; 21864562236bSHarry Wentland struct transform *xfm; 21875e7773a2SAnthony Koo struct abm *abm; 21884562236bSHarry Wentland 21894562236bSHarry Wentland bp = dc->ctx->dc_bios; 21904562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 21914562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 21924562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 21934562236bSHarry Wentland 21944562236bSHarry Wentland dc->hwss.enable_display_power_gating( 21954562236bSHarry Wentland dc, i, bp, 21964562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 21974562236bSHarry Wentland dc->hwss.enable_display_power_gating( 21984562236bSHarry Wentland dc, i, bp, 21994562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 22004562236bSHarry Wentland dc->hwss.enable_display_pipe_clock_gating( 22014562236bSHarry Wentland dc->ctx, 22024562236bSHarry Wentland true); 22034562236bSHarry Wentland } 22044562236bSHarry Wentland 2205e166ad43SJulia Lawall dce_clock_gating_power_up(dc->hwseq, false); 22064562236bSHarry Wentland /***************************************/ 22074562236bSHarry Wentland 22084562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 22094562236bSHarry Wentland /****************************************/ 22104562236bSHarry Wentland /* Power up AND update implementation according to the 22114562236bSHarry Wentland * required signal (which may be different from the 22124562236bSHarry Wentland * default signal on connector). */ 22134562236bSHarry Wentland struct core_link *link = dc->links[i]; 22144562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 22154562236bSHarry Wentland } 22164562236bSHarry Wentland 22174562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 22184562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 22194562236bSHarry Wentland 22204562236bSHarry Wentland tg->funcs->disable_vga(tg); 22214562236bSHarry Wentland 22224562236bSHarry Wentland /* Blank controller using driver code instead of 22234562236bSHarry Wentland * command table. */ 22244562236bSHarry Wentland tg->funcs->set_blank(tg, true); 22254b5e7d62SHersen Wu hwss_wait_for_blank_complete(tg); 22264562236bSHarry Wentland } 22274562236bSHarry Wentland 22284562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 22294562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 22304562236bSHarry Wentland audio->funcs->hw_init(audio); 22314562236bSHarry Wentland } 22325e7773a2SAnthony Koo 22335e7773a2SAnthony Koo abm = dc->res_pool->abm; 22346728b30cSAnthony Koo if (abm != NULL) { 22356728b30cSAnthony Koo abm->funcs->init_backlight(abm); 22365e7773a2SAnthony Koo abm->funcs->abm_init(abm); 22374562236bSHarry Wentland } 22381663ae1cSBhawanpreet Lakha #ifdef ENABLE_FBC 22391663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 22401663ae1cSBhawanpreet Lakha #endif 22416728b30cSAnthony Koo } 22424562236bSHarry Wentland 224328f72454SJordan Lazare void dce110_fill_display_configs( 2244cf437593SDmytro Laktyushkin const struct validate_context *context, 2245cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg) 22464562236bSHarry Wentland { 2247cf437593SDmytro Laktyushkin int j; 2248cf437593SDmytro Laktyushkin int num_cfgs = 0; 2249cf437593SDmytro Laktyushkin 2250cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 2251cf437593SDmytro Laktyushkin int k; 2252cf437593SDmytro Laktyushkin 2253cf437593SDmytro Laktyushkin const struct core_stream *stream = context->streams[j]; 2254cf437593SDmytro Laktyushkin struct dm_pp_single_disp_config *cfg = 2255cf437593SDmytro Laktyushkin &pp_display_cfg->disp_configs[num_cfgs]; 2256cf437593SDmytro Laktyushkin const struct pipe_ctx *pipe_ctx = NULL; 2257cf437593SDmytro Laktyushkin 2258cf437593SDmytro Laktyushkin for (k = 0; k < MAX_PIPES; k++) 2259cf437593SDmytro Laktyushkin if (stream == context->res_ctx.pipe_ctx[k].stream) { 2260cf437593SDmytro Laktyushkin pipe_ctx = &context->res_ctx.pipe_ctx[k]; 2261cf437593SDmytro Laktyushkin break; 22624562236bSHarry Wentland } 22634562236bSHarry Wentland 2264cf437593SDmytro Laktyushkin ASSERT(pipe_ctx != NULL); 2265cf437593SDmytro Laktyushkin 2266cf437593SDmytro Laktyushkin num_cfgs++; 2267cf437593SDmytro Laktyushkin cfg->signal = pipe_ctx->stream->signal; 2268cf437593SDmytro Laktyushkin cfg->pipe_idx = pipe_ctx->pipe_idx; 2269cf437593SDmytro Laktyushkin cfg->src_height = stream->public.src.height; 2270cf437593SDmytro Laktyushkin cfg->src_width = stream->public.src.width; 2271cf437593SDmytro Laktyushkin cfg->ddi_channel_mapping = 2272cf437593SDmytro Laktyushkin stream->sink->link->ddi_channel_mapping.raw; 2273cf437593SDmytro Laktyushkin cfg->transmitter = 2274cf437593SDmytro Laktyushkin stream->sink->link->link_enc->transmitter; 2275cf437593SDmytro Laktyushkin cfg->link_settings.lane_count = 2276cf437593SDmytro Laktyushkin stream->sink->link->public.cur_link_settings.lane_count; 2277cf437593SDmytro Laktyushkin cfg->link_settings.link_rate = 2278cf437593SDmytro Laktyushkin stream->sink->link->public.cur_link_settings.link_rate; 2279cf437593SDmytro Laktyushkin cfg->link_settings.link_spread = 2280cf437593SDmytro Laktyushkin stream->sink->link->public.cur_link_settings.link_spread; 2281cf437593SDmytro Laktyushkin cfg->sym_clock = stream->phy_pix_clk; 2282cf437593SDmytro Laktyushkin /* Round v_refresh*/ 2283cf437593SDmytro Laktyushkin cfg->v_refresh = stream->public.timing.pix_clk_khz * 1000; 2284cf437593SDmytro Laktyushkin cfg->v_refresh /= stream->public.timing.h_total; 2285cf437593SDmytro Laktyushkin cfg->v_refresh = (cfg->v_refresh + stream->public.timing.v_total / 2) 2286cf437593SDmytro Laktyushkin / stream->public.timing.v_total; 2287cf437593SDmytro Laktyushkin } 2288cf437593SDmytro Laktyushkin 2289cf437593SDmytro Laktyushkin pp_display_cfg->display_count = num_cfgs; 2290cf437593SDmytro Laktyushkin } 2291cf437593SDmytro Laktyushkin 229228f72454SJordan Lazare uint32_t dce110_get_min_vblank_time_us(const struct validate_context *context) 2293cf437593SDmytro Laktyushkin { 2294cf437593SDmytro Laktyushkin uint8_t j; 2295cf437593SDmytro Laktyushkin uint32_t min_vertical_blank_time = -1; 2296cf437593SDmytro Laktyushkin 2297cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 2298cf437593SDmytro Laktyushkin const struct dc_stream *stream = &context->streams[j]->public; 2299cf437593SDmytro Laktyushkin uint32_t vertical_blank_in_pixels = 0; 2300cf437593SDmytro Laktyushkin uint32_t vertical_blank_time = 0; 2301cf437593SDmytro Laktyushkin 2302cf437593SDmytro Laktyushkin vertical_blank_in_pixels = stream->timing.h_total * 2303cf437593SDmytro Laktyushkin (stream->timing.v_total 2304cf437593SDmytro Laktyushkin - stream->timing.v_addressable); 2305cf437593SDmytro Laktyushkin 2306cf437593SDmytro Laktyushkin vertical_blank_time = vertical_blank_in_pixels 2307cf437593SDmytro Laktyushkin * 1000 / stream->timing.pix_clk_khz; 2308cf437593SDmytro Laktyushkin 2309cf437593SDmytro Laktyushkin if (min_vertical_blank_time > vertical_blank_time) 2310cf437593SDmytro Laktyushkin min_vertical_blank_time = vertical_blank_time; 2311cf437593SDmytro Laktyushkin } 2312cf437593SDmytro Laktyushkin 2313cf437593SDmytro Laktyushkin return min_vertical_blank_time; 2314cf437593SDmytro Laktyushkin } 2315cf437593SDmytro Laktyushkin 2316cf437593SDmytro Laktyushkin static int determine_sclk_from_bounding_box( 2317cf437593SDmytro Laktyushkin const struct core_dc *dc, 2318cf437593SDmytro Laktyushkin int required_sclk) 23194562236bSHarry Wentland { 23204562236bSHarry Wentland int i; 23214562236bSHarry Wentland 2322cf437593SDmytro Laktyushkin /* 2323cf437593SDmytro Laktyushkin * Some asics do not give us sclk levels, so we just report the actual 2324cf437593SDmytro Laktyushkin * required sclk 2325cf437593SDmytro Laktyushkin */ 2326cf437593SDmytro Laktyushkin if (dc->sclk_lvls.num_levels == 0) 2327cf437593SDmytro Laktyushkin return required_sclk; 23284562236bSHarry Wentland 2329cf437593SDmytro Laktyushkin for (i = 0; i < dc->sclk_lvls.num_levels; i++) { 2330cf437593SDmytro Laktyushkin if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk) 2331cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[i]; 2332cf437593SDmytro Laktyushkin } 2333cf437593SDmytro Laktyushkin /* 2334cf437593SDmytro Laktyushkin * even maximum level could not satisfy requirement, this 2335cf437593SDmytro Laktyushkin * is unexpected at this stage, should have been caught at 2336cf437593SDmytro Laktyushkin * validation time 2337cf437593SDmytro Laktyushkin */ 2338cf437593SDmytro Laktyushkin ASSERT(0); 2339cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1]; 23404562236bSHarry Wentland } 23414562236bSHarry Wentland 2342cf437593SDmytro Laktyushkin static void pplib_apply_display_requirements( 2343cf437593SDmytro Laktyushkin struct core_dc *dc, 2344cf437593SDmytro Laktyushkin struct validate_context *context) 2345cf437593SDmytro Laktyushkin { 2346cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 2347cf437593SDmytro Laktyushkin 2348cf437593SDmytro Laktyushkin pp_display_cfg->all_displays_in_sync = 23499037d802SDmytro Laktyushkin context->bw.dce.all_displays_in_sync; 2350cf437593SDmytro Laktyushkin pp_display_cfg->nb_pstate_switch_disable = 23519037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_enable == false; 2352cf437593SDmytro Laktyushkin pp_display_cfg->cpu_cc6_disable = 23539037d802SDmytro Laktyushkin context->bw.dce.cpuc_state_change_enable == false; 2354cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_disable = 23559037d802SDmytro Laktyushkin context->bw.dce.cpup_state_change_enable == false; 2356cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_separation_time = 23579037d802SDmytro Laktyushkin context->bw.dce.blackout_recovery_time_us; 2358cf437593SDmytro Laktyushkin 23599037d802SDmytro Laktyushkin pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz 2360cf437593SDmytro Laktyushkin / MEMORY_TYPE_MULTIPLIER; 2361cf437593SDmytro Laktyushkin 2362cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( 2363cf437593SDmytro Laktyushkin dc, 23649037d802SDmytro Laktyushkin context->bw.dce.sclk_khz); 2365cf437593SDmytro Laktyushkin 2366cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_deep_sleep_khz 23679037d802SDmytro Laktyushkin = context->bw.dce.sclk_deep_sleep_khz; 2368cf437593SDmytro Laktyushkin 2369cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_us = 237028f72454SJordan Lazare dce110_get_min_vblank_time_us(context); 2371cf437593SDmytro Laktyushkin /* TODO: dce11.2*/ 2372cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; 2373cf437593SDmytro Laktyushkin 23749037d802SDmytro Laktyushkin pp_display_cfg->disp_clk_khz = context->bw.dce.dispclk_khz; 2375cf437593SDmytro Laktyushkin 237628f72454SJordan Lazare dce110_fill_display_configs(context, pp_display_cfg); 2377cf437593SDmytro Laktyushkin 2378cf437593SDmytro Laktyushkin /* TODO: is this still applicable?*/ 2379cf437593SDmytro Laktyushkin if (pp_display_cfg->display_count == 1) { 2380cf437593SDmytro Laktyushkin const struct dc_crtc_timing *timing = 2381cf437593SDmytro Laktyushkin &context->streams[0]->public.timing; 2382cf437593SDmytro Laktyushkin 2383cf437593SDmytro Laktyushkin pp_display_cfg->crtc_index = 2384cf437593SDmytro Laktyushkin pp_display_cfg->disp_configs[0].pipe_idx; 2385cf437593SDmytro Laktyushkin pp_display_cfg->line_time_in_us = timing->h_total * 1000 2386cf437593SDmytro Laktyushkin / timing->pix_clk_khz; 2387cf437593SDmytro Laktyushkin } 2388cf437593SDmytro Laktyushkin 2389cf437593SDmytro Laktyushkin if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( 2390cf437593SDmytro Laktyushkin struct dm_pp_display_configuration)) != 0) 2391cf437593SDmytro Laktyushkin dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); 2392cf437593SDmytro Laktyushkin 2393cf437593SDmytro Laktyushkin dc->prev_display_config = *pp_display_cfg; 2394cf437593SDmytro Laktyushkin } 2395cf437593SDmytro Laktyushkin 2396cf437593SDmytro Laktyushkin static void dce110_set_bandwidth( 2397cf437593SDmytro Laktyushkin struct core_dc *dc, 2398cf437593SDmytro Laktyushkin struct validate_context *context, 2399cf437593SDmytro Laktyushkin bool decrease_allowed) 2400cf437593SDmytro Laktyushkin { 24012180e7ccSDmytro Laktyushkin dce110_set_displaymarks(dc, context); 2402cf437593SDmytro Laktyushkin 24039037d802SDmytro Laktyushkin if (decrease_allowed || context->bw.dce.dispclk_khz > dc->current_context->bw.dce.dispclk_khz) { 2404a2b8659dSTony Cheng dc->res_pool->display_clock->funcs->set_clock( 2405a2b8659dSTony Cheng dc->res_pool->display_clock, 24069037d802SDmytro Laktyushkin context->bw.dce.dispclk_khz * 115 / 100); 24079037d802SDmytro Laktyushkin dc->current_context->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz; 2408cf437593SDmytro Laktyushkin } 2409cf437593SDmytro Laktyushkin 2410cf437593SDmytro Laktyushkin pplib_apply_display_requirements(dc, context); 24114562236bSHarry Wentland } 24124562236bSHarry Wentland 24134562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 24144562236bSHarry Wentland struct core_dc *dc, struct pipe_ctx *pipe_ctx) 24154562236bSHarry Wentland { 24164562236bSHarry Wentland struct mem_input *mi = pipe_ctx->mi; 24174562236bSHarry Wentland struct pipe_ctx *old_pipe = NULL; 24184562236bSHarry Wentland struct core_surface *surface = pipe_ctx->surface; 24194562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 24204562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 24214562236bSHarry Wentland unsigned int i; 24224562236bSHarry Wentland 24234562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 24244562236bSHarry Wentland 24254562236bSHarry Wentland if (dc->current_context) 24264562236bSHarry Wentland old_pipe = &dc->current_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; 24274562236bSHarry Wentland 24284562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 24294562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 24304562236bSHarry Wentland 24314562236bSHarry Wentland dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true); 24324562236bSHarry Wentland 24334562236bSHarry Wentland set_default_colors(pipe_ctx); 24344562236bSHarry Wentland if (pipe_ctx->stream->public.csc_color_matrix.enable_adjustment 24354562236bSHarry Wentland == true) { 24364562236bSHarry Wentland tbl_entry.color_space = 24374562236bSHarry Wentland pipe_ctx->stream->public.output_color_space; 24384562236bSHarry Wentland 24394562236bSHarry Wentland for (i = 0; i < 12; i++) 24404562236bSHarry Wentland tbl_entry.regval[i] = 24414562236bSHarry Wentland pipe_ctx->stream->public.csc_color_matrix.matrix[i]; 24424562236bSHarry Wentland 24434562236bSHarry Wentland pipe_ctx->opp->funcs->opp_set_csc_adjustment 24444562236bSHarry Wentland (pipe_ctx->opp, &tbl_entry); 24454562236bSHarry Wentland } 24464562236bSHarry Wentland 24474562236bSHarry Wentland if (pipe_ctx->stream->public.gamut_remap_matrix.enable_remap == true) { 24484562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 24494562236bSHarry Wentland adjust.temperature_matrix[0] = 24504562236bSHarry Wentland pipe_ctx->stream-> 24514562236bSHarry Wentland public.gamut_remap_matrix.matrix[0]; 24524562236bSHarry Wentland adjust.temperature_matrix[1] = 24534562236bSHarry Wentland pipe_ctx->stream-> 24544562236bSHarry Wentland public.gamut_remap_matrix.matrix[1]; 24554562236bSHarry Wentland adjust.temperature_matrix[2] = 24564562236bSHarry Wentland pipe_ctx->stream-> 24574562236bSHarry Wentland public.gamut_remap_matrix.matrix[2]; 24584562236bSHarry Wentland adjust.temperature_matrix[3] = 24594562236bSHarry Wentland pipe_ctx->stream-> 24604562236bSHarry Wentland public.gamut_remap_matrix.matrix[4]; 24614562236bSHarry Wentland adjust.temperature_matrix[4] = 24624562236bSHarry Wentland pipe_ctx->stream-> 24634562236bSHarry Wentland public.gamut_remap_matrix.matrix[5]; 24644562236bSHarry Wentland adjust.temperature_matrix[5] = 24654562236bSHarry Wentland pipe_ctx->stream-> 24664562236bSHarry Wentland public.gamut_remap_matrix.matrix[6]; 24674562236bSHarry Wentland adjust.temperature_matrix[6] = 24684562236bSHarry Wentland pipe_ctx->stream-> 24694562236bSHarry Wentland public.gamut_remap_matrix.matrix[8]; 24704562236bSHarry Wentland adjust.temperature_matrix[7] = 24714562236bSHarry Wentland pipe_ctx->stream-> 24724562236bSHarry Wentland public.gamut_remap_matrix.matrix[9]; 24734562236bSHarry Wentland adjust.temperature_matrix[8] = 24744562236bSHarry Wentland pipe_ctx->stream-> 24754562236bSHarry Wentland public.gamut_remap_matrix.matrix[10]; 24764562236bSHarry Wentland } 24774562236bSHarry Wentland 24784562236bSHarry Wentland pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust); 24794562236bSHarry Wentland 24804562236bSHarry Wentland pipe_ctx->scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 2481c1473558SAndrey Grodzovsky 24824562236bSHarry Wentland program_scaler(dc, pipe_ctx); 24834562236bSHarry Wentland 24844562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 24854562236bSHarry Wentland mi, 24864562236bSHarry Wentland surface->public.format, 24874562236bSHarry Wentland &surface->public.tiling_info, 24884562236bSHarry Wentland &surface->public.plane_size, 24894562236bSHarry Wentland surface->public.rotation, 2490624d7c47SYongqiang Sun NULL, 24914b28b76bSDmytro Laktyushkin false); 24924b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 24934b28b76bSDmytro Laktyushkin mi->funcs->set_blank(mi, pipe_ctx->surface->public.visible); 24944562236bSHarry Wentland 24954562236bSHarry Wentland if (dc->public.config.gpu_vm_support) 24964562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 24974562236bSHarry Wentland pipe_ctx->mi, 24984562236bSHarry Wentland surface->public.format, 24994562236bSHarry Wentland &surface->public.tiling_info, 25004562236bSHarry Wentland surface->public.rotation); 25014562236bSHarry Wentland 25024562236bSHarry Wentland dm_logger_write(dc->ctx->logger, LOG_SURFACE, 25034562236bSHarry Wentland "Pipe:%d 0x%x: addr hi:0x%x, " 25044562236bSHarry Wentland "addr low:0x%x, " 25054562236bSHarry Wentland "src: %d, %d, %d," 25064562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 25074562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 25084562236bSHarry Wentland pipe_ctx->pipe_idx, 25094562236bSHarry Wentland pipe_ctx->surface, 25104562236bSHarry Wentland pipe_ctx->surface->public.address.grph.addr.high_part, 25114562236bSHarry Wentland pipe_ctx->surface->public.address.grph.addr.low_part, 25124562236bSHarry Wentland pipe_ctx->surface->public.src_rect.x, 25134562236bSHarry Wentland pipe_ctx->surface->public.src_rect.y, 25144562236bSHarry Wentland pipe_ctx->surface->public.src_rect.width, 25154562236bSHarry Wentland pipe_ctx->surface->public.src_rect.height, 25164562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.x, 25174562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.y, 25184562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.width, 25194562236bSHarry Wentland pipe_ctx->surface->public.dst_rect.height, 25204562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.x, 25214562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.y, 25224562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.width, 25234562236bSHarry Wentland pipe_ctx->surface->public.clip_rect.height); 25244562236bSHarry Wentland 25254562236bSHarry Wentland dm_logger_write(dc->ctx->logger, LOG_SURFACE, 25264562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 25274562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 25284562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 25294562236bSHarry Wentland pipe_ctx->pipe_idx, 25304562236bSHarry Wentland pipe_ctx->scl_data.viewport.width, 25314562236bSHarry Wentland pipe_ctx->scl_data.viewport.height, 25324562236bSHarry Wentland pipe_ctx->scl_data.viewport.x, 25334562236bSHarry Wentland pipe_ctx->scl_data.viewport.y, 25344562236bSHarry Wentland pipe_ctx->scl_data.recout.width, 25354562236bSHarry Wentland pipe_ctx->scl_data.recout.height, 25364562236bSHarry Wentland pipe_ctx->scl_data.recout.x, 25374562236bSHarry Wentland pipe_ctx->scl_data.recout.y); 25384562236bSHarry Wentland } 25394562236bSHarry Wentland 25404562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 25414562236bSHarry Wentland struct core_dc *dc, 25424562236bSHarry Wentland struct core_surface *surface, 25434562236bSHarry Wentland struct validate_context *context) 25444562236bSHarry Wentland { 25454562236bSHarry Wentland int i; 25464562236bSHarry Wentland 25474562236bSHarry Wentland /* TODO remove when removing the surface reset workaroud*/ 25484562236bSHarry Wentland if (!surface) 25494562236bSHarry Wentland return; 25504562236bSHarry Wentland 2551a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 25524562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 25534562236bSHarry Wentland 25544562236bSHarry Wentland if (pipe_ctx->surface != surface) 25554562236bSHarry Wentland continue; 25564562236bSHarry Wentland 25574562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 2558b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 25594562236bSHarry Wentland 25604562236bSHarry Wentland } 25614562236bSHarry Wentland } 25624562236bSHarry Wentland 2563cfe4645eSDmytro Laktyushkin static void dce110_power_down_fe(struct core_dc *dc, int fe_idx) 25644562236bSHarry Wentland { 25657950f0f9SDmytro Laktyushkin /* Do not power down fe when stream is active on dce*/ 2566cfe4645eSDmytro Laktyushkin if (dc->current_context->res_ctx.pipe_ctx[fe_idx].stream) 25674562236bSHarry Wentland return; 25684562236bSHarry Wentland 25694562236bSHarry Wentland dc->hwss.enable_display_power_gating( 2570cfe4645eSDmytro Laktyushkin dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 2571cfe4645eSDmytro Laktyushkin 2572cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 2573cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]); 25744562236bSHarry Wentland } 25754562236bSHarry Wentland 25764562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 25771bf56e62SZeyu Fan .program_gamut_remap = program_gamut_remap, 25784562236bSHarry Wentland .init_hw = init_hw, 25794562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 25804562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 25814562236bSHarry Wentland .set_plane_config = set_plane_config, 25824562236bSHarry Wentland .update_plane_addr = update_plane_addr, 25834562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 2584d7194cf6SAric Cyr .set_input_transfer_func = dce110_set_input_transfer_func, 258590e508baSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 25864562236bSHarry Wentland .power_down = dce110_power_down, 25874562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 25884562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 25894562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 25904562236bSHarry Wentland .enable_stream = dce110_enable_stream, 25914562236bSHarry Wentland .disable_stream = dce110_disable_stream, 25924562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 25934562236bSHarry Wentland .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 25944562236bSHarry Wentland .enable_display_power_gating = dce110_enable_display_power_gating, 25954562236bSHarry Wentland .power_down_front_end = dce110_power_down_fe, 25964562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 25974562236bSHarry Wentland .set_bandwidth = dce110_set_bandwidth, 25984562236bSHarry Wentland .set_drr = set_drr, 259972ada5f7SEric Cook .get_position = get_position, 26004562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 26014562236bSHarry Wentland .reset_hw_ctx_wrap = reset_hw_ctx_wrap, 26024b5e7d62SHersen Wu .prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg, 26037f5c22d1SVitaly Prosyak .setup_stereo = NULL 26044562236bSHarry Wentland }; 26054562236bSHarry Wentland 26064562236bSHarry Wentland bool dce110_hw_sequencer_construct(struct core_dc *dc) 26074562236bSHarry Wentland { 26084562236bSHarry Wentland dc->hwss = dce110_funcs; 26094562236bSHarry Wentland 26104562236bSHarry Wentland return true; 26114562236bSHarry Wentland } 26124562236bSHarry Wentland 2613