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" 3587401969SAndrew Jiang #include "gpio_service_interface.h" 364562236bSHarry Wentland 373eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 381663ae1cSBhawanpreet Lakha #include "dce110_compressor.h" 391663ae1cSBhawanpreet Lakha #endif 401663ae1cSBhawanpreet Lakha 414562236bSHarry Wentland #include "bios/bios_parser_helper.h" 424562236bSHarry Wentland #include "timing_generator.h" 434562236bSHarry Wentland #include "mem_input.h" 444562236bSHarry Wentland #include "opp.h" 454562236bSHarry Wentland #include "ipp.h" 464562236bSHarry Wentland #include "transform.h" 474562236bSHarry Wentland #include "stream_encoder.h" 484562236bSHarry Wentland #include "link_encoder.h" 4987401969SAndrew Jiang #include "link_hwss.h" 504562236bSHarry Wentland #include "clock_source.h" 515e7773a2SAnthony Koo #include "abm.h" 524562236bSHarry Wentland #include "audio.h" 5308b16886SZeyu Fan #include "reg_helper.h" 544562236bSHarry Wentland 554562236bSHarry Wentland /* include DCE11 register header files */ 564562236bSHarry Wentland #include "dce/dce_11_0_d.h" 574562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 58e266fdf6SVitaly Prosyak #include "custom_float.h" 594562236bSHarry Wentland 604cac1e6dSYongqiang Sun #include "atomfirmware.h" 614cac1e6dSYongqiang Sun 6287401969SAndrew Jiang /* 6387401969SAndrew Jiang * All values are in milliseconds; 6487401969SAndrew Jiang * For eDP, after power-up/power/down, 6587401969SAndrew Jiang * 300/500 msec max. delay from LCDVCC to black video generation 6687401969SAndrew Jiang */ 6787401969SAndrew Jiang #define PANEL_POWER_UP_TIMEOUT 300 6887401969SAndrew Jiang #define PANEL_POWER_DOWN_TIMEOUT 500 6987401969SAndrew Jiang #define HPD_CHECK_INTERVAL 10 7087401969SAndrew Jiang 715eefbc40SYue Hin Lau #define CTX \ 725eefbc40SYue Hin Lau hws->ctx 735d4b05ddSBhawanpreet Lakha 745d4b05ddSBhawanpreet Lakha #define DC_LOGGER_INIT() 755d4b05ddSBhawanpreet Lakha 765eefbc40SYue Hin Lau #define REG(reg)\ 775eefbc40SYue Hin Lau hws->regs->reg 785eefbc40SYue Hin Lau 795eefbc40SYue Hin Lau #undef FN 805eefbc40SYue Hin Lau #define FN(reg_name, field_name) \ 815eefbc40SYue Hin Lau hws->shifts->field_name, hws->masks->field_name 825eefbc40SYue Hin Lau 834562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 844562236bSHarry Wentland uint32_t crtc; 854562236bSHarry Wentland }; 864562236bSHarry Wentland 874562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 884562236bSHarry Wentland { 894562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 904562236bSHarry Wentland }, 914562236bSHarry Wentland { 924562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 934562236bSHarry Wentland }, 944562236bSHarry Wentland { 954562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 964562236bSHarry Wentland }, 974562236bSHarry Wentland { 984562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 994562236bSHarry Wentland } 1004562236bSHarry Wentland }; 1014562236bSHarry Wentland 1024562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 1034562236bSHarry Wentland (reg + reg_offsets[id].blnd) 1044562236bSHarry Wentland 1054562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 1064562236bSHarry Wentland (reg + reg_offsets[id].crtc) 1074562236bSHarry Wentland 1084562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 1094562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 1104562236bSHarry Wentland 1114562236bSHarry Wentland /******************************************************************************* 1124562236bSHarry Wentland * Private definitions 1134562236bSHarry Wentland ******************************************************************************/ 1144562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 1154562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 1164562236bSHarry Wentland { 1174562236bSHarry Wentland uint32_t addr; 1184562236bSHarry Wentland uint32_t value = 0; 1194562236bSHarry Wentland uint32_t chunk_int = 0; 1204562236bSHarry Wentland uint32_t chunk_mul = 0; 1214562236bSHarry Wentland 1224562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 1234562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1244562236bSHarry Wentland 1254562236bSHarry Wentland set_reg_field_value( 1264562236bSHarry Wentland value, 1274562236bSHarry Wentland 0, 1284562236bSHarry Wentland DVMM_PTE_CONTROL, 1294562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1304562236bSHarry Wentland 1314562236bSHarry Wentland set_reg_field_value( 1324562236bSHarry Wentland value, 1334562236bSHarry Wentland 1, 1344562236bSHarry Wentland DVMM_PTE_CONTROL, 1354562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1364562236bSHarry Wentland 1374562236bSHarry Wentland set_reg_field_value( 1384562236bSHarry Wentland value, 1394562236bSHarry Wentland 1, 1404562236bSHarry Wentland DVMM_PTE_CONTROL, 1414562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1424562236bSHarry Wentland 1434562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1444562236bSHarry Wentland 1454562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1464562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1474562236bSHarry Wentland 1484562236bSHarry Wentland chunk_int = get_reg_field_value( 1494562236bSHarry Wentland value, 1504562236bSHarry Wentland DVMM_PTE_REQ, 1514562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1524562236bSHarry Wentland 1534562236bSHarry Wentland chunk_mul = get_reg_field_value( 1544562236bSHarry Wentland value, 1554562236bSHarry Wentland DVMM_PTE_REQ, 1564562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1574562236bSHarry Wentland 1584562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1594562236bSHarry Wentland 1604562236bSHarry Wentland set_reg_field_value( 1614562236bSHarry Wentland value, 1624562236bSHarry Wentland 255, 1634562236bSHarry Wentland DVMM_PTE_REQ, 1644562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1654562236bSHarry Wentland 1664562236bSHarry Wentland set_reg_field_value( 1674562236bSHarry Wentland value, 1684562236bSHarry Wentland 4, 1694562236bSHarry Wentland DVMM_PTE_REQ, 1704562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1714562236bSHarry Wentland 1724562236bSHarry Wentland set_reg_field_value( 1734562236bSHarry Wentland value, 1744562236bSHarry Wentland 4, 1754562236bSHarry Wentland DVMM_PTE_REQ, 1764562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1774562236bSHarry Wentland 1784562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1794562236bSHarry Wentland } 1804562236bSHarry Wentland } 1814562236bSHarry Wentland /**************************************************************************/ 1824562236bSHarry Wentland 1834562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1844562236bSHarry Wentland struct dc_context *ctx, 1854562236bSHarry Wentland bool clock_gating) 1864562236bSHarry Wentland { 1874562236bSHarry Wentland /*TODO*/ 1884562236bSHarry Wentland } 1894562236bSHarry Wentland 1904562236bSHarry Wentland static bool dce110_enable_display_power_gating( 191fb3466a4SBhawanpreet Lakha struct dc *dc, 1924562236bSHarry Wentland uint8_t controller_id, 1934562236bSHarry Wentland struct dc_bios *dcb, 1944562236bSHarry Wentland enum pipe_gating_control power_gating) 1954562236bSHarry Wentland { 1964562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 1974562236bSHarry Wentland enum bp_pipe_control_action cntl; 1984562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 1994562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 2004562236bSHarry Wentland 2014562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 2024562236bSHarry Wentland return true; 2034562236bSHarry Wentland 2044562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 2054562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 2064562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 2074562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 2084562236bSHarry Wentland else 2094562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 2104562236bSHarry Wentland 2114562236bSHarry Wentland if (controller_id == underlay_idx) 2124562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 2134562236bSHarry Wentland 2144562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){ 2154562236bSHarry Wentland 2164562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 2174562236bSHarry Wentland dcb, controller_id + 1, cntl); 2184562236bSHarry Wentland 2194562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 2204562236bSHarry Wentland * by default when command table is called 2214562236bSHarry Wentland * 2224562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 2234562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 2244562236bSHarry Wentland * than 3. 2254562236bSHarry Wentland */ 2264562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 2274562236bSHarry Wentland dm_write_reg(ctx, 2284562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 2294562236bSHarry Wentland 0); 2304562236bSHarry Wentland } 2314562236bSHarry Wentland 2324562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2334562236bSHarry Wentland dce110_init_pte(ctx); 2344562236bSHarry Wentland 2354562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2364562236bSHarry Wentland return true; 2374562236bSHarry Wentland else 2384562236bSHarry Wentland return false; 2394562236bSHarry Wentland } 2404562236bSHarry Wentland 2414562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2423be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2434562236bSHarry Wentland { 2444562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2454562236bSHarry Wentland 2463be5262eSHarry Wentland switch (plane_state->format) { 2474562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2488693049aSTony Cheng case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 2494562236bSHarry Wentland prescale_params->scale = 0x2020; 2504562236bSHarry Wentland break; 2514562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2524562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2534562236bSHarry Wentland prescale_params->scale = 0x2008; 2544562236bSHarry Wentland break; 2554562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 2564562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2574562236bSHarry Wentland prescale_params->scale = 0x2000; 2584562236bSHarry Wentland break; 2594562236bSHarry Wentland default: 2604562236bSHarry Wentland ASSERT(false); 261d7194cf6SAric Cyr break; 2624562236bSHarry Wentland } 2634562236bSHarry Wentland } 2644562236bSHarry Wentland 265a6114e85SHarry Wentland static bool 266a6114e85SHarry Wentland dce110_set_input_transfer_func(struct pipe_ctx *pipe_ctx, 2673be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2684562236bSHarry Wentland { 26986a66c4eSHarry Wentland struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 2707b0c470fSLeo (Sunpeng) Li const struct dc_transfer_func *tf = NULL; 27190e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 27290e508baSAnthony Koo bool result = true; 27390e508baSAnthony Koo 27490e508baSAnthony Koo if (ipp == NULL) 27590e508baSAnthony Koo return false; 27690e508baSAnthony Koo 2773be5262eSHarry Wentland if (plane_state->in_transfer_func) 2783be5262eSHarry Wentland tf = plane_state->in_transfer_func; 27990e508baSAnthony Koo 2803be5262eSHarry Wentland build_prescale_params(&prescale_params, plane_state); 28190e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 28290e508baSAnthony Koo 28384ffa801SLeo (Sunpeng) Li if (plane_state->gamma_correction && 28484ffa801SLeo (Sunpeng) Li !plane_state->gamma_correction->is_identity && 28584ffa801SLeo (Sunpeng) Li dce_use_lut(plane_state->format)) 2863be5262eSHarry Wentland ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction); 287d7194cf6SAric Cyr 28890e508baSAnthony Koo if (tf == NULL) { 28990e508baSAnthony Koo /* Default case if no input transfer function specified */ 290a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 2917b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_PREDEFINED) { 2927b0c470fSLeo (Sunpeng) Li switch (tf->tf) { 29390e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 294a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 29590e508baSAnthony Koo break; 29690e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 297a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC); 29890e508baSAnthony Koo break; 29990e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 300a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 30190e508baSAnthony Koo break; 30290e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 30390e508baSAnthony Koo default: 30490e508baSAnthony Koo result = false; 305d7194cf6SAric Cyr break; 30690e508baSAnthony Koo } 3077b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_BYPASS) { 30870063a59SAmy Zhang ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 30990e508baSAnthony Koo } else { 31090e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 31190e508baSAnthony Koo result = false; 31290e508baSAnthony Koo } 31390e508baSAnthony Koo 31490e508baSAnthony Koo return result; 31590e508baSAnthony Koo } 31690e508baSAnthony Koo 317bd1be8e8SHarry Wentland static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted, 318fcd2f4bfSAmy Zhang struct curve_points *arr_points, 319fcd2f4bfSAmy Zhang uint32_t hw_points_num) 320fcd2f4bfSAmy Zhang { 321fcd2f4bfSAmy Zhang struct custom_float_format fmt; 322fcd2f4bfSAmy Zhang 323fcd2f4bfSAmy Zhang struct pwl_result_data *rgb = rgb_resulted; 324fcd2f4bfSAmy Zhang 325fcd2f4bfSAmy Zhang uint32_t i = 0; 326fcd2f4bfSAmy Zhang 327fcd2f4bfSAmy Zhang fmt.exponenta_bits = 6; 328fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 329fcd2f4bfSAmy Zhang fmt.sign = true; 330fcd2f4bfSAmy Zhang 331bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].x, &fmt, 332fcd2f4bfSAmy Zhang &arr_points[0].custom_float_x)) { 333fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 334fcd2f4bfSAmy Zhang return false; 335fcd2f4bfSAmy Zhang } 336fcd2f4bfSAmy Zhang 337bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].offset, &fmt, 338fcd2f4bfSAmy Zhang &arr_points[0].custom_float_offset)) { 339fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 340fcd2f4bfSAmy Zhang return false; 341fcd2f4bfSAmy Zhang } 342fcd2f4bfSAmy Zhang 343bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].slope, &fmt, 344fcd2f4bfSAmy Zhang &arr_points[0].custom_float_slope)) { 345fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 346fcd2f4bfSAmy Zhang return false; 347fcd2f4bfSAmy Zhang } 348fcd2f4bfSAmy Zhang 349fcd2f4bfSAmy Zhang fmt.mantissa_bits = 10; 350fcd2f4bfSAmy Zhang fmt.sign = false; 351fcd2f4bfSAmy Zhang 352bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].x, &fmt, 353fcd2f4bfSAmy Zhang &arr_points[1].custom_float_x)) { 354fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 355fcd2f4bfSAmy Zhang return false; 356fcd2f4bfSAmy Zhang } 357fcd2f4bfSAmy Zhang 358bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].y, &fmt, 359fcd2f4bfSAmy Zhang &arr_points[1].custom_float_y)) { 360fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 361fcd2f4bfSAmy Zhang return false; 362fcd2f4bfSAmy Zhang } 363fcd2f4bfSAmy Zhang 3644d06ccd0SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].slope, &fmt, 3654d06ccd0SHarry Wentland &arr_points[1].custom_float_slope)) { 366fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 367fcd2f4bfSAmy Zhang return false; 368fcd2f4bfSAmy Zhang } 369fcd2f4bfSAmy Zhang 370fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 371fcd2f4bfSAmy Zhang fmt.sign = true; 372fcd2f4bfSAmy Zhang 373fcd2f4bfSAmy Zhang while (i != hw_points_num) { 374bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->red, &fmt, 375fcd2f4bfSAmy Zhang &rgb->red_reg)) { 376fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 377fcd2f4bfSAmy Zhang return false; 378fcd2f4bfSAmy Zhang } 379fcd2f4bfSAmy Zhang 380bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->green, &fmt, 381fcd2f4bfSAmy Zhang &rgb->green_reg)) { 382fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 383fcd2f4bfSAmy Zhang return false; 384fcd2f4bfSAmy Zhang } 385fcd2f4bfSAmy Zhang 386bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->blue, &fmt, 387fcd2f4bfSAmy Zhang &rgb->blue_reg)) { 388fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 389fcd2f4bfSAmy Zhang return false; 390fcd2f4bfSAmy Zhang } 391fcd2f4bfSAmy Zhang 392bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_red, &fmt, 393fcd2f4bfSAmy Zhang &rgb->delta_red_reg)) { 394fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 395fcd2f4bfSAmy Zhang return false; 396fcd2f4bfSAmy Zhang } 397fcd2f4bfSAmy Zhang 398bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_green, &fmt, 399fcd2f4bfSAmy Zhang &rgb->delta_green_reg)) { 400fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 401fcd2f4bfSAmy Zhang return false; 402fcd2f4bfSAmy Zhang } 403fcd2f4bfSAmy Zhang 404bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_blue, &fmt, 405fcd2f4bfSAmy Zhang &rgb->delta_blue_reg)) { 406fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 407fcd2f4bfSAmy Zhang return false; 408fcd2f4bfSAmy Zhang } 409fcd2f4bfSAmy Zhang 410fcd2f4bfSAmy Zhang ++rgb; 411fcd2f4bfSAmy Zhang ++i; 412fcd2f4bfSAmy Zhang } 413fcd2f4bfSAmy Zhang 414fcd2f4bfSAmy Zhang return true; 415fcd2f4bfSAmy Zhang } 416fcd2f4bfSAmy Zhang 41708616da5SLeo (Sunpeng) Li #define MAX_LOW_POINT 25 4188f8372c7SKrunoslav Kovac #define NUMBER_REGIONS 16 4198f8372c7SKrunoslav Kovac #define NUMBER_SW_SEGMENTS 16 4208f8372c7SKrunoslav Kovac 421b310b081SHarry Wentland static bool 422b310b081SHarry Wentland dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, 423b310b081SHarry Wentland 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 4358f8372c7SKrunoslav Kovac int32_t region_start, region_end; 4368f8372c7SKrunoslav Kovac uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points; 43723ae4f8eSAmy Zhang 438b310b081SHarry Wentland if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS) 43923ae4f8eSAmy Zhang return false; 44023ae4f8eSAmy Zhang 44123ae4f8eSAmy Zhang arr_points = regamma_params->arr_points; 44223ae4f8eSAmy Zhang rgb_resulted = regamma_params->rgb_resulted; 44323ae4f8eSAmy Zhang hw_points = 0; 444fcd2f4bfSAmy Zhang 445fcd2f4bfSAmy Zhang memset(regamma_params, 0, sizeof(struct pwl_params)); 446fcd2f4bfSAmy Zhang 447fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 448534db198SAmy Zhang /* 16 segments 449fcd2f4bfSAmy Zhang * segments are from 2^-11 to 2^5 450fcd2f4bfSAmy Zhang */ 45108616da5SLeo (Sunpeng) Li region_start = -11; 45208616da5SLeo (Sunpeng) Li region_end = region_start + NUMBER_REGIONS; 453fcd2f4bfSAmy Zhang 4548f8372c7SKrunoslav Kovac for (i = 0; i < NUMBER_REGIONS; i++) 4558f8372c7SKrunoslav Kovac seg_distr[i] = 4; 456534db198SAmy Zhang 457fcd2f4bfSAmy Zhang } else { 458534db198SAmy Zhang /* 10 segments 459fc6de1c5SLeo (Sunpeng) Li * segment is from 2^-10 to 2^1 460fc6de1c5SLeo (Sunpeng) Li * We include an extra segment for range [2^0, 2^1). This is to 461fc6de1c5SLeo (Sunpeng) Li * ensure that colors with normalized values of 1 don't miss the 462fc6de1c5SLeo (Sunpeng) Li * LUT. 463fcd2f4bfSAmy Zhang */ 4648f8372c7SKrunoslav Kovac region_start = -10; 465fc6de1c5SLeo (Sunpeng) Li region_end = 1; 466534db198SAmy Zhang 4678f8372c7SKrunoslav Kovac seg_distr[0] = 4; 468534db198SAmy Zhang seg_distr[1] = 4; 469534db198SAmy Zhang seg_distr[2] = 4; 470534db198SAmy Zhang seg_distr[3] = 4; 471534db198SAmy Zhang seg_distr[4] = 4; 472534db198SAmy Zhang seg_distr[5] = 4; 473534db198SAmy Zhang seg_distr[6] = 4; 474534db198SAmy Zhang seg_distr[7] = 4; 4758f8372c7SKrunoslav Kovac seg_distr[8] = 4; 4768f8372c7SKrunoslav Kovac seg_distr[9] = 4; 477fc6de1c5SLeo (Sunpeng) Li seg_distr[10] = 0; 478534db198SAmy Zhang seg_distr[11] = -1; 479534db198SAmy Zhang seg_distr[12] = -1; 480534db198SAmy Zhang seg_distr[13] = -1; 481534db198SAmy Zhang seg_distr[14] = -1; 482534db198SAmy Zhang seg_distr[15] = -1; 483fcd2f4bfSAmy Zhang } 484fcd2f4bfSAmy Zhang 485534db198SAmy Zhang for (k = 0; k < 16; k++) { 486534db198SAmy Zhang if (seg_distr[k] != -1) 487534db198SAmy Zhang hw_points += (1 << seg_distr[k]); 488534db198SAmy Zhang } 489534db198SAmy Zhang 490fcd2f4bfSAmy Zhang j = 0; 4918f8372c7SKrunoslav Kovac for (k = 0; k < (region_end - region_start); k++) { 492ec47734aSLeo (Sunpeng) Li increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 4938f8372c7SKrunoslav Kovac start_index = (region_start + k + MAX_LOW_POINT) * 4948f8372c7SKrunoslav Kovac NUMBER_SW_SEGMENTS; 4958f8372c7SKrunoslav Kovac for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 4968f8372c7SKrunoslav Kovac i += increment) { 497534db198SAmy Zhang if (j == hw_points - 1) 498fcd2f4bfSAmy Zhang break; 499fcd2f4bfSAmy Zhang rgb_resulted[j].red = output_tf->tf_pts.red[i]; 500fcd2f4bfSAmy Zhang rgb_resulted[j].green = output_tf->tf_pts.green[i]; 501fcd2f4bfSAmy Zhang rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 502fcd2f4bfSAmy Zhang j++; 503fcd2f4bfSAmy Zhang } 504534db198SAmy Zhang } 505534db198SAmy Zhang 506534db198SAmy Zhang /* last point */ 5078f8372c7SKrunoslav Kovac start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 508b310b081SHarry Wentland rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 509b310b081SHarry Wentland rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 510b310b081SHarry Wentland rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 511fcd2f4bfSAmy Zhang 512fcd2f4bfSAmy Zhang arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 5138f8372c7SKrunoslav Kovac dal_fixed31_32_from_int(region_start)); 514fcd2f4bfSAmy Zhang arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2), 5158f8372c7SKrunoslav Kovac dal_fixed31_32_from_int(region_end)); 516fcd2f4bfSAmy Zhang 517fcd2f4bfSAmy Zhang y_r = rgb_resulted[0].red; 518fcd2f4bfSAmy Zhang y_g = rgb_resulted[0].green; 519fcd2f4bfSAmy Zhang y_b = rgb_resulted[0].blue; 520fcd2f4bfSAmy Zhang 521fcd2f4bfSAmy Zhang y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b)); 522fcd2f4bfSAmy Zhang 523fcd2f4bfSAmy Zhang arr_points[0].y = y1_min; 524b310b081SHarry Wentland arr_points[0].slope = dal_fixed31_32_div(arr_points[0].y, 525fcd2f4bfSAmy Zhang arr_points[0].x); 526fcd2f4bfSAmy Zhang 527fcd2f4bfSAmy Zhang y_r = rgb_resulted[hw_points - 1].red; 528fcd2f4bfSAmy Zhang y_g = rgb_resulted[hw_points - 1].green; 529fcd2f4bfSAmy Zhang y_b = rgb_resulted[hw_points - 1].blue; 530fcd2f4bfSAmy Zhang 531fcd2f4bfSAmy Zhang /* see comment above, m_arrPoints[1].y should be the Y value for the 532fcd2f4bfSAmy Zhang * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 533fcd2f4bfSAmy Zhang */ 534fcd2f4bfSAmy Zhang y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b)); 535fcd2f4bfSAmy Zhang 536fcd2f4bfSAmy Zhang arr_points[1].y = y3_max; 537fcd2f4bfSAmy Zhang 538fcd2f4bfSAmy Zhang arr_points[1].slope = dal_fixed31_32_zero; 539fcd2f4bfSAmy Zhang 540fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 541fcd2f4bfSAmy Zhang /* for PQ, we want to have a straight line from last HW X point, 542fcd2f4bfSAmy Zhang * and the slope to be such that we hit 1.0 at 10000 nits. 543fcd2f4bfSAmy Zhang */ 544b310b081SHarry Wentland const struct fixed31_32 end_value = dal_fixed31_32_from_int(125); 545fcd2f4bfSAmy Zhang 546fcd2f4bfSAmy Zhang arr_points[1].slope = dal_fixed31_32_div( 547fcd2f4bfSAmy Zhang dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y), 548fcd2f4bfSAmy Zhang dal_fixed31_32_sub(end_value, arr_points[1].x)); 549fcd2f4bfSAmy Zhang } 550fcd2f4bfSAmy Zhang 551fcd2f4bfSAmy Zhang regamma_params->hw_points_num = hw_points; 552fcd2f4bfSAmy Zhang 553534db198SAmy Zhang i = 1; 554534db198SAmy Zhang for (k = 0; k < 16 && i < 16; k++) { 555534db198SAmy Zhang if (seg_distr[k] != -1) { 556b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 557534db198SAmy Zhang regamma_params->arr_curve_points[i].offset = 558b310b081SHarry Wentland regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 559fcd2f4bfSAmy Zhang } 560534db198SAmy Zhang i++; 561534db198SAmy Zhang } 562534db198SAmy Zhang 563534db198SAmy Zhang if (seg_distr[k] != -1) 564b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 565fcd2f4bfSAmy Zhang 56623ae4f8eSAmy Zhang rgb = rgb_resulted; 56723ae4f8eSAmy Zhang rgb_plus_1 = rgb_resulted + 1; 568fcd2f4bfSAmy Zhang 569fcd2f4bfSAmy Zhang i = 1; 570fcd2f4bfSAmy Zhang 571fcd2f4bfSAmy Zhang while (i != hw_points + 1) { 572fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red)) 573fcd2f4bfSAmy Zhang rgb_plus_1->red = rgb->red; 574fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green)) 575fcd2f4bfSAmy Zhang rgb_plus_1->green = rgb->green; 576fcd2f4bfSAmy Zhang if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue)) 577fcd2f4bfSAmy Zhang rgb_plus_1->blue = rgb->blue; 578fcd2f4bfSAmy Zhang 579b310b081SHarry Wentland rgb->delta_red = dal_fixed31_32_sub(rgb_plus_1->red, rgb->red); 580b310b081SHarry Wentland rgb->delta_green = dal_fixed31_32_sub(rgb_plus_1->green, rgb->green); 581b310b081SHarry Wentland rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue); 582fcd2f4bfSAmy Zhang 583fcd2f4bfSAmy Zhang ++rgb_plus_1; 584fcd2f4bfSAmy Zhang ++rgb; 585fcd2f4bfSAmy Zhang ++i; 586fcd2f4bfSAmy Zhang } 587fcd2f4bfSAmy Zhang 588fcd2f4bfSAmy Zhang convert_to_custom_float(rgb_resulted, arr_points, hw_points); 589fcd2f4bfSAmy Zhang 590fcd2f4bfSAmy Zhang return true; 591fcd2f4bfSAmy Zhang } 592fcd2f4bfSAmy Zhang 593a6114e85SHarry Wentland static bool 594a6114e85SHarry Wentland dce110_set_output_transfer_func(struct pipe_ctx *pipe_ctx, 5950971c40eSHarry Wentland const struct dc_stream_state *stream) 59690e508baSAnthony Koo { 59786a66c4eSHarry Wentland struct transform *xfm = pipe_ctx->plane_res.xfm; 5984562236bSHarry Wentland 5997a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, true); 6007a09f5beSYue Hin Lau xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 6014562236bSHarry Wentland 6024fa086b9SLeo (Sunpeng) Li if (stream->out_transfer_func && 603efd52204SHarry Wentland stream->out_transfer_func->type == TF_TYPE_PREDEFINED && 604efd52204SHarry Wentland stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) { 6057a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 606efd52204SHarry Wentland } else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func, 607efd52204SHarry Wentland &xfm->regamma_params)) { 6087a09f5beSYue Hin Lau xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 6097a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 6104562236bSHarry Wentland } else { 6117a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 6124562236bSHarry Wentland } 6134562236bSHarry Wentland 6147a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, false); 6154562236bSHarry Wentland 616cc0cb445SLeon Elazar return true; 6174562236bSHarry Wentland } 6184562236bSHarry Wentland 6194562236bSHarry Wentland static enum dc_status bios_parser_crtc_source_select( 6204562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 6214562236bSHarry Wentland { 6224562236bSHarry Wentland struct dc_bios *dcb; 6234562236bSHarry Wentland /* call VBIOS table to set CRTC source for the HW 6244562236bSHarry Wentland * encoder block 6254562236bSHarry Wentland * note: video bios clears all FMT setting here. */ 6264562236bSHarry Wentland struct bp_crtc_source_select crtc_source_select = {0}; 627b73a22d3SHarry Wentland const struct dc_sink *sink = pipe_ctx->stream->sink; 6284562236bSHarry Wentland 6298e9c4c8cSHarry Wentland crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id; 630e07f541fSYongqiang Sun crtc_source_select.controller_id = pipe_ctx->stream_res.tg->inst + 1; 6314562236bSHarry Wentland /*TODO: Need to un-hardcode color depth, dp_audio and account for 6324562236bSHarry Wentland * the case where signal and sink signal is different (translator 6334562236bSHarry Wentland * encoder)*/ 6344562236bSHarry Wentland crtc_source_select.signal = pipe_ctx->stream->signal; 6354562236bSHarry Wentland crtc_source_select.enable_dp_audio = false; 6364562236bSHarry Wentland crtc_source_select.sink_signal = pipe_ctx->stream->signal; 6371b7441b0SCharlene Liu 6381b7441b0SCharlene Liu switch (pipe_ctx->stream->timing.display_color_depth) { 6391b7441b0SCharlene Liu case COLOR_DEPTH_666: 6401b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_6BIT_COLOR; 6411b7441b0SCharlene Liu break; 6421b7441b0SCharlene Liu case COLOR_DEPTH_888: 6434562236bSHarry Wentland crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 6441b7441b0SCharlene Liu break; 6451b7441b0SCharlene Liu case COLOR_DEPTH_101010: 6461b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_10BIT_COLOR; 6471b7441b0SCharlene Liu break; 6481b7441b0SCharlene Liu case COLOR_DEPTH_121212: 6491b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_12BIT_COLOR; 6501b7441b0SCharlene Liu break; 6511b7441b0SCharlene Liu default: 6521b7441b0SCharlene Liu BREAK_TO_DEBUGGER(); 6531b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 6541b7441b0SCharlene Liu break; 6551b7441b0SCharlene Liu } 6564562236bSHarry Wentland 6574562236bSHarry Wentland dcb = sink->ctx->dc_bios; 6584562236bSHarry Wentland 6594562236bSHarry Wentland if (BP_RESULT_OK != dcb->funcs->crtc_source_select( 6604562236bSHarry Wentland dcb, 6614562236bSHarry Wentland &crtc_source_select)) { 6624562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 6634562236bSHarry Wentland } 6644562236bSHarry Wentland 6654562236bSHarry Wentland return DC_OK; 6664562236bSHarry Wentland } 6674562236bSHarry Wentland 6684562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 6694562236bSHarry Wentland { 67086e2e1beSHersen Wu ASSERT(pipe_ctx->stream); 67186e2e1beSHersen Wu 6728e9c4c8cSHarry Wentland if (pipe_ctx->stream_res.stream_enc == NULL) 67386e2e1beSHersen Wu return; /* this is not root pipe */ 67486e2e1beSHersen Wu 6754562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 6768e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 6778e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 67896c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6794562236bSHarry Wentland else if (dc_is_dp_signal(pipe_ctx->stream->signal)) 6808e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 6818e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 68296c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6834562236bSHarry Wentland } 6844562236bSHarry Wentland 6854562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 6864562236bSHarry Wentland { 6874562236bSHarry Wentland enum dc_lane_count lane_count = 688d0778ebfSHarry Wentland pipe_ctx->stream->sink->link->cur_link_settings.lane_count; 6894562236bSHarry Wentland 6904fa086b9SLeo (Sunpeng) Li struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 691d0778ebfSHarry Wentland struct dc_link *link = pipe_ctx->stream->sink->link; 6924562236bSHarry Wentland 693f215a57dSEric Yang 6944562236bSHarry Wentland uint32_t active_total_with_borders; 6954562236bSHarry Wentland uint32_t early_control = 0; 6966b670fa9SHarry Wentland struct timing_generator *tg = pipe_ctx->stream_res.tg; 6974562236bSHarry Wentland 698f215a57dSEric Yang /* For MST, there are multiply stream go to only one link. 699f215a57dSEric Yang * connect DIG back_end to front_end while enable_stream and 700f215a57dSEric Yang * disconnect them during disable_stream 701f215a57dSEric Yang * BY this, it is logic clean to separate stream and link */ 702f215a57dSEric Yang link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 703f215a57dSEric Yang pipe_ctx->stream_res.stream_enc->id, true); 704f215a57dSEric Yang 705f215a57dSEric Yang /* update AVI info frame (HDMI, DP)*/ 706f215a57dSEric Yang /* TODO: FPGA may change to hwss.update_info_frame */ 7074562236bSHarry Wentland dce110_update_info_frame(pipe_ctx); 708f215a57dSEric Yang 7094562236bSHarry Wentland /* enable early control to avoid corruption on DP monitor*/ 7104562236bSHarry Wentland active_total_with_borders = 7114562236bSHarry Wentland timing->h_addressable 7124562236bSHarry Wentland + timing->h_border_left 7134562236bSHarry Wentland + timing->h_border_right; 7144562236bSHarry Wentland 7154562236bSHarry Wentland if (lane_count != 0) 7164562236bSHarry Wentland early_control = active_total_with_borders % lane_count; 7174562236bSHarry Wentland 7184562236bSHarry Wentland if (early_control == 0) 7194562236bSHarry Wentland early_control = lane_count; 7204562236bSHarry Wentland 7214562236bSHarry Wentland tg->funcs->set_early_control(tg, early_control); 7224562236bSHarry Wentland 7234562236bSHarry Wentland /* enable audio only within mode set */ 724afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 7254562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7268e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); 7274562236bSHarry Wentland } 7284562236bSHarry Wentland 729f215a57dSEric Yang 730f215a57dSEric Yang 7314562236bSHarry Wentland 7324562236bSHarry Wentland } 7334562236bSHarry Wentland 7345eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/ 7355eefbc40SYue Hin Lau static bool is_panel_backlight_on(struct dce_hwseq *hws) 7365eefbc40SYue Hin Lau { 7375eefbc40SYue Hin Lau uint32_t value; 7385eefbc40SYue Hin Lau 7395eefbc40SYue Hin Lau REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value); 7405eefbc40SYue Hin Lau 7415eefbc40SYue Hin Lau return value; 7425eefbc40SYue Hin Lau } 7435eefbc40SYue Hin Lau 74487401969SAndrew Jiang static bool is_panel_powered_on(struct dce_hwseq *hws) 74587401969SAndrew Jiang { 746d03f3f63SEric Yang uint32_t pwr_seq_state, dig_on, dig_on_ovrd; 74787401969SAndrew Jiang 748d03f3f63SEric Yang 749d03f3f63SEric Yang REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &pwr_seq_state); 750d03f3f63SEric Yang 751d03f3f63SEric Yang REG_GET_2(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON, &dig_on, LVTMA_DIGON_OVRD, &dig_on_ovrd); 752d03f3f63SEric Yang 753d03f3f63SEric Yang return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1); 75487401969SAndrew Jiang } 75587401969SAndrew Jiang 7565eefbc40SYue Hin Lau static enum bp_result link_transmitter_control( 75787401969SAndrew Jiang struct dc_bios *bios, 7585eefbc40SYue Hin Lau struct bp_transmitter_control *cntl) 7595eefbc40SYue Hin Lau { 7605eefbc40SYue Hin Lau enum bp_result result; 7615eefbc40SYue Hin Lau 76287401969SAndrew Jiang result = bios->funcs->transmitter_control(bios, cntl); 7635eefbc40SYue Hin Lau 7645eefbc40SYue Hin Lau return result; 7655eefbc40SYue Hin Lau } 7665eefbc40SYue Hin Lau 76787401969SAndrew Jiang /* 76887401969SAndrew Jiang * @brief 76987401969SAndrew Jiang * eDP only. 77087401969SAndrew Jiang */ 77187401969SAndrew Jiang void hwss_edp_wait_for_hpd_ready( 772069d418fSAndrew Jiang struct dc_link *link, 77387401969SAndrew Jiang bool power_up) 77487401969SAndrew Jiang { 775069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 776069d418fSAndrew Jiang struct graphics_object_id connector = link->link_enc->connector; 77787401969SAndrew Jiang struct gpio *hpd; 77887401969SAndrew Jiang bool edp_hpd_high = false; 77987401969SAndrew Jiang uint32_t time_elapsed = 0; 78087401969SAndrew Jiang uint32_t timeout = power_up ? 78187401969SAndrew Jiang PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; 78287401969SAndrew Jiang 78387401969SAndrew Jiang if (dal_graphics_object_id_get_connector_id(connector) 78487401969SAndrew Jiang != CONNECTOR_ID_EDP) { 78587401969SAndrew Jiang BREAK_TO_DEBUGGER(); 78687401969SAndrew Jiang return; 78787401969SAndrew Jiang } 78887401969SAndrew Jiang 78987401969SAndrew Jiang if (!power_up) 79087401969SAndrew Jiang /* 79187401969SAndrew Jiang * From KV, we will not HPD low after turning off VCC - 79287401969SAndrew Jiang * instead, we will check the SW timer in power_up(). 79387401969SAndrew Jiang */ 79487401969SAndrew Jiang return; 79587401969SAndrew Jiang 79687401969SAndrew Jiang /* 79787401969SAndrew Jiang * When we power on/off the eDP panel, 79887401969SAndrew Jiang * we need to wait until SENSE bit is high/low. 79987401969SAndrew Jiang */ 80087401969SAndrew Jiang 80187401969SAndrew Jiang /* obtain HPD */ 80287401969SAndrew Jiang /* TODO what to do with this? */ 80387401969SAndrew Jiang hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); 80487401969SAndrew Jiang 80587401969SAndrew Jiang if (!hpd) { 80687401969SAndrew Jiang BREAK_TO_DEBUGGER(); 80787401969SAndrew Jiang return; 80887401969SAndrew Jiang } 80987401969SAndrew Jiang 81087401969SAndrew Jiang dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); 81187401969SAndrew Jiang 81287401969SAndrew Jiang /* wait until timeout or panel detected */ 81387401969SAndrew Jiang 81487401969SAndrew Jiang do { 81587401969SAndrew Jiang uint32_t detected = 0; 81687401969SAndrew Jiang 81787401969SAndrew Jiang dal_gpio_get_value(hpd, &detected); 81887401969SAndrew Jiang 81987401969SAndrew Jiang if (!(detected ^ power_up)) { 82087401969SAndrew Jiang edp_hpd_high = true; 82187401969SAndrew Jiang break; 82287401969SAndrew Jiang } 82387401969SAndrew Jiang 82487401969SAndrew Jiang msleep(HPD_CHECK_INTERVAL); 82587401969SAndrew Jiang 82687401969SAndrew Jiang time_elapsed += HPD_CHECK_INTERVAL; 82787401969SAndrew Jiang } while (time_elapsed < timeout); 82887401969SAndrew Jiang 82987401969SAndrew Jiang dal_gpio_close(hpd); 83087401969SAndrew Jiang 83187401969SAndrew Jiang dal_gpio_destroy_irq(&hpd); 83287401969SAndrew Jiang 83387401969SAndrew Jiang if (false == edp_hpd_high) { 8341296423bSBhawanpreet Lakha DC_LOG_ERROR( 83587401969SAndrew Jiang "%s: wait timed out!\n", __func__); 83687401969SAndrew Jiang } 83787401969SAndrew Jiang } 83887401969SAndrew Jiang 83987401969SAndrew Jiang void hwss_edp_power_control( 840069d418fSAndrew Jiang struct dc_link *link, 84187401969SAndrew Jiang bool power_up) 84287401969SAndrew Jiang { 843069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 84487401969SAndrew Jiang struct dce_hwseq *hwseq = ctx->dc->hwseq; 84587401969SAndrew Jiang struct bp_transmitter_control cntl = { 0 }; 84687401969SAndrew Jiang enum bp_result bp_result; 84787401969SAndrew Jiang 84887401969SAndrew Jiang 849069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 85087401969SAndrew Jiang != CONNECTOR_ID_EDP) { 85187401969SAndrew Jiang BREAK_TO_DEBUGGER(); 85287401969SAndrew Jiang return; 85387401969SAndrew Jiang } 85487401969SAndrew Jiang 85587401969SAndrew Jiang if (power_up != is_panel_powered_on(hwseq)) { 85687401969SAndrew Jiang /* Send VBIOS command to prompt eDP panel power */ 85778d5d04dSCharlene Liu if (power_up) { 85878d5d04dSCharlene Liu unsigned long long current_ts = dm_get_timestamp(ctx); 85978d5d04dSCharlene Liu unsigned long long duration_in_ms = 86078d5d04dSCharlene Liu dm_get_elapse_time_in_ns( 86178d5d04dSCharlene Liu ctx, 86278d5d04dSCharlene Liu current_ts, 86345a2d58eSHarry Wentland div64_u64(link->link_trace.time_stamp.edp_poweroff, 1000000)); 86478d5d04dSCharlene Liu unsigned long long wait_time_ms = 0; 86578d5d04dSCharlene Liu 86678d5d04dSCharlene Liu /* max 500ms from LCDVDD off to on */ 86778d5d04dSCharlene Liu if (link->link_trace.time_stamp.edp_poweroff == 0) 86878d5d04dSCharlene Liu wait_time_ms = 500; 86978d5d04dSCharlene Liu else if (duration_in_ms < 500) 87078d5d04dSCharlene Liu wait_time_ms = 500 - duration_in_ms; 87178d5d04dSCharlene Liu 87278d5d04dSCharlene Liu if (wait_time_ms) { 87378d5d04dSCharlene Liu msleep(wait_time_ms); 87478d5d04dSCharlene Liu dm_output_to_console("%s: wait %lld ms to power on eDP.\n", 87578d5d04dSCharlene Liu __func__, wait_time_ms); 87678d5d04dSCharlene Liu } 87778d5d04dSCharlene Liu 87878d5d04dSCharlene Liu } 87987401969SAndrew Jiang 8801296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 88187401969SAndrew Jiang "%s: Panel Power action: %s\n", 88287401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 88387401969SAndrew Jiang 88487401969SAndrew Jiang cntl.action = power_up ? 88587401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_ON : 88687401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_OFF; 887069d418fSAndrew Jiang cntl.transmitter = link->link_enc->transmitter; 888069d418fSAndrew Jiang cntl.connector_obj_id = link->link_enc->connector; 88987401969SAndrew Jiang cntl.coherent = false; 89087401969SAndrew Jiang cntl.lanes_number = LANE_COUNT_FOUR; 891069d418fSAndrew Jiang cntl.hpd_sel = link->link_enc->hpd_source; 89287401969SAndrew Jiang bp_result = link_transmitter_control(ctx->dc_bios, &cntl); 89387401969SAndrew Jiang 89478d5d04dSCharlene Liu if (!power_up) 89578d5d04dSCharlene Liu /*save driver power off time stamp*/ 89678d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx); 89778d5d04dSCharlene Liu else 89878d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweron = dm_get_timestamp(ctx); 89978d5d04dSCharlene Liu 90087401969SAndrew Jiang if (bp_result != BP_RESULT_OK) 9011296423bSBhawanpreet Lakha DC_LOG_ERROR( 90287401969SAndrew Jiang "%s: Panel Power bp_result: %d\n", 90387401969SAndrew Jiang __func__, bp_result); 90487401969SAndrew Jiang } else { 9051296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 90687401969SAndrew Jiang "%s: Skipping Panel Power action: %s\n", 90787401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 90887401969SAndrew Jiang } 90987401969SAndrew Jiang } 9105eefbc40SYue Hin Lau 9115eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/ 9125eefbc40SYue Hin Lau /* 9135eefbc40SYue Hin Lau * @brief 9145eefbc40SYue Hin Lau * eDP only. Control the backlight of the eDP panel 9155eefbc40SYue Hin Lau */ 91687401969SAndrew Jiang void hwss_edp_backlight_control( 9175eefbc40SYue Hin Lau struct dc_link *link, 9185eefbc40SYue Hin Lau bool enable) 9195eefbc40SYue Hin Lau { 920069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 921069d418fSAndrew Jiang struct dce_hwseq *hws = ctx->dc->hwseq; 9225eefbc40SYue Hin Lau struct bp_transmitter_control cntl = { 0 }; 9235eefbc40SYue Hin Lau 924069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 9255eefbc40SYue Hin Lau != CONNECTOR_ID_EDP) { 9265eefbc40SYue Hin Lau BREAK_TO_DEBUGGER(); 9275eefbc40SYue Hin Lau return; 9285eefbc40SYue Hin Lau } 9295eefbc40SYue Hin Lau 9305eefbc40SYue Hin Lau if (enable && is_panel_backlight_on(hws)) { 9311296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 9325eefbc40SYue Hin Lau "%s: panel already powered up. Do nothing.\n", 9335eefbc40SYue Hin Lau __func__); 9345eefbc40SYue Hin Lau return; 9355eefbc40SYue Hin Lau } 9365eefbc40SYue Hin Lau 9375eefbc40SYue Hin Lau /* Send VBIOS command to control eDP panel backlight */ 9385eefbc40SYue Hin Lau 9391296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 9405eefbc40SYue Hin Lau "%s: backlight action: %s\n", 9415eefbc40SYue Hin Lau __func__, (enable ? "On":"Off")); 9425eefbc40SYue Hin Lau 9435eefbc40SYue Hin Lau cntl.action = enable ? 9445eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_ON : 9455eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_OFF; 94687401969SAndrew Jiang 9475eefbc40SYue Hin Lau /*cntl.engine_id = ctx->engine;*/ 9485eefbc40SYue Hin Lau cntl.transmitter = link->link_enc->transmitter; 9495eefbc40SYue Hin Lau cntl.connector_obj_id = link->link_enc->connector; 9505eefbc40SYue Hin Lau /*todo: unhardcode*/ 9515eefbc40SYue Hin Lau cntl.lanes_number = LANE_COUNT_FOUR; 9525eefbc40SYue Hin Lau cntl.hpd_sel = link->link_enc->hpd_source; 953cf1835f0SCharlene Liu cntl.signal = SIGNAL_TYPE_EDP; 9545eefbc40SYue Hin Lau 9555eefbc40SYue Hin Lau /* For eDP, the following delays might need to be considered 9565eefbc40SYue Hin Lau * after link training completed: 9575eefbc40SYue Hin Lau * idle period - min. accounts for required BS-Idle pattern, 9585eefbc40SYue Hin Lau * max. allows for source frame synchronization); 9595eefbc40SYue Hin Lau * 50 msec max. delay from valid video data from source 9605eefbc40SYue Hin Lau * to video on dislpay or backlight enable. 9615eefbc40SYue Hin Lau * 9625eefbc40SYue Hin Lau * Disable the delay for now. 9635eefbc40SYue Hin Lau * Enable it in the future if necessary. 9645eefbc40SYue Hin Lau */ 9655eefbc40SYue Hin Lau /* dc_service_sleep_in_milliseconds(50); */ 9665180d4a4SCharlene Liu /*edp 1.2*/ 9675180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 9685180d4a4SCharlene Liu edp_receiver_ready_T7(link); 969069d418fSAndrew Jiang link_transmitter_control(ctx->dc_bios, &cntl); 97069b9723aSCharlene Liu /*edp 1.2*/ 9715180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) 97269b9723aSCharlene Liu edp_receiver_ready_T9(link); 9735eefbc40SYue Hin Lau } 9745eefbc40SYue Hin Lau 9754176664bSCharlene Liu void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) 9764562236bSHarry Wentland { 9770971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 978d0778ebfSHarry Wentland struct dc_link *link = stream->sink->link; 9794176664bSCharlene Liu struct dc *dc = pipe_ctx->stream->ctx->dc; 9804562236bSHarry Wentland 9812b7c97d6SCharlene Liu if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 9822b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 9832b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc); 9842b7c97d6SCharlene Liu 9852b7c97d6SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 9862b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 9872b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc); 9882b7c97d6SCharlene Liu 9892b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 9902b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc, true); 991afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio) { 9927c357e61SCharlene Liu if (option != KEEP_ACQUIRED_RESOURCE || 9937c357e61SCharlene Liu !dc->debug.az_endpoint_mute_only) { 9947c357e61SCharlene Liu /*only disalbe az_endpoint if power down or free*/ 995afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); 9967c357e61SCharlene Liu } 9974562236bSHarry Wentland 9984562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 9998e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( 10008e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 10014562236bSHarry Wentland else 10028e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( 10038e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 10044176664bSCharlene Liu /*don't free audio if it is from retrain or internal disable stream*/ 10054176664bSCharlene Liu if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) { 10064176664bSCharlene Liu /*we have to dynamic arbitrate the audio endpoints*/ 10074176664bSCharlene Liu pipe_ctx->stream_res.audio = NULL; 10084176664bSCharlene Liu /*we free the resource, need reset is_audio_acquired*/ 10094176664bSCharlene Liu update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); 10104176664bSCharlene Liu } 10114562236bSHarry Wentland 10124562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 10134562236bSHarry Wentland * add audio mode list change flag */ 10144562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 10154562236bSHarry Wentland * stream->stream_engine_id); 10164562236bSHarry Wentland */ 10174562236bSHarry Wentland } 10184562236bSHarry Wentland 1019904623eeSYongqiang Sun 10204562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe( 10214562236bSHarry Wentland link->link_enc, 10228e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->id, 10234562236bSHarry Wentland false); 10244562236bSHarry Wentland 10254562236bSHarry Wentland } 10264562236bSHarry Wentland 10274562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 10284562236bSHarry Wentland struct dc_link_settings *link_settings) 10294562236bSHarry Wentland { 10304562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 103141b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 103241b49742SCharlene Liu struct dc_link *link = stream->sink->link; 10334562236bSHarry Wentland 10344562236bSHarry Wentland /* only 3 items below are used by unblank */ 10356235b23cSTony Cheng params.pixel_clk_khz = 10364fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.pix_clk_khz; 10374562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 103841b49742SCharlene Liu 103941b49742SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10408e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); 104141b49742SCharlene Liu 104214d6f644SYongqiang Sun if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 104341b49742SCharlene Liu link->dc->hwss.edp_backlight_control(link, true); 10445282cbe3SYongqiang Sun stream->bl_pwm_level = EDP_BACKLIGHT_RAMP_DISABLE_LEVEL; 104514d6f644SYongqiang Sun } 104641b49742SCharlene Liu } 104741b49742SCharlene Liu void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 104841b49742SCharlene Liu { 104941b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 105041b49742SCharlene Liu struct dc_link *link = stream->sink->link; 105141b49742SCharlene Liu 1052ab892598SRoman Li if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 105341b49742SCharlene Liu link->dc->hwss.edp_backlight_control(link, false); 1054ab892598SRoman Li dc_link_set_abm_disable(link); 1055ab892598SRoman Li } 105641b49742SCharlene Liu 105741b49742SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 105841b49742SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); 10594562236bSHarry Wentland } 10604562236bSHarry Wentland 106115e17335SCharlene Liu 106215e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 106315e17335SCharlene Liu { 10648e9c4c8cSHarry Wentland if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL) 10658e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 106615e17335SCharlene Liu } 106715e17335SCharlene Liu 10684562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 10694562236bSHarry Wentland { 10704562236bSHarry Wentland switch (crtc_id) { 10714562236bSHarry Wentland case CONTROLLER_ID_D0: 10724562236bSHarry Wentland return DTO_SOURCE_ID0; 10734562236bSHarry Wentland case CONTROLLER_ID_D1: 10744562236bSHarry Wentland return DTO_SOURCE_ID1; 10754562236bSHarry Wentland case CONTROLLER_ID_D2: 10764562236bSHarry Wentland return DTO_SOURCE_ID2; 10774562236bSHarry Wentland case CONTROLLER_ID_D3: 10784562236bSHarry Wentland return DTO_SOURCE_ID3; 10794562236bSHarry Wentland case CONTROLLER_ID_D4: 10804562236bSHarry Wentland return DTO_SOURCE_ID4; 10814562236bSHarry Wentland case CONTROLLER_ID_D5: 10824562236bSHarry Wentland return DTO_SOURCE_ID5; 10834562236bSHarry Wentland default: 10844562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 10854562236bSHarry Wentland } 10864562236bSHarry Wentland } 10874562236bSHarry Wentland 10884562236bSHarry Wentland static void build_audio_output( 1089ab8db3e1SAndrey Grodzovsky struct dc_state *state, 10904562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 10914562236bSHarry Wentland struct audio_output *audio_output) 10924562236bSHarry Wentland { 10930971c40eSHarry Wentland const struct dc_stream_state *stream = pipe_ctx->stream; 10948e9c4c8cSHarry Wentland audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id; 10954562236bSHarry Wentland 10964562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 10974562236bSHarry Wentland 10984562236bSHarry Wentland /* audio_crtc_info */ 10994562236bSHarry Wentland 11004562236bSHarry Wentland audio_output->crtc_info.h_total = 11014fa086b9SLeo (Sunpeng) Li stream->timing.h_total; 11024562236bSHarry Wentland 11034562236bSHarry Wentland /* 11044562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 11054562236bSHarry Wentland * need to specify actual active signal portion 11064562236bSHarry Wentland */ 11074562236bSHarry Wentland audio_output->crtc_info.h_active = 11084fa086b9SLeo (Sunpeng) Li stream->timing.h_addressable 11094fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_left 11104fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_right; 11114562236bSHarry Wentland 11124562236bSHarry Wentland audio_output->crtc_info.v_active = 11134fa086b9SLeo (Sunpeng) Li stream->timing.v_addressable 11144fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_top 11154fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_bottom; 11164562236bSHarry Wentland 11174562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 11184562236bSHarry Wentland 11194562236bSHarry Wentland audio_output->crtc_info.interlaced = 11204fa086b9SLeo (Sunpeng) Li stream->timing.flags.INTERLACE; 11214562236bSHarry Wentland 11224562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 11234fa086b9SLeo (Sunpeng) Li (stream->timing.pix_clk_khz*1000)/ 11244fa086b9SLeo (Sunpeng) Li (stream->timing.h_total*stream->timing.v_total); 11254562236bSHarry Wentland 11264562236bSHarry Wentland audio_output->crtc_info.color_depth = 11274fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth; 11284562236bSHarry Wentland 11294562236bSHarry Wentland audio_output->crtc_info.requested_pixel_clock = 113010688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 11314562236bSHarry Wentland 11324562236bSHarry Wentland audio_output->crtc_info.calculated_pixel_clock = 113310688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 11344562236bSHarry Wentland 113587b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/ 113687b58768SCharlene Liu if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && 113787b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock == 11384fa086b9SLeo (Sunpeng) Li stream->timing.pix_clk_khz) { 113910688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 114087b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock = 114187b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock/2; 114287b58768SCharlene Liu audio_output->crtc_info.calculated_pixel_clock = 114310688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk/2; 114487b58768SCharlene Liu 114587b58768SCharlene Liu } 114687b58768SCharlene Liu } 114787b58768SCharlene Liu 11484562236bSHarry Wentland if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 11494562236bSHarry Wentland pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { 11504562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 1151ab8db3e1SAndrey Grodzovsky state->dis_clk->funcs->get_dp_ref_clk_frequency( 1152ab8db3e1SAndrey Grodzovsky state->dis_clk); 11534562236bSHarry Wentland } 11544562236bSHarry Wentland 11554562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 11564562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 11574562236bSHarry Wentland 11584562236bSHarry Wentland audio_output->pll_info.dto_source = 11594562236bSHarry Wentland translate_to_dto_source( 1160e07f541fSYongqiang Sun pipe_ctx->stream_res.tg->inst + 1); 11614562236bSHarry Wentland 11624562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 11634562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 11644562236bSHarry Wentland 11654562236bSHarry Wentland audio_output->pll_info.ss_percentage = 11664562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 11674562236bSHarry Wentland } 11684562236bSHarry Wentland 11694562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 11704562236bSHarry Wentland struct tg_color *color) 11714562236bSHarry Wentland { 11722a54bd6eSJerry (Fangzhi) Zuo uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4; 11734562236bSHarry Wentland 11746702a9acSHarry Wentland switch (pipe_ctx->plane_res.scl_data.format) { 11754562236bSHarry Wentland case PIXEL_FORMAT_ARGB8888: 11764562236bSHarry Wentland /* set boarder color to red */ 11774562236bSHarry Wentland color->color_r_cr = color_value; 11784562236bSHarry Wentland break; 11794562236bSHarry Wentland 11804562236bSHarry Wentland case PIXEL_FORMAT_ARGB2101010: 11814562236bSHarry Wentland /* set boarder color to blue */ 11824562236bSHarry Wentland color->color_b_cb = color_value; 11834562236bSHarry Wentland break; 118487449a90SAnthony Koo case PIXEL_FORMAT_420BPP8: 11854562236bSHarry Wentland /* set boarder color to green */ 11864562236bSHarry Wentland color->color_g_y = color_value; 11874562236bSHarry Wentland break; 118887449a90SAnthony Koo case PIXEL_FORMAT_420BPP10: 118987449a90SAnthony Koo /* set boarder color to yellow */ 119087449a90SAnthony Koo color->color_g_y = color_value; 119187449a90SAnthony Koo color->color_r_cr = color_value; 119287449a90SAnthony Koo break; 11934562236bSHarry Wentland case PIXEL_FORMAT_FP16: 11944562236bSHarry Wentland /* set boarder color to white */ 11954562236bSHarry Wentland color->color_r_cr = color_value; 11964562236bSHarry Wentland color->color_b_cb = color_value; 11974562236bSHarry Wentland color->color_g_y = color_value; 11984562236bSHarry Wentland break; 11994562236bSHarry Wentland default: 12004562236bSHarry Wentland break; 12014562236bSHarry Wentland } 12024562236bSHarry Wentland } 12034562236bSHarry Wentland 1204fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc, 12054562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 12064562236bSHarry Wentland { 12074562236bSHarry Wentland struct tg_color color = {0}; 12084562236bSHarry Wentland 1209ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1210ff5ef992SAlex Deucher /* TOFPGA */ 121186a66c4eSHarry Wentland if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) 1212ff5ef992SAlex Deucher return; 1213ff5ef992SAlex Deucher #endif 1214ff5ef992SAlex Deucher 1215fb3466a4SBhawanpreet Lakha if (dc->debug.surface_visual_confirm) 12164562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 12174562236bSHarry Wentland else 12184562236bSHarry Wentland color_space_to_black_color(dc, 12194fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space, 12204562236bSHarry Wentland &color); 12214562236bSHarry Wentland 122286a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 122386a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, 12246702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.depth, 12254562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 12264562236bSHarry Wentland 12276b670fa9SHarry Wentland if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) 12286b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 12296b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 12304562236bSHarry Wentland &color); 12314562236bSHarry Wentland 123286a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 12336702a9acSHarry Wentland &pipe_ctx->plane_res.scl_data); 12344562236bSHarry Wentland } 12354562236bSHarry Wentland 12363158223eSEric Bernstein static enum dc_status dce110_enable_stream_timing( 12374562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1238608ac7bbSJerry Zuo struct dc_state *context, 1239fb3466a4SBhawanpreet Lakha struct dc *dc) 12404562236bSHarry Wentland { 12410971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1242608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 12434562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 12444562236bSHarry Wentland struct tg_color black_color = {0}; 12454562236bSHarry Wentland 12464562236bSHarry Wentland if (!pipe_ctx_old->stream) { 12474562236bSHarry Wentland 12484562236bSHarry Wentland /* program blank color */ 12494562236bSHarry Wentland color_space_to_black_color(dc, 12504fa086b9SLeo (Sunpeng) Li stream->output_color_space, &black_color); 12516b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank_color( 12526b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 12534562236bSHarry Wentland &black_color); 12544b5e7d62SHersen Wu 12554562236bSHarry Wentland /* 12564562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 12574562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 12584562236bSHarry Wentland */ 12596b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true); 12604562236bSHarry Wentland 12614562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 12624562236bSHarry Wentland pipe_ctx->clock_source, 126310688217SHarry Wentland &pipe_ctx->stream_res.pix_clk_params, 12644562236bSHarry Wentland &pipe_ctx->pll_settings)) { 12654562236bSHarry Wentland BREAK_TO_DEBUGGER(); 12664562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 12674562236bSHarry Wentland } 12684562236bSHarry Wentland 12696b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->program_timing( 12706b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 12714fa086b9SLeo (Sunpeng) Li &stream->timing, 12724562236bSHarry Wentland true); 127394267b3dSSylvia Tsai 12746b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 12756b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 127694267b3dSSylvia Tsai 0x182); 12774562236bSHarry Wentland } 12784562236bSHarry Wentland 12794562236bSHarry Wentland if (!pipe_ctx_old->stream) { 12806b670fa9SHarry Wentland if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc( 12816b670fa9SHarry Wentland pipe_ctx->stream_res.tg)) { 12824562236bSHarry Wentland BREAK_TO_DEBUGGER(); 12834562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 12844562236bSHarry Wentland } 12854562236bSHarry Wentland } 12864562236bSHarry Wentland 128794267b3dSSylvia Tsai 128894267b3dSSylvia Tsai 12894562236bSHarry Wentland return DC_OK; 12904562236bSHarry Wentland } 12914562236bSHarry Wentland 12924562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 12934562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1294608ac7bbSJerry Zuo struct dc_state *context, 1295fb3466a4SBhawanpreet Lakha struct dc *dc) 12964562236bSHarry Wentland { 12970971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1298608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 12994562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 13004562236bSHarry Wentland 13014562236bSHarry Wentland /* */ 13023158223eSEric Bernstein dc->hwss.enable_stream_timing(pipe_ctx, context, dc); 13034562236bSHarry Wentland 1304f0c4d997SCorbin McElhanney /* FPGA does not program backend */ 1305f0c4d997SCorbin McElhanney if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 1306a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1307a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 13084562236bSHarry Wentland COLOR_SPACE_YCBCR601, 13094fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth, 13104562236bSHarry Wentland pipe_ctx->stream->signal); 13114562236bSHarry Wentland 1312a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1313a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 13144562236bSHarry Wentland &stream->bit_depth_params, 13154562236bSHarry Wentland &stream->clamping); 13164562236bSHarry Wentland return DC_OK; 1317181a888fSCharlene Liu } 13184562236bSHarry Wentland /* TODO: move to stream encoder */ 13194562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 13204562236bSHarry Wentland if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) { 13214562236bSHarry Wentland BREAK_TO_DEBUGGER(); 13224562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 13234562236bSHarry Wentland } 1324f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1325f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp, 1326f0c4d997SCorbin McElhanney COLOR_SPACE_YCBCR601, 1327f0c4d997SCorbin McElhanney stream->timing.display_color_depth, 1328f0c4d997SCorbin McElhanney pipe_ctx->stream->signal); 13294562236bSHarry Wentland 13304562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 13314562236bSHarry Wentland stream->sink->link->link_enc->funcs->setup( 13324562236bSHarry Wentland stream->sink->link->link_enc, 13334562236bSHarry Wentland pipe_ctx->stream->signal); 13344562236bSHarry Wentland 1335ab3c1798SVitaly Prosyak if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 13368e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync( 13378e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 13386b670fa9SHarry Wentland pipe_ctx->stream_res.tg->inst, 13394fa086b9SLeo (Sunpeng) Li stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE); 1340ab3c1798SVitaly Prosyak 1341ab3c1798SVitaly Prosyak 1342a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1343a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 1344181a888fSCharlene Liu &stream->bit_depth_params, 1345181a888fSCharlene Liu &stream->clamping); 1346603767f9STony Cheng 13474562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 13488e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute( 13498e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 13504fa086b9SLeo (Sunpeng) Li &stream->timing, 13514fa086b9SLeo (Sunpeng) Li stream->output_color_space); 13524562236bSHarry Wentland 13534562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 13548e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute( 13558e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 13564fa086b9SLeo (Sunpeng) Li &stream->timing, 13574562236bSHarry Wentland stream->phy_pix_clk, 1358afaacef4SHarry Wentland pipe_ctx->stream_res.audio != NULL); 13594562236bSHarry Wentland 13604562236bSHarry Wentland if (dc_is_dvi_signal(pipe_ctx->stream->signal)) 13618e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute( 13628e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 13634fa086b9SLeo (Sunpeng) Li &stream->timing, 13644562236bSHarry Wentland (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? 13654562236bSHarry Wentland true : false); 13664562236bSHarry Wentland 136715e17335SCharlene Liu resource_build_info_frame(pipe_ctx); 13683639fa68SZeyu Fan dce110_update_info_frame(pipe_ctx); 1369f0362823SYongqiang Sun if (!pipe_ctx_old->stream) 1370ab8db3e1SAndrey Grodzovsky core_link_enable_stream(context, pipe_ctx); 13714562236bSHarry Wentland 13726702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 13734562236bSHarry Wentland 137494267b3dSSylvia Tsai pipe_ctx->stream->sink->link->psr_enabled = false; 137594267b3dSSylvia Tsai 13764562236bSHarry Wentland return DC_OK; 13774562236bSHarry Wentland } 13784562236bSHarry Wentland 13794562236bSHarry Wentland /******************************************************************************/ 13804562236bSHarry Wentland 1381fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc) 13824562236bSHarry Wentland { 13834562236bSHarry Wentland int i; 1384a0c38ebaSCharlene Liu enum connector_id connector_id; 138568d77dd8SAndrew Jiang enum signal_type signal = SIGNAL_TYPE_NONE; 1386b9b171ffSHersen Wu 1387b9b171ffSHersen Wu /* do not know BIOS back-front mapping, simply blank all. It will not 1388b9b171ffSHersen Wu * hurt for non-DP 1389b9b171ffSHersen Wu */ 1390b9b171ffSHersen Wu for (i = 0; i < dc->res_pool->stream_enc_count; i++) { 1391b9b171ffSHersen Wu dc->res_pool->stream_enc[i]->funcs->dp_blank( 1392b9b171ffSHersen Wu dc->res_pool->stream_enc[i]); 1393b9b171ffSHersen Wu } 1394b9b171ffSHersen Wu 13954562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 1396a0c38ebaSCharlene Liu connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id); 1397a0c38ebaSCharlene Liu if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) || 1398a0c38ebaSCharlene Liu (connector_id == CONNECTOR_ID_EDP)) { 1399a0c38ebaSCharlene Liu 1400a0c38ebaSCharlene Liu if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) 1401a0c38ebaSCharlene Liu dp_receiver_power_ctrl(dc->links[i], false); 1402904623eeSYongqiang Sun if (connector_id == CONNECTOR_ID_EDP) 140368d77dd8SAndrew Jiang signal = SIGNAL_TYPE_EDP; 1404a0c38ebaSCharlene Liu } 1405a0c38ebaSCharlene Liu 14064562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 1407069d418fSAndrew Jiang dc->links[i]->link_enc, signal); 14084562236bSHarry Wentland } 14094562236bSHarry Wentland } 14104562236bSHarry Wentland 1411fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc) 14124562236bSHarry Wentland { 14134562236bSHarry Wentland int i; 14144562236bSHarry Wentland 14154562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 14164562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 14174562236bSHarry Wentland dc->res_pool->timing_generators[i]); 14184562236bSHarry Wentland } 14194562236bSHarry Wentland } 14204562236bSHarry Wentland 1421fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc) 14224562236bSHarry Wentland { 14234562236bSHarry Wentland int i; 14244562236bSHarry Wentland 14254562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 14264562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 14274562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 14284562236bSHarry Wentland 14294562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 14304562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 14314562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 14324562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 14334562236bSHarry Wentland } 14344562236bSHarry Wentland } 14354562236bSHarry Wentland 1436fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc) 14374562236bSHarry Wentland { 14384562236bSHarry Wentland power_down_encoders(dc); 14394562236bSHarry Wentland 14404562236bSHarry Wentland power_down_controllers(dc); 14414562236bSHarry Wentland 14424562236bSHarry Wentland power_down_clock_sources(dc); 14431663ae1cSBhawanpreet Lakha 14443eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 14452f3bfb27SRoman Li if (dc->fbc_compressor) 14461663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 14471663ae1cSBhawanpreet Lakha #endif 14484562236bSHarry Wentland } 14494562236bSHarry Wentland 14504562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 1451fb3466a4SBhawanpreet Lakha struct dc *dc) 14524562236bSHarry Wentland { 14534562236bSHarry Wentland int i; 14544562236bSHarry Wentland struct timing_generator *tg; 14554562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 14564562236bSHarry Wentland 14574562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 14584562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 14594562236bSHarry Wentland 14600a87425aSTony Cheng if (tg->funcs->disable_vga) 14614562236bSHarry Wentland tg->funcs->disable_vga(tg); 14624562236bSHarry Wentland 14634562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 14644562236bSHarry Wentland * powergating. */ 14654562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 14664562236bSHarry Wentland true); 14674562236bSHarry Wentland 1468e6c258cbSYongqiang Sun dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i; 14697f914a62SYongqiang Sun dc->hwss.disable_plane(dc, 1470e6c258cbSYongqiang Sun &dc->current_state->res_ctx.pipe_ctx[i]); 14714562236bSHarry Wentland } 14724562236bSHarry Wentland } 14734562236bSHarry Wentland 1474f0c0761bSYongqiang Sun static struct dc_link *get_link_for_edp(struct dc *dc) 1475339cc82aSYongqiang Sun { 1476339cc82aSYongqiang Sun int i; 1477339cc82aSYongqiang Sun 1478f0c0761bSYongqiang Sun for (i = 0; i < dc->link_count; i++) { 1479f0c0761bSYongqiang Sun if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) 1480f0c0761bSYongqiang Sun return dc->links[i]; 1481339cc82aSYongqiang Sun } 1482f0c0761bSYongqiang Sun return NULL; 1483339cc82aSYongqiang Sun } 1484339cc82aSYongqiang Sun 1485cf1835f0SCharlene Liu static struct dc_link *get_link_for_edp_not_in_use( 148625292028SYongqiang Sun struct dc *dc, 148725292028SYongqiang Sun struct dc_state *context) 148825292028SYongqiang Sun { 148925292028SYongqiang Sun int i; 149025292028SYongqiang Sun struct dc_link *link = NULL; 149125292028SYongqiang Sun 149225292028SYongqiang Sun /* check if eDP panel is suppose to be set mode, if yes, no need to disable */ 149325292028SYongqiang Sun for (i = 0; i < context->stream_count; i++) { 149425292028SYongqiang Sun if (context->streams[i]->signal == SIGNAL_TYPE_EDP) 149525292028SYongqiang Sun return NULL; 149625292028SYongqiang Sun } 149725292028SYongqiang Sun 149825292028SYongqiang Sun /* check if there is an eDP panel not in use */ 149925292028SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 150025292028SYongqiang Sun if (dc->links[i]->local_sink && 150125292028SYongqiang Sun dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 150225292028SYongqiang Sun link = dc->links[i]; 150325292028SYongqiang Sun break; 150425292028SYongqiang Sun } 150525292028SYongqiang Sun } 150625292028SYongqiang Sun 150725292028SYongqiang Sun return link; 150825292028SYongqiang Sun } 150925292028SYongqiang Sun 15104562236bSHarry Wentland /** 15114562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 15124562236bSHarry Wentland * 1. Power down all DC HW blocks 15134562236bSHarry Wentland * 2. Disable VGA engine on all controllers 15144562236bSHarry Wentland * 3. Enable power gating for controller 15154562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 15164562236bSHarry Wentland */ 151725292028SYongqiang Sun void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 15184562236bSHarry Wentland { 15194cac1e6dSYongqiang Sun struct dc_link *edp_link_to_turnoff = NULL; 1520f0c0761bSYongqiang Sun struct dc_link *edp_link = get_link_for_edp(dc); 1521f0c0761bSYongqiang Sun bool can_eDP_fast_boot_optimize = false; 15224cac1e6dSYongqiang Sun 1523f0c0761bSYongqiang Sun if (edp_link) { 1524f0c0761bSYongqiang Sun can_eDP_fast_boot_optimize = 1525f0c0761bSYongqiang Sun edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc); 1526f0c0761bSYongqiang Sun } 1527f0c0761bSYongqiang Sun 1528f0c0761bSYongqiang Sun if (can_eDP_fast_boot_optimize) { 15294cac1e6dSYongqiang Sun edp_link_to_turnoff = get_link_for_edp_not_in_use(dc, context); 15304cac1e6dSYongqiang Sun 15312c37e49aSYongqiang Sun /* if OS doesn't light up eDP and eDP link is available, we want to disable 15322c37e49aSYongqiang Sun * If resume from S4/S5, should optimization. 15332c37e49aSYongqiang Sun */ 1534f0c0761bSYongqiang Sun if (!edp_link_to_turnoff) 15354cac1e6dSYongqiang Sun dc->apply_edp_fast_boot_optimization = true; 15364cac1e6dSYongqiang Sun } 15374cac1e6dSYongqiang Sun 15384cac1e6dSYongqiang Sun if (!dc->apply_edp_fast_boot_optimization) { 15394cac1e6dSYongqiang Sun if (edp_link_to_turnoff) { 15404cac1e6dSYongqiang Sun /*turn off backlight before DP_blank and encoder powered down*/ 15414cac1e6dSYongqiang Sun dc->hwss.edp_backlight_control(edp_link_to_turnoff, false); 1542c5fc7f59SCharlene Liu } 1543c5fc7f59SCharlene Liu /*resume from S3, no vbios posting, no need to power down again*/ 154425292028SYongqiang Sun power_down_all_hw_blocks(dc); 15454562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 1546cf1835f0SCharlene Liu if (edp_link_to_turnoff) 1547cf1835f0SCharlene Liu dc->hwss.edp_power_control(edp_link_to_turnoff, false); 1548c5fc7f59SCharlene Liu } 15494562236bSHarry Wentland bios_set_scratch_acc_mode_change(dc->ctx->dc_bios); 15504562236bSHarry Wentland } 15514562236bSHarry Wentland 15524562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 15534562236bSHarry Wentland struct bw_fixed blackout_duration, 15540971c40eSHarry Wentland const struct dc_stream_state *stream) 15554562236bSHarry Wentland { 15564562236bSHarry Wentland uint32_t total_dest_line_time_ns; 15574562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 15584562236bSHarry Wentland 15594562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 15604562236bSHarry Wentland 15614562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 15624fa086b9SLeo (Sunpeng) Li stream->timing.h_total / 15634fa086b9SLeo (Sunpeng) Li stream->timing.pix_clk_khz + 15644562236bSHarry Wentland pstate_blackout_duration_ns; 15654562236bSHarry Wentland 15664562236bSHarry Wentland return total_dest_line_time_ns; 15674562236bSHarry Wentland } 15684562236bSHarry Wentland 1569f774b339SEric Yang static void dce110_set_displaymarks( 1570fb3466a4SBhawanpreet Lakha const struct dc *dc, 1571608ac7bbSJerry Zuo struct dc_state *context) 15724562236bSHarry Wentland { 15734562236bSHarry Wentland uint8_t i, num_pipes; 15744562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 15754562236bSHarry Wentland 15764562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 15774562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 15784562236bSHarry Wentland uint32_t total_dest_line_time_ns; 15794562236bSHarry Wentland 15804562236bSHarry Wentland if (pipe_ctx->stream == NULL) 15814562236bSHarry Wentland continue; 15824562236bSHarry Wentland 15834562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 158477a4ea53SBhawanpreet Lakha dc->bw_vbios->blackout_duration, pipe_ctx->stream); 158586a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( 158686a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 15879037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 15889037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 15893722c794SMikita Lipski context->bw.dce.stutter_entry_wm_ns[num_pipes], 15909037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 15914562236bSHarry Wentland total_dest_line_time_ns); 15924562236bSHarry Wentland if (i == underlay_idx) { 15934562236bSHarry Wentland num_pipes++; 159486a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( 159586a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 15969037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 15979037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 15989037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 15994562236bSHarry Wentland total_dest_line_time_ns); 16004562236bSHarry Wentland } 16014562236bSHarry Wentland num_pipes++; 16024562236bSHarry Wentland } 16034562236bSHarry Wentland } 16044562236bSHarry Wentland 1605a2b8659dSTony Cheng static void set_safe_displaymarks( 1606a2b8659dSTony Cheng struct resource_context *res_ctx, 1607a2b8659dSTony Cheng const struct resource_pool *pool) 16084562236bSHarry Wentland { 16094562236bSHarry Wentland int i; 1610a2b8659dSTony Cheng int underlay_idx = pool->underlay_pipe_index; 16119037d802SDmytro Laktyushkin struct dce_watermarks max_marks = { 16124562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 16139037d802SDmytro Laktyushkin struct dce_watermarks nbp_marks = { 16144562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 16153722c794SMikita Lipski struct dce_watermarks min_marks = { 0, 0, 0, 0}; 16164562236bSHarry Wentland 16174562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 16188feabd03SYue Hin Lau if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) 16194562236bSHarry Wentland continue; 16204562236bSHarry Wentland 162186a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 162286a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 16234562236bSHarry Wentland nbp_marks, 16244562236bSHarry Wentland max_marks, 16253722c794SMikita Lipski min_marks, 16264562236bSHarry Wentland max_marks, 16274562236bSHarry Wentland MAX_WATERMARK); 16288feabd03SYue Hin Lau 16294562236bSHarry Wentland if (i == underlay_idx) 163086a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 163186a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 16324562236bSHarry Wentland nbp_marks, 16334562236bSHarry Wentland max_marks, 16344562236bSHarry Wentland max_marks, 16354562236bSHarry Wentland MAX_WATERMARK); 16368feabd03SYue Hin Lau 16374562236bSHarry Wentland } 16384562236bSHarry Wentland } 16394562236bSHarry Wentland 16404562236bSHarry Wentland /******************************************************************************* 16414562236bSHarry Wentland * Public functions 16424562236bSHarry Wentland ******************************************************************************/ 16434562236bSHarry Wentland 16444562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 16454562236bSHarry Wentland int num_pipes, int vmin, int vmax) 16464562236bSHarry Wentland { 16474562236bSHarry Wentland int i = 0; 16484562236bSHarry Wentland struct drr_params params = {0}; 16494562236bSHarry Wentland 16504562236bSHarry Wentland params.vertical_total_max = vmax; 16514562236bSHarry Wentland params.vertical_total_min = vmin; 16524562236bSHarry Wentland 16534562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 16544562236bSHarry Wentland * some GSL stuff 16554562236bSHarry Wentland */ 16564562236bSHarry Wentland 16574562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 16586b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, ¶ms); 16594562236bSHarry Wentland } 16604562236bSHarry Wentland } 16614562236bSHarry Wentland 166272ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx, 166372ada5f7SEric Cook int num_pipes, 166472ada5f7SEric Cook struct crtc_position *position) 166572ada5f7SEric Cook { 166672ada5f7SEric Cook int i = 0; 166772ada5f7SEric Cook 166872ada5f7SEric Cook /* TODO: handle pipes > 1 166972ada5f7SEric Cook */ 167072ada5f7SEric Cook for (i = 0; i < num_pipes; i++) 16716b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position); 167272ada5f7SEric Cook } 167372ada5f7SEric Cook 16744562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 167594267b3dSSylvia Tsai int num_pipes, const struct dc_static_screen_events *events) 16764562236bSHarry Wentland { 16774562236bSHarry Wentland unsigned int i; 167894267b3dSSylvia Tsai unsigned int value = 0; 167994267b3dSSylvia Tsai 168094267b3dSSylvia Tsai if (events->overlay_update) 168194267b3dSSylvia Tsai value |= 0x100; 168294267b3dSSylvia Tsai if (events->surface_update) 168394267b3dSSylvia Tsai value |= 0x80; 168494267b3dSSylvia Tsai if (events->cursor_update) 168594267b3dSSylvia Tsai value |= 0x2; 1686ed8462acSCharlene Liu if (events->force_trigger) 1687ed8462acSCharlene Liu value |= 0x1; 16884562236bSHarry Wentland 16893eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 1690c3aa1d67SBhawanpreet Lakha value |= 0x84; 1691c3aa1d67SBhawanpreet Lakha #endif 1692c3aa1d67SBhawanpreet Lakha 16934562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 16946b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs-> 16956b670fa9SHarry Wentland set_static_screen_control(pipe_ctx[i]->stream_res.tg, value); 16964562236bSHarry Wentland } 16974562236bSHarry Wentland 16984562236bSHarry Wentland /* unit: in_khz before mode set, get pixel clock from context. ASIC register 16994562236bSHarry Wentland * may not be programmed yet. 17004562236bSHarry Wentland * TODO: after mode set, pre_mode_set = false, 17014562236bSHarry Wentland * may read PLL register to get pixel clock 17024562236bSHarry Wentland */ 17034562236bSHarry Wentland static uint32_t get_max_pixel_clock_for_all_paths( 1704fb3466a4SBhawanpreet Lakha struct dc *dc, 1705608ac7bbSJerry Zuo struct dc_state *context, 17064562236bSHarry Wentland bool pre_mode_set) 17074562236bSHarry Wentland { 17084562236bSHarry Wentland uint32_t max_pix_clk = 0; 17094562236bSHarry Wentland int i; 17104562236bSHarry Wentland 17114562236bSHarry Wentland if (!pre_mode_set) { 17124562236bSHarry Wentland /* TODO: read ASIC register to get pixel clock */ 17134562236bSHarry Wentland ASSERT(0); 17144562236bSHarry Wentland } 17154562236bSHarry Wentland 17164562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 17174562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 17184562236bSHarry Wentland 17194562236bSHarry Wentland if (pipe_ctx->stream == NULL) 17204562236bSHarry Wentland continue; 17214562236bSHarry Wentland 17224562236bSHarry Wentland /* do not check under lay */ 17234562236bSHarry Wentland if (pipe_ctx->top_pipe) 17244562236bSHarry Wentland continue; 17254562236bSHarry Wentland 172610688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk) 17274562236bSHarry Wentland max_pix_clk = 172810688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 17294562236bSHarry Wentland } 17304562236bSHarry Wentland 17314562236bSHarry Wentland if (max_pix_clk == 0) 17324562236bSHarry Wentland ASSERT(0); 17334562236bSHarry Wentland 17344562236bSHarry Wentland return max_pix_clk; 17354562236bSHarry Wentland } 17364562236bSHarry Wentland 1737f6baff4dSHarry Wentland /* 1738f6baff4dSHarry Wentland * Find clock state based on clock requested. if clock value is 0, simply 17394562236bSHarry Wentland * set clock state as requested without finding clock state by clock value 17404562236bSHarry Wentland */ 1741f6baff4dSHarry Wentland 17424562236bSHarry Wentland static void apply_min_clocks( 1743fb3466a4SBhawanpreet Lakha struct dc *dc, 1744608ac7bbSJerry Zuo struct dc_state *context, 1745e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state *clocks_state, 17464562236bSHarry Wentland bool pre_mode_set) 17474562236bSHarry Wentland { 17484562236bSHarry Wentland struct state_dependent_clocks req_clocks = {0}; 17494562236bSHarry Wentland 17504562236bSHarry Wentland if (!pre_mode_set) { 17514562236bSHarry Wentland /* set clock_state without verification */ 1752ab8db3e1SAndrey Grodzovsky if (context->dis_clk->funcs->set_min_clocks_state) { 1753ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->set_min_clocks_state( 1754ab8db3e1SAndrey Grodzovsky context->dis_clk, *clocks_state); 17554562236bSHarry Wentland return; 17565d6d185fSDmytro Laktyushkin } 17574562236bSHarry Wentland 17582c8ad2d5SAlex Deucher /* TODO: This is incorrect. Figure out how to fix. */ 1759ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1760ab8db3e1SAndrey Grodzovsky context->dis_clk, 17612c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAY_CLK, 1762ab8db3e1SAndrey Grodzovsky context->dis_clk->cur_clocks_value.dispclk_in_khz, 17632c8ad2d5SAlex Deucher pre_mode_set, 17642c8ad2d5SAlex Deucher false); 17652c8ad2d5SAlex Deucher 1766ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1767ab8db3e1SAndrey Grodzovsky context->dis_clk, 17682c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_PIXELCLK, 1769ab8db3e1SAndrey Grodzovsky context->dis_clk->cur_clocks_value.max_pixelclk_in_khz, 17702c8ad2d5SAlex Deucher pre_mode_set, 17712c8ad2d5SAlex Deucher false); 17722c8ad2d5SAlex Deucher 1773ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1774ab8db3e1SAndrey Grodzovsky context->dis_clk, 17752c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, 1776ab8db3e1SAndrey Grodzovsky context->dis_clk->cur_clocks_value.max_non_dp_phyclk_in_khz, 17772c8ad2d5SAlex Deucher pre_mode_set, 17782c8ad2d5SAlex Deucher false); 17792c8ad2d5SAlex Deucher return; 17804562236bSHarry Wentland } 17814562236bSHarry Wentland 17824562236bSHarry Wentland /* get the required state based on state dependent clocks: 17834562236bSHarry Wentland * display clock and pixel clock 17844562236bSHarry Wentland */ 17859037d802SDmytro Laktyushkin req_clocks.display_clk_khz = context->bw.dce.dispclk_khz; 17864562236bSHarry Wentland 17874562236bSHarry Wentland req_clocks.pixel_clk_khz = get_max_pixel_clock_for_all_paths( 17884562236bSHarry Wentland dc, context, true); 17894562236bSHarry Wentland 1790ab8db3e1SAndrey Grodzovsky if (context->dis_clk->funcs->get_required_clocks_state) { 1791ab8db3e1SAndrey Grodzovsky *clocks_state = context->dis_clk->funcs->get_required_clocks_state( 1792ab8db3e1SAndrey Grodzovsky context->dis_clk, &req_clocks); 1793ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->set_min_clocks_state( 1794ab8db3e1SAndrey Grodzovsky context->dis_clk, *clocks_state); 17954562236bSHarry Wentland } else { 1796ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1797ab8db3e1SAndrey Grodzovsky context->dis_clk, 17982c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAY_CLK, 17992c8ad2d5SAlex Deucher req_clocks.display_clk_khz, 18002c8ad2d5SAlex Deucher pre_mode_set, 18012c8ad2d5SAlex Deucher false); 18022c8ad2d5SAlex Deucher 1803ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1804ab8db3e1SAndrey Grodzovsky context->dis_clk, 18052c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_PIXELCLK, 18062c8ad2d5SAlex Deucher req_clocks.pixel_clk_khz, 18072c8ad2d5SAlex Deucher pre_mode_set, 18082c8ad2d5SAlex Deucher false); 18092c8ad2d5SAlex Deucher 1810ab8db3e1SAndrey Grodzovsky context->dis_clk->funcs->apply_clock_voltage_request( 1811ab8db3e1SAndrey Grodzovsky context->dis_clk, 18122c8ad2d5SAlex Deucher DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, 18132c8ad2d5SAlex Deucher req_clocks.pixel_clk_khz, 18142c8ad2d5SAlex Deucher pre_mode_set, 18152c8ad2d5SAlex Deucher false); 18164562236bSHarry Wentland } 18174562236bSHarry Wentland } 18184562236bSHarry Wentland 18193eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 1820690b5e39SRoman Li 1821690b5e39SRoman Li /* 1822690b5e39SRoman Li * Check if FBC can be enabled 1823690b5e39SRoman Li */ 18249c6569deSHarry Wentland static bool should_enable_fbc(struct dc *dc, 18253bc4aaa9SRoman Li struct dc_state *context, 18263bc4aaa9SRoman Li uint32_t *pipe_idx) 1827690b5e39SRoman Li { 18283bc4aaa9SRoman Li uint32_t i; 18293bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = NULL; 18303bc4aaa9SRoman Li struct resource_context *res_ctx = &context->res_ctx; 18313bc4aaa9SRoman Li 1832690b5e39SRoman Li 1833690b5e39SRoman Li ASSERT(dc->fbc_compressor); 1834690b5e39SRoman Li 1835690b5e39SRoman Li /* FBC memory should be allocated */ 1836690b5e39SRoman Li if (!dc->ctx->fbc_gpu_addr) 18379c6569deSHarry Wentland return false; 1838690b5e39SRoman Li 1839690b5e39SRoman Li /* Only supports single display */ 1840690b5e39SRoman Li if (context->stream_count != 1) 18419c6569deSHarry Wentland return false; 1842690b5e39SRoman Li 18433bc4aaa9SRoman Li for (i = 0; i < dc->res_pool->pipe_count; i++) { 18443bc4aaa9SRoman Li if (res_ctx->pipe_ctx[i].stream) { 18453bc4aaa9SRoman Li pipe_ctx = &res_ctx->pipe_ctx[i]; 18463bc4aaa9SRoman Li *pipe_idx = i; 18473bc4aaa9SRoman Li break; 18483bc4aaa9SRoman Li } 18493bc4aaa9SRoman Li } 18503bc4aaa9SRoman Li 18517a840773SRoman Li /* Pipe context should be found */ 18527a840773SRoman Li ASSERT(pipe_ctx); 18537a840773SRoman Li 1854690b5e39SRoman Li /* Only supports eDP */ 1855690b5e39SRoman Li if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) 18569c6569deSHarry Wentland return false; 1857690b5e39SRoman Li 1858690b5e39SRoman Li /* PSR should not be enabled */ 1859690b5e39SRoman Li if (pipe_ctx->stream->sink->link->psr_enabled) 18609c6569deSHarry Wentland return false; 1861690b5e39SRoman Li 186293984bbcSShirish S /* Nothing to compress */ 186393984bbcSShirish S if (!pipe_ctx->plane_state) 18649c6569deSHarry Wentland return false; 186593984bbcSShirish S 186605230fa9SRoman Li /* Only for non-linear tiling */ 186705230fa9SRoman Li if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 18689c6569deSHarry Wentland return false; 186905230fa9SRoman Li 18709c6569deSHarry Wentland return true; 1871690b5e39SRoman Li } 1872690b5e39SRoman Li 1873690b5e39SRoman Li /* 1874690b5e39SRoman Li * Enable FBC 1875690b5e39SRoman Li */ 18769c6569deSHarry Wentland static void enable_fbc(struct dc *dc, 1877608ac7bbSJerry Zuo struct dc_state *context) 1878690b5e39SRoman Li { 18793bc4aaa9SRoman Li uint32_t pipe_idx = 0; 18803bc4aaa9SRoman Li 18813bc4aaa9SRoman Li if (should_enable_fbc(dc, context, &pipe_idx)) { 1882690b5e39SRoman Li /* Program GRPH COMPRESSED ADDRESS and PITCH */ 1883690b5e39SRoman Li struct compr_addr_and_pitch_params params = {0, 0, 0}; 1884690b5e39SRoman Li struct compressor *compr = dc->fbc_compressor; 18853bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 18863bc4aaa9SRoman Li 1887690b5e39SRoman Li 18889c6569deSHarry Wentland params.source_view_width = pipe_ctx->stream->timing.h_addressable; 18899c6569deSHarry Wentland params.source_view_height = pipe_ctx->stream->timing.v_addressable; 1890690b5e39SRoman Li 1891690b5e39SRoman Li compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 1892690b5e39SRoman Li 1893690b5e39SRoman Li compr->funcs->surface_address_and_pitch(compr, ¶ms); 1894690b5e39SRoman Li compr->funcs->set_fbc_invalidation_triggers(compr, 1); 1895690b5e39SRoman Li 1896690b5e39SRoman Li compr->funcs->enable_fbc(compr, ¶ms); 1897690b5e39SRoman Li } 1898690b5e39SRoman Li } 1899690b5e39SRoman Li #endif 1900690b5e39SRoman Li 190154e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap( 1902fb3466a4SBhawanpreet Lakha struct dc *dc, 1903608ac7bbSJerry Zuo struct dc_state *context) 19044562236bSHarry Wentland { 19054562236bSHarry Wentland int i; 19064562236bSHarry Wentland 19074562236bSHarry Wentland /* Reset old context */ 19084562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 1909a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 19104562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 1911608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 19124562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 19134562236bSHarry Wentland 19144562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 19154562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 19164562236bSHarry Wentland * PHY when not already disabled. 19174562236bSHarry Wentland */ 19184562236bSHarry Wentland 19194562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 19204562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 19214562236bSHarry Wentland continue; 19224562236bSHarry Wentland 19234562236bSHarry Wentland if (!pipe_ctx->stream || 192454e8695eSDmytro Laktyushkin pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 192521e67d4dSHarry Wentland struct clock_source *old_clk = pipe_ctx_old->clock_source; 192621e67d4dSHarry Wentland 1927827f11e9SLeo (Sunpeng) Li /* Disable if new stream is null. O/w, if stream is 1928827f11e9SLeo (Sunpeng) Li * disabled already, no need to disable again. 1929827f11e9SLeo (Sunpeng) Li */ 1930827f11e9SLeo (Sunpeng) Li if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) 19314176664bSCharlene Liu core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); 1932d050f8edSHersen Wu 19336b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 19346b670fa9SHarry Wentland if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 193554e8695eSDmytro Laktyushkin dm_error("DC: failed to blank crtc!\n"); 193654e8695eSDmytro Laktyushkin BREAK_TO_DEBUGGER(); 193754e8695eSDmytro Laktyushkin } 19386b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); 193986a66c4eSHarry Wentland pipe_ctx_old->plane_res.mi->funcs->free_mem_input( 1940608ac7bbSJerry Zuo pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); 194154e8695eSDmytro Laktyushkin 194221e67d4dSHarry Wentland if (old_clk) 194321e67d4dSHarry Wentland old_clk->funcs->cs_power_down(old_clk); 194421e67d4dSHarry Wentland 19457f914a62SYongqiang Sun dc->hwss.disable_plane(dc, pipe_ctx_old); 194654e8695eSDmytro Laktyushkin 194754e8695eSDmytro Laktyushkin pipe_ctx_old->stream = NULL; 194854e8695eSDmytro Laktyushkin } 19494562236bSHarry Wentland } 19504562236bSHarry Wentland } 19514562236bSHarry Wentland 1952cf437593SDmytro Laktyushkin 19534562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 1954fb3466a4SBhawanpreet Lakha struct dc *dc, 1955608ac7bbSJerry Zuo struct dc_state *context) 19564562236bSHarry Wentland { 19574562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 19584562236bSHarry Wentland enum dc_status status; 19594562236bSHarry Wentland int i; 1960e9c58bb4SDmytro Laktyushkin enum dm_pp_clocks_state clocks_state = DM_PP_CLOCKS_STATE_INVALID; 19614562236bSHarry Wentland 19624562236bSHarry Wentland /* Reset old context */ 19634562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 19644562236bSHarry Wentland dc->hwss.reset_hw_ctx_wrap(dc, context); 19654562236bSHarry Wentland 19664562236bSHarry Wentland /* Skip applying if no targets */ 1967ab2541b6SAric Cyr if (context->stream_count <= 0) 19684562236bSHarry Wentland return DC_OK; 19694562236bSHarry Wentland 19704562236bSHarry Wentland /* Apply new context */ 19714562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 19724562236bSHarry Wentland 19734562236bSHarry Wentland /* below is for real asic only */ 1974a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 19754562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 1976608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 19774562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 19784562236bSHarry Wentland 19794562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 19804562236bSHarry Wentland continue; 19814562236bSHarry Wentland 19824562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 19834562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 19844562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 19854562236bSHarry Wentland pipe_ctx->clock_source, i); 19864562236bSHarry Wentland continue; 19874562236bSHarry Wentland } 19884562236bSHarry Wentland 19894562236bSHarry Wentland dc->hwss.enable_display_power_gating( 19904562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 19914562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 19924562236bSHarry Wentland } 19934562236bSHarry Wentland 1994a2b8659dSTony Cheng set_safe_displaymarks(&context->res_ctx, dc->res_pool); 19951663ae1cSBhawanpreet Lakha 19963eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 19972f3bfb27SRoman Li if (dc->fbc_compressor) 19981663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 19991663ae1cSBhawanpreet Lakha #endif 20004562236bSHarry Wentland /*TODO: when pplib works*/ 20014562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, true); 20024562236bSHarry Wentland 2003ff5ef992SAlex Deucher #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 20043639fa68SZeyu Fan if (dc->ctx->dce_version >= DCN_VERSION_1_0) { 20059037d802SDmytro Laktyushkin if (context->bw.dcn.calc_clk.fclk_khz 2006608ac7bbSJerry Zuo > dc->current_state->bw.dcn.cur_clk.fclk_khz) { 2007ff5ef992SAlex Deucher struct dm_pp_clock_for_voltage_req clock; 2008ff5ef992SAlex Deucher 2009ff5ef992SAlex Deucher clock.clk_type = DM_PP_CLOCK_TYPE_FCLK; 20109037d802SDmytro Laktyushkin clock.clocks_in_khz = context->bw.dcn.calc_clk.fclk_khz; 2011ff5ef992SAlex Deucher dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 2012608ac7bbSJerry Zuo dc->current_state->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 2013c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.fclk_khz = clock.clocks_in_khz; 2014ff5ef992SAlex Deucher } 20159037d802SDmytro Laktyushkin if (context->bw.dcn.calc_clk.dcfclk_khz 2016608ac7bbSJerry Zuo > dc->current_state->bw.dcn.cur_clk.dcfclk_khz) { 2017ff5ef992SAlex Deucher struct dm_pp_clock_for_voltage_req clock; 2018ff5ef992SAlex Deucher 2019ff5ef992SAlex Deucher clock.clk_type = DM_PP_CLOCK_TYPE_DCFCLK; 20209037d802SDmytro Laktyushkin clock.clocks_in_khz = context->bw.dcn.calc_clk.dcfclk_khz; 2021ff5ef992SAlex Deucher dm_pp_apply_clock_for_voltage_request(dc->ctx, &clock); 2022608ac7bbSJerry Zuo dc->current_state->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 2023c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.dcfclk_khz = clock.clocks_in_khz; 2024ff5ef992SAlex Deucher } 2025c66a54dcSDmytro Laktyushkin if (context->bw.dcn.calc_clk.dispclk_khz 2026608ac7bbSJerry Zuo > dc->current_state->bw.dcn.cur_clk.dispclk_khz) { 2027c66a54dcSDmytro Laktyushkin dc->res_pool->display_clock->funcs->set_clock( 2028c66a54dcSDmytro Laktyushkin dc->res_pool->display_clock, 2029c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz); 2030608ac7bbSJerry Zuo dc->current_state->bw.dcn.cur_clk.dispclk_khz = 2031c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz; 2032c66a54dcSDmytro Laktyushkin context->bw.dcn.cur_clk.dispclk_khz = 2033c66a54dcSDmytro Laktyushkin context->bw.dcn.calc_clk.dispclk_khz; 2034c66a54dcSDmytro Laktyushkin } 2035c66a54dcSDmytro Laktyushkin } else 2036ff5ef992SAlex Deucher #endif 20379037d802SDmytro Laktyushkin if (context->bw.dce.dispclk_khz 2038608ac7bbSJerry Zuo > dc->current_state->bw.dce.dispclk_khz) { 2039a2b8659dSTony Cheng dc->res_pool->display_clock->funcs->set_clock( 2040a2b8659dSTony Cheng dc->res_pool->display_clock, 20419037d802SDmytro Laktyushkin context->bw.dce.dispclk_khz * 115 / 100); 20421ce71fcdSCharlene Liu } 2043ab8812a3SHersen Wu /* program audio wall clock. use HDMI as clock source if HDMI 2044ab8812a3SHersen Wu * audio active. Otherwise, use DP as clock source 2045ab8812a3SHersen Wu * first, loop to find any HDMI audio, if not, loop find DP audio 2046ab8812a3SHersen Wu */ 20474562236bSHarry Wentland /* Setup audio rate clock source */ 20484562236bSHarry Wentland /* Issue: 20494562236bSHarry Wentland * Audio lag happened on DP monitor when unplug a HDMI monitor 20504562236bSHarry Wentland * 20514562236bSHarry Wentland * Cause: 20524562236bSHarry Wentland * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 20534562236bSHarry Wentland * is set to either dto0 or dto1, audio should work fine. 20544562236bSHarry Wentland * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 20554562236bSHarry Wentland * set to dto0 will cause audio lag. 20564562236bSHarry Wentland * 20574562236bSHarry Wentland * Solution: 20584562236bSHarry Wentland * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 20594562236bSHarry Wentland * find first available pipe with audio, setup audio wall DTO per topology 20604562236bSHarry Wentland * instead of per pipe. 20614562236bSHarry Wentland */ 2062a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 2063ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2064ab8812a3SHersen Wu 2065ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 2066ab8812a3SHersen Wu continue; 2067ab8812a3SHersen Wu 2068ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 2069ab8812a3SHersen Wu continue; 2070ab8812a3SHersen Wu 2071ab8812a3SHersen Wu if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 2072ab8812a3SHersen Wu continue; 2073ab8812a3SHersen Wu 2074afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 2075ab8812a3SHersen Wu struct audio_output audio_output; 2076ab8812a3SHersen Wu 2077ab8db3e1SAndrey Grodzovsky build_audio_output(context, pipe_ctx, &audio_output); 2078ab8812a3SHersen Wu 2079afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2080afaacef4SHarry Wentland pipe_ctx->stream_res.audio, 2081ab8812a3SHersen Wu pipe_ctx->stream->signal, 2082ab8812a3SHersen Wu &audio_output.crtc_info, 2083ab8812a3SHersen Wu &audio_output.pll_info); 2084ab8812a3SHersen Wu break; 2085ab8812a3SHersen Wu } 2086ab8812a3SHersen Wu } 2087ab8812a3SHersen Wu 2088ab8812a3SHersen Wu /* no HDMI audio is found, try DP audio */ 2089a2b8659dSTony Cheng if (i == dc->res_pool->pipe_count) { 2090a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 2091ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2092ab8812a3SHersen Wu 2093ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 2094ab8812a3SHersen Wu continue; 2095ab8812a3SHersen Wu 2096ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 2097ab8812a3SHersen Wu continue; 2098ab8812a3SHersen Wu 2099ab8812a3SHersen Wu if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 2100ab8812a3SHersen Wu continue; 2101ab8812a3SHersen Wu 2102afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 2103ab8812a3SHersen Wu struct audio_output audio_output; 2104ab8812a3SHersen Wu 2105ab8db3e1SAndrey Grodzovsky build_audio_output(context, pipe_ctx, &audio_output); 2106ab8812a3SHersen Wu 2107afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2108afaacef4SHarry Wentland pipe_ctx->stream_res.audio, 2109ab8812a3SHersen Wu pipe_ctx->stream->signal, 2110ab8812a3SHersen Wu &audio_output.crtc_info, 2111ab8812a3SHersen Wu &audio_output.pll_info); 2112ab8812a3SHersen Wu break; 2113ab8812a3SHersen Wu } 2114ab8812a3SHersen Wu } 2115ab8812a3SHersen Wu } 2116ab8812a3SHersen Wu 2117a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 2118ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx_old = 2119608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 2120ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2121ab8812a3SHersen Wu 2122ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 2123ab8812a3SHersen Wu continue; 2124ab8812a3SHersen Wu 2125ab8812a3SHersen Wu if (pipe_ctx->stream == pipe_ctx_old->stream) 2126ab8812a3SHersen Wu continue; 2127ab8812a3SHersen Wu 21285b92d9d4SHarry Wentland if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 2129313bf4ffSYongqiang Sun continue; 2130313bf4ffSYongqiang Sun 2131ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 2132ab8812a3SHersen Wu continue; 2133ab8812a3SHersen Wu 2134afaacef4SHarry Wentland if (context->res_ctx.pipe_ctx[i].stream_res.audio != NULL) { 2135ab8812a3SHersen Wu 21364562236bSHarry Wentland struct audio_output audio_output; 21374562236bSHarry Wentland 2138ab8db3e1SAndrey Grodzovsky build_audio_output(context, pipe_ctx, &audio_output); 21394562236bSHarry Wentland 21404562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 21418e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( 21428e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 2143afaacef4SHarry Wentland pipe_ctx->stream_res.audio->inst, 21444fa086b9SLeo (Sunpeng) Li &pipe_ctx->stream->audio_info); 21454562236bSHarry Wentland else 21468e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( 21478e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 2148afaacef4SHarry Wentland pipe_ctx->stream_res.audio->inst, 21494fa086b9SLeo (Sunpeng) Li &pipe_ctx->stream->audio_info, 21504562236bSHarry Wentland &audio_output.crtc_info); 21514562236bSHarry Wentland 2152afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->az_configure( 2153afaacef4SHarry Wentland pipe_ctx->stream_res.audio, 21544562236bSHarry Wentland pipe_ctx->stream->signal, 21554562236bSHarry Wentland &audio_output.crtc_info, 21564fa086b9SLeo (Sunpeng) Li &pipe_ctx->stream->audio_info); 21574562236bSHarry Wentland } 21584562236bSHarry Wentland 21594562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 21604562236bSHarry Wentland pipe_ctx, 21614562236bSHarry Wentland context, 21624562236bSHarry Wentland dc); 21634562236bSHarry Wentland 21644562236bSHarry Wentland if (DC_OK != status) 21654562236bSHarry Wentland return status; 21664562236bSHarry Wentland } 21674562236bSHarry Wentland 21684562236bSHarry Wentland /* to save power */ 21694562236bSHarry Wentland apply_min_clocks(dc, context, &clocks_state, false); 21704562236bSHarry Wentland 21714562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, false); 21724562236bSHarry Wentland 21733eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 2174690b5e39SRoman Li if (dc->fbc_compressor) 2175690b5e39SRoman Li enable_fbc(dc, context); 2176690b5e39SRoman Li 2177690b5e39SRoman Li #endif 2178cf437593SDmytro Laktyushkin 21794562236bSHarry Wentland return DC_OK; 21804562236bSHarry Wentland } 21814562236bSHarry Wentland 21824562236bSHarry Wentland /******************************************************************************* 21834562236bSHarry Wentland * Front End programming 21844562236bSHarry Wentland ******************************************************************************/ 21854562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 21864562236bSHarry Wentland { 21874562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 21884562236bSHarry Wentland 21894562236bSHarry Wentland default_adjust.force_hw_default = false; 219034996173SHarry Wentland default_adjust.in_color_space = pipe_ctx->plane_state->color_space; 219134996173SHarry Wentland default_adjust.out_color_space = pipe_ctx->stream->output_color_space; 21924562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 21936702a9acSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 21944562236bSHarry Wentland 21954562236bSHarry Wentland /* display color depth */ 21964562236bSHarry Wentland default_adjust.color_depth = 21974fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.display_color_depth; 21984562236bSHarry Wentland 21994562236bSHarry Wentland /* Lb color depth */ 22006702a9acSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 22014562236bSHarry Wentland 220286a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 220386a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, &default_adjust); 22044562236bSHarry Wentland } 22054562236bSHarry Wentland 2206b06b7680SLeon Elazar 2207b06b7680SLeon Elazar /******************************************************************************* 2208b06b7680SLeon Elazar * In order to turn on/off specific surface we will program 2209b06b7680SLeon Elazar * Blender + CRTC 2210b06b7680SLeon Elazar * 2211b06b7680SLeon Elazar * In case that we have two surfaces and they have a different visibility 2212b06b7680SLeon Elazar * we can't turn off the CRTC since it will turn off the entire display 2213b06b7680SLeon Elazar * 2214b06b7680SLeon Elazar * |----------------------------------------------- | 2215b06b7680SLeon Elazar * |bottom pipe|curr pipe | | | 2216b06b7680SLeon Elazar * |Surface |Surface | Blender | CRCT | 2217b06b7680SLeon Elazar * |visibility |visibility | Configuration| | 2218b06b7680SLeon Elazar * |------------------------------------------------| 2219b06b7680SLeon Elazar * | off | off | CURRENT_PIPE | blank | 2220b06b7680SLeon Elazar * | off | on | CURRENT_PIPE | unblank | 2221b06b7680SLeon Elazar * | on | off | OTHER_PIPE | unblank | 2222b06b7680SLeon Elazar * | on | on | BLENDING | unblank | 2223b06b7680SLeon Elazar * -------------------------------------------------| 2224b06b7680SLeon Elazar * 2225b06b7680SLeon Elazar ******************************************************************************/ 2226fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc, 22274562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 22284562236bSHarry Wentland { 22294562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 2230b06b7680SLeon Elazar bool blank_target = false; 22314562236bSHarry Wentland 22324562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 2233b06b7680SLeon Elazar 2234b06b7680SLeon Elazar /* For now we are supporting only two pipes */ 2235b06b7680SLeon Elazar ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 2236b06b7680SLeon Elazar 22373be5262eSHarry Wentland if (pipe_ctx->bottom_pipe->plane_state->visible) { 22383be5262eSHarry Wentland if (pipe_ctx->plane_state->visible) 22394562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 22404562236bSHarry Wentland else 22414562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 2242b06b7680SLeon Elazar 22433be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2244b06b7680SLeon Elazar blank_target = true; 2245b06b7680SLeon Elazar 22463be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2247b06b7680SLeon Elazar blank_target = true; 2248b06b7680SLeon Elazar 2249e07f541fSYongqiang Sun dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode); 22506b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 2251b06b7680SLeon Elazar 22524562236bSHarry Wentland } 22534562236bSHarry Wentland 22541bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 22551bf56e62SZeyu Fan { 2256146a9f63SKrunoslav Kovac int i = 0; 22571bf56e62SZeyu Fan struct xfm_grph_csc_adjustment adjust; 22581bf56e62SZeyu Fan memset(&adjust, 0, sizeof(adjust)); 22591bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 22601bf56e62SZeyu Fan 22611bf56e62SZeyu Fan 22624fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 22631bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2264146a9f63SKrunoslav Kovac 2265146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2266146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2267146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 22681bf56e62SZeyu Fan } 22691bf56e62SZeyu Fan 227086a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 22711bf56e62SZeyu Fan } 22721bf56e62SZeyu Fan 22734562236bSHarry Wentland /** 22744562236bSHarry Wentland * TODO REMOVE, USE UPDATE INSTEAD 22754562236bSHarry Wentland */ 22764562236bSHarry Wentland static void set_plane_config( 2277fb3466a4SBhawanpreet Lakha const struct dc *dc, 22784562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 22794562236bSHarry Wentland struct resource_context *res_ctx) 22804562236bSHarry Wentland { 228186a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 22823be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 22834562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 22844562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 22854562236bSHarry Wentland unsigned int i; 22864562236bSHarry Wentland 22874562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 22884562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 22894562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 22904562236bSHarry Wentland 2291e07f541fSYongqiang Sun dce_enable_fe_clock(dc->hwseq, mi->inst, true); 22924562236bSHarry Wentland 22934562236bSHarry Wentland set_default_colors(pipe_ctx); 229456ef6ed9SAnthony Koo if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { 22954562236bSHarry Wentland tbl_entry.color_space = 22964fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 22974562236bSHarry Wentland 22984562236bSHarry Wentland for (i = 0; i < 12; i++) 22994562236bSHarry Wentland tbl_entry.regval[i] = 23004fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 23014562236bSHarry Wentland 230286a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 230386a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 23044562236bSHarry Wentland } 23054562236bSHarry Wentland 23064fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 23074562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2308146a9f63SKrunoslav Kovac 2309146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2310146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2311146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 23124562236bSHarry Wentland } 23134562236bSHarry Wentland 231486a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 23154562236bSHarry Wentland 23166702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 23174562236bSHarry Wentland program_scaler(dc, pipe_ctx); 23184562236bSHarry Wentland 2319b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 23204562236bSHarry Wentland 23214562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 23224562236bSHarry Wentland mi, 23233be5262eSHarry Wentland plane_state->format, 23243be5262eSHarry Wentland &plane_state->tiling_info, 23253be5262eSHarry Wentland &plane_state->plane_size, 23263be5262eSHarry Wentland plane_state->rotation, 23274562236bSHarry Wentland NULL, 23284b28b76bSDmytro Laktyushkin false); 23294b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 23303be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 23314562236bSHarry Wentland 2332fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 23334562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 233486a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 23353be5262eSHarry Wentland plane_state->format, 23363be5262eSHarry Wentland &plane_state->tiling_info, 23373be5262eSHarry Wentland plane_state->rotation); 23384562236bSHarry Wentland } 23394562236bSHarry Wentland 2340fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc, 23414562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 23424562236bSHarry Wentland { 23433be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 23444562236bSHarry Wentland 23453be5262eSHarry Wentland if (plane_state == NULL) 23464562236bSHarry Wentland return; 23474562236bSHarry Wentland 234886a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 234986a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 23503be5262eSHarry Wentland &plane_state->address, 23513be5262eSHarry Wentland plane_state->flip_immediate); 23524562236bSHarry Wentland 23533be5262eSHarry Wentland plane_state->status.requested_address = plane_state->address; 23544562236bSHarry Wentland } 23554562236bSHarry Wentland 2356f774b339SEric Yang static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 23574562236bSHarry Wentland { 23583be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 23594562236bSHarry Wentland 23603be5262eSHarry Wentland if (plane_state == NULL) 23614562236bSHarry Wentland return; 23624562236bSHarry Wentland 23633be5262eSHarry Wentland plane_state->status.is_flip_pending = 236486a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 236586a66c4eSHarry Wentland pipe_ctx->plane_res.mi); 23664562236bSHarry Wentland 23673be5262eSHarry Wentland if (plane_state->status.is_flip_pending && !plane_state->visible) 236886a66c4eSHarry Wentland pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address; 23694562236bSHarry Wentland 237086a66c4eSHarry Wentland plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 237186a66c4eSHarry Wentland if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 23726b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) { 23733be5262eSHarry Wentland plane_state->status.is_right_eye =\ 23746b670fa9SHarry Wentland !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 23757f5c22d1SVitaly Prosyak } 23764562236bSHarry Wentland } 23774562236bSHarry Wentland 2378fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc) 23794562236bSHarry Wentland { 23804562236bSHarry Wentland power_down_all_hw_blocks(dc); 23814562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 23824562236bSHarry Wentland } 23834562236bSHarry Wentland 23844562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 23854562236bSHarry Wentland struct dc_context *dc_ctx, 23864562236bSHarry Wentland struct timing_generator *tg) 23874562236bSHarry Wentland { 23884562236bSHarry Wentland bool rc = false; 23894562236bSHarry Wentland 23904562236bSHarry Wentland /* To avoid endless loop we wait at most 23914562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 23924562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 23934562236bSHarry Wentland uint32_t i; 23944562236bSHarry Wentland 23954562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 23964562236bSHarry Wentland 23974562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 23984562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 23994562236bSHarry Wentland break; 24004562236bSHarry Wentland } 24014562236bSHarry Wentland 24024562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 24034562236bSHarry Wentland rc = true; 24044562236bSHarry Wentland /* usually occurs at i=1 */ 24054562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 24064562236bSHarry Wentland i); 24074562236bSHarry Wentland break; 24084562236bSHarry Wentland } 24094562236bSHarry Wentland 24104562236bSHarry Wentland /* Wait for one frame. */ 24114562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 24124562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 24134562236bSHarry Wentland } 24144562236bSHarry Wentland 24154562236bSHarry Wentland if (false == rc) 24164562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 24174562236bSHarry Wentland 24184562236bSHarry Wentland return rc; 24194562236bSHarry Wentland } 24204562236bSHarry Wentland 24214562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 24224562236bSHarry Wentland static void dce110_enable_timing_synchronization( 2423fb3466a4SBhawanpreet Lakha struct dc *dc, 24244562236bSHarry Wentland int group_index, 24254562236bSHarry Wentland int group_size, 24264562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 24274562236bSHarry Wentland { 24284562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 24294562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 24304562236bSHarry Wentland int i; 24314562236bSHarry Wentland 24324562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 24334562236bSHarry Wentland 24344562236bSHarry Wentland /* Designate a single TG in the group as a master. 24354562236bSHarry Wentland * Since HW doesn't care which one, we always assign 24364562236bSHarry Wentland * the 1st one in the group. */ 24374562236bSHarry Wentland gsl_params.gsl_group = 0; 24386b670fa9SHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst; 24394562236bSHarry Wentland 24404562236bSHarry Wentland for (i = 0; i < group_size; i++) 24416b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 24426b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg, &gsl_params); 24434562236bSHarry Wentland 24444562236bSHarry Wentland /* Reset slave controllers on master VSync */ 24454562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 24464562236bSHarry Wentland 24474562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 24486b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( 2449fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2450fa2123dbSMikita Lipski gsl_params.gsl_group); 24514562236bSHarry Wentland 24524562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 24534562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 24546b670fa9SHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2455fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( 2456fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg); 24574562236bSHarry Wentland } 24584562236bSHarry Wentland 24594562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 24604562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 24614562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 24624562236bSHarry Wentland for (i = 0; i < group_size; i++) 24636b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 24644562236bSHarry Wentland 24654562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 24664562236bSHarry Wentland } 24674562236bSHarry Wentland 2468fa2123dbSMikita Lipski static void dce110_enable_per_frame_crtc_position_reset( 2469fa2123dbSMikita Lipski struct dc *dc, 2470fa2123dbSMikita Lipski int group_size, 2471fa2123dbSMikita Lipski struct pipe_ctx *grouped_pipes[]) 2472fa2123dbSMikita Lipski { 2473fa2123dbSMikita Lipski struct dc_context *dc_ctx = dc->ctx; 2474fa2123dbSMikita Lipski struct dcp_gsl_params gsl_params = { 0 }; 2475fa2123dbSMikita Lipski int i; 2476fa2123dbSMikita Lipski 2477fa2123dbSMikita Lipski gsl_params.gsl_group = 0; 2478fa2123dbSMikita Lipski gsl_params.gsl_master = grouped_pipes[0]->stream->triggered_crtc_reset.event_source->status.primary_otg_inst; 2479fa2123dbSMikita Lipski 2480fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2481fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 2482fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, &gsl_params); 2483fa2123dbSMikita Lipski 2484fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 2485fa2123dbSMikita Lipski 2486fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2487fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( 2488fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2489fa2123dbSMikita Lipski gsl_params.gsl_master, 2490fa2123dbSMikita Lipski &grouped_pipes[i]->stream->triggered_crtc_reset); 2491fa2123dbSMikita Lipski 2492fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 2493fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2494fa2123dbSMikita Lipski wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2495fa2123dbSMikita Lipski 2496fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2497fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 2498fa2123dbSMikita Lipski 2499fa2123dbSMikita Lipski } 2500fa2123dbSMikita Lipski 2501fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc) 25024562236bSHarry Wentland { 25034562236bSHarry Wentland int i; 25044562236bSHarry Wentland struct dc_bios *bp; 25054562236bSHarry Wentland struct transform *xfm; 25065e7773a2SAnthony Koo struct abm *abm; 25074562236bSHarry Wentland 25084562236bSHarry Wentland bp = dc->ctx->dc_bios; 25094562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 25104562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 25114562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 25124562236bSHarry Wentland 25134562236bSHarry Wentland dc->hwss.enable_display_power_gating( 25144562236bSHarry Wentland dc, i, bp, 25154562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 25164562236bSHarry Wentland dc->hwss.enable_display_power_gating( 25174562236bSHarry Wentland dc, i, bp, 25184562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 25194562236bSHarry Wentland dc->hwss.enable_display_pipe_clock_gating( 25204562236bSHarry Wentland dc->ctx, 25214562236bSHarry Wentland true); 25224562236bSHarry Wentland } 25234562236bSHarry Wentland 2524e166ad43SJulia Lawall dce_clock_gating_power_up(dc->hwseq, false); 25254562236bSHarry Wentland /***************************************/ 25264562236bSHarry Wentland 25274562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 25284562236bSHarry Wentland /****************************************/ 25294562236bSHarry Wentland /* Power up AND update implementation according to the 25304562236bSHarry Wentland * required signal (which may be different from the 25314562236bSHarry Wentland * default signal on connector). */ 2532d0778ebfSHarry Wentland struct dc_link *link = dc->links[i]; 2533069d418fSAndrew Jiang 2534069d418fSAndrew Jiang if (link->link_enc->connector.id == CONNECTOR_ID_EDP) 2535069d418fSAndrew Jiang dc->hwss.edp_power_control(link, true); 2536069d418fSAndrew Jiang 25374562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 25384562236bSHarry Wentland } 25394562236bSHarry Wentland 25404562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 25414562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 25424562236bSHarry Wentland 25434562236bSHarry Wentland tg->funcs->disable_vga(tg); 25444562236bSHarry Wentland 25454562236bSHarry Wentland /* Blank controller using driver code instead of 25464562236bSHarry Wentland * command table. */ 25474562236bSHarry Wentland tg->funcs->set_blank(tg, true); 25484b5e7d62SHersen Wu hwss_wait_for_blank_complete(tg); 25494562236bSHarry Wentland } 25504562236bSHarry Wentland 25514562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 25524562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 25534562236bSHarry Wentland audio->funcs->hw_init(audio); 25544562236bSHarry Wentland } 25555e7773a2SAnthony Koo 25565e7773a2SAnthony Koo abm = dc->res_pool->abm; 25576728b30cSAnthony Koo if (abm != NULL) { 25586728b30cSAnthony Koo abm->funcs->init_backlight(abm); 25595e7773a2SAnthony Koo abm->funcs->abm_init(abm); 25604562236bSHarry Wentland } 25613eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 25622f3bfb27SRoman Li if (dc->fbc_compressor) 25631663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 25641663ae1cSBhawanpreet Lakha #endif 2565690b5e39SRoman Li 25666728b30cSAnthony Koo } 25674562236bSHarry Wentland 256828f72454SJordan Lazare void dce110_fill_display_configs( 2569608ac7bbSJerry Zuo const struct dc_state *context, 2570cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg) 25714562236bSHarry Wentland { 2572cf437593SDmytro Laktyushkin int j; 2573cf437593SDmytro Laktyushkin int num_cfgs = 0; 2574cf437593SDmytro Laktyushkin 2575cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 2576cf437593SDmytro Laktyushkin int k; 2577cf437593SDmytro Laktyushkin 25780971c40eSHarry Wentland const struct dc_stream_state *stream = context->streams[j]; 2579cf437593SDmytro Laktyushkin struct dm_pp_single_disp_config *cfg = 2580cf437593SDmytro Laktyushkin &pp_display_cfg->disp_configs[num_cfgs]; 2581cf437593SDmytro Laktyushkin const struct pipe_ctx *pipe_ctx = NULL; 2582cf437593SDmytro Laktyushkin 2583cf437593SDmytro Laktyushkin for (k = 0; k < MAX_PIPES; k++) 2584cf437593SDmytro Laktyushkin if (stream == context->res_ctx.pipe_ctx[k].stream) { 2585cf437593SDmytro Laktyushkin pipe_ctx = &context->res_ctx.pipe_ctx[k]; 2586cf437593SDmytro Laktyushkin break; 25874562236bSHarry Wentland } 25884562236bSHarry Wentland 2589cf437593SDmytro Laktyushkin ASSERT(pipe_ctx != NULL); 2590cf437593SDmytro Laktyushkin 2591631aaa0aSHersen Wu /* only notify active stream */ 2592631aaa0aSHersen Wu if (stream->dpms_off) 2593631aaa0aSHersen Wu continue; 2594631aaa0aSHersen Wu 2595cf437593SDmytro Laktyushkin num_cfgs++; 2596cf437593SDmytro Laktyushkin cfg->signal = pipe_ctx->stream->signal; 2597e07f541fSYongqiang Sun cfg->pipe_idx = pipe_ctx->stream_res.tg->inst; 25984fa086b9SLeo (Sunpeng) Li cfg->src_height = stream->src.height; 25994fa086b9SLeo (Sunpeng) Li cfg->src_width = stream->src.width; 2600cf437593SDmytro Laktyushkin cfg->ddi_channel_mapping = 2601cf437593SDmytro Laktyushkin stream->sink->link->ddi_channel_mapping.raw; 2602cf437593SDmytro Laktyushkin cfg->transmitter = 2603cf437593SDmytro Laktyushkin stream->sink->link->link_enc->transmitter; 2604cf437593SDmytro Laktyushkin cfg->link_settings.lane_count = 2605d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.lane_count; 2606cf437593SDmytro Laktyushkin cfg->link_settings.link_rate = 2607d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.link_rate; 2608cf437593SDmytro Laktyushkin cfg->link_settings.link_spread = 2609d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.link_spread; 2610cf437593SDmytro Laktyushkin cfg->sym_clock = stream->phy_pix_clk; 2611cf437593SDmytro Laktyushkin /* Round v_refresh*/ 26124fa086b9SLeo (Sunpeng) Li cfg->v_refresh = stream->timing.pix_clk_khz * 1000; 26134fa086b9SLeo (Sunpeng) Li cfg->v_refresh /= stream->timing.h_total; 26144fa086b9SLeo (Sunpeng) Li cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) 26154fa086b9SLeo (Sunpeng) Li / stream->timing.v_total; 2616cf437593SDmytro Laktyushkin } 2617cf437593SDmytro Laktyushkin 2618cf437593SDmytro Laktyushkin pp_display_cfg->display_count = num_cfgs; 2619cf437593SDmytro Laktyushkin } 2620cf437593SDmytro Laktyushkin 2621608ac7bbSJerry Zuo uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context) 2622cf437593SDmytro Laktyushkin { 2623cf437593SDmytro Laktyushkin uint8_t j; 2624cf437593SDmytro Laktyushkin uint32_t min_vertical_blank_time = -1; 2625cf437593SDmytro Laktyushkin 2626cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 26270971c40eSHarry Wentland struct dc_stream_state *stream = context->streams[j]; 2628cf437593SDmytro Laktyushkin uint32_t vertical_blank_in_pixels = 0; 2629cf437593SDmytro Laktyushkin uint32_t vertical_blank_time = 0; 2630cf437593SDmytro Laktyushkin 2631cf437593SDmytro Laktyushkin vertical_blank_in_pixels = stream->timing.h_total * 2632cf437593SDmytro Laktyushkin (stream->timing.v_total 2633cf437593SDmytro Laktyushkin - stream->timing.v_addressable); 2634cf437593SDmytro Laktyushkin 2635cf437593SDmytro Laktyushkin vertical_blank_time = vertical_blank_in_pixels 2636cf437593SDmytro Laktyushkin * 1000 / stream->timing.pix_clk_khz; 2637cf437593SDmytro Laktyushkin 2638cf437593SDmytro Laktyushkin if (min_vertical_blank_time > vertical_blank_time) 2639cf437593SDmytro Laktyushkin min_vertical_blank_time = vertical_blank_time; 2640cf437593SDmytro Laktyushkin } 2641cf437593SDmytro Laktyushkin 2642cf437593SDmytro Laktyushkin return min_vertical_blank_time; 2643cf437593SDmytro Laktyushkin } 2644cf437593SDmytro Laktyushkin 2645cf437593SDmytro Laktyushkin static int determine_sclk_from_bounding_box( 2646fb3466a4SBhawanpreet Lakha const struct dc *dc, 2647cf437593SDmytro Laktyushkin int required_sclk) 26484562236bSHarry Wentland { 26494562236bSHarry Wentland int i; 26504562236bSHarry Wentland 2651cf437593SDmytro Laktyushkin /* 2652cf437593SDmytro Laktyushkin * Some asics do not give us sclk levels, so we just report the actual 2653cf437593SDmytro Laktyushkin * required sclk 2654cf437593SDmytro Laktyushkin */ 2655cf437593SDmytro Laktyushkin if (dc->sclk_lvls.num_levels == 0) 2656cf437593SDmytro Laktyushkin return required_sclk; 26574562236bSHarry Wentland 2658cf437593SDmytro Laktyushkin for (i = 0; i < dc->sclk_lvls.num_levels; i++) { 2659cf437593SDmytro Laktyushkin if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk) 2660cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[i]; 2661cf437593SDmytro Laktyushkin } 2662cf437593SDmytro Laktyushkin /* 2663cf437593SDmytro Laktyushkin * even maximum level could not satisfy requirement, this 2664cf437593SDmytro Laktyushkin * is unexpected at this stage, should have been caught at 2665cf437593SDmytro Laktyushkin * validation time 2666cf437593SDmytro Laktyushkin */ 2667cf437593SDmytro Laktyushkin ASSERT(0); 2668cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1]; 26694562236bSHarry Wentland } 26704562236bSHarry Wentland 2671cf437593SDmytro Laktyushkin static void pplib_apply_display_requirements( 2672fb3466a4SBhawanpreet Lakha struct dc *dc, 2673608ac7bbSJerry Zuo struct dc_state *context) 2674cf437593SDmytro Laktyushkin { 2675cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 2676cf437593SDmytro Laktyushkin 2677cf437593SDmytro Laktyushkin pp_display_cfg->all_displays_in_sync = 26789037d802SDmytro Laktyushkin context->bw.dce.all_displays_in_sync; 2679cf437593SDmytro Laktyushkin pp_display_cfg->nb_pstate_switch_disable = 26809037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_enable == false; 2681cf437593SDmytro Laktyushkin pp_display_cfg->cpu_cc6_disable = 26829037d802SDmytro Laktyushkin context->bw.dce.cpuc_state_change_enable == false; 2683cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_disable = 26849037d802SDmytro Laktyushkin context->bw.dce.cpup_state_change_enable == false; 2685cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_separation_time = 26869037d802SDmytro Laktyushkin context->bw.dce.blackout_recovery_time_us; 2687cf437593SDmytro Laktyushkin 26889037d802SDmytro Laktyushkin pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz 2689cf437593SDmytro Laktyushkin / MEMORY_TYPE_MULTIPLIER; 2690cf437593SDmytro Laktyushkin 2691cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( 2692cf437593SDmytro Laktyushkin dc, 26939037d802SDmytro Laktyushkin context->bw.dce.sclk_khz); 2694cf437593SDmytro Laktyushkin 2695cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_deep_sleep_khz 26969037d802SDmytro Laktyushkin = context->bw.dce.sclk_deep_sleep_khz; 2697cf437593SDmytro Laktyushkin 2698cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_us = 269928f72454SJordan Lazare dce110_get_min_vblank_time_us(context); 2700cf437593SDmytro Laktyushkin /* TODO: dce11.2*/ 2701cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; 2702cf437593SDmytro Laktyushkin 27039037d802SDmytro Laktyushkin pp_display_cfg->disp_clk_khz = context->bw.dce.dispclk_khz; 2704cf437593SDmytro Laktyushkin 270528f72454SJordan Lazare dce110_fill_display_configs(context, pp_display_cfg); 2706cf437593SDmytro Laktyushkin 2707cf437593SDmytro Laktyushkin /* TODO: is this still applicable?*/ 2708cf437593SDmytro Laktyushkin if (pp_display_cfg->display_count == 1) { 2709cf437593SDmytro Laktyushkin const struct dc_crtc_timing *timing = 27104fa086b9SLeo (Sunpeng) Li &context->streams[0]->timing; 2711cf437593SDmytro Laktyushkin 2712cf437593SDmytro Laktyushkin pp_display_cfg->crtc_index = 2713cf437593SDmytro Laktyushkin pp_display_cfg->disp_configs[0].pipe_idx; 2714cf437593SDmytro Laktyushkin pp_display_cfg->line_time_in_us = timing->h_total * 1000 2715cf437593SDmytro Laktyushkin / timing->pix_clk_khz; 2716cf437593SDmytro Laktyushkin } 2717cf437593SDmytro Laktyushkin 2718cf437593SDmytro Laktyushkin if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( 2719cf437593SDmytro Laktyushkin struct dm_pp_display_configuration)) != 0) 2720cf437593SDmytro Laktyushkin dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); 2721cf437593SDmytro Laktyushkin 2722cf437593SDmytro Laktyushkin dc->prev_display_config = *pp_display_cfg; 2723cf437593SDmytro Laktyushkin } 2724cf437593SDmytro Laktyushkin 2725cf437593SDmytro Laktyushkin static void dce110_set_bandwidth( 2726fb3466a4SBhawanpreet Lakha struct dc *dc, 2727608ac7bbSJerry Zuo struct dc_state *context, 2728cf437593SDmytro Laktyushkin bool decrease_allowed) 2729cf437593SDmytro Laktyushkin { 27302180e7ccSDmytro Laktyushkin dce110_set_displaymarks(dc, context); 2731cf437593SDmytro Laktyushkin 2732608ac7bbSJerry Zuo if (decrease_allowed || context->bw.dce.dispclk_khz > dc->current_state->bw.dce.dispclk_khz) { 2733a2b8659dSTony Cheng dc->res_pool->display_clock->funcs->set_clock( 2734a2b8659dSTony Cheng dc->res_pool->display_clock, 27359037d802SDmytro Laktyushkin context->bw.dce.dispclk_khz * 115 / 100); 2736608ac7bbSJerry Zuo dc->current_state->bw.dce.dispclk_khz = context->bw.dce.dispclk_khz; 2737cf437593SDmytro Laktyushkin } 2738cf437593SDmytro Laktyushkin 2739cf437593SDmytro Laktyushkin pplib_apply_display_requirements(dc, context); 27404562236bSHarry Wentland } 27414562236bSHarry Wentland 27424562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 2743fb3466a4SBhawanpreet Lakha struct dc *dc, struct pipe_ctx *pipe_ctx) 27444562236bSHarry Wentland { 274586a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 27464562236bSHarry Wentland struct pipe_ctx *old_pipe = NULL; 27473be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 27484562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 27494562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 275087ac8fb0SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 275187ac8fb0SShirish S unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 275287ac8fb0SShirish S #endif 27534562236bSHarry Wentland unsigned int i; 27545d4b05ddSBhawanpreet Lakha DC_LOGGER_INIT(); 27554562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 27564562236bSHarry Wentland 2757608ac7bbSJerry Zuo if (dc->current_state) 2758608ac7bbSJerry Zuo old_pipe = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; 27594562236bSHarry Wentland 27604562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 27614562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 27624562236bSHarry Wentland 2763e07f541fSYongqiang Sun dce_enable_fe_clock(dc->hwseq, mi->inst, true); 27644562236bSHarry Wentland 27654562236bSHarry Wentland set_default_colors(pipe_ctx); 27664fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 27674562236bSHarry Wentland == true) { 27684562236bSHarry Wentland tbl_entry.color_space = 27694fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 27704562236bSHarry Wentland 27714562236bSHarry Wentland for (i = 0; i < 12; i++) 27724562236bSHarry Wentland tbl_entry.regval[i] = 27734fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 27744562236bSHarry Wentland 277586a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 277686a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 27774562236bSHarry Wentland } 27784562236bSHarry Wentland 27794fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 27804562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2781146a9f63SKrunoslav Kovac 2782146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2783146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2784146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 27854562236bSHarry Wentland } 27864562236bSHarry Wentland 278786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 27884562236bSHarry Wentland 27896702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 2790c1473558SAndrey Grodzovsky 27914562236bSHarry Wentland program_scaler(dc, pipe_ctx); 27924562236bSHarry Wentland 27933eab7916SShirish S #if defined(CONFIG_DRM_AMD_DC_FBC) 279487ac8fb0SShirish S /* fbc not applicable on Underlay pipe */ 279587ac8fb0SShirish S if (dc->fbc_compressor && old_pipe->stream && 279687ac8fb0SShirish S pipe_ctx->pipe_idx != underlay_idx) { 2797e008b0bcSRoman Li if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 2798e008b0bcSRoman Li dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 2799e008b0bcSRoman Li else 2800e008b0bcSRoman Li enable_fbc(dc, dc->current_state); 2801e008b0bcSRoman Li } 2802e008b0bcSRoman Li #endif 2803e008b0bcSRoman Li 28044562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 28054562236bSHarry Wentland mi, 28063be5262eSHarry Wentland plane_state->format, 28073be5262eSHarry Wentland &plane_state->tiling_info, 28083be5262eSHarry Wentland &plane_state->plane_size, 28093be5262eSHarry Wentland plane_state->rotation, 2810624d7c47SYongqiang Sun NULL, 28114b28b76bSDmytro Laktyushkin false); 28124b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 28133be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 28144562236bSHarry Wentland 2815fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 28164562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 281786a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 28183be5262eSHarry Wentland plane_state->format, 28193be5262eSHarry Wentland &plane_state->tiling_info, 28203be5262eSHarry Wentland plane_state->rotation); 28214562236bSHarry Wentland 2822067c878aSYongqiang Sun /* Moved programming gamma from dc to hwss */ 2823405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update || 2824405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 2825405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.gamma_change) 2826a6114e85SHarry Wentland dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state); 2827405c50a0SAndrew Jiang 2828405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update) 2829a6114e85SHarry Wentland dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); 2830067c878aSYongqiang Sun 28311296423bSBhawanpreet Lakha DC_LOG_SURFACE( 28323032deb5SBhawanpreet Lakha "Pipe:%d %p: addr hi:0x%x, " 28334562236bSHarry Wentland "addr low:0x%x, " 28344562236bSHarry Wentland "src: %d, %d, %d," 28354562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 28364562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 28374562236bSHarry Wentland pipe_ctx->pipe_idx, 28383032deb5SBhawanpreet Lakha (void *) pipe_ctx->plane_state, 28393be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.high_part, 28403be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.low_part, 28413be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.x, 28423be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.y, 28433be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.width, 28443be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.height, 28453be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.x, 28463be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.y, 28473be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.width, 28483be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.height, 28493be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.x, 28503be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.y, 28513be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.width, 28523be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.height); 28534562236bSHarry Wentland 28541296423bSBhawanpreet Lakha DC_LOG_SURFACE( 28554562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 28564562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 28574562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 28584562236bSHarry Wentland pipe_ctx->pipe_idx, 28596702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.width, 28606702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.height, 28616702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.x, 28626702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.y, 28636702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.width, 28646702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.height, 28656702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.x, 28666702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.y); 28674562236bSHarry Wentland } 28684562236bSHarry Wentland 28694562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 2870fb3466a4SBhawanpreet Lakha struct dc *dc, 28713e9ad616SEric Yang const struct dc_stream_state *stream, 28723e9ad616SEric Yang int num_planes, 2873608ac7bbSJerry Zuo struct dc_state *context) 28744562236bSHarry Wentland { 28752194e3aeSRoman Li int i; 28764562236bSHarry Wentland 28773e9ad616SEric Yang if (num_planes == 0) 28784562236bSHarry Wentland return; 28794562236bSHarry Wentland 28803e9ad616SEric Yang for (i = 0; i < dc->res_pool->pipe_count; i++) { 28813dc780ecSYongqiang Sun struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 28823dc780ecSYongqiang Sun struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 28833dc780ecSYongqiang Sun 28842194e3aeSRoman Li if (stream == pipe_ctx->stream) { 28853dc780ecSYongqiang Sun if (!pipe_ctx->top_pipe && 28863dc780ecSYongqiang Sun (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) 28873dc780ecSYongqiang Sun dc->hwss.pipe_control_lock(dc, pipe_ctx, true); 28883e9ad616SEric Yang } 28893e9ad616SEric Yang } 28903e9ad616SEric Yang 2891a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 28924562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 28934562236bSHarry Wentland 2894a2607aefSHarry Wentland if (pipe_ctx->stream != stream) 28954562236bSHarry Wentland continue; 28964562236bSHarry Wentland 28973b21b6d2SJerry Zuo /* Need to allocate mem before program front end for Fiji */ 28983b21b6d2SJerry Zuo pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 28993b21b6d2SJerry Zuo pipe_ctx->plane_res.mi, 29003b21b6d2SJerry Zuo pipe_ctx->stream->timing.h_total, 29013b21b6d2SJerry Zuo pipe_ctx->stream->timing.v_total, 29023b21b6d2SJerry Zuo pipe_ctx->stream->timing.pix_clk_khz, 29033b21b6d2SJerry Zuo context->stream_count); 29043b21b6d2SJerry Zuo 29054562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 29064f804817SYongqiang Sun 29074f804817SYongqiang Sun dc->hwss.update_plane_addr(dc, pipe_ctx); 29084f804817SYongqiang Sun 2909b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 29104562236bSHarry Wentland 29114562236bSHarry Wentland } 29123dc780ecSYongqiang Sun 29133dc780ecSYongqiang Sun for (i = 0; i < dc->res_pool->pipe_count; i++) { 29143dc780ecSYongqiang Sun struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 29153dc780ecSYongqiang Sun struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 29163dc780ecSYongqiang Sun 29173dc780ecSYongqiang Sun if ((stream == pipe_ctx->stream) && 29183dc780ecSYongqiang Sun (!pipe_ctx->top_pipe) && 29193dc780ecSYongqiang Sun (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) 29203dc780ecSYongqiang Sun dc->hwss.pipe_control_lock(dc, pipe_ctx, false); 29213dc780ecSYongqiang Sun } 29224562236bSHarry Wentland } 29234562236bSHarry Wentland 2924e6c258cbSYongqiang Sun static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) 29254562236bSHarry Wentland { 2926bc373a89SRoman Li int fe_idx = pipe_ctx->plane_res.mi ? 2927bc373a89SRoman Li pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx; 2928e6c258cbSYongqiang Sun 29297950f0f9SDmytro Laktyushkin /* Do not power down fe when stream is active on dce*/ 2930608ac7bbSJerry Zuo if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) 29314562236bSHarry Wentland return; 29324562236bSHarry Wentland 29334562236bSHarry Wentland dc->hwss.enable_display_power_gating( 2934cfe4645eSDmytro Laktyushkin dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 2935cfe4645eSDmytro Laktyushkin 2936cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 2937cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]); 29384562236bSHarry Wentland } 29394562236bSHarry Wentland 29406be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect( 2941fb3466a4SBhawanpreet Lakha struct dc *dc, 29426be425f3SEric Yang struct resource_pool *res_pool, 29436be425f3SEric Yang struct pipe_ctx *pipe_ctx) 2944b6762f0cSEric Yang { 2945b6762f0cSEric Yang /* do nothing*/ 2946b6762f0cSEric Yang } 2947b6762f0cSEric Yang 2948bdf9a1a0SYue Hin Lau static void program_csc_matrix(struct pipe_ctx *pipe_ctx, 2949bdf9a1a0SYue Hin Lau enum dc_color_space colorspace, 2950bdf9a1a0SYue Hin Lau uint16_t *matrix) 2951bdf9a1a0SYue Hin Lau { 2952bdf9a1a0SYue Hin Lau int i; 2953bdf9a1a0SYue Hin Lau struct out_csc_color_matrix tbl_entry; 2954bdf9a1a0SYue Hin Lau 2955bdf9a1a0SYue Hin Lau if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 2956bdf9a1a0SYue Hin Lau == true) { 2957bdf9a1a0SYue Hin Lau enum dc_color_space color_space = 2958bdf9a1a0SYue Hin Lau pipe_ctx->stream->output_color_space; 2959bdf9a1a0SYue Hin Lau 2960bdf9a1a0SYue Hin Lau //uint16_t matrix[12]; 2961bdf9a1a0SYue Hin Lau for (i = 0; i < 12; i++) 2962bdf9a1a0SYue Hin Lau tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; 2963bdf9a1a0SYue Hin Lau 2964bdf9a1a0SYue Hin Lau tbl_entry.color_space = color_space; 2965bdf9a1a0SYue Hin Lau //tbl_entry.regval = matrix; 296686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry); 2967bdf9a1a0SYue Hin Lau } 2968bdf9a1a0SYue Hin Lau } 2969bdf9a1a0SYue Hin Lau 297033fd17d9SEric Yang void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) 297133fd17d9SEric Yang { 297233fd17d9SEric Yang struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; 297333fd17d9SEric Yang struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 297433fd17d9SEric Yang struct mem_input *mi = pipe_ctx->plane_res.mi; 297533fd17d9SEric Yang struct dc_cursor_mi_param param = { 297633fd17d9SEric Yang .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, 297733fd17d9SEric Yang .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, 297833fd17d9SEric Yang .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x, 297933fd17d9SEric Yang .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width, 298033fd17d9SEric Yang .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz 298133fd17d9SEric Yang }; 298233fd17d9SEric Yang 298333fd17d9SEric Yang if (pipe_ctx->plane_state->address.type 298433fd17d9SEric Yang == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) 298533fd17d9SEric Yang pos_cpy.enable = false; 298633fd17d9SEric Yang 298733fd17d9SEric Yang if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 298833fd17d9SEric Yang pos_cpy.enable = false; 298933fd17d9SEric Yang 2990dc75dd70SRoman Li if (ipp->funcs->ipp_cursor_set_position) 299133fd17d9SEric Yang ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); 2992dc75dd70SRoman Li if (mi->funcs->set_cursor_position) 299333fd17d9SEric Yang mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); 299433fd17d9SEric Yang } 299533fd17d9SEric Yang 299633fd17d9SEric Yang void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) 299733fd17d9SEric Yang { 299833fd17d9SEric Yang struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; 299933fd17d9SEric Yang 3000d1aaad05SHarry Wentland if (pipe_ctx->plane_res.ipp && 3001d1aaad05SHarry Wentland pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) 300233fd17d9SEric Yang pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( 300333fd17d9SEric Yang pipe_ctx->plane_res.ipp, attributes); 300433fd17d9SEric Yang 3005d1aaad05SHarry Wentland if (pipe_ctx->plane_res.mi && 3006d1aaad05SHarry Wentland pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) 300733fd17d9SEric Yang pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( 300833fd17d9SEric Yang pipe_ctx->plane_res.mi, attributes); 300933fd17d9SEric Yang 3010d1aaad05SHarry Wentland if (pipe_ctx->plane_res.xfm && 3011d1aaad05SHarry Wentland pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) 301233fd17d9SEric Yang pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( 301333fd17d9SEric Yang pipe_ctx->plane_res.xfm, attributes); 301433fd17d9SEric Yang } 301533fd17d9SEric Yang 30166bf52028SHersen Wu static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} 301741f97c07SHersen Wu 301841f97c07SHersen Wu static void optimize_shared_resources(struct dc *dc) {} 301941f97c07SHersen Wu 30204562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 30211bf56e62SZeyu Fan .program_gamut_remap = program_gamut_remap, 3022bdf9a1a0SYue Hin Lau .program_csc_matrix = program_csc_matrix, 30234562236bSHarry Wentland .init_hw = init_hw, 30244562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 30254562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 30264562236bSHarry Wentland .set_plane_config = set_plane_config, 30274562236bSHarry Wentland .update_plane_addr = update_plane_addr, 30284562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 3029d7194cf6SAric Cyr .set_input_transfer_func = dce110_set_input_transfer_func, 303090e508baSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 30314562236bSHarry Wentland .power_down = dce110_power_down, 30324562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 30334562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 3034fa2123dbSMikita Lipski .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, 30354562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 30364562236bSHarry Wentland .enable_stream = dce110_enable_stream, 30374562236bSHarry Wentland .disable_stream = dce110_disable_stream, 30384562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 303941b49742SCharlene Liu .blank_stream = dce110_blank_stream, 30404562236bSHarry Wentland .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 30414562236bSHarry Wentland .enable_display_power_gating = dce110_enable_display_power_gating, 30427f914a62SYongqiang Sun .disable_plane = dce110_power_down_fe, 30434562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 30444562236bSHarry Wentland .set_bandwidth = dce110_set_bandwidth, 30454562236bSHarry Wentland .set_drr = set_drr, 304672ada5f7SEric Cook .get_position = get_position, 30474562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 304854e8695eSDmytro Laktyushkin .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 30493158223eSEric Bernstein .enable_stream_timing = dce110_enable_stream_timing, 305015e17335SCharlene Liu .setup_stereo = NULL, 305115e17335SCharlene Liu .set_avmute = dce110_set_avmute, 305241f97c07SHersen Wu .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 305341f97c07SHersen Wu .ready_shared_resources = ready_shared_resources, 305441f97c07SHersen Wu .optimize_shared_resources = optimize_shared_resources, 3055631aaa0aSHersen Wu .pplib_apply_display_requirements = pplib_apply_display_requirements, 305687401969SAndrew Jiang .edp_backlight_control = hwss_edp_backlight_control, 305787401969SAndrew Jiang .edp_power_control = hwss_edp_power_control, 3058904623eeSYongqiang Sun .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, 305933fd17d9SEric Yang .set_cursor_position = dce110_set_cursor_position, 306033fd17d9SEric Yang .set_cursor_attribute = dce110_set_cursor_attribute 30614562236bSHarry Wentland }; 30624562236bSHarry Wentland 3063c13b408bSDave Airlie void dce110_hw_sequencer_construct(struct dc *dc) 30644562236bSHarry Wentland { 30654562236bSHarry Wentland dc->hwss = dce110_funcs; 30664562236bSHarry Wentland } 30674562236bSHarry Wentland 3068