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" 5208b16886SZeyu Fan #include "reg_helper.h" 534562236bSHarry Wentland 544562236bSHarry Wentland /* include DCE11 register header files */ 554562236bSHarry Wentland #include "dce/dce_11_0_d.h" 564562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 57e266fdf6SVitaly Prosyak #include "custom_float.h" 584562236bSHarry Wentland 594562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 604562236bSHarry Wentland uint32_t crtc; 614562236bSHarry Wentland }; 624562236bSHarry Wentland 634562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 644562236bSHarry Wentland { 654562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 664562236bSHarry Wentland }, 674562236bSHarry Wentland { 684562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 694562236bSHarry Wentland }, 704562236bSHarry Wentland { 714562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 724562236bSHarry Wentland }, 734562236bSHarry Wentland { 744562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 754562236bSHarry Wentland } 764562236bSHarry Wentland }; 774562236bSHarry Wentland 784562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 794562236bSHarry Wentland (reg + reg_offsets[id].blnd) 804562236bSHarry Wentland 814562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 824562236bSHarry Wentland (reg + reg_offsets[id].crtc) 834562236bSHarry Wentland 844562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 854562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 864562236bSHarry Wentland 874562236bSHarry Wentland /******************************************************************************* 884562236bSHarry Wentland * Private definitions 894562236bSHarry Wentland ******************************************************************************/ 904562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 914562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 924562236bSHarry Wentland { 934562236bSHarry Wentland uint32_t addr; 944562236bSHarry Wentland uint32_t value = 0; 954562236bSHarry Wentland uint32_t chunk_int = 0; 964562236bSHarry Wentland uint32_t chunk_mul = 0; 974562236bSHarry Wentland 984562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 994562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1004562236bSHarry Wentland 1014562236bSHarry Wentland set_reg_field_value( 1024562236bSHarry Wentland value, 1034562236bSHarry Wentland 0, 1044562236bSHarry Wentland DVMM_PTE_CONTROL, 1054562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1064562236bSHarry Wentland 1074562236bSHarry Wentland set_reg_field_value( 1084562236bSHarry Wentland value, 1094562236bSHarry Wentland 1, 1104562236bSHarry Wentland DVMM_PTE_CONTROL, 1114562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1124562236bSHarry Wentland 1134562236bSHarry Wentland set_reg_field_value( 1144562236bSHarry Wentland value, 1154562236bSHarry Wentland 1, 1164562236bSHarry Wentland DVMM_PTE_CONTROL, 1174562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1184562236bSHarry Wentland 1194562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1204562236bSHarry Wentland 1214562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1224562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1234562236bSHarry Wentland 1244562236bSHarry Wentland chunk_int = get_reg_field_value( 1254562236bSHarry Wentland value, 1264562236bSHarry Wentland DVMM_PTE_REQ, 1274562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1284562236bSHarry Wentland 1294562236bSHarry Wentland chunk_mul = get_reg_field_value( 1304562236bSHarry Wentland value, 1314562236bSHarry Wentland DVMM_PTE_REQ, 1324562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1334562236bSHarry Wentland 1344562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1354562236bSHarry Wentland 1364562236bSHarry Wentland set_reg_field_value( 1374562236bSHarry Wentland value, 1384562236bSHarry Wentland 255, 1394562236bSHarry Wentland DVMM_PTE_REQ, 1404562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1414562236bSHarry Wentland 1424562236bSHarry Wentland set_reg_field_value( 1434562236bSHarry Wentland value, 1444562236bSHarry Wentland 4, 1454562236bSHarry Wentland DVMM_PTE_REQ, 1464562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1474562236bSHarry Wentland 1484562236bSHarry Wentland set_reg_field_value( 1494562236bSHarry Wentland value, 1504562236bSHarry Wentland 4, 1514562236bSHarry Wentland DVMM_PTE_REQ, 1524562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1534562236bSHarry Wentland 1544562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1554562236bSHarry Wentland } 1564562236bSHarry Wentland } 1574562236bSHarry Wentland /**************************************************************************/ 1584562236bSHarry Wentland 1594562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1604562236bSHarry Wentland struct dc_context *ctx, 1614562236bSHarry Wentland bool clock_gating) 1624562236bSHarry Wentland { 1634562236bSHarry Wentland /*TODO*/ 1644562236bSHarry Wentland } 1654562236bSHarry Wentland 1664562236bSHarry Wentland static bool dce110_enable_display_power_gating( 167fb3466a4SBhawanpreet Lakha struct dc *dc, 1684562236bSHarry Wentland uint8_t controller_id, 1694562236bSHarry Wentland struct dc_bios *dcb, 1704562236bSHarry Wentland enum pipe_gating_control power_gating) 1714562236bSHarry Wentland { 1724562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 1734562236bSHarry Wentland enum bp_pipe_control_action cntl; 1744562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 1754562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 1764562236bSHarry Wentland 1774562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 1784562236bSHarry Wentland return true; 1794562236bSHarry Wentland 1804562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 1814562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 1824562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 1834562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 1844562236bSHarry Wentland else 1854562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 1864562236bSHarry Wentland 1874562236bSHarry Wentland if (controller_id == underlay_idx) 1884562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 1894562236bSHarry Wentland 1904562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){ 1914562236bSHarry Wentland 1924562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 1934562236bSHarry Wentland dcb, controller_id + 1, cntl); 1944562236bSHarry Wentland 1954562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 1964562236bSHarry Wentland * by default when command table is called 1974562236bSHarry Wentland * 1984562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 1994562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 2004562236bSHarry Wentland * than 3. 2014562236bSHarry Wentland */ 2024562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 2034562236bSHarry Wentland dm_write_reg(ctx, 2044562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 2054562236bSHarry Wentland 0); 2064562236bSHarry Wentland } 2074562236bSHarry Wentland 2084562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2094562236bSHarry Wentland dce110_init_pte(ctx); 2104562236bSHarry Wentland 2114562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2124562236bSHarry Wentland return true; 2134562236bSHarry Wentland else 2144562236bSHarry Wentland return false; 2154562236bSHarry Wentland } 2164562236bSHarry Wentland 2174562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2183be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2194562236bSHarry Wentland { 2204562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2214562236bSHarry Wentland 2223be5262eSHarry Wentland switch (plane_state->format) { 2234562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2248693049aSTony Cheng case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 2254562236bSHarry Wentland prescale_params->scale = 0x2020; 2264562236bSHarry Wentland break; 2274562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2284562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2294562236bSHarry Wentland prescale_params->scale = 0x2008; 2304562236bSHarry Wentland break; 2314562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 2324562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2334562236bSHarry Wentland prescale_params->scale = 0x2000; 2344562236bSHarry Wentland break; 2354562236bSHarry Wentland default: 2364562236bSHarry Wentland ASSERT(false); 237d7194cf6SAric Cyr break; 2384562236bSHarry Wentland } 2394562236bSHarry Wentland } 2404562236bSHarry Wentland 241d7194cf6SAric Cyr static bool dce110_set_input_transfer_func( 242fb735a9fSAnthony Koo struct pipe_ctx *pipe_ctx, 2433be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2444562236bSHarry Wentland { 24586a66c4eSHarry Wentland struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 2467b0c470fSLeo (Sunpeng) Li const struct dc_transfer_func *tf = NULL; 24790e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 24890e508baSAnthony Koo bool result = true; 24990e508baSAnthony Koo 25090e508baSAnthony Koo if (ipp == NULL) 25190e508baSAnthony Koo return false; 25290e508baSAnthony Koo 2533be5262eSHarry Wentland if (plane_state->in_transfer_func) 2543be5262eSHarry Wentland tf = plane_state->in_transfer_func; 25590e508baSAnthony Koo 2563be5262eSHarry Wentland build_prescale_params(&prescale_params, plane_state); 25790e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 25890e508baSAnthony Koo 2593be5262eSHarry Wentland if (plane_state->gamma_correction && dce_use_lut(plane_state)) 2603be5262eSHarry Wentland ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction); 261d7194cf6SAric Cyr 26290e508baSAnthony Koo if (tf == NULL) { 26390e508baSAnthony Koo /* Default case if no input transfer function specified */ 26490e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 265306dadf0SAmy Zhang IPP_DEGAMMA_MODE_HW_sRGB); 2667b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_PREDEFINED) { 2677b0c470fSLeo (Sunpeng) Li switch (tf->tf) { 26890e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 26990e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 27090e508baSAnthony Koo IPP_DEGAMMA_MODE_HW_sRGB); 27190e508baSAnthony Koo break; 27290e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 27390e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 27490e508baSAnthony Koo IPP_DEGAMMA_MODE_HW_xvYCC); 27590e508baSAnthony Koo break; 27690e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 27790e508baSAnthony Koo ipp->funcs->ipp_set_degamma(ipp, 27890e508baSAnthony Koo IPP_DEGAMMA_MODE_BYPASS); 27990e508baSAnthony Koo break; 28090e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 28190e508baSAnthony Koo result = false; 28290e508baSAnthony Koo break; 28390e508baSAnthony Koo default: 28490e508baSAnthony Koo result = false; 285d7194cf6SAric Cyr break; 28690e508baSAnthony Koo } 2877b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_BYPASS) { 28870063a59SAmy Zhang ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 28990e508baSAnthony Koo } else { 29090e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 29190e508baSAnthony Koo result = false; 29290e508baSAnthony Koo } 29390e508baSAnthony Koo 29490e508baSAnthony Koo return result; 29590e508baSAnthony Koo } 29690e508baSAnthony Koo 297fcd2f4bfSAmy Zhang static bool convert_to_custom_float( 298fcd2f4bfSAmy Zhang struct pwl_result_data *rgb_resulted, 299fcd2f4bfSAmy Zhang struct curve_points *arr_points, 300fcd2f4bfSAmy Zhang uint32_t hw_points_num) 301fcd2f4bfSAmy Zhang { 302fcd2f4bfSAmy Zhang struct custom_float_format fmt; 303fcd2f4bfSAmy Zhang 304fcd2f4bfSAmy Zhang struct pwl_result_data *rgb = rgb_resulted; 305fcd2f4bfSAmy Zhang 306fcd2f4bfSAmy Zhang uint32_t i = 0; 307fcd2f4bfSAmy Zhang 308fcd2f4bfSAmy Zhang fmt.exponenta_bits = 6; 309fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 310fcd2f4bfSAmy Zhang fmt.sign = true; 311fcd2f4bfSAmy Zhang 312fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 313fcd2f4bfSAmy Zhang arr_points[0].x, 314fcd2f4bfSAmy Zhang &fmt, 315fcd2f4bfSAmy Zhang &arr_points[0].custom_float_x)) { 316fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 317fcd2f4bfSAmy Zhang return false; 318fcd2f4bfSAmy Zhang } 319fcd2f4bfSAmy Zhang 320fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 321fcd2f4bfSAmy Zhang arr_points[0].offset, 322fcd2f4bfSAmy Zhang &fmt, 323fcd2f4bfSAmy Zhang &arr_points[0].custom_float_offset)) { 324fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 325fcd2f4bfSAmy Zhang return false; 326fcd2f4bfSAmy Zhang } 327fcd2f4bfSAmy Zhang 328fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 329fcd2f4bfSAmy Zhang arr_points[0].slope, 330fcd2f4bfSAmy Zhang &fmt, 331fcd2f4bfSAmy Zhang &arr_points[0].custom_float_slope)) { 332fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 333fcd2f4bfSAmy Zhang return false; 334fcd2f4bfSAmy Zhang } 335fcd2f4bfSAmy Zhang 336fcd2f4bfSAmy Zhang fmt.mantissa_bits = 10; 337fcd2f4bfSAmy Zhang fmt.sign = false; 338fcd2f4bfSAmy Zhang 339fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 340fcd2f4bfSAmy Zhang arr_points[1].x, 341fcd2f4bfSAmy Zhang &fmt, 342fcd2f4bfSAmy Zhang &arr_points[1].custom_float_x)) { 343fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 344fcd2f4bfSAmy Zhang return false; 345fcd2f4bfSAmy Zhang } 346fcd2f4bfSAmy Zhang 347fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 348fcd2f4bfSAmy Zhang arr_points[1].y, 349fcd2f4bfSAmy Zhang &fmt, 350fcd2f4bfSAmy Zhang &arr_points[1].custom_float_y)) { 351fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 352fcd2f4bfSAmy Zhang return false; 353fcd2f4bfSAmy Zhang } 354fcd2f4bfSAmy Zhang 355fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 356fcd2f4bfSAmy Zhang arr_points[2].slope, 357fcd2f4bfSAmy Zhang &fmt, 358fcd2f4bfSAmy Zhang &arr_points[2].custom_float_slope)) { 359fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 360fcd2f4bfSAmy Zhang return false; 361fcd2f4bfSAmy Zhang } 362fcd2f4bfSAmy Zhang 363fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 364fcd2f4bfSAmy Zhang fmt.sign = true; 365fcd2f4bfSAmy Zhang 366fcd2f4bfSAmy Zhang while (i != hw_points_num) { 367fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 368fcd2f4bfSAmy Zhang rgb->red, 369fcd2f4bfSAmy Zhang &fmt, 370fcd2f4bfSAmy Zhang &rgb->red_reg)) { 371fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 372fcd2f4bfSAmy Zhang return false; 373fcd2f4bfSAmy Zhang } 374fcd2f4bfSAmy Zhang 375fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 376fcd2f4bfSAmy Zhang rgb->green, 377fcd2f4bfSAmy Zhang &fmt, 378fcd2f4bfSAmy Zhang &rgb->green_reg)) { 379fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 380fcd2f4bfSAmy Zhang return false; 381fcd2f4bfSAmy Zhang } 382fcd2f4bfSAmy Zhang 383fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 384fcd2f4bfSAmy Zhang rgb->blue, 385fcd2f4bfSAmy Zhang &fmt, 386fcd2f4bfSAmy Zhang &rgb->blue_reg)) { 387fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 388fcd2f4bfSAmy Zhang return false; 389fcd2f4bfSAmy Zhang } 390fcd2f4bfSAmy Zhang 391fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 392fcd2f4bfSAmy Zhang rgb->delta_red, 393fcd2f4bfSAmy Zhang &fmt, 394fcd2f4bfSAmy Zhang &rgb->delta_red_reg)) { 395fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 396fcd2f4bfSAmy Zhang return false; 397fcd2f4bfSAmy Zhang } 398fcd2f4bfSAmy Zhang 399fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 400fcd2f4bfSAmy Zhang rgb->delta_green, 401fcd2f4bfSAmy Zhang &fmt, 402fcd2f4bfSAmy Zhang &rgb->delta_green_reg)) { 403fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 404fcd2f4bfSAmy Zhang return false; 405fcd2f4bfSAmy Zhang } 406fcd2f4bfSAmy Zhang 407fcd2f4bfSAmy Zhang if (!convert_to_custom_float_format( 408fcd2f4bfSAmy Zhang rgb->delta_blue, 409fcd2f4bfSAmy Zhang &fmt, 410fcd2f4bfSAmy Zhang &rgb->delta_blue_reg)) { 411fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 412fcd2f4bfSAmy Zhang return false; 413fcd2f4bfSAmy Zhang } 414fcd2f4bfSAmy Zhang 415fcd2f4bfSAmy Zhang ++rgb; 416fcd2f4bfSAmy Zhang ++i; 417fcd2f4bfSAmy Zhang } 418fcd2f4bfSAmy Zhang 419fcd2f4bfSAmy Zhang return true; 420fcd2f4bfSAmy Zhang } 421fcd2f4bfSAmy Zhang 422e266fdf6SVitaly Prosyak static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func 423fcd2f4bfSAmy Zhang *output_tf, struct pwl_params *regamma_params) 424fcd2f4bfSAmy Zhang { 42523ae4f8eSAmy Zhang struct curve_points *arr_points; 42623ae4f8eSAmy Zhang struct pwl_result_data *rgb_resulted; 42723ae4f8eSAmy Zhang struct pwl_result_data *rgb; 42823ae4f8eSAmy Zhang struct pwl_result_data *rgb_plus_1; 429fcd2f4bfSAmy Zhang struct fixed31_32 y_r; 430fcd2f4bfSAmy Zhang struct fixed31_32 y_g; 431fcd2f4bfSAmy Zhang struct fixed31_32 y_b; 432fcd2f4bfSAmy Zhang struct fixed31_32 y1_min; 433fcd2f4bfSAmy Zhang struct fixed31_32 y3_max; 434fcd2f4bfSAmy Zhang 435fcd2f4bfSAmy Zhang int32_t segment_start, segment_end; 43623ae4f8eSAmy Zhang uint32_t i, j, k, seg_distr[16], increment, start_index, hw_points; 43723ae4f8eSAmy Zhang 43870063a59SAmy Zhang if (output_tf == NULL || regamma_params == NULL || 43970063a59SAmy Zhang output_tf->type == TF_TYPE_BYPASS) 44023ae4f8eSAmy Zhang return false; 44123ae4f8eSAmy Zhang 44223ae4f8eSAmy Zhang arr_points = regamma_params->arr_points; 44323ae4f8eSAmy Zhang rgb_resulted = regamma_params->rgb_resulted; 44423ae4f8eSAmy Zhang hw_points = 0; 445fcd2f4bfSAmy Zhang 446fcd2f4bfSAmy Zhang memset(regamma_params, 0, sizeof(struct pwl_params)); 447fcd2f4bfSAmy Zhang 448fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 449534db198SAmy Zhang /* 16 segments 450fcd2f4bfSAmy Zhang * segments are from 2^-11 to 2^5 451fcd2f4bfSAmy Zhang */ 452fcd2f4bfSAmy Zhang segment_start = -11; 453fcd2f4bfSAmy Zhang segment_end = 5; 454fcd2f4bfSAmy Zhang 455534db198SAmy Zhang seg_distr[0] = 2; 456534db198SAmy Zhang seg_distr[1] = 2; 457534db198SAmy Zhang seg_distr[2] = 2; 458534db198SAmy Zhang seg_distr[3] = 2; 459534db198SAmy Zhang seg_distr[4] = 2; 460534db198SAmy Zhang seg_distr[5] = 2; 461534db198SAmy Zhang seg_distr[6] = 3; 462534db198SAmy Zhang seg_distr[7] = 4; 463534db198SAmy Zhang seg_distr[8] = 4; 464534db198SAmy Zhang seg_distr[9] = 4; 465534db198SAmy Zhang seg_distr[10] = 4; 466534db198SAmy Zhang seg_distr[11] = 5; 467534db198SAmy Zhang seg_distr[12] = 5; 468534db198SAmy Zhang seg_distr[13] = 5; 469534db198SAmy Zhang seg_distr[14] = 5; 470534db198SAmy Zhang seg_distr[15] = 5; 471534db198SAmy Zhang 472fcd2f4bfSAmy Zhang } else { 473534db198SAmy Zhang /* 10 segments 474fcd2f4bfSAmy Zhang * segment is from 2^-10 to 2^0 475fcd2f4bfSAmy Zhang */ 476fcd2f4bfSAmy Zhang segment_start = -10; 477fcd2f4bfSAmy Zhang segment_end = 0; 478534db198SAmy Zhang 479534db198SAmy Zhang seg_distr[0] = 3; 480534db198SAmy Zhang seg_distr[1] = 4; 481534db198SAmy Zhang seg_distr[2] = 4; 482534db198SAmy Zhang seg_distr[3] = 4; 483534db198SAmy Zhang seg_distr[4] = 4; 484534db198SAmy Zhang seg_distr[5] = 4; 485534db198SAmy Zhang seg_distr[6] = 4; 486534db198SAmy Zhang seg_distr[7] = 4; 487534db198SAmy Zhang seg_distr[8] = 5; 488534db198SAmy Zhang seg_distr[9] = 5; 489534db198SAmy Zhang seg_distr[10] = -1; 490534db198SAmy Zhang seg_distr[11] = -1; 491534db198SAmy Zhang seg_distr[12] = -1; 492534db198SAmy Zhang seg_distr[13] = -1; 493534db198SAmy Zhang seg_distr[14] = -1; 494534db198SAmy Zhang seg_distr[15] = -1; 495fcd2f4bfSAmy Zhang } 496fcd2f4bfSAmy Zhang 497534db198SAmy Zhang for (k = 0; k < 16; k++) { 498534db198SAmy Zhang if (seg_distr[k] != -1) 499534db198SAmy Zhang hw_points += (1 << seg_distr[k]); 500534db198SAmy Zhang } 501534db198SAmy Zhang 502fcd2f4bfSAmy Zhang j = 0; 503534db198SAmy Zhang for (k = 0; k < (segment_end - segment_start); k++) { 504534db198SAmy Zhang increment = 32 / (1 << seg_distr[k]); 505534db198SAmy Zhang start_index = (segment_start + k + 25) * 32; 506534db198SAmy Zhang for (i = start_index; i < start_index + 32; i += increment) { 507534db198SAmy Zhang if (j == hw_points - 1) 508fcd2f4bfSAmy Zhang break; 509fcd2f4bfSAmy Zhang rgb_resulted[j].red = output_tf->tf_pts.red[i]; 510fcd2f4bfSAmy Zhang rgb_resulted[j].green = output_tf->tf_pts.green[i]; 511fcd2f4bfSAmy Zhang rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 512fcd2f4bfSAmy Zhang j++; 513fcd2f4bfSAmy Zhang } 514534db198SAmy Zhang } 515534db198SAmy Zhang 516534db198SAmy Zhang /* last point */ 517534db198SAmy Zhang start_index = (segment_end + 25) * 32; 518534db198SAmy Zhang rgb_resulted[hw_points - 1].red = 519534db198SAmy Zhang output_tf->tf_pts.red[start_index]; 520534db198SAmy Zhang rgb_resulted[hw_points - 1].green = 521534db198SAmy Zhang output_tf->tf_pts.green[start_index]; 522534db198SAmy Zhang rgb_resulted[hw_points - 1].blue = 523534db198SAmy Zhang output_tf->tf_pts.blue[start_index]; 524fcd2f4bfSAmy Zhang 525fcd2f4bfSAmy Zhang arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 526fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(segment_start)); 527fcd2f4bfSAmy Zhang arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 528fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(segment_end)); 529fcd2f4bfSAmy Zhang arr_points[2].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 530fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(segment_end)); 531fcd2f4bfSAmy Zhang 532fcd2f4bfSAmy Zhang y_r = rgb_resulted[0].red; 533fcd2f4bfSAmy Zhang y_g = rgb_resulted[0].green; 534fcd2f4bfSAmy Zhang y_b = rgb_resulted[0].blue; 535fcd2f4bfSAmy Zhang 536fcd2f4bfSAmy Zhang y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); 537fcd2f4bfSAmy Zhang 538fcd2f4bfSAmy Zhang arr_points[0].y = y1_min; 539fcd2f4bfSAmy Zhang arr_points[0].slope = dal_fixed31_32_div( 540fcd2f4bfSAmy Zhang arr_points[0].y, 541fcd2f4bfSAmy Zhang arr_points[0].x); 542fcd2f4bfSAmy Zhang 543fcd2f4bfSAmy Zhang y_r = rgb_resulted[hw_points - 1].red; 544fcd2f4bfSAmy Zhang y_g = rgb_resulted[hw_points - 1].green; 545fcd2f4bfSAmy Zhang y_b = rgb_resulted[hw_points - 1].blue; 546fcd2f4bfSAmy Zhang 547fcd2f4bfSAmy Zhang /* see comment above, m_arrPoints[1].y should be the Y value for the 548fcd2f4bfSAmy Zhang * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 549fcd2f4bfSAmy Zhang */ 550fcd2f4bfSAmy Zhang y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); 551fcd2f4bfSAmy Zhang 552fcd2f4bfSAmy Zhang arr_points[1].y = y3_max; 553fcd2f4bfSAmy Zhang arr_points[2].y = y3_max; 554fcd2f4bfSAmy Zhang 555fcd2f4bfSAmy Zhang arr_points[1].slope = dal_fixed31_32_zero; 556fcd2f4bfSAmy Zhang arr_points[2].slope = dal_fixed31_32_zero; 557fcd2f4bfSAmy Zhang 558fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 559fcd2f4bfSAmy Zhang /* for PQ, we want to have a straight line from last HW X point, 560fcd2f4bfSAmy Zhang * and the slope to be such that we hit 1.0 at 10000 nits. 561fcd2f4bfSAmy Zhang */ 562fcd2f4bfSAmy Zhang const struct fixed31_32 end_value = 563fcd2f4bfSAmy Zhang dal_fixed31_32_from_int(125); 564fcd2f4bfSAmy Zhang 565fcd2f4bfSAmy Zhang arr_points[1].slope = dal_fixed31_32_div( 566fcd2f4bfSAmy Zhang dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 567fcd2f4bfSAmy Zhang dal_fixed31_32_sub(end_value, arr_points[1].x)); 568fcd2f4bfSAmy Zhang arr_points[2].slope = dal_fixed31_32_div( 569fcd2f4bfSAmy Zhang dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 570fcd2f4bfSAmy Zhang dal_fixed31_32_sub(end_value, arr_points[1].x)); 571fcd2f4bfSAmy Zhang } 572fcd2f4bfSAmy Zhang 573fcd2f4bfSAmy Zhang regamma_params->hw_points_num = hw_points; 574fcd2f4bfSAmy Zhang 575534db198SAmy Zhang i = 1; 576534db198SAmy Zhang for (k = 0; k < 16 && i < 16; k++) { 577534db198SAmy Zhang if (seg_distr[k] != -1) { 578534db198SAmy Zhang regamma_params->arr_curve_points[k].segments_num = 579534db198SAmy Zhang seg_distr[k]; 580534db198SAmy Zhang regamma_params->arr_curve_points[i].offset = 581534db198SAmy Zhang regamma_params->arr_curve_points[k]. 582534db198SAmy Zhang offset + (1 << seg_distr[k]); 583fcd2f4bfSAmy Zhang } 584534db198SAmy Zhang i++; 585534db198SAmy Zhang } 586534db198SAmy Zhang 587534db198SAmy Zhang if (seg_distr[k] != -1) 588534db198SAmy Zhang regamma_params->arr_curve_points[k].segments_num = 589534db198SAmy Zhang seg_distr[k]; 590fcd2f4bfSAmy Zhang 59123ae4f8eSAmy Zhang rgb = rgb_resulted; 59223ae4f8eSAmy Zhang rgb_plus_1 = rgb_resulted + 1; 593fcd2f4bfSAmy Zhang 594fcd2f4bfSAmy Zhang i = 1; 595fcd2f4bfSAmy Zhang 596fcd2f4bfSAmy Zhang while (i != hw_points + 1) { 597fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) 598fcd2f4bfSAmy Zhang rgb_plus_1->red = rgb->red; 599fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) 600fcd2f4bfSAmy Zhang rgb_plus_1->green = rgb->green; 601fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) 602fcd2f4bfSAmy Zhang rgb_plus_1->blue = rgb->blue; 603fcd2f4bfSAmy Zhang 604fcd2f4bfSAmy Zhang rgb->delta_red = dal_fixed31_32_sub( 605fcd2f4bfSAmy Zhang rgb_plus_1->red, 606fcd2f4bfSAmy Zhang rgb->red); 607fcd2f4bfSAmy Zhang rgb->delta_green = dal_fixed31_32_sub( 608fcd2f4bfSAmy Zhang rgb_plus_1->green, 609fcd2f4bfSAmy Zhang rgb->green); 610fcd2f4bfSAmy Zhang rgb->delta_blue = dal_fixed31_32_sub( 611fcd2f4bfSAmy Zhang rgb_plus_1->blue, 612fcd2f4bfSAmy Zhang rgb->blue); 613fcd2f4bfSAmy Zhang 614fcd2f4bfSAmy Zhang ++rgb_plus_1; 615fcd2f4bfSAmy Zhang ++rgb; 616fcd2f4bfSAmy Zhang ++i; 617fcd2f4bfSAmy Zhang } 618fcd2f4bfSAmy Zhang 619fcd2f4bfSAmy Zhang convert_to_custom_float(rgb_resulted, arr_points, hw_points); 620fcd2f4bfSAmy Zhang 621fcd2f4bfSAmy Zhang return true; 622fcd2f4bfSAmy Zhang } 623fcd2f4bfSAmy Zhang 62490e508baSAnthony Koo static bool dce110_set_output_transfer_func( 62590e508baSAnthony Koo struct pipe_ctx *pipe_ctx, 6260971c40eSHarry Wentland const struct dc_stream_state *stream) 62790e508baSAnthony Koo { 62886a66c4eSHarry Wentland struct transform *xfm = pipe_ctx->plane_res.xfm; 6294562236bSHarry Wentland 6307a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, true); 6317a09f5beSYue Hin Lau xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 6324562236bSHarry Wentland 6334fa086b9SLeo (Sunpeng) Li if (stream->out_transfer_func && 6344fa086b9SLeo (Sunpeng) Li stream->out_transfer_func->type == 635fcd2f4bfSAmy Zhang TF_TYPE_PREDEFINED && 6364fa086b9SLeo (Sunpeng) Li stream->out_transfer_func->tf == 637fcd2f4bfSAmy Zhang TRANSFER_FUNCTION_SRGB) { 6387a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 639fcd2f4bfSAmy Zhang } else if (dce110_translate_regamma_to_hw_format( 6407a09f5beSYue Hin Lau stream->out_transfer_func, &xfm->regamma_params)) { 6417a09f5beSYue Hin Lau xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 6427a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 6434562236bSHarry Wentland } else { 6447a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 6454562236bSHarry Wentland } 6464562236bSHarry Wentland 6477a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, false); 6484562236bSHarry Wentland 649cc0cb445SLeon Elazar return true; 6504562236bSHarry Wentland } 6514562236bSHarry Wentland 6524562236bSHarry Wentland static enum dc_status bios_parser_crtc_source_select( 6534562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 6544562236bSHarry Wentland { 6554562236bSHarry Wentland struct dc_bios *dcb; 6564562236bSHarry Wentland /* call VBIOS table to set CRTC source for the HW 6574562236bSHarry Wentland * encoder block 6584562236bSHarry Wentland * note: video bios clears all FMT setting here. */ 6594562236bSHarry Wentland struct bp_crtc_source_select crtc_source_select = {0}; 660b73a22d3SHarry Wentland const struct dc_sink *sink = pipe_ctx->stream->sink; 6614562236bSHarry Wentland 6628e9c4c8cSHarry Wentland crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id; 6634562236bSHarry Wentland crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1; 6644562236bSHarry Wentland /*TODO: Need to un-hardcode color depth, dp_audio and account for 6654562236bSHarry Wentland * the case where signal and sink signal is different (translator 6664562236bSHarry Wentland * encoder)*/ 6674562236bSHarry Wentland crtc_source_select.signal = pipe_ctx->stream->signal; 6684562236bSHarry Wentland crtc_source_select.enable_dp_audio = false; 6694562236bSHarry Wentland crtc_source_select.sink_signal = pipe_ctx->stream->signal; 6701b7441b0SCharlene Liu 6711b7441b0SCharlene Liu switch (pipe_ctx->stream->timing.display_color_depth) { 6721b7441b0SCharlene Liu case COLOR_DEPTH_666: 6731b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_6BIT_COLOR; 6741b7441b0SCharlene Liu break; 6751b7441b0SCharlene Liu case COLOR_DEPTH_888: 6764562236bSHarry Wentland crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 6771b7441b0SCharlene Liu break; 6781b7441b0SCharlene Liu case COLOR_DEPTH_101010: 6791b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_10BIT_COLOR; 6801b7441b0SCharlene Liu break; 6811b7441b0SCharlene Liu case COLOR_DEPTH_121212: 6821b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_12BIT_COLOR; 6831b7441b0SCharlene Liu break; 6841b7441b0SCharlene Liu default: 6851b7441b0SCharlene Liu BREAK_TO_DEBUGGER(); 6861b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 6871b7441b0SCharlene Liu break; 6881b7441b0SCharlene Liu } 6894562236bSHarry Wentland 6904562236bSHarry Wentland dcb = sink->ctx->dc_bios; 6914562236bSHarry Wentland 6924562236bSHarry Wentland if (BP_RESULT_OK != dcb->funcs->crtc_source_select( 6934562236bSHarry Wentland dcb, 6944562236bSHarry Wentland &crtc_source_select)) { 6954562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 6964562236bSHarry Wentland } 6974562236bSHarry Wentland 6984562236bSHarry Wentland return DC_OK; 6994562236bSHarry Wentland } 7004562236bSHarry Wentland 7014562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 7024562236bSHarry Wentland { 70386e2e1beSHersen Wu ASSERT(pipe_ctx->stream); 70486e2e1beSHersen Wu 7058e9c4c8cSHarry Wentland if (pipe_ctx->stream_res.stream_enc == NULL) 70686e2e1beSHersen Wu return; /* this is not root pipe */ 70786e2e1beSHersen Wu 7084562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 7098e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 7108e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 71196c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 7124562236bSHarry Wentland else if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7138e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 7148e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 71596c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 7164562236bSHarry Wentland } 7174562236bSHarry Wentland 7184562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 7194562236bSHarry Wentland { 7204562236bSHarry Wentland enum dc_lane_count lane_count = 721d0778ebfSHarry Wentland pipe_ctx->stream->sink->link->cur_link_settings.lane_count; 7224562236bSHarry Wentland 7234fa086b9SLeo (Sunpeng) Li struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 724d0778ebfSHarry Wentland struct dc_link *link = pipe_ctx->stream->sink->link; 7254562236bSHarry Wentland 7264562236bSHarry Wentland /* 1. update AVI info frame (HDMI, DP) 7274562236bSHarry Wentland * we always need to update info frame 7284562236bSHarry Wentland */ 7294562236bSHarry Wentland uint32_t active_total_with_borders; 7304562236bSHarry Wentland uint32_t early_control = 0; 7316b670fa9SHarry Wentland struct timing_generator *tg = pipe_ctx->stream_res.tg; 7324562236bSHarry Wentland 7334562236bSHarry Wentland /* TODOFPGA may change to hwss.update_info_frame */ 7344562236bSHarry Wentland dce110_update_info_frame(pipe_ctx); 7354562236bSHarry Wentland /* enable early control to avoid corruption on DP monitor*/ 7364562236bSHarry Wentland active_total_with_borders = 7374562236bSHarry Wentland timing->h_addressable 7384562236bSHarry Wentland + timing->h_border_left 7394562236bSHarry Wentland + timing->h_border_right; 7404562236bSHarry Wentland 7414562236bSHarry Wentland if (lane_count != 0) 7424562236bSHarry Wentland early_control = active_total_with_borders % lane_count; 7434562236bSHarry Wentland 7444562236bSHarry Wentland if (early_control == 0) 7454562236bSHarry Wentland early_control = lane_count; 7464562236bSHarry Wentland 7474562236bSHarry Wentland tg->funcs->set_early_control(tg, early_control); 7484562236bSHarry Wentland 7494562236bSHarry Wentland /* enable audio only within mode set */ 750afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 7514562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7528e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); 7534562236bSHarry Wentland } 7544562236bSHarry Wentland 7554562236bSHarry Wentland /* For MST, there are multiply stream go to only one link. 7564562236bSHarry Wentland * connect DIG back_end to front_end while enable_stream and 7574562236bSHarry Wentland * disconnect them during disable_stream 7584562236bSHarry Wentland * BY this, it is logic clean to separate stream and link */ 7594562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 7608e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->id, true); 7614562236bSHarry Wentland 7624562236bSHarry Wentland } 7634562236bSHarry Wentland 7644562236bSHarry Wentland void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 7654562236bSHarry Wentland { 7660971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 767d0778ebfSHarry Wentland struct dc_link *link = stream->sink->link; 7684562236bSHarry Wentland 769afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio) { 770afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); 7714562236bSHarry Wentland 7724562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7738e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( 7748e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 7754562236bSHarry Wentland else 7768e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( 7778e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 7784562236bSHarry Wentland 7794562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 7804562236bSHarry Wentland * add audio mode list change flag */ 7814562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 7824562236bSHarry Wentland * stream->stream_engine_id); 7834562236bSHarry Wentland */ 7844562236bSHarry Wentland } 7854562236bSHarry Wentland 7864562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 7878e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 7888e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 7894562236bSHarry Wentland 7904562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7918e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 7928e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 7934562236bSHarry Wentland 7948e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 7958e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, true); 7964562236bSHarry Wentland 7974562236bSHarry Wentland 7984562236bSHarry Wentland /* blank at encoder level */ 7991e4cee77SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 8001e4cee77SCharlene Liu if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP) 8011e4cee77SCharlene Liu link->link_enc->funcs->backlight_control(link->link_enc, false); 8028e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); 8031e4cee77SCharlene Liu } 8044562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe( 8054562236bSHarry Wentland link->link_enc, 8068e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->id, 8074562236bSHarry Wentland false); 8084562236bSHarry Wentland 8094562236bSHarry Wentland } 8104562236bSHarry Wentland 8114562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 8124562236bSHarry Wentland struct dc_link_settings *link_settings) 8134562236bSHarry Wentland { 8144562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 8151e4cee77SCharlene Liu struct dc_link *link = pipe_ctx->stream->sink->link; 8164562236bSHarry Wentland 8174562236bSHarry Wentland /* only 3 items below are used by unblank */ 8186235b23cSTony Cheng params.pixel_clk_khz = 8194fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.pix_clk_khz; 8204562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 8218e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); 8221e4cee77SCharlene Liu if (link->connector_signal == SIGNAL_TYPE_EDP) 8231e4cee77SCharlene Liu link->link_enc->funcs->backlight_control(link->link_enc, true); 8244562236bSHarry Wentland } 8254562236bSHarry Wentland 82615e17335SCharlene Liu 82715e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 82815e17335SCharlene Liu { 8298e9c4c8cSHarry Wentland if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL) 8308e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 83115e17335SCharlene Liu } 83215e17335SCharlene Liu 8334562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 8344562236bSHarry Wentland { 8354562236bSHarry Wentland switch (crtc_id) { 8364562236bSHarry Wentland case CONTROLLER_ID_D0: 8374562236bSHarry Wentland return DTO_SOURCE_ID0; 8384562236bSHarry Wentland case CONTROLLER_ID_D1: 8394562236bSHarry Wentland return DTO_SOURCE_ID1; 8404562236bSHarry Wentland case CONTROLLER_ID_D2: 8414562236bSHarry Wentland return DTO_SOURCE_ID2; 8424562236bSHarry Wentland case CONTROLLER_ID_D3: 8434562236bSHarry Wentland return DTO_SOURCE_ID3; 8444562236bSHarry Wentland case CONTROLLER_ID_D4: 8454562236bSHarry Wentland return DTO_SOURCE_ID4; 8464562236bSHarry Wentland case CONTROLLER_ID_D5: 8474562236bSHarry Wentland return DTO_SOURCE_ID5; 8484562236bSHarry Wentland default: 8494562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 8504562236bSHarry Wentland } 8514562236bSHarry Wentland } 8524562236bSHarry Wentland 8534562236bSHarry Wentland static void build_audio_output( 854ab8db3e1SAndrey Grodzovsky struct dc_state *state, 8554562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 8564562236bSHarry Wentland struct audio_output *audio_output) 8574562236bSHarry Wentland { 8580971c40eSHarry Wentland const struct dc_stream_state *stream = pipe_ctx->stream; 8598e9c4c8cSHarry Wentland audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id; 8604562236bSHarry Wentland 8614562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 8624562236bSHarry Wentland 8634562236bSHarry Wentland /* audio_crtc_info */ 8644562236bSHarry Wentland 8654562236bSHarry Wentland audio_output->crtc_info.h_total = 8664fa086b9SLeo (Sunpeng) Li stream->timing.h_total; 8674562236bSHarry Wentland 8684562236bSHarry Wentland /* 8694562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 8704562236bSHarry Wentland * need to specify actual active signal portion 8714562236bSHarry Wentland */ 8724562236bSHarry Wentland audio_output->crtc_info.h_active = 8734fa086b9SLeo (Sunpeng) Li stream->timing.h_addressable 8744fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_left 8754fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_right; 8764562236bSHarry Wentland 8774562236bSHarry Wentland audio_output->crtc_info.v_active = 8784fa086b9SLeo (Sunpeng) Li stream->timing.v_addressable 8794fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_top 8804fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_bottom; 8814562236bSHarry Wentland 8824562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 8834562236bSHarry Wentland 8844562236bSHarry Wentland audio_output->crtc_info.interlaced = 8854fa086b9SLeo (Sunpeng) Li stream->timing.flags.INTERLACE; 8864562236bSHarry Wentland 8874562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 8884fa086b9SLeo (Sunpeng) Li (stream->timing.pix_clk_khz*1000)/ 8894fa086b9SLeo (Sunpeng) Li (stream->timing.h_total*stream->timing.v_total); 8904562236bSHarry Wentland 8914562236bSHarry Wentland audio_output->crtc_info.color_depth = 8924fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth; 8934562236bSHarry Wentland 8944562236bSHarry Wentland audio_output->crtc_info.requested_pixel_clock = 89510688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 8964562236bSHarry Wentland 8974562236bSHarry Wentland audio_output->crtc_info.calculated_pixel_clock = 89810688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 8994562236bSHarry Wentland 90087b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/ 90187b58768SCharlene Liu if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && 90287b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock == 9034fa086b9SLeo (Sunpeng) Li stream->timing.pix_clk_khz) { 90410688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 90587b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock = 90687b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock/2; 90787b58768SCharlene Liu audio_output->crtc_info.calculated_pixel_clock = 90810688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk/2; 90987b58768SCharlene Liu 91087b58768SCharlene Liu } 91187b58768SCharlene Liu } 91287b58768SCharlene Liu 9134562236bSHarry Wentland if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 9144562236bSHarry Wentland pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { 9154562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 916ab8db3e1SAndrey Grodzovsky state->dis_clk->funcs->get_dp_ref_clk_frequency( 917ab8db3e1SAndrey Grodzovsky state->dis_clk); 9184562236bSHarry Wentland } 9194562236bSHarry Wentland 9204562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 9214562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 9224562236bSHarry Wentland 9234562236bSHarry Wentland audio_output->pll_info.dto_source = 9244562236bSHarry Wentland translate_to_dto_source( 9254562236bSHarry Wentland pipe_ctx->pipe_idx + 1); 9264562236bSHarry Wentland 9274562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 9284562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 9294562236bSHarry Wentland 9304562236bSHarry Wentland audio_output->pll_info.ss_percentage = 9314562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 9324562236bSHarry Wentland } 9334562236bSHarry Wentland 9344562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 9354562236bSHarry Wentland struct tg_color *color) 9364562236bSHarry Wentland { 9374562236bSHarry Wentland uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->pipe_idx) / 4; 9384562236bSHarry Wentland 9396702a9acSHarry Wentland switch (pipe_ctx->plane_res.scl_data.format) { 9404562236bSHarry Wentland case PIXEL_FORMAT_ARGB8888: 9414562236bSHarry Wentland /* set boarder color to red */ 9424562236bSHarry Wentland color->color_r_cr = color_value; 9434562236bSHarry Wentland break; 9444562236bSHarry Wentland 9454562236bSHarry Wentland case PIXEL_FORMAT_ARGB2101010: 9464562236bSHarry Wentland /* set boarder color to blue */ 9474562236bSHarry Wentland color->color_b_cb = color_value; 9484562236bSHarry Wentland break; 94987449a90SAnthony Koo case PIXEL_FORMAT_420BPP8: 9504562236bSHarry Wentland /* set boarder color to green */ 9514562236bSHarry Wentland color->color_g_y = color_value; 9524562236bSHarry Wentland break; 95387449a90SAnthony Koo case PIXEL_FORMAT_420BPP10: 95487449a90SAnthony Koo /* set boarder color to yellow */ 95587449a90SAnthony Koo color->color_g_y = color_value; 95687449a90SAnthony Koo color->color_r_cr = color_value; 95787449a90SAnthony Koo break; 9584562236bSHarry Wentland case PIXEL_FORMAT_FP16: 9594562236bSHarry Wentland /* set boarder color to white */ 9604562236bSHarry Wentland color->color_r_cr = color_value; 9614562236bSHarry Wentland color->color_b_cb = color_value; 9624562236bSHarry Wentland color->color_g_y = color_value; 9634562236bSHarry Wentland break; 9644562236bSHarry Wentland default: 9654562236bSHarry Wentland break; 9664562236bSHarry Wentland } 9674562236bSHarry Wentland } 9684562236bSHarry Wentland 969fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc, 9704562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 9714562236bSHarry Wentland { 9724562236bSHarry Wentland struct tg_color color = {0}; 9734562236bSHarry Wentland 974ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 975ff5ef992SAlex Deucher /* TOFPGA */ 97686a66c4eSHarry Wentland if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) 977ff5ef992SAlex Deucher return; 978ff5ef992SAlex Deucher #endif 979ff5ef992SAlex Deucher 980fb3466a4SBhawanpreet Lakha if (dc->debug.surface_visual_confirm) 9814562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 9824562236bSHarry Wentland else 9834562236bSHarry Wentland color_space_to_black_color(dc, 9844fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space, 9854562236bSHarry Wentland &color); 9864562236bSHarry Wentland 98786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 98886a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, 9896702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.depth, 9904562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 9914562236bSHarry Wentland 9926b670fa9SHarry Wentland if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) 9936b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 9946b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 9954562236bSHarry Wentland &color); 9964562236bSHarry Wentland 99786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 9986702a9acSHarry Wentland &pipe_ctx->plane_res.scl_data); 9994562236bSHarry Wentland } 10004562236bSHarry Wentland 10014b5e7d62SHersen Wu static enum dc_status dce110_prog_pixclk_crtc_otg( 10024562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1003608ac7bbSJerry Zuo struct dc_state *context, 1004fb3466a4SBhawanpreet Lakha struct dc *dc) 10054562236bSHarry Wentland { 10060971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1007608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 10084562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 10094562236bSHarry Wentland struct tg_color black_color = {0}; 10104562236bSHarry Wentland 10114562236bSHarry Wentland if (!pipe_ctx_old->stream) { 10124562236bSHarry Wentland 10134562236bSHarry Wentland /* program blank color */ 10144562236bSHarry Wentland color_space_to_black_color(dc, 10154fa086b9SLeo (Sunpeng) Li stream->output_color_space, &black_color); 10166b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank_color( 10176b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 10184562236bSHarry Wentland &black_color); 10194b5e7d62SHersen Wu 10204562236bSHarry Wentland /* 10214562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 10224562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 10234562236bSHarry Wentland */ 10246b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true); 10254562236bSHarry Wentland 10264562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 10274562236bSHarry Wentland pipe_ctx->clock_source, 102810688217SHarry Wentland &pipe_ctx->stream_res.pix_clk_params, 10294562236bSHarry Wentland &pipe_ctx->pll_settings)) { 10304562236bSHarry Wentland BREAK_TO_DEBUGGER(); 10314562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 10324562236bSHarry Wentland } 10334562236bSHarry Wentland 10346b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->program_timing( 10356b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 10364fa086b9SLeo (Sunpeng) Li &stream->timing, 10374562236bSHarry Wentland true); 103894267b3dSSylvia Tsai 10396b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 10406b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 104194267b3dSSylvia Tsai 0x182); 10424562236bSHarry Wentland } 10434562236bSHarry Wentland 10444562236bSHarry Wentland if (!pipe_ctx_old->stream) { 10456b670fa9SHarry Wentland if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc( 10466b670fa9SHarry Wentland pipe_ctx->stream_res.tg)) { 10474562236bSHarry Wentland BREAK_TO_DEBUGGER(); 10484562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 10494562236bSHarry Wentland } 10504562236bSHarry Wentland } 10514562236bSHarry Wentland 105294267b3dSSylvia Tsai 105394267b3dSSylvia Tsai 10544562236bSHarry Wentland return DC_OK; 10554562236bSHarry Wentland } 10564562236bSHarry Wentland 10574562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 10584562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1059608ac7bbSJerry Zuo struct dc_state *context, 1060fb3466a4SBhawanpreet Lakha struct dc *dc) 10614562236bSHarry Wentland { 10620971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1063608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 10644562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 10654562236bSHarry Wentland 10664562236bSHarry Wentland /* */ 10674562236bSHarry Wentland dc->hwss.prog_pixclk_crtc_otg(pipe_ctx, context, dc); 10684562236bSHarry Wentland 1069f0c4d997SCorbin McElhanney /* FPGA does not program backend */ 1070f0c4d997SCorbin McElhanney if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 1071a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1072a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 10734562236bSHarry Wentland COLOR_SPACE_YCBCR601, 10744fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth, 10754562236bSHarry Wentland pipe_ctx->stream->signal); 10764562236bSHarry Wentland 1077a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1078a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 10794562236bSHarry Wentland &stream->bit_depth_params, 10804562236bSHarry Wentland &stream->clamping); 10814562236bSHarry Wentland return DC_OK; 1082181a888fSCharlene Liu } 10834562236bSHarry Wentland /* TODO: move to stream encoder */ 10844562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 10854562236bSHarry Wentland if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) { 10864562236bSHarry Wentland BREAK_TO_DEBUGGER(); 10874562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 10884562236bSHarry Wentland } 1089f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1090f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp, 1091f0c4d997SCorbin McElhanney COLOR_SPACE_YCBCR601, 1092f0c4d997SCorbin McElhanney stream->timing.display_color_depth, 1093f0c4d997SCorbin McElhanney pipe_ctx->stream->signal); 10944562236bSHarry Wentland 10954562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 10964562236bSHarry Wentland stream->sink->link->link_enc->funcs->setup( 10974562236bSHarry Wentland stream->sink->link->link_enc, 10984562236bSHarry Wentland pipe_ctx->stream->signal); 10994562236bSHarry Wentland 1100ab3c1798SVitaly Prosyak if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 11018e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync( 11028e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 11036b670fa9SHarry Wentland pipe_ctx->stream_res.tg->inst, 11044fa086b9SLeo (Sunpeng) Li stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE); 1105ab3c1798SVitaly Prosyak 1106ab3c1798SVitaly Prosyak 1107a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1108a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 1109181a888fSCharlene Liu &stream->bit_depth_params, 1110181a888fSCharlene Liu &stream->clamping); 1111603767f9STony Cheng 11124562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 11138e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute( 11148e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 11154fa086b9SLeo (Sunpeng) Li &stream->timing, 11164fa086b9SLeo (Sunpeng) Li stream->output_color_space); 11174562236bSHarry Wentland 11184562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 11198e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute( 11208e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 11214fa086b9SLeo (Sunpeng) Li &stream->timing, 11224562236bSHarry Wentland stream->phy_pix_clk, 1123afaacef4SHarry Wentland pipe_ctx->stream_res.audio != NULL); 11244562236bSHarry Wentland 11254562236bSHarry Wentland if (dc_is_dvi_signal(pipe_ctx->stream->signal)) 11268e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute( 11278e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 11284fa086b9SLeo (Sunpeng) Li &stream->timing, 11294562236bSHarry Wentland (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? 11304562236bSHarry Wentland true : false); 11314562236bSHarry Wentland 113215e17335SCharlene Liu resource_build_info_frame(pipe_ctx); 11333639fa68SZeyu Fan dce110_update_info_frame(pipe_ctx); 11344562236bSHarry Wentland if (!pipe_ctx_old->stream) { 1135ab8db3e1SAndrey Grodzovsky core_link_enable_stream(context, pipe_ctx); 11364562236bSHarry Wentland 11373639fa68SZeyu Fan 11384562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 11394562236bSHarry Wentland dce110_unblank_stream(pipe_ctx, 1140d0778ebfSHarry Wentland &stream->sink->link->cur_link_settings); 11414562236bSHarry Wentland } 11424562236bSHarry Wentland 11436702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 11444562236bSHarry Wentland /* program_scaler and allocate_mem_input are not new asic */ 1145866294f8SHarry Wentland if ((!pipe_ctx_old || 11466702a9acSHarry Wentland memcmp(&pipe_ctx_old->plane_res.scl_data, &pipe_ctx->plane_res.scl_data, 1147866294f8SHarry Wentland sizeof(struct scaler_data)) != 0) && 11483be5262eSHarry Wentland pipe_ctx->plane_state) { 11494562236bSHarry Wentland program_scaler(dc, pipe_ctx); 1150866294f8SHarry Wentland } 11514562236bSHarry Wentland 11524562236bSHarry Wentland /* mst support - use total stream count */ 1153ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 115486a66c4eSHarry Wentland if (pipe_ctx->plane_res.mi->funcs->allocate_mem_input != NULL) 1155ff5ef992SAlex Deucher #endif 115686a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 115786a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 11584fa086b9SLeo (Sunpeng) Li stream->timing.h_total, 11594fa086b9SLeo (Sunpeng) Li stream->timing.v_total, 11604fa086b9SLeo (Sunpeng) Li stream->timing.pix_clk_khz, 1161ab2541b6SAric Cyr context->stream_count); 11624562236bSHarry Wentland 116394267b3dSSylvia Tsai pipe_ctx->stream->sink->link->psr_enabled = false; 116494267b3dSSylvia Tsai 11654562236bSHarry Wentland return DC_OK; 11664562236bSHarry Wentland } 11674562236bSHarry Wentland 11684562236bSHarry Wentland /******************************************************************************/ 11694562236bSHarry Wentland 1170fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc) 11714562236bSHarry Wentland { 11724562236bSHarry Wentland int i; 1173a0c38ebaSCharlene Liu enum connector_id connector_id; 11744562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 1175a0c38ebaSCharlene Liu connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id); 1176a0c38ebaSCharlene Liu if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) || 1177a0c38ebaSCharlene Liu (connector_id == CONNECTOR_ID_EDP)) { 1178a0c38ebaSCharlene Liu 1179a0c38ebaSCharlene Liu if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) 1180a0c38ebaSCharlene Liu dp_receiver_power_ctrl(dc->links[i], false); 1181a0c38ebaSCharlene Liu } 1182a0c38ebaSCharlene Liu 11834562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 11844562236bSHarry Wentland dc->links[i]->link_enc, SIGNAL_TYPE_NONE); 11854562236bSHarry Wentland } 11864562236bSHarry Wentland } 11874562236bSHarry Wentland 1188fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc) 11894562236bSHarry Wentland { 11904562236bSHarry Wentland int i; 11914562236bSHarry Wentland 11924562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 11934562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 11944562236bSHarry Wentland dc->res_pool->timing_generators[i]); 11954562236bSHarry Wentland } 11964562236bSHarry Wentland } 11974562236bSHarry Wentland 1198fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc) 11994562236bSHarry Wentland { 12004562236bSHarry Wentland int i; 12014562236bSHarry Wentland 12024562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 12034562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 12044562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 12054562236bSHarry Wentland 12064562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 12074562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 12084562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 12094562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 12104562236bSHarry Wentland } 12114562236bSHarry Wentland } 12124562236bSHarry Wentland 1213fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc) 12144562236bSHarry Wentland { 12154562236bSHarry Wentland power_down_encoders(dc); 12164562236bSHarry Wentland 12174562236bSHarry Wentland power_down_controllers(dc); 12184562236bSHarry Wentland 12194562236bSHarry Wentland power_down_clock_sources(dc); 12201663ae1cSBhawanpreet Lakha 12211663ae1cSBhawanpreet Lakha #ifdef ENABLE_FBC 12222f3bfb27SRoman Li if (dc->fbc_compressor) 12231663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 12241663ae1cSBhawanpreet Lakha #endif 12254562236bSHarry Wentland } 12264562236bSHarry Wentland 12274562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 1228fb3466a4SBhawanpreet Lakha struct dc *dc) 12294562236bSHarry Wentland { 12304562236bSHarry Wentland int i; 12314562236bSHarry Wentland struct timing_generator *tg; 12324562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 12334562236bSHarry Wentland 12344562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 12354562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 12364562236bSHarry Wentland 12370a87425aSTony Cheng if (tg->funcs->disable_vga) 12384562236bSHarry Wentland tg->funcs->disable_vga(tg); 12394562236bSHarry Wentland 12404562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 12414562236bSHarry Wentland * powergating. */ 12424562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 12434562236bSHarry Wentland true); 12444562236bSHarry Wentland 1245cfe4645eSDmytro Laktyushkin dc->hwss.power_down_front_end(dc, i); 12464562236bSHarry Wentland } 12474562236bSHarry Wentland } 12484562236bSHarry Wentland 12494562236bSHarry Wentland /** 12504562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 12514562236bSHarry Wentland * 1. Power down all DC HW blocks 12524562236bSHarry Wentland * 2. Disable VGA engine on all controllers 12534562236bSHarry Wentland * 3. Enable power gating for controller 12544562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 12554562236bSHarry Wentland */ 1256fb3466a4SBhawanpreet Lakha void dce110_enable_accelerated_mode(struct dc *dc) 12574562236bSHarry Wentland { 12584562236bSHarry Wentland power_down_all_hw_blocks(dc); 12594562236bSHarry Wentland 12604562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 12614562236bSHarry Wentland bios_set_scratch_acc_mode_change(dc->ctx->dc_bios); 12624562236bSHarry Wentland } 12634562236bSHarry Wentland 12644562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 12654562236bSHarry Wentland struct bw_fixed blackout_duration, 12660971c40eSHarry Wentland const struct dc_stream_state *stream) 12674562236bSHarry Wentland { 12684562236bSHarry Wentland uint32_t total_dest_line_time_ns; 12694562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 12704562236bSHarry Wentland 12714562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 12724562236bSHarry Wentland 12734562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 12744fa086b9SLeo (Sunpeng) Li stream->timing.h_total / 12754fa086b9SLeo (Sunpeng) Li stream->timing.pix_clk_khz + 12764562236bSHarry Wentland pstate_blackout_duration_ns; 12774562236bSHarry Wentland 12784562236bSHarry Wentland return total_dest_line_time_ns; 12794562236bSHarry Wentland } 12804562236bSHarry Wentland 12814562236bSHarry Wentland void dce110_set_displaymarks( 1282fb3466a4SBhawanpreet Lakha const struct dc *dc, 1283608ac7bbSJerry Zuo struct dc_state *context) 12844562236bSHarry Wentland { 12854562236bSHarry Wentland uint8_t i, num_pipes; 12864562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 12874562236bSHarry Wentland 12884562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 12894562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 12904562236bSHarry Wentland uint32_t total_dest_line_time_ns; 12914562236bSHarry Wentland 12924562236bSHarry Wentland if (pipe_ctx->stream == NULL) 12934562236bSHarry Wentland continue; 12944562236bSHarry Wentland 12954562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 129677a4ea53SBhawanpreet Lakha dc->bw_vbios->blackout_duration, pipe_ctx->stream); 129786a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( 129886a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 12999037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 13009037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 13019037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 13024562236bSHarry Wentland total_dest_line_time_ns); 13034562236bSHarry Wentland if (i == underlay_idx) { 13044562236bSHarry Wentland num_pipes++; 130586a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( 130686a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 13079037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 13089037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 13099037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 13104562236bSHarry Wentland total_dest_line_time_ns); 13114562236bSHarry Wentland } 13124562236bSHarry Wentland num_pipes++; 13134562236bSHarry Wentland } 13144562236bSHarry Wentland } 13154562236bSHarry Wentland 1316a2b8659dSTony Cheng static void set_safe_displaymarks( 1317a2b8659dSTony Cheng struct resource_context *res_ctx, 1318a2b8659dSTony Cheng const struct resource_pool *pool) 13194562236bSHarry Wentland { 13204562236bSHarry Wentland int i; 1321a2b8659dSTony Cheng int underlay_idx = pool->underlay_pipe_index; 13229037d802SDmytro Laktyushkin struct dce_watermarks max_marks = { 13234562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 13249037d802SDmytro Laktyushkin struct dce_watermarks nbp_marks = { 13254562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 13264562236bSHarry Wentland 13274562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 13284562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream == NULL) 13294562236bSHarry Wentland continue; 13304562236bSHarry Wentland 133186a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 133286a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 13334562236bSHarry Wentland nbp_marks, 13344562236bSHarry Wentland max_marks, 13354562236bSHarry Wentland max_marks, 13364562236bSHarry Wentland MAX_WATERMARK); 13374562236bSHarry Wentland if (i == underlay_idx) 133886a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 133986a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 13404562236bSHarry Wentland nbp_marks, 13414562236bSHarry Wentland max_marks, 13424562236bSHarry Wentland max_marks, 13434562236bSHarry Wentland MAX_WATERMARK); 13444562236bSHarry Wentland } 13454562236bSHarry Wentland } 13464562236bSHarry Wentland 13474562236bSHarry Wentland static void switch_dp_clock_sources( 1348fb3466a4SBhawanpreet Lakha const struct dc *dc, 13494562236bSHarry Wentland struct resource_context *res_ctx) 13504562236bSHarry Wentland { 13514562236bSHarry Wentland uint8_t i; 13524562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 13534562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; 13544562236bSHarry Wentland 13554562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 13564562236bSHarry Wentland continue; 13574562236bSHarry Wentland 13584562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 13594562236bSHarry Wentland struct clock_source *clk_src = 13604562236bSHarry Wentland resource_find_used_clk_src_for_sharing( 13614562236bSHarry Wentland res_ctx, pipe_ctx); 13624562236bSHarry Wentland 13634562236bSHarry Wentland if (clk_src && 13644562236bSHarry Wentland clk_src != pipe_ctx->clock_source) { 13654562236bSHarry Wentland resource_unreference_clock_source( 1366a2b8659dSTony Cheng res_ctx, dc->res_pool, 1367a2b8659dSTony Cheng &pipe_ctx->clock_source); 13684562236bSHarry Wentland pipe_ctx->clock_source = clk_src; 1369a2b8659dSTony Cheng resource_reference_clock_source( 1370a2b8659dSTony Cheng res_ctx, dc->res_pool, clk_src); 13714562236bSHarry Wentland 13724562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, clk_src, i); 13734562236bSHarry Wentland } 13744562236bSHarry Wentland } 13754562236bSHarry Wentland } 13764562236bSHarry Wentland } 13774562236bSHarry Wentland 13784562236bSHarry Wentland /******************************************************************************* 13794562236bSHarry Wentland * Public functions 13804562236bSHarry Wentland ******************************************************************************/ 13814562236bSHarry Wentland 13824562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 13834562236bSHarry Wentland int num_pipes, int vmin, int vmax) 13844562236bSHarry Wentland { 13854562236bSHarry Wentland int i = 0; 13864562236bSHarry Wentland struct drr_params params = {0}; 13874562236bSHarry Wentland 13884562236bSHarry Wentland params.vertical_total_max = vmax; 13894562236bSHarry Wentland params.vertical_total_min = vmin; 13904562236bSHarry Wentland 13914562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 13924562236bSHarry Wentland * some GSL stuff 13934562236bSHarry Wentland */ 13944562236bSHarry Wentland 13954562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 13966b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, ¶ms); 13974562236bSHarry Wentland } 13984562236bSHarry Wentland } 13994562236bSHarry Wentland 140072ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx, 140172ada5f7SEric Cook int num_pipes, 140272ada5f7SEric Cook struct crtc_position *position) 140372ada5f7SEric Cook { 140472ada5f7SEric Cook int i = 0; 140572ada5f7SEric Cook 140672ada5f7SEric Cook /* TODO: handle pipes > 1 140772ada5f7SEric Cook */ 140872ada5f7SEric Cook for (i = 0; i < num_pipes; i++) 14096b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position); 141072ada5f7SEric Cook } 141172ada5f7SEric Cook 14124562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 141394267b3dSSylvia Tsai int num_pipes, const struct dc_static_screen_events *events) 14144562236bSHarry Wentland { 14154562236bSHarry Wentland unsigned int i; 141694267b3dSSylvia Tsai unsigned int value = 0; 141794267b3dSSylvia Tsai 141894267b3dSSylvia Tsai if (events->overlay_update) 141994267b3dSSylvia Tsai value |= 0x100; 142094267b3dSSylvia Tsai if (events->surface_update) 142194267b3dSSylvia Tsai value |= 0x80; 142294267b3dSSylvia Tsai if (events->cursor_update) 142394267b3dSSylvia Tsai value |= 0x2; 14244562236bSHarry Wentland 1425c3aa1d67SBhawanpreet Lakha #ifdef ENABLE_FBC 1426c3aa1d67SBhawanpreet Lakha value |= 0x84; 1427c3aa1d67SBhawanpreet Lakha #endif 1428c3aa1d67SBhawanpreet Lakha 14294562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 14306b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs-> 14316b670fa9SHarry Wentland set_static_screen_control(pipe_ctx[i]->stream_res.tg, value); 14324562236bSHarry Wentland } 14334562236bSHarry Wentland 14344562236bSHarry Wentland /* unit: in_khz before mode set, get pixel clock from context. ASIC register 14354562236bSHarry Wentland * may not be programmed yet. 14364562236bSHarry Wentland * TODO: after mode set, pre_mode_set = false, 14374562236bSHarry Wentland * may read PLL register to get pixel clock 14384562236bSHarry Wentland */ 14394562236bSHarry Wentland static uint32_t get_max_pixel_clock_for_all_paths( 1440fb3466a4SBhawanpreet Lakha struct dc *dc, 1441608ac7bbSJerry Zuo struct dc_state *context, 14424562236bSHarry Wentland bool pre_mode_set) 14434562236bSHarry Wentland { 14444562236bSHarry Wentland uint32_t max_pix_clk = 0; 14454562236bSHarry Wentland int i; 14464562236bSHarry Wentland 14474562236bSHarry Wentland if (!pre_mode_set) { 14484562236bSHarry Wentland /* TODO: read ASIC register to get pixel clock */ 14494562236bSHarry Wentland ASSERT(0); 14504562236bSHarry Wentland } 14514562236bSHarry Wentland 14524562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 14534562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 14544562236bSHarry Wentland 14554562236bSHarry Wentland if (pipe_ctx->stream == NULL) 14564562236bSHarry Wentland continue; 14574562236bSHarry Wentland 14584562236bSHarry Wentland /* do not check under lay */ 14594562236bSHarry Wentland if (pipe_ctx->top_pipe) 14604562236bSHarry Wentland continue; 14614562236bSHarry Wentland 146210688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk) 14634562236bSHarry Wentland max_pix_clk = 146410688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 14654562236bSHarry Wentland } 14664562236bSHarry Wentland 14674562236bSHarry Wentland if (max_pix_clk == 0) 14684562236bSHarry Wentland ASSERT(0); 14694562236bSHarry Wentland 14704562236bSHarry Wentland return max_pix_clk; 14714562236bSHarry Wentland } 14724562236bSHarry Wentland 14732c8ad2d5SAlex Deucher /* Find clock state based on clock requested. if clock value is 0, simply 14744562236bSHarry Wentland * set clock state as requested without finding clock state by clock value 14752c8ad2d5SAlex Deucher *TODO: when dce120_hw_sequencer.c is created, override apply_min_clock. 14762c8ad2d5SAlex Deucher * 14772c8ad2d5SAlex Deucher * TODOFPGA remove TODO after implement dal_display_clock_get_cur_clocks_value 14782c8ad2d5SAlex Deucher * etc support for dcn1.0 14794562236bSHarry Wentland */ 14804562236bSHarry Wentland static void apply_min_clocks( 1481fb3466a4SBhawanpreet Lakha struct dc *dc, 1482608ac7bbSJerry Zuo struct dc_state *context, 1483e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state *clocks_state, 14844562236bSHarry Wentland bool pre_mode_set) 14854562236bSHarry Wentland { 14864562236bSHarry Wentland struct state_dependent_clocks req_clocks = {0}; 14874562236bSHarry Wentland 14884562236bSHarry Wentland if (!pre_mode_set) { 14894562236bSHarry Wentland /* set clock_state without verification */ 1490ab8db3e1SAndrey Grodzovsky if (context->dis_clk->funcs->set_min_clocks_state) { 1491ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->set_min_clocks_state( 1492ab8db3e1SAndrey Grodzovsky context->dis_clk, *clocks_state); 14934562236bSHarry Wentland return; 14945d6d185fSDmytro Laktyushkin } 14954562236bSHarry Wentland 14962c8ad2d5SAlex Deucher /* TODO: This is incorrect. Figure out how to fix. */ 1497ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1498ab8db3e1SAndrey Grodzovsky context->dis_clk, 14992c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAY_CLK, 1500ab8db3e1SAndrey Grodzovsky context->dis_clk->cur_clocks_value.dispclk_in_khz, 15012c8ad2d5SAlex Deucher pre_mode_set, 15022c8ad2d5SAlex Deucher false); 15032c8ad2d5SAlex Deucher 1504ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1505ab8db3e1SAndrey Grodzovsky context->dis_clk, 15062c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_PIXELCLK, 1507ab8db3e1SAndrey Grodzovsky context->dis_clk->cur_clocks_value.max_pixelclk_in_khz, 15082c8ad2d5SAlex Deucher pre_mode_set, 15092c8ad2d5SAlex Deucher false); 15102c8ad2d5SAlex Deucher 1511ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1512ab8db3e1SAndrey Grodzovsky context->dis_clk, 15132c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, 1514ab8db3e1SAndrey Grodzovsky context->dis_clk->cur_clocks_value.max_non_dp_phyclk_in_khz, 15152c8ad2d5SAlex Deucher pre_mode_set, 15162c8ad2d5SAlex Deucher false); 15172c8ad2d5SAlex Deucher return; 15184562236bSHarry Wentland } 15194562236bSHarry Wentland 15204562236bSHarry Wentland /* get the required state based on state dependent clocks: 15214562236bSHarry Wentland * display clock and pixel clock 15224562236bSHarry Wentland */ 15239037d802SDmytro Laktyushkin req_clocks.display_clk_khz = context->bw.dce.dispclk_khz; 15244562236bSHarry Wentland 15254562236bSHarry Wentland req_clocks.pixel_clk_khz = get_max_pixel_clock_for_all_paths( 15264562236bSHarry Wentland dc, context, true); 15274562236bSHarry Wentland 1528ab8db3e1SAndrey Grodzovsky if (context->dis_clk->funcs->get_required_clocks_state) { 1529ab8db3e1SAndrey Grodzovsky *clocks_state = context->dis_clk->funcs->get_required_clocks_state( 1530ab8db3e1SAndrey Grodzovsky context->dis_clk, &req_clocks); 1531ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->set_min_clocks_state( 1532ab8db3e1SAndrey Grodzovsky context->dis_clk, *clocks_state); 15334562236bSHarry Wentland } else { 1534ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1535ab8db3e1SAndrey Grodzovsky context->dis_clk, 15362c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAY_CLK, 15372c8ad2d5SAlex Deucher req_clocks.display_clk_khz, 15382c8ad2d5SAlex Deucher pre_mode_set, 15392c8ad2d5SAlex Deucher false); 15402c8ad2d5SAlex Deucher 1541ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1542ab8db3e1SAndrey Grodzovsky context->dis_clk, 15432c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_PIXELCLK, 15442c8ad2d5SAlex Deucher req_clocks.pixel_clk_khz, 15452c8ad2d5SAlex Deucher pre_mode_set, 15462c8ad2d5SAlex Deucher false); 15472c8ad2d5SAlex Deucher 1548ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1549ab8db3e1SAndrey Grodzovsky context->dis_clk, 15502c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, 15512c8ad2d5SAlex Deucher req_clocks.pixel_clk_khz, 15522c8ad2d5SAlex Deucher pre_mode_set, 15532c8ad2d5SAlex Deucher false); 15544562236bSHarry Wentland } 15554562236bSHarry Wentland } 15564562236bSHarry Wentland 1557690b5e39SRoman Li #ifdef ENABLE_FBC 1558690b5e39SRoman Li 1559690b5e39SRoman Li /* 1560690b5e39SRoman Li * Check if FBC can be enabled 1561690b5e39SRoman Li */ 1562fb3466a4SBhawanpreet Lakha static enum dc_status validate_fbc(struct dc *dc, 1563608ac7bbSJerry Zuo struct dc_state *context) 1564690b5e39SRoman Li { 1565690b5e39SRoman Li struct pipe_ctx *pipe_ctx = 1566690b5e39SRoman Li &context->res_ctx.pipe_ctx[0]; 1567690b5e39SRoman Li 1568690b5e39SRoman Li ASSERT(dc->fbc_compressor); 1569690b5e39SRoman Li 1570690b5e39SRoman Li /* FBC memory should be allocated */ 1571690b5e39SRoman Li if (!dc->ctx->fbc_gpu_addr) 1572690b5e39SRoman Li return DC_ERROR_UNEXPECTED; 1573690b5e39SRoman Li 1574690b5e39SRoman Li /* Only supports single display */ 1575690b5e39SRoman Li if (context->stream_count != 1) 1576690b5e39SRoman Li return DC_ERROR_UNEXPECTED; 1577690b5e39SRoman Li 1578690b5e39SRoman Li /* Only supports eDP */ 1579690b5e39SRoman Li if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) 1580690b5e39SRoman Li return DC_ERROR_UNEXPECTED; 1581690b5e39SRoman Li 1582690b5e39SRoman Li /* PSR should not be enabled */ 1583690b5e39SRoman Li if (pipe_ctx->stream->sink->link->psr_enabled) 1584690b5e39SRoman Li return DC_ERROR_UNEXPECTED; 1585690b5e39SRoman Li 1586690b5e39SRoman Li return DC_OK; 1587690b5e39SRoman Li } 1588690b5e39SRoman Li 1589690b5e39SRoman Li /* 1590690b5e39SRoman Li * Enable FBC 1591690b5e39SRoman Li */ 1592fb3466a4SBhawanpreet Lakha static enum dc_status enable_fbc(struct dc *dc, 1593608ac7bbSJerry Zuo struct dc_state *context) 1594690b5e39SRoman Li { 1595690b5e39SRoman Li enum dc_status status = validate_fbc(dc, context); 1596690b5e39SRoman Li 1597690b5e39SRoman Li if (status == DC_OK) { 1598690b5e39SRoman Li /* Program GRPH COMPRESSED ADDRESS and PITCH */ 1599690b5e39SRoman Li struct compr_addr_and_pitch_params params = {0, 0, 0}; 1600690b5e39SRoman Li struct compressor *compr = dc->fbc_compressor; 1601690b5e39SRoman Li struct pipe_ctx *pipe_ctx = 1602690b5e39SRoman Li &context->res_ctx.pipe_ctx[0]; 1603690b5e39SRoman Li 1604690b5e39SRoman Li params.source_view_width = 1605690b5e39SRoman Li pipe_ctx->stream->timing.h_addressable; 1606690b5e39SRoman Li params.source_view_height = 1607690b5e39SRoman Li pipe_ctx->stream->timing.v_addressable; 1608690b5e39SRoman Li 1609690b5e39SRoman Li compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 1610690b5e39SRoman Li 1611690b5e39SRoman Li compr->funcs->surface_address_and_pitch(compr, ¶ms); 1612690b5e39SRoman Li compr->funcs->set_fbc_invalidation_triggers(compr, 1); 1613690b5e39SRoman Li 1614690b5e39SRoman Li compr->funcs->enable_fbc(compr, ¶ms); 1615690b5e39SRoman Li } 1616690b5e39SRoman Li return status; 1617690b5e39SRoman Li } 1618690b5e39SRoman Li #endif 1619690b5e39SRoman Li 16204562236bSHarry Wentland static enum dc_status apply_ctx_to_hw_fpga( 1621fb3466a4SBhawanpreet Lakha struct dc *dc, 1622608ac7bbSJerry Zuo struct dc_state *context) 16234562236bSHarry Wentland { 16244562236bSHarry Wentland enum dc_status status = DC_ERROR_UNEXPECTED; 16254562236bSHarry Wentland int i; 16264562236bSHarry Wentland 1627a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 16284562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 1629608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 16304562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 16314562236bSHarry Wentland 16324562236bSHarry Wentland if (pipe_ctx->stream == NULL) 16334562236bSHarry Wentland continue; 16344562236bSHarry Wentland 16354562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) 16364562236bSHarry Wentland continue; 16374562236bSHarry Wentland 16384562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 16394562236bSHarry Wentland pipe_ctx, 16404562236bSHarry Wentland context, 16414562236bSHarry Wentland dc); 16424562236bSHarry Wentland 16434562236bSHarry Wentland if (status != DC_OK) 16444562236bSHarry Wentland return status; 16454562236bSHarry Wentland } 16464562236bSHarry Wentland 16474562236bSHarry Wentland return DC_OK; 16484562236bSHarry Wentland } 16494562236bSHarry Wentland 165054e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap( 1651fb3466a4SBhawanpreet Lakha struct dc *dc, 1652608ac7bbSJerry Zuo struct dc_state *context) 16534562236bSHarry Wentland { 16544562236bSHarry Wentland int i; 16554562236bSHarry Wentland 16564562236bSHarry Wentland /* Reset old context */ 16574562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 1658a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 16594562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 1660608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 16614562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 16624562236bSHarry Wentland 16634562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 16644562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 16654562236bSHarry Wentland * PHY when not already disabled. 16664562236bSHarry Wentland */ 16674562236bSHarry Wentland 16684562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 16694562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 16704562236bSHarry Wentland continue; 16714562236bSHarry Wentland 16724562236bSHarry Wentland if (!pipe_ctx->stream || 167354e8695eSDmytro Laktyushkin pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 167454e8695eSDmytro Laktyushkin core_link_disable_stream(pipe_ctx_old); 16756b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 16766b670fa9SHarry Wentland if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 167754e8695eSDmytro Laktyushkin dm_error("DC: failed to blank crtc!\n"); 167854e8695eSDmytro Laktyushkin BREAK_TO_DEBUGGER(); 167954e8695eSDmytro Laktyushkin } 16806b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); 168186a66c4eSHarry Wentland pipe_ctx_old->plane_res.mi->funcs->free_mem_input( 1682608ac7bbSJerry Zuo pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); 168354e8695eSDmytro Laktyushkin resource_unreference_clock_source( 1684608ac7bbSJerry Zuo &dc->current_state->res_ctx, dc->res_pool, 168554e8695eSDmytro Laktyushkin &pipe_ctx_old->clock_source); 168654e8695eSDmytro Laktyushkin 168754e8695eSDmytro Laktyushkin dc->hwss.power_down_front_end(dc, pipe_ctx_old->pipe_idx); 168854e8695eSDmytro Laktyushkin 168954e8695eSDmytro Laktyushkin pipe_ctx_old->stream = NULL; 169054e8695eSDmytro Laktyushkin } 16914562236bSHarry Wentland } 16924562236bSHarry Wentland } 16934562236bSHarry Wentland 1694cf437593SDmytro Laktyushkin 16954562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 1696fb3466a4SBhawanpreet Lakha struct dc *dc, 1697608ac7bbSJerry Zuo struct dc_state *context) 16984562236bSHarry Wentland { 16994562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 17004562236bSHarry Wentland enum dc_status status; 17014562236bSHarry Wentland int i; 1702e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID; 17034562236bSHarry Wentland 17044562236bSHarry Wentland /* Reset old context */ 17054562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 17064562236bSHarry Wentland dc->hwss.reset_hw_ctx_wrap(dc, context); 17074562236bSHarry Wentland 17084562236bSHarry Wentland /* Skip applying if no targets */ 1709ab2541b6SAric Cyr if (context->stream_count <= 0) 17104562236bSHarry Wentland return DC_OK; 17114562236bSHarry Wentland 17124562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 17134562236bSHarry Wentland apply_ctx_to_hw_fpga(dc, context); 17144562236bSHarry Wentland return DC_OK; 17154562236bSHarry Wentland } 17164562236bSHarry Wentland 17174562236bSHarry Wentland /* Apply new context */ 17184562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 17194562236bSHarry Wentland 17204562236bSHarry Wentland /* below is for real asic only */ 1721a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 17224562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 1723608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 17244562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 17254562236bSHarry Wentland 17264562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 17274562236bSHarry Wentland continue; 17284562236bSHarry Wentland 17294562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 17304562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 17314562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 17324562236bSHarry Wentland pipe_ctx->clock_source, i); 17334562236bSHarry Wentland continue; 17344562236bSHarry Wentland } 17354562236bSHarry Wentland 17364562236bSHarry Wentland dc->hwss.enable_display_power_gating( 17374562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 17384562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 17394562236bSHarry Wentland } 17404562236bSHarry Wentland 1741a2b8659dSTony Cheng set_safe_displaymarks(&context->res_ctx, dc->res_pool); 17421663ae1cSBhawanpreet Lakha 17431663ae1cSBhawanpreet Lakha #ifdef ENABLE_FBC 17442f3bfb27SRoman Li if (dc->fbc_compressor) 17451663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 17461663ae1cSBhawanpreet Lakha #endif 17474562236bSHarry Wentland /*TODO: when pplib works*/ 17484562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, true); 17494562236bSHarry Wentland 1750ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 17513639fa68SZeyu Fan if (dc->ctx->dce_version >= DCN_VERSION_1_0) { 17529037d802SDmytro Laktyushkin if (context->bw.dcn.calc_clk.fclk_khz 1753608ac7bbSJerry Zuo > dc->current_state->bw.dcn.cur_clk.fclk_khz) { 1754ff5ef992SAlex Deucher struct dm_pp_clock_for_voltage_req clock; 1755ff5ef992SAlex Deucher 1756ff5ef992SAlex Deucher clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; 17579037d802SDmytro Laktyushkin clock.clocks_in_khz = context->bw.dcn.calc_clk.fclk_khz; 1758ff5ef992SAlex Deucher dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 1759608ac7bbSJerry Zuo dc->current_state->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 1760c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 1761ff5ef992SAlex Deucher } 17629037d802SDmytro Laktyushkin if (context->bw.dcn.calc_clk.dcfclk_khz 1763608ac7bbSJerry Zuo > dc->current_state->bw.dcn.cur_clk.dcfclk_khz) { 1764ff5ef992SAlex Deucher struct dm_pp_clock_for_voltage_req clock; 1765ff5ef992SAlex Deucher 1766ff5ef992SAlex Deucher clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; 17679037d802SDmytro Laktyushkin clock.clocks_in_khz = context->bw.dcn.calc_clk.dcfclk_khz; 1768ff5ef992SAlex Deucher dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 1769608ac7bbSJerry Zuo dc->current_state->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 1770c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 1771ff5ef992SAlex Deucher } 1772c66a54dcSDmytro Laktyushkin if (context->bw.dcn.calc_clk.dispclk_khz 1773608ac7bbSJerry Zuo > dc->current_state->bw.dcn.cur_clk.dispclk_khz) { 1774c66a54dcSDmytro Laktyushkin dc->res_pool->display_clock->funcs->set_clock( 1775c66a54dcSDmytro Laktyushkin dc->res_pool->display_clock, 1776c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz); 1777608ac7bbSJerry Zuo dc->current_state->bw.dcn.cur_clk.dispclk_khz = 1778c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz; 1779c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.dispclk_khz = 1780c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz; 1781c66a54dcSDmytro Laktyushkin } 1782c66a54dcSDmytro Laktyushkin } else 1783ff5ef992SAlex Deucher #endif 17849037d802SDmytro Laktyushkin if (context->bw.dce.dispclk_khz 1785608ac7bbSJerry Zuo > dc->current_state->bw.dce.dispclk_khz) { 1786a2b8659dSTony Cheng dc->res_pool->display_clock->funcs->set_clock( 1787a2b8659dSTony Cheng dc->res_pool->display_clock, 17889037d802SDmytro Laktyushkin context->bw.dce.dispclk_khz * 115 / 100); 17891ce71fcdSCharlene Liu } 1790ab8812a3SHersen Wu /* program audio wall clock. use HDMI as clock source if HDMI 1791ab8812a3SHersen Wu * audio active. Otherwise, use DP as clock source 1792ab8812a3SHersen Wu * first, loop to find any HDMI audio, if not, loop find DP audio 1793ab8812a3SHersen Wu */ 17944562236bSHarry Wentland /* Setup audio rate clock source */ 17954562236bSHarry Wentland /* Issue: 17964562236bSHarry Wentland * Audio lag happened on DP monitor when unplug a HDMI monitor 17974562236bSHarry Wentland * 17984562236bSHarry Wentland * Cause: 17994562236bSHarry Wentland * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 18004562236bSHarry Wentland * is set to either dto0 or dto1, audio should work fine. 18014562236bSHarry Wentland * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 18024562236bSHarry Wentland * set to dto0 will cause audio lag. 18034562236bSHarry Wentland * 18044562236bSHarry Wentland * Solution: 18054562236bSHarry Wentland * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 18064562236bSHarry Wentland * find first available pipe with audio, setup audio wall DTO per topology 18074562236bSHarry Wentland * instead of per pipe. 18084562236bSHarry Wentland */ 1809a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 1810ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1811ab8812a3SHersen Wu 1812ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 1813ab8812a3SHersen Wu continue; 1814ab8812a3SHersen Wu 1815ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 1816ab8812a3SHersen Wu continue; 1817ab8812a3SHersen Wu 1818ab8812a3SHersen Wu if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 1819ab8812a3SHersen Wu continue; 1820ab8812a3SHersen Wu 1821afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 1822ab8812a3SHersen Wu struct audio_output audio_output; 1823ab8812a3SHersen Wu 1824ab8db3e1SAndrey Grodzovsky build_audio_output(context, pipe_ctx, &audio_output); 1825ab8812a3SHersen Wu 1826afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 1827afaacef4SHarry Wentland pipe_ctx->stream_res.audio, 1828ab8812a3SHersen Wu pipe_ctx->stream->signal, 1829ab8812a3SHersen Wu &audio_output.crtc_info, 1830ab8812a3SHersen Wu &audio_output.pll_info); 1831ab8812a3SHersen Wu break; 1832ab8812a3SHersen Wu } 1833ab8812a3SHersen Wu } 1834ab8812a3SHersen Wu 1835ab8812a3SHersen Wu /* no HDMI audio is found, try DP audio */ 1836a2b8659dSTony Cheng if (i == dc->res_pool->pipe_count) { 1837a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 1838ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1839ab8812a3SHersen Wu 1840ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 1841ab8812a3SHersen Wu continue; 1842ab8812a3SHersen Wu 1843ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 1844ab8812a3SHersen Wu continue; 1845ab8812a3SHersen Wu 1846ab8812a3SHersen Wu if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 1847ab8812a3SHersen Wu continue; 1848ab8812a3SHersen Wu 1849afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 1850ab8812a3SHersen Wu struct audio_output audio_output; 1851ab8812a3SHersen Wu 1852ab8db3e1SAndrey Grodzovsky build_audio_output(context, pipe_ctx, &audio_output); 1853ab8812a3SHersen Wu 1854afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 1855afaacef4SHarry Wentland pipe_ctx->stream_res.audio, 1856ab8812a3SHersen Wu pipe_ctx->stream->signal, 1857ab8812a3SHersen Wu &audio_output.crtc_info, 1858ab8812a3SHersen Wu &audio_output.pll_info); 1859ab8812a3SHersen Wu break; 1860ab8812a3SHersen Wu } 1861ab8812a3SHersen Wu } 1862ab8812a3SHersen Wu } 1863ab8812a3SHersen Wu 1864a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 1865ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx_old = 1866608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 1867ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1868ab8812a3SHersen Wu 1869ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 1870ab8812a3SHersen Wu continue; 1871ab8812a3SHersen Wu 1872ab8812a3SHersen Wu if (pipe_ctx->stream == pipe_ctx_old->stream) 1873ab8812a3SHersen Wu continue; 1874ab8812a3SHersen Wu 1875313bf4ffSYongqiang Sun if (pipe_ctx->stream && pipe_ctx_old->stream 1876313bf4ffSYongqiang Sun && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 1877313bf4ffSYongqiang Sun continue; 1878313bf4ffSYongqiang Sun 1879ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 1880ab8812a3SHersen Wu continue; 1881ab8812a3SHersen Wu 1882afaacef4SHarry Wentland if (context->res_ctx.pipe_ctx[i].stream_res.audio != NULL) { 1883ab8812a3SHersen Wu 18844562236bSHarry Wentland struct audio_output audio_output; 18854562236bSHarry Wentland 1886ab8db3e1SAndrey Grodzovsky build_audio_output(context, pipe_ctx, &audio_output); 18874562236bSHarry Wentland 18884562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 18898e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( 18908e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 1891afaacef4SHarry Wentland pipe_ctx->stream_res.audio->inst, 18924fa086b9SLeo (Sunpeng) Li &pipe_ctx->stream->audio_info); 18934562236bSHarry Wentland else 18948e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( 18958e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 1896afaacef4SHarry Wentland pipe_ctx->stream_res.audio->inst, 18974fa086b9SLeo (Sunpeng) Li &pipe_ctx->stream->audio_info, 18984562236bSHarry Wentland &audio_output.crtc_info); 18994562236bSHarry Wentland 1900afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->az_configure( 1901afaacef4SHarry Wentland pipe_ctx->stream_res.audio, 19024562236bSHarry Wentland pipe_ctx->stream->signal, 19034562236bSHarry Wentland &audio_output.crtc_info, 19044fa086b9SLeo (Sunpeng) Li &pipe_ctx->stream->audio_info); 19054562236bSHarry Wentland } 19064562236bSHarry Wentland 19074562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 19084562236bSHarry Wentland pipe_ctx, 19094562236bSHarry Wentland context, 19104562236bSHarry Wentland dc); 19114562236bSHarry Wentland 191218f7a1e4SYongqiang Sun if (dc->hwss.power_on_front_end) 191318f7a1e4SYongqiang Sun dc->hwss.power_on_front_end(dc, pipe_ctx, context); 191418f7a1e4SYongqiang Sun 19154562236bSHarry Wentland if (DC_OK != status) 19164562236bSHarry Wentland return status; 19174562236bSHarry Wentland } 19184562236bSHarry Wentland 1919cf437593SDmytro Laktyushkin dc->hwss.set_bandwidth(dc, context, true); 19204562236bSHarry Wentland 19214562236bSHarry Wentland /* to save power */ 19224562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, false); 19234562236bSHarry Wentland 19244562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, false); 19254562236bSHarry Wentland 19264562236bSHarry Wentland switch_dp_clock_sources(dc, &context->res_ctx); 19274562236bSHarry Wentland 1928690b5e39SRoman Li #ifdef ENABLE_FBC 1929690b5e39SRoman Li if (dc->fbc_compressor) 1930690b5e39SRoman Li enable_fbc(dc, context); 1931690b5e39SRoman Li 1932690b5e39SRoman Li #endif 1933cf437593SDmytro Laktyushkin 19344562236bSHarry Wentland return DC_OK; 19354562236bSHarry Wentland } 19364562236bSHarry Wentland 19374562236bSHarry Wentland /******************************************************************************* 19384562236bSHarry Wentland * Front End programming 19394562236bSHarry Wentland ******************************************************************************/ 19404562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 19414562236bSHarry Wentland { 19424562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 19434562236bSHarry Wentland 19444562236bSHarry Wentland default_adjust.force_hw_default = false; 19453be5262eSHarry Wentland if (pipe_ctx->plane_state == NULL) 19464562236bSHarry Wentland default_adjust.in_color_space = COLOR_SPACE_SRGB; 19474562236bSHarry Wentland else 19484562236bSHarry Wentland default_adjust.in_color_space = 19493be5262eSHarry Wentland pipe_ctx->plane_state->color_space; 19504562236bSHarry Wentland if (pipe_ctx->stream == NULL) 19514562236bSHarry Wentland default_adjust.out_color_space = COLOR_SPACE_SRGB; 19524562236bSHarry Wentland else 19534562236bSHarry Wentland default_adjust.out_color_space = 19544fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 19554562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 19566702a9acSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 19574562236bSHarry Wentland 19584562236bSHarry Wentland /* display color depth */ 19594562236bSHarry Wentland default_adjust.color_depth = 19604fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.display_color_depth; 19614562236bSHarry Wentland 19624562236bSHarry Wentland /* Lb color depth */ 19636702a9acSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 19644562236bSHarry Wentland 196586a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 196686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, &default_adjust); 19674562236bSHarry Wentland } 19684562236bSHarry Wentland 1969b06b7680SLeon Elazar 1970b06b7680SLeon Elazar /******************************************************************************* 1971b06b7680SLeon Elazar * In order to turn on/off specific surface we will program 1972b06b7680SLeon Elazar * Blender + CRTC 1973b06b7680SLeon Elazar * 1974b06b7680SLeon Elazar * In case that we have two surfaces and they have a different visibility 1975b06b7680SLeon Elazar * we can't turn off the CRTC since it will turn off the entire display 1976b06b7680SLeon Elazar * 1977b06b7680SLeon Elazar * |----------------------------------------------- | 1978b06b7680SLeon Elazar * |bottom pipe|curr pipe | | | 1979b06b7680SLeon Elazar * |Surface |Surface | Blender | CRCT | 1980b06b7680SLeon Elazar * |visibility |visibility | Configuration| | 1981b06b7680SLeon Elazar * |------------------------------------------------| 1982b06b7680SLeon Elazar * | off | off | CURRENT_PIPE | blank | 1983b06b7680SLeon Elazar * | off | on | CURRENT_PIPE | unblank | 1984b06b7680SLeon Elazar * | on | off | OTHER_PIPE | unblank | 1985b06b7680SLeon Elazar * | on | on | BLENDING | unblank | 1986b06b7680SLeon Elazar * -------------------------------------------------| 1987b06b7680SLeon Elazar * 1988b06b7680SLeon Elazar ******************************************************************************/ 1989fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc, 19904562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 19914562236bSHarry Wentland { 19924562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 1993b06b7680SLeon Elazar bool blank_target = false; 19944562236bSHarry Wentland 19954562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 1996b06b7680SLeon Elazar 1997b06b7680SLeon Elazar /* For now we are supporting only two pipes */ 1998b06b7680SLeon Elazar ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 1999b06b7680SLeon Elazar 20003be5262eSHarry Wentland if (pipe_ctx->bottom_pipe->plane_state->visible) { 20013be5262eSHarry Wentland if (pipe_ctx->plane_state->visible) 20024562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 20034562236bSHarry Wentland else 20044562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 2005b06b7680SLeon Elazar 20063be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2007b06b7680SLeon Elazar blank_target = true; 2008b06b7680SLeon Elazar 20093be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2010b06b7680SLeon Elazar blank_target = true; 2011b06b7680SLeon Elazar 20124562236bSHarry Wentland dce_set_blender_mode(dc->hwseq, pipe_ctx->pipe_idx, blender_mode); 20136b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 2014b06b7680SLeon Elazar 20154562236bSHarry Wentland } 20164562236bSHarry Wentland 20171bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 20181bf56e62SZeyu Fan { 20191bf56e62SZeyu Fan struct xfm_grph_csc_adjustment adjust; 20201bf56e62SZeyu Fan memset(&adjust, 0, sizeof(adjust)); 20211bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 20221bf56e62SZeyu Fan 20231bf56e62SZeyu Fan 20244fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 20251bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 20261bf56e62SZeyu Fan adjust.temperature_matrix[0] = 20271bf56e62SZeyu Fan pipe_ctx->stream-> 20284fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[0]; 20291bf56e62SZeyu Fan adjust.temperature_matrix[1] = 20301bf56e62SZeyu Fan pipe_ctx->stream-> 20314fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[1]; 20321bf56e62SZeyu Fan adjust.temperature_matrix[2] = 20331bf56e62SZeyu Fan pipe_ctx->stream-> 20344fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[2]; 20351bf56e62SZeyu Fan adjust.temperature_matrix[3] = 20361bf56e62SZeyu Fan pipe_ctx->stream-> 20374fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[4]; 20381bf56e62SZeyu Fan adjust.temperature_matrix[4] = 20391bf56e62SZeyu Fan pipe_ctx->stream-> 20404fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[5]; 20411bf56e62SZeyu Fan adjust.temperature_matrix[5] = 20421bf56e62SZeyu Fan pipe_ctx->stream-> 20434fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[6]; 20441bf56e62SZeyu Fan adjust.temperature_matrix[6] = 20451bf56e62SZeyu Fan pipe_ctx->stream-> 20464fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[8]; 20471bf56e62SZeyu Fan adjust.temperature_matrix[7] = 20481bf56e62SZeyu Fan pipe_ctx->stream-> 20494fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[9]; 20501bf56e62SZeyu Fan adjust.temperature_matrix[8] = 20511bf56e62SZeyu Fan pipe_ctx->stream-> 20524fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[10]; 20531bf56e62SZeyu Fan } 20541bf56e62SZeyu Fan 205586a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 20561bf56e62SZeyu Fan } 20571bf56e62SZeyu Fan 20584562236bSHarry Wentland /** 20594562236bSHarry Wentland * TODO REMOVE, USE UPDATE INSTEAD 20604562236bSHarry Wentland */ 20614562236bSHarry Wentland static void set_plane_config( 2062fb3466a4SBhawanpreet Lakha const struct dc *dc, 20634562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 20644562236bSHarry Wentland struct resource_context *res_ctx) 20654562236bSHarry Wentland { 206686a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 20673be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 20684562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 20694562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 20704562236bSHarry Wentland unsigned int i; 20714562236bSHarry Wentland 20724562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 20734562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 20744562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 20754562236bSHarry Wentland 20764562236bSHarry Wentland dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true); 20774562236bSHarry Wentland 20784562236bSHarry Wentland set_default_colors(pipe_ctx); 20794fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 20804562236bSHarry Wentland == true) { 20814562236bSHarry Wentland tbl_entry.color_space = 20824fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 20834562236bSHarry Wentland 20844562236bSHarry Wentland for (i = 0; i < 12; i++) 20854562236bSHarry Wentland tbl_entry.regval[i] = 20864fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 20874562236bSHarry Wentland 208886a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 208986a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 20904562236bSHarry Wentland } 20914562236bSHarry Wentland 20924fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 20934562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 20944562236bSHarry Wentland adjust.temperature_matrix[0] = 20954562236bSHarry Wentland pipe_ctx->stream-> 20964fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[0]; 20974562236bSHarry Wentland adjust.temperature_matrix[1] = 20984562236bSHarry Wentland pipe_ctx->stream-> 20994fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[1]; 21004562236bSHarry Wentland adjust.temperature_matrix[2] = 21014562236bSHarry Wentland pipe_ctx->stream-> 21024fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[2]; 21034562236bSHarry Wentland adjust.temperature_matrix[3] = 21044562236bSHarry Wentland pipe_ctx->stream-> 21054fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[4]; 21064562236bSHarry Wentland adjust.temperature_matrix[4] = 21074562236bSHarry Wentland pipe_ctx->stream-> 21084fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[5]; 21094562236bSHarry Wentland adjust.temperature_matrix[5] = 21104562236bSHarry Wentland pipe_ctx->stream-> 21114fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[6]; 21124562236bSHarry Wentland adjust.temperature_matrix[6] = 21134562236bSHarry Wentland pipe_ctx->stream-> 21144fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[8]; 21154562236bSHarry Wentland adjust.temperature_matrix[7] = 21164562236bSHarry Wentland pipe_ctx->stream-> 21174fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[9]; 21184562236bSHarry Wentland adjust.temperature_matrix[8] = 21194562236bSHarry Wentland pipe_ctx->stream-> 21204fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[10]; 21214562236bSHarry Wentland } 21224562236bSHarry Wentland 212386a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 21244562236bSHarry Wentland 21256702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 21264562236bSHarry Wentland program_scaler(dc, pipe_ctx); 21274562236bSHarry Wentland 2128b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 21294562236bSHarry Wentland 21304562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 21314562236bSHarry Wentland mi, 21323be5262eSHarry Wentland plane_state->format, 21333be5262eSHarry Wentland &plane_state->tiling_info, 21343be5262eSHarry Wentland &plane_state->plane_size, 21353be5262eSHarry Wentland plane_state->rotation, 21364562236bSHarry Wentland NULL, 21374b28b76bSDmytro Laktyushkin false); 21384b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 21393be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 21404562236bSHarry Wentland 2141fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 21424562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 214386a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 21443be5262eSHarry Wentland plane_state->format, 21453be5262eSHarry Wentland &plane_state->tiling_info, 21463be5262eSHarry Wentland plane_state->rotation); 21474562236bSHarry Wentland } 21484562236bSHarry Wentland 2149fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc, 21504562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 21514562236bSHarry Wentland { 21523be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 21534562236bSHarry Wentland 21543be5262eSHarry Wentland if (plane_state == NULL) 21554562236bSHarry Wentland return; 21564562236bSHarry Wentland 215786a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 215886a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 21593be5262eSHarry Wentland &plane_state->address, 21603be5262eSHarry Wentland plane_state->flip_immediate); 21614562236bSHarry Wentland 21623be5262eSHarry Wentland plane_state->status.requested_address = plane_state->address; 21634562236bSHarry Wentland } 21644562236bSHarry Wentland 21654562236bSHarry Wentland void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 21664562236bSHarry Wentland { 21673be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 21684562236bSHarry Wentland 21693be5262eSHarry Wentland if (plane_state == NULL) 21704562236bSHarry Wentland return; 21714562236bSHarry Wentland 21723be5262eSHarry Wentland plane_state->status.is_flip_pending = 217386a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 217486a66c4eSHarry Wentland pipe_ctx->plane_res.mi); 21754562236bSHarry Wentland 21763be5262eSHarry Wentland if (plane_state->status.is_flip_pending && !plane_state->visible) 217786a66c4eSHarry Wentland pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address; 21784562236bSHarry Wentland 217986a66c4eSHarry Wentland plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 218086a66c4eSHarry Wentland if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 21816b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) { 21823be5262eSHarry Wentland plane_state->status.is_right_eye =\ 21836b670fa9SHarry Wentland !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 21847f5c22d1SVitaly Prosyak } 21854562236bSHarry Wentland } 21864562236bSHarry Wentland 2187fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc) 21884562236bSHarry Wentland { 21894562236bSHarry Wentland power_down_all_hw_blocks(dc); 21904562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 21914562236bSHarry Wentland } 21924562236bSHarry Wentland 21934562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 21944562236bSHarry Wentland struct dc_context *dc_ctx, 21954562236bSHarry Wentland struct timing_generator *tg) 21964562236bSHarry Wentland { 21974562236bSHarry Wentland bool rc = false; 21984562236bSHarry Wentland 21994562236bSHarry Wentland /* To avoid endless loop we wait at most 22004562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 22014562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 22024562236bSHarry Wentland uint32_t i; 22034562236bSHarry Wentland 22044562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 22054562236bSHarry Wentland 22064562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 22074562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 22084562236bSHarry Wentland break; 22094562236bSHarry Wentland } 22104562236bSHarry Wentland 22114562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 22124562236bSHarry Wentland rc = true; 22134562236bSHarry Wentland /* usually occurs at i=1 */ 22144562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 22154562236bSHarry Wentland i); 22164562236bSHarry Wentland break; 22174562236bSHarry Wentland } 22184562236bSHarry Wentland 22194562236bSHarry Wentland /* Wait for one frame. */ 22204562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 22214562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 22224562236bSHarry Wentland } 22234562236bSHarry Wentland 22244562236bSHarry Wentland if (false == rc) 22254562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 22264562236bSHarry Wentland 22274562236bSHarry Wentland return rc; 22284562236bSHarry Wentland } 22294562236bSHarry Wentland 22304562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 22314562236bSHarry Wentland static void dce110_enable_timing_synchronization( 2232fb3466a4SBhawanpreet Lakha struct dc *dc, 22334562236bSHarry Wentland int group_index, 22344562236bSHarry Wentland int group_size, 22354562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 22364562236bSHarry Wentland { 22374562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 22384562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 22394562236bSHarry Wentland int i; 22404562236bSHarry Wentland 22414562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 22424562236bSHarry Wentland 22434562236bSHarry Wentland /* Designate a single TG in the group as a master. 22444562236bSHarry Wentland * Since HW doesn't care which one, we always assign 22454562236bSHarry Wentland * the 1st one in the group. */ 22464562236bSHarry Wentland gsl_params.gsl_group = 0; 22476b670fa9SHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst; 22484562236bSHarry Wentland 22494562236bSHarry Wentland for (i = 0; i < group_size; i++) 22506b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 22516b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg, &gsl_params); 22524562236bSHarry Wentland 22534562236bSHarry Wentland /* Reset slave controllers on master VSync */ 22544562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 22554562236bSHarry Wentland 22564562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 22576b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( 22586b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg, gsl_params.gsl_group); 22594562236bSHarry Wentland 22604562236bSHarry Wentland 22614562236bSHarry Wentland 22624562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 22634562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 22646b670fa9SHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 22654562236bSHarry Wentland /* Regardless of success of the wait above, remove the reset or 22664562236bSHarry Wentland * the driver will start timing out on Display requests. */ 22674562236bSHarry Wentland DC_SYNC_INFO("GSL: disabling trigger-reset.\n"); 22686b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(grouped_pipes[i]->stream_res.tg); 22694562236bSHarry Wentland } 22704562236bSHarry Wentland 22714562236bSHarry Wentland 22724562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 22734562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 22744562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 22754562236bSHarry Wentland for (i = 0; i < group_size; i++) 22766b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 22774562236bSHarry Wentland 22784562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 22794562236bSHarry Wentland } 22804562236bSHarry Wentland 2281fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc) 22824562236bSHarry Wentland { 22834562236bSHarry Wentland int i; 22844562236bSHarry Wentland struct dc_bios *bp; 22854562236bSHarry Wentland struct transform *xfm; 22865e7773a2SAnthony Koo struct abm *abm; 22874562236bSHarry Wentland 22884562236bSHarry Wentland bp = dc->ctx->dc_bios; 22894562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 22904562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 22914562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 22924562236bSHarry Wentland 22934562236bSHarry Wentland dc->hwss.enable_display_power_gating( 22944562236bSHarry Wentland dc, i, bp, 22954562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 22964562236bSHarry Wentland dc->hwss.enable_display_power_gating( 22974562236bSHarry Wentland dc, i, bp, 22984562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 22994562236bSHarry Wentland dc->hwss.enable_display_pipe_clock_gating( 23004562236bSHarry Wentland dc->ctx, 23014562236bSHarry Wentland true); 23024562236bSHarry Wentland } 23034562236bSHarry Wentland 2304e166ad43SJulia Lawall dce_clock_gating_power_up(dc->hwseq, false); 23054562236bSHarry Wentland /***************************************/ 23064562236bSHarry Wentland 23074562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 23084562236bSHarry Wentland /****************************************/ 23094562236bSHarry Wentland /* Power up AND update implementation according to the 23104562236bSHarry Wentland * required signal (which may be different from the 23114562236bSHarry Wentland * default signal on connector). */ 2312d0778ebfSHarry Wentland struct dc_link *link = dc->links[i]; 23134562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 23144562236bSHarry Wentland } 23154562236bSHarry Wentland 23164562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 23174562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 23184562236bSHarry Wentland 23194562236bSHarry Wentland tg->funcs->disable_vga(tg); 23204562236bSHarry Wentland 23214562236bSHarry Wentland /* Blank controller using driver code instead of 23224562236bSHarry Wentland * command table. */ 23234562236bSHarry Wentland tg->funcs->set_blank(tg, true); 23244b5e7d62SHersen Wu hwss_wait_for_blank_complete(tg); 23254562236bSHarry Wentland } 23264562236bSHarry Wentland 23274562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 23284562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 23294562236bSHarry Wentland audio->funcs->hw_init(audio); 23304562236bSHarry Wentland } 23315e7773a2SAnthony Koo 23325e7773a2SAnthony Koo abm = dc->res_pool->abm; 23336728b30cSAnthony Koo if (abm != NULL) { 23346728b30cSAnthony Koo abm->funcs->init_backlight(abm); 23355e7773a2SAnthony Koo abm->funcs->abm_init(abm); 23364562236bSHarry Wentland } 23371663ae1cSBhawanpreet Lakha #ifdef ENABLE_FBC 23382f3bfb27SRoman Li if (dc->fbc_compressor) 23391663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 23401663ae1cSBhawanpreet Lakha #endif 2341690b5e39SRoman Li 23426728b30cSAnthony Koo } 23434562236bSHarry Wentland 234428f72454SJordan Lazare void dce110_fill_display_configs( 2345608ac7bbSJerry Zuo const struct dc_state *context, 2346cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg) 23474562236bSHarry Wentland { 2348cf437593SDmytro Laktyushkin int j; 2349cf437593SDmytro Laktyushkin int num_cfgs = 0; 2350cf437593SDmytro Laktyushkin 2351cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 2352cf437593SDmytro Laktyushkin int k; 2353cf437593SDmytro Laktyushkin 23540971c40eSHarry Wentland const struct dc_stream_state *stream = context->streams[j]; 2355cf437593SDmytro Laktyushkin struct dm_pp_single_disp_config *cfg = 2356cf437593SDmytro Laktyushkin &pp_display_cfg->disp_configs[num_cfgs]; 2357cf437593SDmytro Laktyushkin const struct pipe_ctx *pipe_ctx = NULL; 2358cf437593SDmytro Laktyushkin 2359cf437593SDmytro Laktyushkin for (k = 0; k < MAX_PIPES; k++) 2360cf437593SDmytro Laktyushkin if (stream == context->res_ctx.pipe_ctx[k].stream) { 2361cf437593SDmytro Laktyushkin pipe_ctx = &context->res_ctx.pipe_ctx[k]; 2362cf437593SDmytro Laktyushkin break; 23634562236bSHarry Wentland } 23644562236bSHarry Wentland 2365cf437593SDmytro Laktyushkin ASSERT(pipe_ctx != NULL); 2366cf437593SDmytro Laktyushkin 2367cf437593SDmytro Laktyushkin num_cfgs++; 2368cf437593SDmytro Laktyushkin cfg->signal = pipe_ctx->stream->signal; 2369cf437593SDmytro Laktyushkin cfg->pipe_idx = pipe_ctx->pipe_idx; 23704fa086b9SLeo (Sunpeng) Li cfg->src_height = stream->src.height; 23714fa086b9SLeo (Sunpeng) Li cfg->src_width = stream->src.width; 2372cf437593SDmytro Laktyushkin cfg->ddi_channel_mapping = 2373cf437593SDmytro Laktyushkin stream->sink->link->ddi_channel_mapping.raw; 2374cf437593SDmytro Laktyushkin cfg->transmitter = 2375cf437593SDmytro Laktyushkin stream->sink->link->link_enc->transmitter; 2376cf437593SDmytro Laktyushkin cfg->link_settings.lane_count = 2377d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.lane_count; 2378cf437593SDmytro Laktyushkin cfg->link_settings.link_rate = 2379d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.link_rate; 2380cf437593SDmytro Laktyushkin cfg->link_settings.link_spread = 2381d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.link_spread; 2382cf437593SDmytro Laktyushkin cfg->sym_clock = stream->phy_pix_clk; 2383cf437593SDmytro Laktyushkin /* Round v_refresh*/ 23844fa086b9SLeo (Sunpeng) Li cfg->v_refresh = stream->timing.pix_clk_khz * 1000; 23854fa086b9SLeo (Sunpeng) Li cfg->v_refresh /= stream->timing.h_total; 23864fa086b9SLeo (Sunpeng) Li cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) 23874fa086b9SLeo (Sunpeng) Li / stream->timing.v_total; 2388cf437593SDmytro Laktyushkin } 2389cf437593SDmytro Laktyushkin 2390cf437593SDmytro Laktyushkin pp_display_cfg->display_count = num_cfgs; 2391cf437593SDmytro Laktyushkin } 2392cf437593SDmytro Laktyushkin 2393608ac7bbSJerry Zuo uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context) 2394cf437593SDmytro Laktyushkin { 2395cf437593SDmytro Laktyushkin uint8_t j; 2396cf437593SDmytro Laktyushkin uint32_t min_vertical_blank_time = -1; 2397cf437593SDmytro Laktyushkin 2398cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 23990971c40eSHarry Wentland struct dc_stream_state *stream = context->streams[j]; 2400cf437593SDmytro Laktyushkin uint32_t vertical_blank_in_pixels = 0; 2401cf437593SDmytro Laktyushkin uint32_t vertical_blank_time = 0; 2402cf437593SDmytro Laktyushkin 2403cf437593SDmytro Laktyushkin vertical_blank_in_pixels = stream->timing.h_total * 2404cf437593SDmytro Laktyushkin (stream->timing.v_total 2405cf437593SDmytro Laktyushkin - stream->timing.v_addressable); 2406cf437593SDmytro Laktyushkin 2407cf437593SDmytro Laktyushkin vertical_blank_time = vertical_blank_in_pixels 2408cf437593SDmytro Laktyushkin * 1000 / stream->timing.pix_clk_khz; 2409cf437593SDmytro Laktyushkin 2410cf437593SDmytro Laktyushkin if (min_vertical_blank_time > vertical_blank_time) 2411cf437593SDmytro Laktyushkin min_vertical_blank_time = vertical_blank_time; 2412cf437593SDmytro Laktyushkin } 2413cf437593SDmytro Laktyushkin 2414cf437593SDmytro Laktyushkin return min_vertical_blank_time; 2415cf437593SDmytro Laktyushkin } 2416cf437593SDmytro Laktyushkin 2417cf437593SDmytro Laktyushkin static int determine_sclk_from_bounding_box( 2418fb3466a4SBhawanpreet Lakha const struct dc *dc, 2419cf437593SDmytro Laktyushkin int required_sclk) 24204562236bSHarry Wentland { 24214562236bSHarry Wentland int i; 24224562236bSHarry Wentland 2423cf437593SDmytro Laktyushkin /* 2424cf437593SDmytro Laktyushkin * Some asics do not give us sclk levels, so we just report the actual 2425cf437593SDmytro Laktyushkin * required sclk 2426cf437593SDmytro Laktyushkin */ 2427cf437593SDmytro Laktyushkin if (dc->sclk_lvls.num_levels == 0) 2428cf437593SDmytro Laktyushkin return required_sclk; 24294562236bSHarry Wentland 2430cf437593SDmytro Laktyushkin for (i = 0; i < dc->sclk_lvls.num_levels; i++) { 2431cf437593SDmytro Laktyushkin if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk) 2432cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[i]; 2433cf437593SDmytro Laktyushkin } 2434cf437593SDmytro Laktyushkin /* 2435cf437593SDmytro Laktyushkin * even maximum level could not satisfy requirement, this 2436cf437593SDmytro Laktyushkin * is unexpected at this stage, should have been caught at 2437cf437593SDmytro Laktyushkin * validation time 2438cf437593SDmytro Laktyushkin */ 2439cf437593SDmytro Laktyushkin ASSERT(0); 2440cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1]; 24414562236bSHarry Wentland } 24424562236bSHarry Wentland 2443cf437593SDmytro Laktyushkin static void pplib_apply_display_requirements( 2444fb3466a4SBhawanpreet Lakha struct dc *dc, 2445608ac7bbSJerry Zuo struct dc_state *context) 2446cf437593SDmytro Laktyushkin { 2447cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 2448cf437593SDmytro Laktyushkin 2449cf437593SDmytro Laktyushkin pp_display_cfg->all_displays_in_sync = 24509037d802SDmytro Laktyushkin context->bw.dce.all_displays_in_sync; 2451cf437593SDmytro Laktyushkin pp_display_cfg->nb_pstate_switch_disable = 24529037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_enable == false; 2453cf437593SDmytro Laktyushkin pp_display_cfg->cpu_cc6_disable = 24549037d802SDmytro Laktyushkin context->bw.dce.cpuc_state_change_enable == false; 2455cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_disable = 24569037d802SDmytro Laktyushkin context->bw.dce.cpup_state_change_enable == false; 2457cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_separation_time = 24589037d802SDmytro Laktyushkin context->bw.dce.blackout_recovery_time_us; 2459cf437593SDmytro Laktyushkin 24609037d802SDmytro Laktyushkin pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz 2461cf437593SDmytro Laktyushkin / MEMORY_TYPE_MULTIPLIER; 2462cf437593SDmytro Laktyushkin 2463cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( 2464cf437593SDmytro Laktyushkin dc, 24659037d802SDmytro Laktyushkin context->bw.dce.sclk_khz); 2466cf437593SDmytro Laktyushkin 2467cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_deep_sleep_khz 24689037d802SDmytro Laktyushkin = context->bw.dce.sclk_deep_sleep_khz; 2469cf437593SDmytro Laktyushkin 2470cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_us = 247128f72454SJordan Lazare dce110_get_min_vblank_time_us(context); 2472cf437593SDmytro Laktyushkin /* TODO: dce11.2*/ 2473cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; 2474cf437593SDmytro Laktyushkin 24759037d802SDmytro Laktyushkin pp_display_cfg->disp_clk_khz = context->bw.dce.dispclk_khz; 2476cf437593SDmytro Laktyushkin 247728f72454SJordan Lazare dce110_fill_display_configs(context, pp_display_cfg); 2478cf437593SDmytro Laktyushkin 2479cf437593SDmytro Laktyushkin /* TODO: is this still applicable?*/ 2480cf437593SDmytro Laktyushkin if (pp_display_cfg->display_count == 1) { 2481cf437593SDmytro Laktyushkin const struct dc_crtc_timing *timing = 24824fa086b9SLeo (Sunpeng) Li &context->streams[0]->timing; 2483cf437593SDmytro Laktyushkin 2484cf437593SDmytro Laktyushkin pp_display_cfg->crtc_index = 2485cf437593SDmytro Laktyushkin pp_display_cfg->disp_configs[0].pipe_idx; 2486cf437593SDmytro Laktyushkin pp_display_cfg->line_time_in_us = timing->h_total * 1000 2487cf437593SDmytro Laktyushkin / timing->pix_clk_khz; 2488cf437593SDmytro Laktyushkin } 2489cf437593SDmytro Laktyushkin 2490cf437593SDmytro Laktyushkin if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( 2491cf437593SDmytro Laktyushkin struct dm_pp_display_configuration)) != 0) 2492cf437593SDmytro Laktyushkin dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); 2493cf437593SDmytro Laktyushkin 2494cf437593SDmytro Laktyushkin dc->prev_display_config = *pp_display_cfg; 2495cf437593SDmytro Laktyushkin } 2496cf437593SDmytro Laktyushkin 2497cf437593SDmytro Laktyushkin static void dce110_set_bandwidth( 2498fb3466a4SBhawanpreet Lakha struct dc *dc, 2499608ac7bbSJerry Zuo struct dc_state *context, 2500cf437593SDmytro Laktyushkin bool decrease_allowed) 2501cf437593SDmytro Laktyushkin { 25022180e7ccSDmytro Laktyushkin dce110_set_displaymarks(dc, context); 2503cf437593SDmytro Laktyushkin 2504608ac7bbSJerry Zuo if (decrease_allowed || context->bw.dce.dispclk_khz > dc->current_state->bw.dce.dispclk_khz) { 2505a2b8659dSTony Cheng dc->res_pool->display_clock->funcs->set_clock( 2506a2b8659dSTony Cheng dc->res_pool->display_clock, 25079037d802SDmytro Laktyushkin context->bw.dce.dispclk_khz * 115 / 100); 2508608ac7bbSJerry Zuo dc->current_state->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz; 2509cf437593SDmytro Laktyushkin } 2510cf437593SDmytro Laktyushkin 2511cf437593SDmytro Laktyushkin pplib_apply_display_requirements(dc, context); 25124562236bSHarry Wentland } 25134562236bSHarry Wentland 25144562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 2515fb3466a4SBhawanpreet Lakha struct dc *dc, struct pipe_ctx *pipe_ctx) 25164562236bSHarry Wentland { 251786a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 25184562236bSHarry Wentland struct pipe_ctx *old_pipe = NULL; 25193be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 25204562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 25214562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 25224562236bSHarry Wentland unsigned int i; 25234562236bSHarry Wentland 25244562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 25254562236bSHarry Wentland 2526608ac7bbSJerry Zuo if (dc->current_state) 2527608ac7bbSJerry Zuo old_pipe = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; 25284562236bSHarry Wentland 25294562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 25304562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 25314562236bSHarry Wentland 25324562236bSHarry Wentland dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true); 25334562236bSHarry Wentland 25344562236bSHarry Wentland set_default_colors(pipe_ctx); 25354fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 25364562236bSHarry Wentland == true) { 25374562236bSHarry Wentland tbl_entry.color_space = 25384fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 25394562236bSHarry Wentland 25404562236bSHarry Wentland for (i = 0; i < 12; i++) 25414562236bSHarry Wentland tbl_entry.regval[i] = 25424fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 25434562236bSHarry Wentland 254486a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 254586a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 25464562236bSHarry Wentland } 25474562236bSHarry Wentland 25484fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 25494562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 25504562236bSHarry Wentland adjust.temperature_matrix[0] = 25514562236bSHarry Wentland pipe_ctx->stream-> 25524fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[0]; 25534562236bSHarry Wentland adjust.temperature_matrix[1] = 25544562236bSHarry Wentland pipe_ctx->stream-> 25554fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[1]; 25564562236bSHarry Wentland adjust.temperature_matrix[2] = 25574562236bSHarry Wentland pipe_ctx->stream-> 25584fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[2]; 25594562236bSHarry Wentland adjust.temperature_matrix[3] = 25604562236bSHarry Wentland pipe_ctx->stream-> 25614fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[4]; 25624562236bSHarry Wentland adjust.temperature_matrix[4] = 25634562236bSHarry Wentland pipe_ctx->stream-> 25644fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[5]; 25654562236bSHarry Wentland adjust.temperature_matrix[5] = 25664562236bSHarry Wentland pipe_ctx->stream-> 25674fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[6]; 25684562236bSHarry Wentland adjust.temperature_matrix[6] = 25694562236bSHarry Wentland pipe_ctx->stream-> 25704fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[8]; 25714562236bSHarry Wentland adjust.temperature_matrix[7] = 25724562236bSHarry Wentland pipe_ctx->stream-> 25734fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[9]; 25744562236bSHarry Wentland adjust.temperature_matrix[8] = 25754562236bSHarry Wentland pipe_ctx->stream-> 25764fa086b9SLeo (Sunpeng) Li gamut_remap_matrix.matrix[10]; 25774562236bSHarry Wentland } 25784562236bSHarry Wentland 257986a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 25804562236bSHarry Wentland 25816702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 2582c1473558SAndrey Grodzovsky 25834562236bSHarry Wentland program_scaler(dc, pipe_ctx); 25844562236bSHarry Wentland 25854562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 25864562236bSHarry Wentland mi, 25873be5262eSHarry Wentland plane_state->format, 25883be5262eSHarry Wentland &plane_state->tiling_info, 25893be5262eSHarry Wentland &plane_state->plane_size, 25903be5262eSHarry Wentland plane_state->rotation, 2591624d7c47SYongqiang Sun NULL, 25924b28b76bSDmytro Laktyushkin false); 25934b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 25943be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 25954562236bSHarry Wentland 2596fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 25974562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 259886a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 25993be5262eSHarry Wentland plane_state->format, 26003be5262eSHarry Wentland &plane_state->tiling_info, 26013be5262eSHarry Wentland plane_state->rotation); 26024562236bSHarry Wentland 26034562236bSHarry Wentland dm_logger_write(dc->ctx->logger, LOG_SURFACE, 26044562236bSHarry Wentland "Pipe:%d 0x%x: addr hi:0x%x, " 26054562236bSHarry Wentland "addr low:0x%x, " 26064562236bSHarry Wentland "src: %d, %d, %d," 26074562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 26084562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 26094562236bSHarry Wentland pipe_ctx->pipe_idx, 26103be5262eSHarry Wentland pipe_ctx->plane_state, 26113be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.high_part, 26123be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.low_part, 26133be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.x, 26143be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.y, 26153be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.width, 26163be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.height, 26173be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.x, 26183be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.y, 26193be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.width, 26203be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.height, 26213be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.x, 26223be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.y, 26233be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.width, 26243be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.height); 26254562236bSHarry Wentland 26264562236bSHarry Wentland dm_logger_write(dc->ctx->logger, LOG_SURFACE, 26274562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 26284562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 26294562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 26304562236bSHarry Wentland pipe_ctx->pipe_idx, 26316702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.width, 26326702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.height, 26336702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.x, 26346702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.y, 26356702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.width, 26366702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.height, 26376702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.x, 26386702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.y); 26394562236bSHarry Wentland } 26404562236bSHarry Wentland 26414562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 2642fb3466a4SBhawanpreet Lakha struct dc *dc, 26433e9ad616SEric Yang const struct dc_stream_state *stream, 26443e9ad616SEric Yang int num_planes, 2645608ac7bbSJerry Zuo struct dc_state *context) 26464562236bSHarry Wentland { 26473e9ad616SEric Yang int i, be_idx; 26484562236bSHarry Wentland 26493e9ad616SEric Yang if (num_planes == 0) 26504562236bSHarry Wentland return; 26514562236bSHarry Wentland 26523e9ad616SEric Yang be_idx = -1; 26533e9ad616SEric Yang for (i = 0; i < dc->res_pool->pipe_count; i++) { 26543e9ad616SEric Yang if (stream == context->res_ctx.pipe_ctx[i].stream) { 26553e9ad616SEric Yang be_idx = context->res_ctx.pipe_ctx[i].stream_res.tg->inst; 26563e9ad616SEric Yang break; 26573e9ad616SEric Yang } 26583e9ad616SEric Yang } 26593e9ad616SEric Yang 2660a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 26614562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 26624562236bSHarry Wentland 2663a2607aefSHarry Wentland if (pipe_ctx->stream != stream) 26644562236bSHarry Wentland continue; 26654562236bSHarry Wentland 26664562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 2667b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 26684562236bSHarry Wentland 26694562236bSHarry Wentland } 26704562236bSHarry Wentland } 26714562236bSHarry Wentland 2672fb3466a4SBhawanpreet Lakha static void dce110_power_down_fe(struct dc *dc, int fe_idx) 26734562236bSHarry Wentland { 26747950f0f9SDmytro Laktyushkin /* Do not power down fe when stream is active on dce*/ 2675608ac7bbSJerry Zuo if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) 26764562236bSHarry Wentland return; 26774562236bSHarry Wentland 26784562236bSHarry Wentland dc->hwss.enable_display_power_gating( 2679cfe4645eSDmytro Laktyushkin dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 2680cfe4645eSDmytro Laktyushkin 2681cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 2682cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]); 26834562236bSHarry Wentland } 26844562236bSHarry Wentland 26856be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect( 2686fb3466a4SBhawanpreet Lakha struct dc *dc, 26876be425f3SEric Yang struct resource_pool *res_pool, 26886be425f3SEric Yang struct pipe_ctx *pipe_ctx) 2689b6762f0cSEric Yang { 2690b6762f0cSEric Yang /* do nothing*/ 2691b6762f0cSEric Yang } 2692b6762f0cSEric Yang 2693bdf9a1a0SYue Hin Lau static void program_csc_matrix(struct pipe_ctx *pipe_ctx, 2694bdf9a1a0SYue Hin Lau enum dc_color_space colorspace, 2695bdf9a1a0SYue Hin Lau uint16_t *matrix) 2696bdf9a1a0SYue Hin Lau { 2697bdf9a1a0SYue Hin Lau int i; 2698bdf9a1a0SYue Hin Lau struct out_csc_color_matrix tbl_entry; 2699bdf9a1a0SYue Hin Lau 2700bdf9a1a0SYue Hin Lau if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 2701bdf9a1a0SYue Hin Lau == true) { 2702bdf9a1a0SYue Hin Lau enum dc_color_space color_space = 2703bdf9a1a0SYue Hin Lau pipe_ctx->stream->output_color_space; 2704bdf9a1a0SYue Hin Lau 2705bdf9a1a0SYue Hin Lau //uint16_t matrix[12]; 2706bdf9a1a0SYue Hin Lau for (i = 0; i < 12; i++) 2707bdf9a1a0SYue Hin Lau tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; 2708bdf9a1a0SYue Hin Lau 2709bdf9a1a0SYue Hin Lau tbl_entry.color_space = color_space; 2710bdf9a1a0SYue Hin Lau //tbl_entry.regval = matrix; 271186a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry); 2712bdf9a1a0SYue Hin Lau } 2713bdf9a1a0SYue Hin Lau } 2714bdf9a1a0SYue Hin Lau 271541f97c07SHersen Wu static void ready_shared_resources(struct dc *dc) {} 271641f97c07SHersen Wu 271741f97c07SHersen Wu static void optimize_shared_resources(struct dc *dc) {} 271841f97c07SHersen Wu 27194562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 27201bf56e62SZeyu Fan .program_gamut_remap = program_gamut_remap, 2721bdf9a1a0SYue Hin Lau .program_csc_matrix = program_csc_matrix, 27224562236bSHarry Wentland .init_hw = init_hw, 27234562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 27244562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 27254562236bSHarry Wentland .set_plane_config = set_plane_config, 27264562236bSHarry Wentland .update_plane_addr = update_plane_addr, 27274562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 2728d7194cf6SAric Cyr .set_input_transfer_func = dce110_set_input_transfer_func, 272990e508baSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 27304562236bSHarry Wentland .power_down = dce110_power_down, 27314562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 27324562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 27334562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 27344562236bSHarry Wentland .enable_stream = dce110_enable_stream, 27354562236bSHarry Wentland .disable_stream = dce110_disable_stream, 27364562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 27374562236bSHarry Wentland .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 27384562236bSHarry Wentland .enable_display_power_gating = dce110_enable_display_power_gating, 27394562236bSHarry Wentland .power_down_front_end = dce110_power_down_fe, 27404562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 27414562236bSHarry Wentland .set_bandwidth = dce110_set_bandwidth, 27424562236bSHarry Wentland .set_drr = set_drr, 274372ada5f7SEric Cook .get_position = get_position, 27444562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 274554e8695eSDmytro Laktyushkin .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 27464b5e7d62SHersen Wu .prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg, 274715e17335SCharlene Liu .setup_stereo = NULL, 274815e17335SCharlene Liu .set_avmute = dce110_set_avmute, 274941f97c07SHersen Wu .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 275041f97c07SHersen Wu .ready_shared_resources = ready_shared_resources, 275141f97c07SHersen Wu .optimize_shared_resources = optimize_shared_resources, 275241f97c07SHersen Wu 27534562236bSHarry Wentland }; 27544562236bSHarry Wentland 2755fb3466a4SBhawanpreet Lakha bool dce110_hw_sequencer_construct(struct dc *dc) 27564562236bSHarry Wentland { 27574562236bSHarry Wentland dc->hwss = dce110_funcs; 27584562236bSHarry Wentland 27594562236bSHarry Wentland return true; 27604562236bSHarry Wentland } 27614562236bSHarry Wentland 2762