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 371663ae1cSBhawanpreet Lakha #include "dce110_compressor.h" 381663ae1cSBhawanpreet Lakha 394562236bSHarry Wentland #include "bios/bios_parser_helper.h" 404562236bSHarry Wentland #include "timing_generator.h" 414562236bSHarry Wentland #include "mem_input.h" 424562236bSHarry Wentland #include "opp.h" 434562236bSHarry Wentland #include "ipp.h" 444562236bSHarry Wentland #include "transform.h" 454562236bSHarry Wentland #include "stream_encoder.h" 464562236bSHarry Wentland #include "link_encoder.h" 4787401969SAndrew Jiang #include "link_hwss.h" 484562236bSHarry Wentland #include "clock_source.h" 495e7773a2SAnthony Koo #include "abm.h" 504562236bSHarry Wentland #include "audio.h" 5108b16886SZeyu Fan #include "reg_helper.h" 524562236bSHarry Wentland 534562236bSHarry Wentland /* include DCE11 register header files */ 544562236bSHarry Wentland #include "dce/dce_11_0_d.h" 554562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 56e266fdf6SVitaly Prosyak #include "custom_float.h" 574562236bSHarry Wentland 584cac1e6dSYongqiang Sun #include "atomfirmware.h" 594cac1e6dSYongqiang Sun 6087401969SAndrew Jiang /* 6187401969SAndrew Jiang * All values are in milliseconds; 6287401969SAndrew Jiang * For eDP, after power-up/power/down, 6387401969SAndrew Jiang * 300/500 msec max. delay from LCDVCC to black video generation 6487401969SAndrew Jiang */ 6587401969SAndrew Jiang #define PANEL_POWER_UP_TIMEOUT 300 6687401969SAndrew Jiang #define PANEL_POWER_DOWN_TIMEOUT 500 6787401969SAndrew Jiang #define HPD_CHECK_INTERVAL 10 6887401969SAndrew Jiang 695eefbc40SYue Hin Lau #define CTX \ 705eefbc40SYue Hin Lau hws->ctx 715d4b05ddSBhawanpreet Lakha 725d4b05ddSBhawanpreet Lakha #define DC_LOGGER_INIT() 735d4b05ddSBhawanpreet Lakha 745eefbc40SYue Hin Lau #define REG(reg)\ 755eefbc40SYue Hin Lau hws->regs->reg 765eefbc40SYue Hin Lau 775eefbc40SYue Hin Lau #undef FN 785eefbc40SYue Hin Lau #define FN(reg_name, field_name) \ 795eefbc40SYue Hin Lau hws->shifts->field_name, hws->masks->field_name 805eefbc40SYue Hin Lau 814562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 824562236bSHarry Wentland uint32_t crtc; 834562236bSHarry Wentland }; 844562236bSHarry Wentland 854562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 864562236bSHarry Wentland { 874562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 884562236bSHarry Wentland }, 894562236bSHarry Wentland { 904562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 914562236bSHarry Wentland }, 924562236bSHarry Wentland { 934562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 944562236bSHarry Wentland }, 954562236bSHarry Wentland { 964562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 974562236bSHarry Wentland } 984562236bSHarry Wentland }; 994562236bSHarry Wentland 1004562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 1014562236bSHarry Wentland (reg + reg_offsets[id].blnd) 1024562236bSHarry Wentland 1034562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 1044562236bSHarry Wentland (reg + reg_offsets[id].crtc) 1054562236bSHarry Wentland 1064562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 1074562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 1084562236bSHarry Wentland 1094562236bSHarry Wentland /******************************************************************************* 1104562236bSHarry Wentland * Private definitions 1114562236bSHarry Wentland ******************************************************************************/ 1124562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 1134562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 1144562236bSHarry Wentland { 1154562236bSHarry Wentland uint32_t addr; 1164562236bSHarry Wentland uint32_t value = 0; 1174562236bSHarry Wentland uint32_t chunk_int = 0; 1184562236bSHarry Wentland uint32_t chunk_mul = 0; 1194562236bSHarry Wentland 1204562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 1214562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1224562236bSHarry Wentland 1234562236bSHarry Wentland set_reg_field_value( 1244562236bSHarry Wentland value, 1254562236bSHarry Wentland 0, 1264562236bSHarry Wentland DVMM_PTE_CONTROL, 1274562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1284562236bSHarry Wentland 1294562236bSHarry Wentland set_reg_field_value( 1304562236bSHarry Wentland value, 1314562236bSHarry Wentland 1, 1324562236bSHarry Wentland DVMM_PTE_CONTROL, 1334562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1344562236bSHarry Wentland 1354562236bSHarry Wentland set_reg_field_value( 1364562236bSHarry Wentland value, 1374562236bSHarry Wentland 1, 1384562236bSHarry Wentland DVMM_PTE_CONTROL, 1394562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1404562236bSHarry Wentland 1414562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1424562236bSHarry Wentland 1434562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1444562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1454562236bSHarry Wentland 1464562236bSHarry Wentland chunk_int = get_reg_field_value( 1474562236bSHarry Wentland value, 1484562236bSHarry Wentland DVMM_PTE_REQ, 1494562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1504562236bSHarry Wentland 1514562236bSHarry Wentland chunk_mul = get_reg_field_value( 1524562236bSHarry Wentland value, 1534562236bSHarry Wentland DVMM_PTE_REQ, 1544562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1554562236bSHarry Wentland 1564562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1574562236bSHarry Wentland 1584562236bSHarry Wentland set_reg_field_value( 1594562236bSHarry Wentland value, 1604562236bSHarry Wentland 255, 1614562236bSHarry Wentland DVMM_PTE_REQ, 1624562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1634562236bSHarry Wentland 1644562236bSHarry Wentland set_reg_field_value( 1654562236bSHarry Wentland value, 1664562236bSHarry Wentland 4, 1674562236bSHarry Wentland DVMM_PTE_REQ, 1684562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1694562236bSHarry Wentland 1704562236bSHarry Wentland set_reg_field_value( 1714562236bSHarry Wentland value, 1724562236bSHarry Wentland 4, 1734562236bSHarry Wentland DVMM_PTE_REQ, 1744562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1754562236bSHarry Wentland 1764562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1774562236bSHarry Wentland } 1784562236bSHarry Wentland } 1794562236bSHarry Wentland /**************************************************************************/ 1804562236bSHarry Wentland 1814562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1824562236bSHarry Wentland struct dc_context *ctx, 1834562236bSHarry Wentland bool clock_gating) 1844562236bSHarry Wentland { 1854562236bSHarry Wentland /*TODO*/ 1864562236bSHarry Wentland } 1874562236bSHarry Wentland 1884562236bSHarry Wentland static bool dce110_enable_display_power_gating( 189fb3466a4SBhawanpreet Lakha struct dc *dc, 1904562236bSHarry Wentland uint8_t controller_id, 1914562236bSHarry Wentland struct dc_bios *dcb, 1924562236bSHarry Wentland enum pipe_gating_control power_gating) 1934562236bSHarry Wentland { 1944562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 1954562236bSHarry Wentland enum bp_pipe_control_action cntl; 1964562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 1974562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 1984562236bSHarry Wentland 1994562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 2004562236bSHarry Wentland return true; 2014562236bSHarry Wentland 2024562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 2034562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 2044562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 2054562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 2064562236bSHarry Wentland else 2074562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 2084562236bSHarry Wentland 2094562236bSHarry Wentland if (controller_id == underlay_idx) 2104562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 2114562236bSHarry Wentland 2124562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){ 2134562236bSHarry Wentland 2144562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 2154562236bSHarry Wentland dcb, controller_id + 1, cntl); 2164562236bSHarry Wentland 2174562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 2184562236bSHarry Wentland * by default when command table is called 2194562236bSHarry Wentland * 2204562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 2214562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 2224562236bSHarry Wentland * than 3. 2234562236bSHarry Wentland */ 2244562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 2254562236bSHarry Wentland dm_write_reg(ctx, 2264562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 2274562236bSHarry Wentland 0); 2284562236bSHarry Wentland } 2294562236bSHarry Wentland 2304562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2314562236bSHarry Wentland dce110_init_pte(ctx); 2324562236bSHarry Wentland 2334562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2344562236bSHarry Wentland return true; 2354562236bSHarry Wentland else 2364562236bSHarry Wentland return false; 2374562236bSHarry Wentland } 2384562236bSHarry Wentland 2394562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2403be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2414562236bSHarry Wentland { 2424562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2434562236bSHarry Wentland 2443be5262eSHarry Wentland switch (plane_state->format) { 2454562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2468693049aSTony Cheng case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 2474562236bSHarry Wentland prescale_params->scale = 0x2020; 2484562236bSHarry Wentland break; 2494562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2504562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2514562236bSHarry Wentland prescale_params->scale = 0x2008; 2524562236bSHarry Wentland break; 2534562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 2544562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2554562236bSHarry Wentland prescale_params->scale = 0x2000; 2564562236bSHarry Wentland break; 2574562236bSHarry Wentland default: 2584562236bSHarry Wentland ASSERT(false); 259d7194cf6SAric Cyr break; 2604562236bSHarry Wentland } 2614562236bSHarry Wentland } 2624562236bSHarry Wentland 263a6114e85SHarry Wentland static bool 264a6114e85SHarry Wentland dce110_set_input_transfer_func(struct pipe_ctx *pipe_ctx, 2653be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2664562236bSHarry Wentland { 26786a66c4eSHarry Wentland struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 2687b0c470fSLeo (Sunpeng) Li const struct dc_transfer_func *tf = NULL; 26990e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 27090e508baSAnthony Koo bool result = true; 27190e508baSAnthony Koo 27290e508baSAnthony Koo if (ipp == NULL) 27390e508baSAnthony Koo return false; 27490e508baSAnthony Koo 2753be5262eSHarry Wentland if (plane_state->in_transfer_func) 2763be5262eSHarry Wentland tf = plane_state->in_transfer_func; 27790e508baSAnthony Koo 2783be5262eSHarry Wentland build_prescale_params(&prescale_params, plane_state); 27990e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 28090e508baSAnthony Koo 28184ffa801SLeo (Sunpeng) Li if (plane_state->gamma_correction && 28284ffa801SLeo (Sunpeng) Li !plane_state->gamma_correction->is_identity && 28384ffa801SLeo (Sunpeng) Li dce_use_lut(plane_state->format)) 2843be5262eSHarry Wentland ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction); 285d7194cf6SAric Cyr 28690e508baSAnthony Koo if (tf == NULL) { 28790e508baSAnthony Koo /* Default case if no input transfer function specified */ 288a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 2897b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_PREDEFINED) { 2907b0c470fSLeo (Sunpeng) Li switch (tf->tf) { 29190e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 292a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 29390e508baSAnthony Koo break; 29490e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 295a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC); 29690e508baSAnthony Koo break; 29790e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 298a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 29990e508baSAnthony Koo break; 30090e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 30190e508baSAnthony Koo default: 30290e508baSAnthony Koo result = false; 303d7194cf6SAric Cyr break; 30490e508baSAnthony Koo } 3057b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_BYPASS) { 30670063a59SAmy Zhang ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 30790e508baSAnthony Koo } else { 30890e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 30990e508baSAnthony Koo result = false; 31090e508baSAnthony Koo } 31190e508baSAnthony Koo 31290e508baSAnthony Koo return result; 31390e508baSAnthony Koo } 31490e508baSAnthony Koo 315bd1be8e8SHarry Wentland static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted, 316fcd2f4bfSAmy Zhang struct curve_points *arr_points, 317fcd2f4bfSAmy Zhang uint32_t hw_points_num) 318fcd2f4bfSAmy Zhang { 319fcd2f4bfSAmy Zhang struct custom_float_format fmt; 320fcd2f4bfSAmy Zhang 321fcd2f4bfSAmy Zhang struct pwl_result_data *rgb = rgb_resulted; 322fcd2f4bfSAmy Zhang 323fcd2f4bfSAmy Zhang uint32_t i = 0; 324fcd2f4bfSAmy Zhang 325fcd2f4bfSAmy Zhang fmt.exponenta_bits = 6; 326fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 327fcd2f4bfSAmy Zhang fmt.sign = true; 328fcd2f4bfSAmy Zhang 329bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].x, &fmt, 330fcd2f4bfSAmy Zhang &arr_points[0].custom_float_x)) { 331fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 332fcd2f4bfSAmy Zhang return false; 333fcd2f4bfSAmy Zhang } 334fcd2f4bfSAmy Zhang 335bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].offset, &fmt, 336fcd2f4bfSAmy Zhang &arr_points[0].custom_float_offset)) { 337fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 338fcd2f4bfSAmy Zhang return false; 339fcd2f4bfSAmy Zhang } 340fcd2f4bfSAmy Zhang 341bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].slope, &fmt, 342fcd2f4bfSAmy Zhang &arr_points[0].custom_float_slope)) { 343fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 344fcd2f4bfSAmy Zhang return false; 345fcd2f4bfSAmy Zhang } 346fcd2f4bfSAmy Zhang 347fcd2f4bfSAmy Zhang fmt.mantissa_bits = 10; 348fcd2f4bfSAmy Zhang fmt.sign = false; 349fcd2f4bfSAmy Zhang 350bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].x, &fmt, 351fcd2f4bfSAmy Zhang &arr_points[1].custom_float_x)) { 352fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 353fcd2f4bfSAmy Zhang return false; 354fcd2f4bfSAmy Zhang } 355fcd2f4bfSAmy Zhang 356bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].y, &fmt, 357fcd2f4bfSAmy Zhang &arr_points[1].custom_float_y)) { 358fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 359fcd2f4bfSAmy Zhang return false; 360fcd2f4bfSAmy Zhang } 361fcd2f4bfSAmy Zhang 3624d06ccd0SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].slope, &fmt, 3634d06ccd0SHarry Wentland &arr_points[1].custom_float_slope)) { 364fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 365fcd2f4bfSAmy Zhang return false; 366fcd2f4bfSAmy Zhang } 367fcd2f4bfSAmy Zhang 368fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 369fcd2f4bfSAmy Zhang fmt.sign = true; 370fcd2f4bfSAmy Zhang 371fcd2f4bfSAmy Zhang while (i != hw_points_num) { 372bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->red, &fmt, 373fcd2f4bfSAmy Zhang &rgb->red_reg)) { 374fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 375fcd2f4bfSAmy Zhang return false; 376fcd2f4bfSAmy Zhang } 377fcd2f4bfSAmy Zhang 378bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->green, &fmt, 379fcd2f4bfSAmy Zhang &rgb->green_reg)) { 380fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 381fcd2f4bfSAmy Zhang return false; 382fcd2f4bfSAmy Zhang } 383fcd2f4bfSAmy Zhang 384bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->blue, &fmt, 385fcd2f4bfSAmy Zhang &rgb->blue_reg)) { 386fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 387fcd2f4bfSAmy Zhang return false; 388fcd2f4bfSAmy Zhang } 389fcd2f4bfSAmy Zhang 390bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_red, &fmt, 391fcd2f4bfSAmy Zhang &rgb->delta_red_reg)) { 392fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 393fcd2f4bfSAmy Zhang return false; 394fcd2f4bfSAmy Zhang } 395fcd2f4bfSAmy Zhang 396bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_green, &fmt, 397fcd2f4bfSAmy Zhang &rgb->delta_green_reg)) { 398fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 399fcd2f4bfSAmy Zhang return false; 400fcd2f4bfSAmy Zhang } 401fcd2f4bfSAmy Zhang 402bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_blue, &fmt, 403fcd2f4bfSAmy Zhang &rgb->delta_blue_reg)) { 404fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 405fcd2f4bfSAmy Zhang return false; 406fcd2f4bfSAmy Zhang } 407fcd2f4bfSAmy Zhang 408fcd2f4bfSAmy Zhang ++rgb; 409fcd2f4bfSAmy Zhang ++i; 410fcd2f4bfSAmy Zhang } 411fcd2f4bfSAmy Zhang 412fcd2f4bfSAmy Zhang return true; 413fcd2f4bfSAmy Zhang } 414fcd2f4bfSAmy Zhang 41508616da5SLeo (Sunpeng) Li #define MAX_LOW_POINT 25 4168f8372c7SKrunoslav Kovac #define NUMBER_REGIONS 16 4178f8372c7SKrunoslav Kovac #define NUMBER_SW_SEGMENTS 16 4188f8372c7SKrunoslav Kovac 419b310b081SHarry Wentland static bool 420b310b081SHarry Wentland dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, 421b310b081SHarry Wentland struct pwl_params *regamma_params) 422fcd2f4bfSAmy Zhang { 42323ae4f8eSAmy Zhang struct curve_points *arr_points; 42423ae4f8eSAmy Zhang struct pwl_result_data *rgb_resulted; 42523ae4f8eSAmy Zhang struct pwl_result_data *rgb; 42623ae4f8eSAmy Zhang struct pwl_result_data *rgb_plus_1; 427fcd2f4bfSAmy Zhang struct fixed31_32 y_r; 428fcd2f4bfSAmy Zhang struct fixed31_32 y_g; 429fcd2f4bfSAmy Zhang struct fixed31_32 y_b; 430fcd2f4bfSAmy Zhang struct fixed31_32 y1_min; 431fcd2f4bfSAmy Zhang struct fixed31_32 y3_max; 432fcd2f4bfSAmy Zhang 4338f8372c7SKrunoslav Kovac int32_t region_start, region_end; 4348f8372c7SKrunoslav Kovac uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points; 43523ae4f8eSAmy Zhang 436b310b081SHarry Wentland if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS) 43723ae4f8eSAmy Zhang return false; 43823ae4f8eSAmy Zhang 43923ae4f8eSAmy Zhang arr_points = regamma_params->arr_points; 44023ae4f8eSAmy Zhang rgb_resulted = regamma_params->rgb_resulted; 44123ae4f8eSAmy Zhang hw_points = 0; 442fcd2f4bfSAmy Zhang 443fcd2f4bfSAmy Zhang memset(regamma_params, 0, sizeof(struct pwl_params)); 444fcd2f4bfSAmy Zhang 445fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 446534db198SAmy Zhang /* 16 segments 447fcd2f4bfSAmy Zhang * segments are from 2^-11 to 2^5 448fcd2f4bfSAmy Zhang */ 44908616da5SLeo (Sunpeng) Li region_start = -11; 45008616da5SLeo (Sunpeng) Li region_end = region_start + NUMBER_REGIONS; 451fcd2f4bfSAmy Zhang 4528f8372c7SKrunoslav Kovac for (i = 0; i < NUMBER_REGIONS; i++) 4538f8372c7SKrunoslav Kovac seg_distr[i] = 4; 454534db198SAmy Zhang 455fcd2f4bfSAmy Zhang } else { 456534db198SAmy Zhang /* 10 segments 457fc6de1c5SLeo (Sunpeng) Li * segment is from 2^-10 to 2^1 458fc6de1c5SLeo (Sunpeng) Li * We include an extra segment for range [2^0, 2^1). This is to 459fc6de1c5SLeo (Sunpeng) Li * ensure that colors with normalized values of 1 don't miss the 460fc6de1c5SLeo (Sunpeng) Li * LUT. 461fcd2f4bfSAmy Zhang */ 4628f8372c7SKrunoslav Kovac region_start = -10; 463fc6de1c5SLeo (Sunpeng) Li region_end = 1; 464534db198SAmy Zhang 4658f8372c7SKrunoslav Kovac seg_distr[0] = 4; 466534db198SAmy Zhang seg_distr[1] = 4; 467534db198SAmy Zhang seg_distr[2] = 4; 468534db198SAmy Zhang seg_distr[3] = 4; 469534db198SAmy Zhang seg_distr[4] = 4; 470534db198SAmy Zhang seg_distr[5] = 4; 471534db198SAmy Zhang seg_distr[6] = 4; 472534db198SAmy Zhang seg_distr[7] = 4; 4738f8372c7SKrunoslav Kovac seg_distr[8] = 4; 4748f8372c7SKrunoslav Kovac seg_distr[9] = 4; 475fc6de1c5SLeo (Sunpeng) Li seg_distr[10] = 0; 476534db198SAmy Zhang seg_distr[11] = -1; 477534db198SAmy Zhang seg_distr[12] = -1; 478534db198SAmy Zhang seg_distr[13] = -1; 479534db198SAmy Zhang seg_distr[14] = -1; 480534db198SAmy Zhang seg_distr[15] = -1; 481fcd2f4bfSAmy Zhang } 482fcd2f4bfSAmy Zhang 483534db198SAmy Zhang for (k = 0; k < 16; k++) { 484534db198SAmy Zhang if (seg_distr[k] != -1) 485534db198SAmy Zhang hw_points += (1 << seg_distr[k]); 486534db198SAmy Zhang } 487534db198SAmy Zhang 488fcd2f4bfSAmy Zhang j = 0; 4898f8372c7SKrunoslav Kovac for (k = 0; k < (region_end - region_start); k++) { 490ec47734aSLeo (Sunpeng) Li increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 4918f8372c7SKrunoslav Kovac start_index = (region_start + k + MAX_LOW_POINT) * 4928f8372c7SKrunoslav Kovac NUMBER_SW_SEGMENTS; 4938f8372c7SKrunoslav Kovac for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 4948f8372c7SKrunoslav Kovac i += increment) { 495534db198SAmy Zhang if (j == hw_points - 1) 496fcd2f4bfSAmy Zhang break; 497fcd2f4bfSAmy Zhang rgb_resulted[j].red = output_tf->tf_pts.red[i]; 498fcd2f4bfSAmy Zhang rgb_resulted[j].green = output_tf->tf_pts.green[i]; 499fcd2f4bfSAmy Zhang rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 500fcd2f4bfSAmy Zhang j++; 501fcd2f4bfSAmy Zhang } 502534db198SAmy Zhang } 503534db198SAmy Zhang 504534db198SAmy Zhang /* last point */ 5058f8372c7SKrunoslav Kovac start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 506b310b081SHarry Wentland rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 507b310b081SHarry Wentland rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 508b310b081SHarry Wentland rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 509fcd2f4bfSAmy Zhang 510eb0e5154SDmytro Laktyushkin arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2), 511eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_start)); 512eb0e5154SDmytro Laktyushkin arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2), 513eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_end)); 514fcd2f4bfSAmy Zhang 515fcd2f4bfSAmy Zhang y_r = rgb_resulted[0].red; 516fcd2f4bfSAmy Zhang y_g = rgb_resulted[0].green; 517fcd2f4bfSAmy Zhang y_b = rgb_resulted[0].blue; 518fcd2f4bfSAmy Zhang 519eb0e5154SDmytro Laktyushkin y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b)); 520fcd2f4bfSAmy Zhang 521fcd2f4bfSAmy Zhang arr_points[0].y = y1_min; 522eb0e5154SDmytro Laktyushkin arr_points[0].slope = dc_fixpt_div(arr_points[0].y, 523fcd2f4bfSAmy Zhang arr_points[0].x); 524fcd2f4bfSAmy Zhang 525fcd2f4bfSAmy Zhang y_r = rgb_resulted[hw_points - 1].red; 526fcd2f4bfSAmy Zhang y_g = rgb_resulted[hw_points - 1].green; 527fcd2f4bfSAmy Zhang y_b = rgb_resulted[hw_points - 1].blue; 528fcd2f4bfSAmy Zhang 529fcd2f4bfSAmy Zhang /* see comment above, m_arrPoints[1].y should be the Y value for the 530fcd2f4bfSAmy Zhang * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 531fcd2f4bfSAmy Zhang */ 532eb0e5154SDmytro Laktyushkin y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b)); 533fcd2f4bfSAmy Zhang 534fcd2f4bfSAmy Zhang arr_points[1].y = y3_max; 535fcd2f4bfSAmy Zhang 536eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_zero; 537fcd2f4bfSAmy Zhang 538fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 539fcd2f4bfSAmy Zhang /* for PQ, we want to have a straight line from last HW X point, 540fcd2f4bfSAmy Zhang * and the slope to be such that we hit 1.0 at 10000 nits. 541fcd2f4bfSAmy Zhang */ 542eb0e5154SDmytro Laktyushkin const struct fixed31_32 end_value = dc_fixpt_from_int(125); 543fcd2f4bfSAmy Zhang 544eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_div( 545eb0e5154SDmytro Laktyushkin dc_fixpt_sub(dc_fixpt_one, arr_points[1].y), 546eb0e5154SDmytro Laktyushkin dc_fixpt_sub(end_value, arr_points[1].x)); 547fcd2f4bfSAmy Zhang } 548fcd2f4bfSAmy Zhang 549fcd2f4bfSAmy Zhang regamma_params->hw_points_num = hw_points; 550fcd2f4bfSAmy Zhang 551534db198SAmy Zhang i = 1; 552534db198SAmy Zhang for (k = 0; k < 16 && i < 16; k++) { 553534db198SAmy Zhang if (seg_distr[k] != -1) { 554b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 555534db198SAmy Zhang regamma_params->arr_curve_points[i].offset = 556b310b081SHarry Wentland regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 557fcd2f4bfSAmy Zhang } 558534db198SAmy Zhang i++; 559534db198SAmy Zhang } 560534db198SAmy Zhang 561534db198SAmy Zhang if (seg_distr[k] != -1) 562b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 563fcd2f4bfSAmy Zhang 56423ae4f8eSAmy Zhang rgb = rgb_resulted; 56523ae4f8eSAmy Zhang rgb_plus_1 = rgb_resulted + 1; 566fcd2f4bfSAmy Zhang 567fcd2f4bfSAmy Zhang i = 1; 568fcd2f4bfSAmy Zhang 569fcd2f4bfSAmy Zhang while (i != hw_points + 1) { 570eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) 571fcd2f4bfSAmy Zhang rgb_plus_1->red = rgb->red; 572eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) 573fcd2f4bfSAmy Zhang rgb_plus_1->green = rgb->green; 574eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) 575fcd2f4bfSAmy Zhang rgb_plus_1->blue = rgb->blue; 576fcd2f4bfSAmy Zhang 577eb0e5154SDmytro Laktyushkin rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); 578eb0e5154SDmytro Laktyushkin rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 579eb0e5154SDmytro Laktyushkin rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 580fcd2f4bfSAmy Zhang 581fcd2f4bfSAmy Zhang ++rgb_plus_1; 582fcd2f4bfSAmy Zhang ++rgb; 583fcd2f4bfSAmy Zhang ++i; 584fcd2f4bfSAmy Zhang } 585fcd2f4bfSAmy Zhang 586fcd2f4bfSAmy Zhang convert_to_custom_float(rgb_resulted, arr_points, hw_points); 587fcd2f4bfSAmy Zhang 588fcd2f4bfSAmy Zhang return true; 589fcd2f4bfSAmy Zhang } 590fcd2f4bfSAmy Zhang 591a6114e85SHarry Wentland static bool 592a6114e85SHarry Wentland dce110_set_output_transfer_func(struct pipe_ctx *pipe_ctx, 5930971c40eSHarry Wentland const struct dc_stream_state *stream) 59490e508baSAnthony Koo { 59586a66c4eSHarry Wentland struct transform *xfm = pipe_ctx->plane_res.xfm; 5964562236bSHarry Wentland 5977a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, true); 5987a09f5beSYue Hin Lau xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 5994562236bSHarry Wentland 6004fa086b9SLeo (Sunpeng) Li if (stream->out_transfer_func && 601efd52204SHarry Wentland stream->out_transfer_func->type == TF_TYPE_PREDEFINED && 602efd52204SHarry Wentland stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) { 6037a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 604efd52204SHarry Wentland } else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func, 605efd52204SHarry Wentland &xfm->regamma_params)) { 6067a09f5beSYue Hin Lau xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 6077a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 6084562236bSHarry Wentland } else { 6097a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 6104562236bSHarry Wentland } 6114562236bSHarry Wentland 6127a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, false); 6134562236bSHarry Wentland 614cc0cb445SLeon Elazar return true; 6154562236bSHarry Wentland } 6164562236bSHarry Wentland 6174562236bSHarry Wentland static enum dc_status bios_parser_crtc_source_select( 6184562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 6194562236bSHarry Wentland { 6204562236bSHarry Wentland struct dc_bios *dcb; 6214562236bSHarry Wentland /* call VBIOS table to set CRTC source for the HW 6224562236bSHarry Wentland * encoder block 6234562236bSHarry Wentland * note: video bios clears all FMT setting here. */ 6244562236bSHarry Wentland struct bp_crtc_source_select crtc_source_select = {0}; 625b73a22d3SHarry Wentland const struct dc_sink *sink = pipe_ctx->stream->sink; 6264562236bSHarry Wentland 6278e9c4c8cSHarry Wentland crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id; 628e07f541fSYongqiang Sun crtc_source_select.controller_id = pipe_ctx->stream_res.tg->inst + 1; 6294562236bSHarry Wentland /*TODO: Need to un-hardcode color depth, dp_audio and account for 6304562236bSHarry Wentland * the case where signal and sink signal is different (translator 6314562236bSHarry Wentland * encoder)*/ 6324562236bSHarry Wentland crtc_source_select.signal = pipe_ctx->stream->signal; 6334562236bSHarry Wentland crtc_source_select.enable_dp_audio = false; 6344562236bSHarry Wentland crtc_source_select.sink_signal = pipe_ctx->stream->signal; 6351b7441b0SCharlene Liu 6361b7441b0SCharlene Liu switch (pipe_ctx->stream->timing.display_color_depth) { 6371b7441b0SCharlene Liu case COLOR_DEPTH_666: 6381b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_6BIT_COLOR; 6391b7441b0SCharlene Liu break; 6401b7441b0SCharlene Liu case COLOR_DEPTH_888: 6414562236bSHarry Wentland crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 6421b7441b0SCharlene Liu break; 6431b7441b0SCharlene Liu case COLOR_DEPTH_101010: 6441b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_10BIT_COLOR; 6451b7441b0SCharlene Liu break; 6461b7441b0SCharlene Liu case COLOR_DEPTH_121212: 6471b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_12BIT_COLOR; 6481b7441b0SCharlene Liu break; 6491b7441b0SCharlene Liu default: 6501b7441b0SCharlene Liu BREAK_TO_DEBUGGER(); 6511b7441b0SCharlene Liu crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR; 6521b7441b0SCharlene Liu break; 6531b7441b0SCharlene Liu } 6544562236bSHarry Wentland 6554562236bSHarry Wentland dcb = sink->ctx->dc_bios; 6564562236bSHarry Wentland 6574562236bSHarry Wentland if (BP_RESULT_OK != dcb->funcs->crtc_source_select( 6584562236bSHarry Wentland dcb, 6594562236bSHarry Wentland &crtc_source_select)) { 6604562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 6614562236bSHarry Wentland } 6624562236bSHarry Wentland 6634562236bSHarry Wentland return DC_OK; 6644562236bSHarry Wentland } 6654562236bSHarry Wentland 6664562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 6674562236bSHarry Wentland { 6686f0db2dcSKrunoslav Kovac bool is_hdmi; 6696f0db2dcSKrunoslav Kovac bool is_dp; 6706f0db2dcSKrunoslav Kovac 67186e2e1beSHersen Wu ASSERT(pipe_ctx->stream); 67286e2e1beSHersen Wu 6738e9c4c8cSHarry Wentland if (pipe_ctx->stream_res.stream_enc == NULL) 67486e2e1beSHersen Wu return; /* this is not root pipe */ 67586e2e1beSHersen Wu 6766f0db2dcSKrunoslav Kovac is_hdmi = dc_is_hdmi_signal(pipe_ctx->stream->signal); 6776f0db2dcSKrunoslav Kovac is_dp = dc_is_dp_signal(pipe_ctx->stream->signal); 6786f0db2dcSKrunoslav Kovac 6796f0db2dcSKrunoslav Kovac if (!is_hdmi && !is_dp) 6806f0db2dcSKrunoslav Kovac return; 6816f0db2dcSKrunoslav Kovac 6826f0db2dcSKrunoslav Kovac if (is_hdmi) 6838e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 6848e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 68596c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6866f0db2dcSKrunoslav Kovac else 6878e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 6888e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 68996c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6904562236bSHarry Wentland } 6914562236bSHarry Wentland 6924562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 6934562236bSHarry Wentland { 6944562236bSHarry Wentland enum dc_lane_count lane_count = 695d0778ebfSHarry Wentland pipe_ctx->stream->sink->link->cur_link_settings.lane_count; 6964562236bSHarry Wentland 6974fa086b9SLeo (Sunpeng) Li struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 698d0778ebfSHarry Wentland struct dc_link *link = pipe_ctx->stream->sink->link; 6994562236bSHarry Wentland 700f215a57dSEric Yang 7014562236bSHarry Wentland uint32_t active_total_with_borders; 7024562236bSHarry Wentland uint32_t early_control = 0; 7036b670fa9SHarry Wentland struct timing_generator *tg = pipe_ctx->stream_res.tg; 7044562236bSHarry Wentland 705f215a57dSEric Yang /* For MST, there are multiply stream go to only one link. 706f215a57dSEric Yang * connect DIG back_end to front_end while enable_stream and 707f215a57dSEric Yang * disconnect them during disable_stream 708f215a57dSEric Yang * BY this, it is logic clean to separate stream and link */ 709f215a57dSEric Yang link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 710f215a57dSEric Yang pipe_ctx->stream_res.stream_enc->id, true); 711f215a57dSEric Yang 712f215a57dSEric Yang /* update AVI info frame (HDMI, DP)*/ 713f215a57dSEric Yang /* TODO: FPGA may change to hwss.update_info_frame */ 7144562236bSHarry Wentland dce110_update_info_frame(pipe_ctx); 715f215a57dSEric Yang 7164562236bSHarry Wentland /* enable early control to avoid corruption on DP monitor*/ 7174562236bSHarry Wentland active_total_with_borders = 7184562236bSHarry Wentland timing->h_addressable 7194562236bSHarry Wentland + timing->h_border_left 7204562236bSHarry Wentland + timing->h_border_right; 7214562236bSHarry Wentland 7224562236bSHarry Wentland if (lane_count != 0) 7234562236bSHarry Wentland early_control = active_total_with_borders % lane_count; 7244562236bSHarry Wentland 7254562236bSHarry Wentland if (early_control == 0) 7264562236bSHarry Wentland early_control = lane_count; 7274562236bSHarry Wentland 7284562236bSHarry Wentland tg->funcs->set_early_control(tg, early_control); 7294562236bSHarry Wentland 7304562236bSHarry Wentland /* enable audio only within mode set */ 731afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 7324562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 7338e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); 7344562236bSHarry Wentland } 7354562236bSHarry Wentland 736f215a57dSEric Yang 737f215a57dSEric Yang 7384562236bSHarry Wentland 7394562236bSHarry Wentland } 7404562236bSHarry Wentland 7415eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/ 7425eefbc40SYue Hin Lau static bool is_panel_backlight_on(struct dce_hwseq *hws) 7435eefbc40SYue Hin Lau { 7445eefbc40SYue Hin Lau uint32_t value; 7455eefbc40SYue Hin Lau 7465eefbc40SYue Hin Lau REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value); 7475eefbc40SYue Hin Lau 7485eefbc40SYue Hin Lau return value; 7495eefbc40SYue Hin Lau } 7505eefbc40SYue Hin Lau 75187401969SAndrew Jiang static bool is_panel_powered_on(struct dce_hwseq *hws) 75287401969SAndrew Jiang { 753d03f3f63SEric Yang uint32_t pwr_seq_state, dig_on, dig_on_ovrd; 75487401969SAndrew Jiang 755d03f3f63SEric Yang 756d03f3f63SEric Yang REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &pwr_seq_state); 757d03f3f63SEric Yang 758d03f3f63SEric Yang REG_GET_2(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON, &dig_on, LVTMA_DIGON_OVRD, &dig_on_ovrd); 759d03f3f63SEric Yang 760d03f3f63SEric Yang return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1); 76187401969SAndrew Jiang } 76287401969SAndrew Jiang 7635eefbc40SYue Hin Lau static enum bp_result link_transmitter_control( 76487401969SAndrew Jiang struct dc_bios *bios, 7655eefbc40SYue Hin Lau struct bp_transmitter_control *cntl) 7665eefbc40SYue Hin Lau { 7675eefbc40SYue Hin Lau enum bp_result result; 7685eefbc40SYue Hin Lau 76987401969SAndrew Jiang result = bios->funcs->transmitter_control(bios, cntl); 7705eefbc40SYue Hin Lau 7715eefbc40SYue Hin Lau return result; 7725eefbc40SYue Hin Lau } 7735eefbc40SYue Hin Lau 77487401969SAndrew Jiang /* 77587401969SAndrew Jiang * @brief 77687401969SAndrew Jiang * eDP only. 77787401969SAndrew Jiang */ 77887401969SAndrew Jiang void hwss_edp_wait_for_hpd_ready( 779069d418fSAndrew Jiang struct dc_link *link, 78087401969SAndrew Jiang bool power_up) 78187401969SAndrew Jiang { 782069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 783069d418fSAndrew Jiang struct graphics_object_id connector = link->link_enc->connector; 78487401969SAndrew Jiang struct gpio *hpd; 78587401969SAndrew Jiang bool edp_hpd_high = false; 78687401969SAndrew Jiang uint32_t time_elapsed = 0; 78787401969SAndrew Jiang uint32_t timeout = power_up ? 78887401969SAndrew Jiang PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; 78987401969SAndrew Jiang 79087401969SAndrew Jiang if (dal_graphics_object_id_get_connector_id(connector) 79187401969SAndrew Jiang != CONNECTOR_ID_EDP) { 79287401969SAndrew Jiang BREAK_TO_DEBUGGER(); 79387401969SAndrew Jiang return; 79487401969SAndrew Jiang } 79587401969SAndrew Jiang 79687401969SAndrew Jiang if (!power_up) 79787401969SAndrew Jiang /* 79887401969SAndrew Jiang * From KV, we will not HPD low after turning off VCC - 79987401969SAndrew Jiang * instead, we will check the SW timer in power_up(). 80087401969SAndrew Jiang */ 80187401969SAndrew Jiang return; 80287401969SAndrew Jiang 80387401969SAndrew Jiang /* 80487401969SAndrew Jiang * When we power on/off the eDP panel, 80587401969SAndrew Jiang * we need to wait until SENSE bit is high/low. 80687401969SAndrew Jiang */ 80787401969SAndrew Jiang 80887401969SAndrew Jiang /* obtain HPD */ 80987401969SAndrew Jiang /* TODO what to do with this? */ 81087401969SAndrew Jiang hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); 81187401969SAndrew Jiang 81287401969SAndrew Jiang if (!hpd) { 81387401969SAndrew Jiang BREAK_TO_DEBUGGER(); 81487401969SAndrew Jiang return; 81587401969SAndrew Jiang } 81687401969SAndrew Jiang 81787401969SAndrew Jiang dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); 81887401969SAndrew Jiang 81987401969SAndrew Jiang /* wait until timeout or panel detected */ 82087401969SAndrew Jiang 82187401969SAndrew Jiang do { 82287401969SAndrew Jiang uint32_t detected = 0; 82387401969SAndrew Jiang 82487401969SAndrew Jiang dal_gpio_get_value(hpd, &detected); 82587401969SAndrew Jiang 82687401969SAndrew Jiang if (!(detected ^ power_up)) { 82787401969SAndrew Jiang edp_hpd_high = true; 82887401969SAndrew Jiang break; 82987401969SAndrew Jiang } 83087401969SAndrew Jiang 83187401969SAndrew Jiang msleep(HPD_CHECK_INTERVAL); 83287401969SAndrew Jiang 83387401969SAndrew Jiang time_elapsed += HPD_CHECK_INTERVAL; 83487401969SAndrew Jiang } while (time_elapsed < timeout); 83587401969SAndrew Jiang 83687401969SAndrew Jiang dal_gpio_close(hpd); 83787401969SAndrew Jiang 83887401969SAndrew Jiang dal_gpio_destroy_irq(&hpd); 83987401969SAndrew Jiang 84087401969SAndrew Jiang if (false == edp_hpd_high) { 8411296423bSBhawanpreet Lakha DC_LOG_ERROR( 84287401969SAndrew Jiang "%s: wait timed out!\n", __func__); 84387401969SAndrew Jiang } 84487401969SAndrew Jiang } 84587401969SAndrew Jiang 84687401969SAndrew Jiang void hwss_edp_power_control( 847069d418fSAndrew Jiang struct dc_link *link, 84887401969SAndrew Jiang bool power_up) 84987401969SAndrew Jiang { 850069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 85187401969SAndrew Jiang struct dce_hwseq *hwseq = ctx->dc->hwseq; 85287401969SAndrew Jiang struct bp_transmitter_control cntl = { 0 }; 85387401969SAndrew Jiang enum bp_result bp_result; 85487401969SAndrew Jiang 85587401969SAndrew Jiang 856069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 85787401969SAndrew Jiang != CONNECTOR_ID_EDP) { 85887401969SAndrew Jiang BREAK_TO_DEBUGGER(); 85987401969SAndrew Jiang return; 86087401969SAndrew Jiang } 86187401969SAndrew Jiang 86287401969SAndrew Jiang if (power_up != is_panel_powered_on(hwseq)) { 86387401969SAndrew Jiang /* Send VBIOS command to prompt eDP panel power */ 86478d5d04dSCharlene Liu if (power_up) { 86578d5d04dSCharlene Liu unsigned long long current_ts = dm_get_timestamp(ctx); 86678d5d04dSCharlene Liu unsigned long long duration_in_ms = 86793ed1814SHugo Hu div64_u64(dm_get_elapse_time_in_ns( 86878d5d04dSCharlene Liu ctx, 86978d5d04dSCharlene Liu current_ts, 87093ed1814SHugo Hu link->link_trace.time_stamp.edp_poweroff), 1000000); 87178d5d04dSCharlene Liu unsigned long long wait_time_ms = 0; 87278d5d04dSCharlene Liu 87378d5d04dSCharlene Liu /* max 500ms from LCDVDD off to on */ 8746c4fff06SYue Hin Lau unsigned long long edp_poweroff_time_ms = 500; 875ff587987SHugo Hu 8766c4fff06SYue Hin Lau if (link->local_sink != NULL) 8776c4fff06SYue Hin Lau edp_poweroff_time_ms = 8786c4fff06SYue Hin Lau 500 + link->local_sink->edid_caps.panel_patch.extra_t12_ms; 87978d5d04dSCharlene Liu if (link->link_trace.time_stamp.edp_poweroff == 0) 880ff587987SHugo Hu wait_time_ms = edp_poweroff_time_ms; 881ff587987SHugo Hu else if (duration_in_ms < edp_poweroff_time_ms) 882ff587987SHugo Hu wait_time_ms = edp_poweroff_time_ms - duration_in_ms; 88378d5d04dSCharlene Liu 88478d5d04dSCharlene Liu if (wait_time_ms) { 88578d5d04dSCharlene Liu msleep(wait_time_ms); 88678d5d04dSCharlene Liu dm_output_to_console("%s: wait %lld ms to power on eDP.\n", 88778d5d04dSCharlene Liu __func__, wait_time_ms); 88878d5d04dSCharlene Liu } 88978d5d04dSCharlene Liu 89078d5d04dSCharlene Liu } 89187401969SAndrew Jiang 8921296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 89387401969SAndrew Jiang "%s: Panel Power action: %s\n", 89487401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 89587401969SAndrew Jiang 89687401969SAndrew Jiang cntl.action = power_up ? 89787401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_ON : 89887401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_OFF; 899069d418fSAndrew Jiang cntl.transmitter = link->link_enc->transmitter; 900069d418fSAndrew Jiang cntl.connector_obj_id = link->link_enc->connector; 90187401969SAndrew Jiang cntl.coherent = false; 90287401969SAndrew Jiang cntl.lanes_number = LANE_COUNT_FOUR; 903069d418fSAndrew Jiang cntl.hpd_sel = link->link_enc->hpd_source; 90487401969SAndrew Jiang bp_result = link_transmitter_control(ctx->dc_bios, &cntl); 90587401969SAndrew Jiang 90678d5d04dSCharlene Liu if (!power_up) 90778d5d04dSCharlene Liu /*save driver power off time stamp*/ 90878d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx); 90978d5d04dSCharlene Liu else 91078d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweron = dm_get_timestamp(ctx); 91178d5d04dSCharlene Liu 91287401969SAndrew Jiang if (bp_result != BP_RESULT_OK) 9131296423bSBhawanpreet Lakha DC_LOG_ERROR( 91487401969SAndrew Jiang "%s: Panel Power bp_result: %d\n", 91587401969SAndrew Jiang __func__, bp_result); 91687401969SAndrew Jiang } else { 9171296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 91887401969SAndrew Jiang "%s: Skipping Panel Power action: %s\n", 91987401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 92087401969SAndrew Jiang } 92187401969SAndrew Jiang } 9225eefbc40SYue Hin Lau 9235eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/ 9245eefbc40SYue Hin Lau /* 9255eefbc40SYue Hin Lau * @brief 9265eefbc40SYue Hin Lau * eDP only. Control the backlight of the eDP panel 9275eefbc40SYue Hin Lau */ 92887401969SAndrew Jiang void hwss_edp_backlight_control( 9295eefbc40SYue Hin Lau struct dc_link *link, 9305eefbc40SYue Hin Lau bool enable) 9315eefbc40SYue Hin Lau { 932069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 933069d418fSAndrew Jiang struct dce_hwseq *hws = ctx->dc->hwseq; 9345eefbc40SYue Hin Lau struct bp_transmitter_control cntl = { 0 }; 9355eefbc40SYue Hin Lau 936069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 9375eefbc40SYue Hin Lau != CONNECTOR_ID_EDP) { 9385eefbc40SYue Hin Lau BREAK_TO_DEBUGGER(); 9395eefbc40SYue Hin Lau return; 9405eefbc40SYue Hin Lau } 9415eefbc40SYue Hin Lau 9425eefbc40SYue Hin Lau if (enable && is_panel_backlight_on(hws)) { 9431296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 9445eefbc40SYue Hin Lau "%s: panel already powered up. Do nothing.\n", 9455eefbc40SYue Hin Lau __func__); 9465eefbc40SYue Hin Lau return; 9475eefbc40SYue Hin Lau } 9485eefbc40SYue Hin Lau 9495eefbc40SYue Hin Lau /* Send VBIOS command to control eDP panel backlight */ 9505eefbc40SYue Hin Lau 9511296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 9525eefbc40SYue Hin Lau "%s: backlight action: %s\n", 9535eefbc40SYue Hin Lau __func__, (enable ? "On":"Off")); 9545eefbc40SYue Hin Lau 9555eefbc40SYue Hin Lau cntl.action = enable ? 9565eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_ON : 9575eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_OFF; 95887401969SAndrew Jiang 9595eefbc40SYue Hin Lau /*cntl.engine_id = ctx->engine;*/ 9605eefbc40SYue Hin Lau cntl.transmitter = link->link_enc->transmitter; 9615eefbc40SYue Hin Lau cntl.connector_obj_id = link->link_enc->connector; 9625eefbc40SYue Hin Lau /*todo: unhardcode*/ 9635eefbc40SYue Hin Lau cntl.lanes_number = LANE_COUNT_FOUR; 9645eefbc40SYue Hin Lau cntl.hpd_sel = link->link_enc->hpd_source; 965cf1835f0SCharlene Liu cntl.signal = SIGNAL_TYPE_EDP; 9665eefbc40SYue Hin Lau 9675eefbc40SYue Hin Lau /* For eDP, the following delays might need to be considered 9685eefbc40SYue Hin Lau * after link training completed: 9695eefbc40SYue Hin Lau * idle period - min. accounts for required BS-Idle pattern, 9705eefbc40SYue Hin Lau * max. allows for source frame synchronization); 9715eefbc40SYue Hin Lau * 50 msec max. delay from valid video data from source 9725eefbc40SYue Hin Lau * to video on dislpay or backlight enable. 9735eefbc40SYue Hin Lau * 9745eefbc40SYue Hin Lau * Disable the delay for now. 9755eefbc40SYue Hin Lau * Enable it in the future if necessary. 9765eefbc40SYue Hin Lau */ 9775eefbc40SYue Hin Lau /* dc_service_sleep_in_milliseconds(50); */ 9785180d4a4SCharlene Liu /*edp 1.2*/ 9795180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 9805180d4a4SCharlene Liu edp_receiver_ready_T7(link); 981069d418fSAndrew Jiang link_transmitter_control(ctx->dc_bios, &cntl); 98269b9723aSCharlene Liu /*edp 1.2*/ 9835180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) 98469b9723aSCharlene Liu edp_receiver_ready_T9(link); 9855eefbc40SYue Hin Lau } 9865eefbc40SYue Hin Lau 9871a05873fSAnthony Koo void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) 9884562236bSHarry Wentland { 9891a05873fSAnthony Koo struct dc *core_dc = pipe_ctx->stream->ctx->dc; 9901a05873fSAnthony Koo /* notify audio driver for audio modes of monitor */ 9911a05873fSAnthony Koo struct pp_smu_funcs_rv *pp_smu = core_dc->res_pool->pp_smu; 9921a05873fSAnthony Koo unsigned int i, num_audio = 1; 9931a05873fSAnthony Koo 9941a05873fSAnthony Koo if (pipe_ctx->stream_res.audio) { 9951a05873fSAnthony Koo for (i = 0; i < MAX_PIPES; i++) { 9961a05873fSAnthony Koo /*current_state not updated yet*/ 9971a05873fSAnthony Koo if (core_dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) 9981a05873fSAnthony Koo num_audio++; 9991a05873fSAnthony Koo } 10001a05873fSAnthony Koo 10011a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); 10021a05873fSAnthony Koo 10031a05873fSAnthony Koo if (num_audio == 1 && pp_smu != NULL && pp_smu->set_pme_wa_enable != NULL) 10041a05873fSAnthony Koo /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 10051a05873fSAnthony Koo pp_smu->set_pme_wa_enable(&pp_smu->pp_smu); 10061a05873fSAnthony Koo /* un-mute audio */ 10071a05873fSAnthony Koo /* TODO: audio should be per stream rather than per link */ 10081a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 10091a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, false); 10101a05873fSAnthony Koo } 10111a05873fSAnthony Koo } 10121a05873fSAnthony Koo 10131a05873fSAnthony Koo void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option) 10141a05873fSAnthony Koo { 10154176664bSCharlene Liu struct dc *dc = pipe_ctx->stream->ctx->dc; 10164562236bSHarry Wentland 10172b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 10182b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc, true); 1019afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio) { 10207c357e61SCharlene Liu if (option != KEEP_ACQUIRED_RESOURCE || 10217c357e61SCharlene Liu !dc->debug.az_endpoint_mute_only) { 10227c357e61SCharlene Liu /*only disalbe az_endpoint if power down or free*/ 1023afaacef4SHarry Wentland pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); 10247c357e61SCharlene Liu } 10254562236bSHarry Wentland 10264562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10278e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( 10288e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 10294562236bSHarry Wentland else 10308e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( 10318e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 10324176664bSCharlene Liu /*don't free audio if it is from retrain or internal disable stream*/ 10334176664bSCharlene Liu if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) { 10344176664bSCharlene Liu /*we have to dynamic arbitrate the audio endpoints*/ 10354176664bSCharlene Liu /*we free the resource, need reset is_audio_acquired*/ 10364176664bSCharlene Liu update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); 1037fb5fb63aSCharlene Liu pipe_ctx->stream_res.audio = NULL; 10384176664bSCharlene Liu } 10394562236bSHarry Wentland 10404562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 10414562236bSHarry Wentland * add audio mode list change flag */ 10424562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 10434562236bSHarry Wentland * stream->stream_engine_id); 10444562236bSHarry Wentland */ 10454562236bSHarry Wentland } 10461a05873fSAnthony Koo } 10474562236bSHarry Wentland 10481a05873fSAnthony Koo void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) 10491a05873fSAnthony Koo { 10501a05873fSAnthony Koo struct dc_stream_state *stream = pipe_ctx->stream; 10511a05873fSAnthony Koo struct dc_link *link = stream->sink->link; 10521a05873fSAnthony Koo struct dc *dc = pipe_ctx->stream->ctx->dc; 10531a05873fSAnthony Koo 10541a05873fSAnthony Koo if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) 10551a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 10561a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 10571a05873fSAnthony Koo 10581a05873fSAnthony Koo if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10591a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 10601a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 10611a05873fSAnthony Koo 10621a05873fSAnthony Koo dc->hwss.disable_audio_stream(pipe_ctx, option); 1063904623eeSYongqiang Sun 10644562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe( 10654562236bSHarry Wentland link->link_enc, 10668e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->id, 10674562236bSHarry Wentland false); 10684562236bSHarry Wentland 10694562236bSHarry Wentland } 10704562236bSHarry Wentland 10714562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 10724562236bSHarry Wentland struct dc_link_settings *link_settings) 10734562236bSHarry Wentland { 10744562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 107541b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 107641b49742SCharlene Liu struct dc_link *link = stream->sink->link; 10774562236bSHarry Wentland 10784562236bSHarry Wentland /* only 3 items below are used by unblank */ 10796235b23cSTony Cheng params.pixel_clk_khz = 10804fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.pix_clk_khz; 10814562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 108241b49742SCharlene Liu 108341b49742SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10848e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); 108541b49742SCharlene Liu 108614d6f644SYongqiang Sun if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 108741b49742SCharlene Liu link->dc->hwss.edp_backlight_control(link, true); 10885282cbe3SYongqiang Sun stream->bl_pwm_level = EDP_BACKLIGHT_RAMP_DISABLE_LEVEL; 108914d6f644SYongqiang Sun } 109041b49742SCharlene Liu } 109141b49742SCharlene Liu void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 109241b49742SCharlene Liu { 109341b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 109441b49742SCharlene Liu struct dc_link *link = stream->sink->link; 109541b49742SCharlene Liu 1096ab892598SRoman Li if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 109741b49742SCharlene Liu link->dc->hwss.edp_backlight_control(link, false); 1098ab892598SRoman Li dc_link_set_abm_disable(link); 1099ab892598SRoman Li } 110041b49742SCharlene Liu 110141b49742SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 110241b49742SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); 11034562236bSHarry Wentland } 11044562236bSHarry Wentland 110515e17335SCharlene Liu 110615e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 110715e17335SCharlene Liu { 11088e9c4c8cSHarry Wentland if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL) 11098e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 111015e17335SCharlene Liu } 111115e17335SCharlene Liu 11124562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 11134562236bSHarry Wentland { 11144562236bSHarry Wentland switch (crtc_id) { 11154562236bSHarry Wentland case CONTROLLER_ID_D0: 11164562236bSHarry Wentland return DTO_SOURCE_ID0; 11174562236bSHarry Wentland case CONTROLLER_ID_D1: 11184562236bSHarry Wentland return DTO_SOURCE_ID1; 11194562236bSHarry Wentland case CONTROLLER_ID_D2: 11204562236bSHarry Wentland return DTO_SOURCE_ID2; 11214562236bSHarry Wentland case CONTROLLER_ID_D3: 11224562236bSHarry Wentland return DTO_SOURCE_ID3; 11234562236bSHarry Wentland case CONTROLLER_ID_D4: 11244562236bSHarry Wentland return DTO_SOURCE_ID4; 11254562236bSHarry Wentland case CONTROLLER_ID_D5: 11264562236bSHarry Wentland return DTO_SOURCE_ID5; 11274562236bSHarry Wentland default: 11284562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 11294562236bSHarry Wentland } 11304562236bSHarry Wentland } 11314562236bSHarry Wentland 11324562236bSHarry Wentland static void build_audio_output( 1133ab8db3e1SAndrey Grodzovsky struct dc_state *state, 11344562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 11354562236bSHarry Wentland struct audio_output *audio_output) 11364562236bSHarry Wentland { 11370971c40eSHarry Wentland const struct dc_stream_state *stream = pipe_ctx->stream; 11388e9c4c8cSHarry Wentland audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id; 11394562236bSHarry Wentland 11404562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 11414562236bSHarry Wentland 11424562236bSHarry Wentland /* audio_crtc_info */ 11434562236bSHarry Wentland 11444562236bSHarry Wentland audio_output->crtc_info.h_total = 11454fa086b9SLeo (Sunpeng) Li stream->timing.h_total; 11464562236bSHarry Wentland 11474562236bSHarry Wentland /* 11484562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 11494562236bSHarry Wentland * need to specify actual active signal portion 11504562236bSHarry Wentland */ 11514562236bSHarry Wentland audio_output->crtc_info.h_active = 11524fa086b9SLeo (Sunpeng) Li stream->timing.h_addressable 11534fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_left 11544fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_right; 11554562236bSHarry Wentland 11564562236bSHarry Wentland audio_output->crtc_info.v_active = 11574fa086b9SLeo (Sunpeng) Li stream->timing.v_addressable 11584fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_top 11594fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_bottom; 11604562236bSHarry Wentland 11614562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 11624562236bSHarry Wentland 11634562236bSHarry Wentland audio_output->crtc_info.interlaced = 11644fa086b9SLeo (Sunpeng) Li stream->timing.flags.INTERLACE; 11654562236bSHarry Wentland 11664562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 11674fa086b9SLeo (Sunpeng) Li (stream->timing.pix_clk_khz*1000)/ 11684fa086b9SLeo (Sunpeng) Li (stream->timing.h_total*stream->timing.v_total); 11694562236bSHarry Wentland 11704562236bSHarry Wentland audio_output->crtc_info.color_depth = 11714fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth; 11724562236bSHarry Wentland 11734562236bSHarry Wentland audio_output->crtc_info.requested_pixel_clock = 117410688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 11754562236bSHarry Wentland 11764562236bSHarry Wentland audio_output->crtc_info.calculated_pixel_clock = 117710688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 11784562236bSHarry Wentland 117987b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/ 118087b58768SCharlene Liu if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && 118187b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock == 11824fa086b9SLeo (Sunpeng) Li stream->timing.pix_clk_khz) { 118310688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 118487b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock = 118587b58768SCharlene Liu audio_output->crtc_info.requested_pixel_clock/2; 118687b58768SCharlene Liu audio_output->crtc_info.calculated_pixel_clock = 118710688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk/2; 118887b58768SCharlene Liu 118987b58768SCharlene Liu } 119087b58768SCharlene Liu } 119187b58768SCharlene Liu 11924562236bSHarry Wentland if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 11934562236bSHarry Wentland pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { 11944562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 1195ab8db3e1SAndrey Grodzovsky state->dis_clk->funcs->get_dp_ref_clk_frequency( 1196ab8db3e1SAndrey Grodzovsky state->dis_clk); 11974562236bSHarry Wentland } 11984562236bSHarry Wentland 11994562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 12004562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 12014562236bSHarry Wentland 12024562236bSHarry Wentland audio_output->pll_info.dto_source = 12034562236bSHarry Wentland translate_to_dto_source( 1204e07f541fSYongqiang Sun pipe_ctx->stream_res.tg->inst + 1); 12054562236bSHarry Wentland 12064562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 12074562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 12084562236bSHarry Wentland 12094562236bSHarry Wentland audio_output->pll_info.ss_percentage = 12104562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 12114562236bSHarry Wentland } 12124562236bSHarry Wentland 12134562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 12144562236bSHarry Wentland struct tg_color *color) 12154562236bSHarry Wentland { 12162a54bd6eSJerry (Fangzhi) Zuo uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4; 12174562236bSHarry Wentland 12186702a9acSHarry Wentland switch (pipe_ctx->plane_res.scl_data.format) { 12194562236bSHarry Wentland case PIXEL_FORMAT_ARGB8888: 12204562236bSHarry Wentland /* set boarder color to red */ 12214562236bSHarry Wentland color->color_r_cr = color_value; 12224562236bSHarry Wentland break; 12234562236bSHarry Wentland 12244562236bSHarry Wentland case PIXEL_FORMAT_ARGB2101010: 12254562236bSHarry Wentland /* set boarder color to blue */ 12264562236bSHarry Wentland color->color_b_cb = color_value; 12274562236bSHarry Wentland break; 122887449a90SAnthony Koo case PIXEL_FORMAT_420BPP8: 12294562236bSHarry Wentland /* set boarder color to green */ 12304562236bSHarry Wentland color->color_g_y = color_value; 12314562236bSHarry Wentland break; 123287449a90SAnthony Koo case PIXEL_FORMAT_420BPP10: 123387449a90SAnthony Koo /* set boarder color to yellow */ 123487449a90SAnthony Koo color->color_g_y = color_value; 123587449a90SAnthony Koo color->color_r_cr = color_value; 123687449a90SAnthony Koo break; 12374562236bSHarry Wentland case PIXEL_FORMAT_FP16: 12384562236bSHarry Wentland /* set boarder color to white */ 12394562236bSHarry Wentland color->color_r_cr = color_value; 12404562236bSHarry Wentland color->color_b_cb = color_value; 12414562236bSHarry Wentland color->color_g_y = color_value; 12424562236bSHarry Wentland break; 12434562236bSHarry Wentland default: 12444562236bSHarry Wentland break; 12454562236bSHarry Wentland } 12464562236bSHarry Wentland } 12474562236bSHarry Wentland 1248fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc, 12494562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 12504562236bSHarry Wentland { 12514562236bSHarry Wentland struct tg_color color = {0}; 12524562236bSHarry Wentland 1253dc37a9a0SLeo (Sunpeng) Li #if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1254ff5ef992SAlex Deucher /* TOFPGA */ 125586a66c4eSHarry Wentland if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) 1256ff5ef992SAlex Deucher return; 1257ff5ef992SAlex Deucher #endif 1258ff5ef992SAlex Deucher 1259bf53769dSGloria Li if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) 12604562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 12614562236bSHarry Wentland else 12624562236bSHarry Wentland color_space_to_black_color(dc, 12634fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space, 12644562236bSHarry Wentland &color); 12654562236bSHarry Wentland 126686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 126786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, 12686702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.depth, 12694562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 12704562236bSHarry Wentland 12716b670fa9SHarry Wentland if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) 12726b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 12736b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 12744562236bSHarry Wentland &color); 12754562236bSHarry Wentland 127686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 12776702a9acSHarry Wentland &pipe_ctx->plane_res.scl_data); 12784562236bSHarry Wentland } 12794562236bSHarry Wentland 12803158223eSEric Bernstein static enum dc_status dce110_enable_stream_timing( 12814562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1282608ac7bbSJerry Zuo struct dc_state *context, 1283fb3466a4SBhawanpreet Lakha struct dc *dc) 12844562236bSHarry Wentland { 12850971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1286608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 12874562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 12884562236bSHarry Wentland struct tg_color black_color = {0}; 128998e6436dSAnthony Koo struct drr_params params = {0}; 129098e6436dSAnthony Koo unsigned int event_triggers = 0; 12914562236bSHarry Wentland 12924562236bSHarry Wentland if (!pipe_ctx_old->stream) { 12934562236bSHarry Wentland 12944562236bSHarry Wentland /* program blank color */ 12954562236bSHarry Wentland color_space_to_black_color(dc, 12964fa086b9SLeo (Sunpeng) Li stream->output_color_space, &black_color); 12976b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank_color( 12986b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 12994562236bSHarry Wentland &black_color); 13004b5e7d62SHersen Wu 13014562236bSHarry Wentland /* 13024562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 13034562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 13044562236bSHarry Wentland */ 13056b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true); 13064562236bSHarry Wentland 13074562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 13084562236bSHarry Wentland pipe_ctx->clock_source, 130910688217SHarry Wentland &pipe_ctx->stream_res.pix_clk_params, 13104562236bSHarry Wentland &pipe_ctx->pll_settings)) { 13114562236bSHarry Wentland BREAK_TO_DEBUGGER(); 13124562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 13134562236bSHarry Wentland } 13144562236bSHarry Wentland 13156b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->program_timing( 13166b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 13174fa086b9SLeo (Sunpeng) Li &stream->timing, 13184562236bSHarry Wentland true); 131994267b3dSSylvia Tsai 132098e6436dSAnthony Koo params.vertical_total_min = stream->adjust.v_total_min; 132198e6436dSAnthony Koo params.vertical_total_max = stream->adjust.v_total_max; 132298e6436dSAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_drr) 132398e6436dSAnthony Koo pipe_ctx->stream_res.tg->funcs->set_drr( 132498e6436dSAnthony Koo pipe_ctx->stream_res.tg, ¶ms); 132598e6436dSAnthony Koo 132698e6436dSAnthony Koo // DRR should set trigger event to monitor surface update event 132798e6436dSAnthony Koo if (stream->adjust.v_total_min != 0 && 132898e6436dSAnthony Koo stream->adjust.v_total_max != 0) 132998e6436dSAnthony Koo event_triggers = 0x80; 133098e6436dSAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control) 13316b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 133298e6436dSAnthony Koo pipe_ctx->stream_res.tg, event_triggers); 13334562236bSHarry Wentland } 13344562236bSHarry Wentland 13354562236bSHarry Wentland if (!pipe_ctx_old->stream) { 13366b670fa9SHarry Wentland if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc( 13376b670fa9SHarry Wentland pipe_ctx->stream_res.tg)) { 13384562236bSHarry Wentland BREAK_TO_DEBUGGER(); 13394562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 13404562236bSHarry Wentland } 13414562236bSHarry Wentland } 13424562236bSHarry Wentland 13434562236bSHarry Wentland return DC_OK; 13444562236bSHarry Wentland } 13454562236bSHarry Wentland 13464562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 13474562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1348608ac7bbSJerry Zuo struct dc_state *context, 1349fb3466a4SBhawanpreet Lakha struct dc *dc) 13504562236bSHarry Wentland { 13510971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 13524562236bSHarry Wentland 13531a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 13541a05873fSAnthony Koo struct audio_output audio_output; 13551a05873fSAnthony Koo 13561a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 13571a05873fSAnthony Koo 13581a05873fSAnthony Koo if (dc_is_dp_signal(pipe_ctx->stream->signal)) 13591a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( 13601a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, 13611a05873fSAnthony Koo pipe_ctx->stream_res.audio->inst, 13621a05873fSAnthony Koo &pipe_ctx->stream->audio_info); 13631a05873fSAnthony Koo else 13641a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( 13651a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, 13661a05873fSAnthony Koo pipe_ctx->stream_res.audio->inst, 13671a05873fSAnthony Koo &pipe_ctx->stream->audio_info, 13681a05873fSAnthony Koo &audio_output.crtc_info); 13691a05873fSAnthony Koo 13701a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_configure( 13711a05873fSAnthony Koo pipe_ctx->stream_res.audio, 13721a05873fSAnthony Koo pipe_ctx->stream->signal, 13731a05873fSAnthony Koo &audio_output.crtc_info, 13741a05873fSAnthony Koo &pipe_ctx->stream->audio_info); 13751a05873fSAnthony Koo } 13761a05873fSAnthony Koo 13774562236bSHarry Wentland /* */ 13783158223eSEric Bernstein dc->hwss.enable_stream_timing(pipe_ctx, context, dc); 13794562236bSHarry Wentland 1380f0c4d997SCorbin McElhanney /* FPGA does not program backend */ 1381f0c4d997SCorbin McElhanney if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { 1382a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1383a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 13844562236bSHarry Wentland COLOR_SPACE_YCBCR601, 13854fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth, 13864562236bSHarry Wentland pipe_ctx->stream->signal); 13874562236bSHarry Wentland 1388a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1389a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 13904562236bSHarry Wentland &stream->bit_depth_params, 13914562236bSHarry Wentland &stream->clamping); 13924562236bSHarry Wentland return DC_OK; 1393181a888fSCharlene Liu } 13944562236bSHarry Wentland /* TODO: move to stream encoder */ 13954562236bSHarry Wentland if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL) 13964562236bSHarry Wentland if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) { 13974562236bSHarry Wentland BREAK_TO_DEBUGGER(); 13984562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 13994562236bSHarry Wentland } 1400f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1401f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp, 1402f0c4d997SCorbin McElhanney COLOR_SPACE_YCBCR601, 1403f0c4d997SCorbin McElhanney stream->timing.display_color_depth, 1404f0c4d997SCorbin McElhanney pipe_ctx->stream->signal); 14054562236bSHarry Wentland 1406a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1407a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 1408181a888fSCharlene Liu &stream->bit_depth_params, 1409181a888fSCharlene Liu &stream->clamping); 1410603767f9STony Cheng 14111e7e86c4SSamson Tam if (!stream->dpms_off) 1412ab8db3e1SAndrey Grodzovsky core_link_enable_stream(context, pipe_ctx); 14134562236bSHarry Wentland 14146702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 14154562236bSHarry Wentland 141694267b3dSSylvia Tsai pipe_ctx->stream->sink->link->psr_enabled = false; 141794267b3dSSylvia Tsai 14184562236bSHarry Wentland return DC_OK; 14194562236bSHarry Wentland } 14204562236bSHarry Wentland 14214562236bSHarry Wentland /******************************************************************************/ 14224562236bSHarry Wentland 1423fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc) 14244562236bSHarry Wentland { 14254562236bSHarry Wentland int i; 1426a0c38ebaSCharlene Liu enum connector_id connector_id; 142768d77dd8SAndrew Jiang enum signal_type signal = SIGNAL_TYPE_NONE; 1428b9b171ffSHersen Wu 1429b9b171ffSHersen Wu /* do not know BIOS back-front mapping, simply blank all. It will not 1430b9b171ffSHersen Wu * hurt for non-DP 1431b9b171ffSHersen Wu */ 1432b9b171ffSHersen Wu for (i = 0; i < dc->res_pool->stream_enc_count; i++) { 1433b9b171ffSHersen Wu dc->res_pool->stream_enc[i]->funcs->dp_blank( 1434b9b171ffSHersen Wu dc->res_pool->stream_enc[i]); 1435b9b171ffSHersen Wu } 1436b9b171ffSHersen Wu 14374562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 1438a0c38ebaSCharlene Liu connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id); 1439a0c38ebaSCharlene Liu if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) || 1440a0c38ebaSCharlene Liu (connector_id == CONNECTOR_ID_EDP)) { 1441a0c38ebaSCharlene Liu 1442a0c38ebaSCharlene Liu if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) 1443a0c38ebaSCharlene Liu dp_receiver_power_ctrl(dc->links[i], false); 1444904623eeSYongqiang Sun if (connector_id == CONNECTOR_ID_EDP) 144568d77dd8SAndrew Jiang signal = SIGNAL_TYPE_EDP; 1446a0c38ebaSCharlene Liu } 1447a0c38ebaSCharlene Liu 14484562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 1449069d418fSAndrew Jiang dc->links[i]->link_enc, signal); 14504562236bSHarry Wentland } 14514562236bSHarry Wentland } 14524562236bSHarry Wentland 1453fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc) 14544562236bSHarry Wentland { 14554562236bSHarry Wentland int i; 14564562236bSHarry Wentland 14577f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 14584562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 14594562236bSHarry Wentland dc->res_pool->timing_generators[i]); 14604562236bSHarry Wentland } 14614562236bSHarry Wentland } 14624562236bSHarry Wentland 1463fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc) 14644562236bSHarry Wentland { 14654562236bSHarry Wentland int i; 14664562236bSHarry Wentland 14674562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 14684562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 14694562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 14704562236bSHarry Wentland 14714562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 14724562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 14734562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 14744562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 14754562236bSHarry Wentland } 14764562236bSHarry Wentland } 14774562236bSHarry Wentland 1478fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc) 14794562236bSHarry Wentland { 14804562236bSHarry Wentland power_down_encoders(dc); 14814562236bSHarry Wentland 14824562236bSHarry Wentland power_down_controllers(dc); 14834562236bSHarry Wentland 14844562236bSHarry Wentland power_down_clock_sources(dc); 14851663ae1cSBhawanpreet Lakha 14862f3bfb27SRoman Li if (dc->fbc_compressor) 14871663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 14884562236bSHarry Wentland } 14894562236bSHarry Wentland 14904562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 1491fb3466a4SBhawanpreet Lakha struct dc *dc) 14924562236bSHarry Wentland { 14934562236bSHarry Wentland int i; 14944562236bSHarry Wentland struct timing_generator *tg; 14954562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 14964562236bSHarry Wentland 14977f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 14984562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 14994562236bSHarry Wentland 15000a87425aSTony Cheng if (tg->funcs->disable_vga) 15014562236bSHarry Wentland tg->funcs->disable_vga(tg); 15027f93c1deSCharlene Liu } 15037f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->pipe_count; i++) { 15044562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 15054562236bSHarry Wentland * powergating. */ 15064562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 15074562236bSHarry Wentland true); 15084562236bSHarry Wentland 1509e6c258cbSYongqiang Sun dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i; 15107f914a62SYongqiang Sun dc->hwss.disable_plane(dc, 1511e6c258cbSYongqiang Sun &dc->current_state->res_ctx.pipe_ctx[i]); 15124562236bSHarry Wentland } 15134562236bSHarry Wentland } 15144562236bSHarry Wentland 1515f0c0761bSYongqiang Sun static struct dc_link *get_link_for_edp(struct dc *dc) 1516339cc82aSYongqiang Sun { 1517339cc82aSYongqiang Sun int i; 1518339cc82aSYongqiang Sun 1519f0c0761bSYongqiang Sun for (i = 0; i < dc->link_count; i++) { 1520f0c0761bSYongqiang Sun if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) 1521f0c0761bSYongqiang Sun return dc->links[i]; 1522339cc82aSYongqiang Sun } 1523f0c0761bSYongqiang Sun return NULL; 1524339cc82aSYongqiang Sun } 1525339cc82aSYongqiang Sun 1526cf1835f0SCharlene Liu static struct dc_link *get_link_for_edp_not_in_use( 152725292028SYongqiang Sun struct dc *dc, 152825292028SYongqiang Sun struct dc_state *context) 152925292028SYongqiang Sun { 153025292028SYongqiang Sun int i; 153125292028SYongqiang Sun struct dc_link *link = NULL; 153225292028SYongqiang Sun 153325292028SYongqiang Sun /* check if eDP panel is suppose to be set mode, if yes, no need to disable */ 153425292028SYongqiang Sun for (i = 0; i < context->stream_count; i++) { 153525292028SYongqiang Sun if (context->streams[i]->signal == SIGNAL_TYPE_EDP) 153625292028SYongqiang Sun return NULL; 153725292028SYongqiang Sun } 153825292028SYongqiang Sun 153925292028SYongqiang Sun /* check if there is an eDP panel not in use */ 154025292028SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 154125292028SYongqiang Sun if (dc->links[i]->local_sink && 154225292028SYongqiang Sun dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 154325292028SYongqiang Sun link = dc->links[i]; 154425292028SYongqiang Sun break; 154525292028SYongqiang Sun } 154625292028SYongqiang Sun } 154725292028SYongqiang Sun 154825292028SYongqiang Sun return link; 154925292028SYongqiang Sun } 155025292028SYongqiang Sun 15514562236bSHarry Wentland /** 15524562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 15534562236bSHarry Wentland * 1. Power down all DC HW blocks 15544562236bSHarry Wentland * 2. Disable VGA engine on all controllers 15554562236bSHarry Wentland * 3. Enable power gating for controller 15564562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 15574562236bSHarry Wentland */ 155825292028SYongqiang Sun void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 15594562236bSHarry Wentland { 1560d82f9942SAnthony Koo int i; 15614cac1e6dSYongqiang Sun struct dc_link *edp_link_to_turnoff = NULL; 1562f0c0761bSYongqiang Sun struct dc_link *edp_link = get_link_for_edp(dc); 1563d82f9942SAnthony Koo bool can_edp_fast_boot_optimize = false; 1564d82f9942SAnthony Koo bool apply_edp_fast_boot_optimization = false; 15654cac1e6dSYongqiang Sun 1566f0c0761bSYongqiang Sun if (edp_link) { 156795f05a3aSAlex Deucher /* this seems to cause blank screens on DCE8 */ 156895f05a3aSAlex Deucher if ((dc->ctx->dce_version == DCE_VERSION_8_0) || 156995f05a3aSAlex Deucher (dc->ctx->dce_version == DCE_VERSION_8_1) || 157095f05a3aSAlex Deucher (dc->ctx->dce_version == DCE_VERSION_8_3)) 1571d82f9942SAnthony Koo can_edp_fast_boot_optimize = false; 157295f05a3aSAlex Deucher else 1573d82f9942SAnthony Koo can_edp_fast_boot_optimize = 1574f0c0761bSYongqiang Sun edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc); 1575f0c0761bSYongqiang Sun } 1576f0c0761bSYongqiang Sun 1577d82f9942SAnthony Koo if (can_edp_fast_boot_optimize) 15784cac1e6dSYongqiang Sun edp_link_to_turnoff = get_link_for_edp_not_in_use(dc, context); 15794cac1e6dSYongqiang Sun 15802c37e49aSYongqiang Sun /* if OS doesn't light up eDP and eDP link is available, we want to disable 15812c37e49aSYongqiang Sun * If resume from S4/S5, should optimization. 15822c37e49aSYongqiang Sun */ 1583d82f9942SAnthony Koo if (can_edp_fast_boot_optimize && !edp_link_to_turnoff) { 1584d82f9942SAnthony Koo /* Find eDP stream and set optimization flag */ 1585d82f9942SAnthony Koo for (i = 0; i < context->stream_count; i++) { 1586d82f9942SAnthony Koo if (context->streams[i]->signal == SIGNAL_TYPE_EDP) { 1587d82f9942SAnthony Koo context->streams[i]->apply_edp_fast_boot_optimization = true; 1588d82f9942SAnthony Koo apply_edp_fast_boot_optimization = true; 1589d82f9942SAnthony Koo } 1590d82f9942SAnthony Koo } 15914cac1e6dSYongqiang Sun } 15924cac1e6dSYongqiang Sun 1593d82f9942SAnthony Koo if (!apply_edp_fast_boot_optimization) { 15944cac1e6dSYongqiang Sun if (edp_link_to_turnoff) { 15954cac1e6dSYongqiang Sun /*turn off backlight before DP_blank and encoder powered down*/ 15964cac1e6dSYongqiang Sun dc->hwss.edp_backlight_control(edp_link_to_turnoff, false); 1597c5fc7f59SCharlene Liu } 1598c5fc7f59SCharlene Liu /*resume from S3, no vbios posting, no need to power down again*/ 159925292028SYongqiang Sun power_down_all_hw_blocks(dc); 16004562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 1601cf1835f0SCharlene Liu if (edp_link_to_turnoff) 1602cf1835f0SCharlene Liu dc->hwss.edp_power_control(edp_link_to_turnoff, false); 1603c5fc7f59SCharlene Liu } 16044562236bSHarry Wentland bios_set_scratch_acc_mode_change(dc->ctx->dc_bios); 16054562236bSHarry Wentland } 16064562236bSHarry Wentland 16074562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 16084562236bSHarry Wentland struct bw_fixed blackout_duration, 16090971c40eSHarry Wentland const struct dc_stream_state *stream) 16104562236bSHarry Wentland { 16114562236bSHarry Wentland uint32_t total_dest_line_time_ns; 16124562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 16134562236bSHarry Wentland 16144562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 16154562236bSHarry Wentland 16164562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 16174fa086b9SLeo (Sunpeng) Li stream->timing.h_total / 16184fa086b9SLeo (Sunpeng) Li stream->timing.pix_clk_khz + 16194562236bSHarry Wentland pstate_blackout_duration_ns; 16204562236bSHarry Wentland 16214562236bSHarry Wentland return total_dest_line_time_ns; 16224562236bSHarry Wentland } 16234562236bSHarry Wentland 1624f774b339SEric Yang static void dce110_set_displaymarks( 1625fb3466a4SBhawanpreet Lakha const struct dc *dc, 1626608ac7bbSJerry Zuo struct dc_state *context) 16274562236bSHarry Wentland { 16284562236bSHarry Wentland uint8_t i, num_pipes; 16294562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 16304562236bSHarry Wentland 16314562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 16324562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 16334562236bSHarry Wentland uint32_t total_dest_line_time_ns; 16344562236bSHarry Wentland 16354562236bSHarry Wentland if (pipe_ctx->stream == NULL) 16364562236bSHarry Wentland continue; 16374562236bSHarry Wentland 16384562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 163977a4ea53SBhawanpreet Lakha dc->bw_vbios->blackout_duration, pipe_ctx->stream); 164086a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( 164186a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 16429037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 16439037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 16443722c794SMikita Lipski context->bw.dce.stutter_entry_wm_ns[num_pipes], 16459037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 16464562236bSHarry Wentland total_dest_line_time_ns); 16474562236bSHarry Wentland if (i == underlay_idx) { 16484562236bSHarry Wentland num_pipes++; 164986a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( 165086a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 16519037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_wm_ns[num_pipes], 16529037d802SDmytro Laktyushkin context->bw.dce.stutter_exit_wm_ns[num_pipes], 16539037d802SDmytro Laktyushkin context->bw.dce.urgent_wm_ns[num_pipes], 16544562236bSHarry Wentland total_dest_line_time_ns); 16554562236bSHarry Wentland } 16564562236bSHarry Wentland num_pipes++; 16574562236bSHarry Wentland } 16584562236bSHarry Wentland } 16594562236bSHarry Wentland 1660fab55d61SDmytro Laktyushkin void dce110_set_safe_displaymarks( 1661a2b8659dSTony Cheng struct resource_context *res_ctx, 1662a2b8659dSTony Cheng const struct resource_pool *pool) 16634562236bSHarry Wentland { 16644562236bSHarry Wentland int i; 1665a2b8659dSTony Cheng int underlay_idx = pool->underlay_pipe_index; 16669037d802SDmytro Laktyushkin struct dce_watermarks max_marks = { 16674562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 16689037d802SDmytro Laktyushkin struct dce_watermarks nbp_marks = { 16694562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 16703722c794SMikita Lipski struct dce_watermarks min_marks = { 0, 0, 0, 0}; 16714562236bSHarry Wentland 16724562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 16738feabd03SYue Hin Lau if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) 16744562236bSHarry Wentland continue; 16754562236bSHarry Wentland 167686a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 167786a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 16784562236bSHarry Wentland nbp_marks, 16794562236bSHarry Wentland max_marks, 16803722c794SMikita Lipski min_marks, 16814562236bSHarry Wentland max_marks, 16824562236bSHarry Wentland MAX_WATERMARK); 16838feabd03SYue Hin Lau 16844562236bSHarry Wentland if (i == underlay_idx) 168586a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 168686a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 16874562236bSHarry Wentland nbp_marks, 16884562236bSHarry Wentland max_marks, 16894562236bSHarry Wentland max_marks, 16904562236bSHarry Wentland MAX_WATERMARK); 16918feabd03SYue Hin Lau 16924562236bSHarry Wentland } 16934562236bSHarry Wentland } 16944562236bSHarry Wentland 16954562236bSHarry Wentland /******************************************************************************* 16964562236bSHarry Wentland * Public functions 16974562236bSHarry Wentland ******************************************************************************/ 16984562236bSHarry Wentland 16994562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 17004562236bSHarry Wentland int num_pipes, int vmin, int vmax) 17014562236bSHarry Wentland { 17024562236bSHarry Wentland int i = 0; 17034562236bSHarry Wentland struct drr_params params = {0}; 170498e6436dSAnthony Koo // DRR should set trigger event to monitor surface update event 170598e6436dSAnthony Koo unsigned int event_triggers = 0x80; 17064562236bSHarry Wentland 17074562236bSHarry Wentland params.vertical_total_max = vmax; 17084562236bSHarry Wentland params.vertical_total_min = vmin; 17094562236bSHarry Wentland 17104562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 171198e6436dSAnthony Koo * some GSL stuff. Static screen triggers may be programmed differently 171298e6436dSAnthony Koo * as well. 17134562236bSHarry Wentland */ 17144562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 171598e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_drr( 171698e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, ¶ms); 171798e6436dSAnthony Koo 171898e6436dSAnthony Koo if (vmax != 0 && vmin != 0) 171998e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( 172098e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, 172198e6436dSAnthony Koo event_triggers); 17224562236bSHarry Wentland } 17234562236bSHarry Wentland } 17244562236bSHarry Wentland 172572ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx, 172672ada5f7SEric Cook int num_pipes, 172772ada5f7SEric Cook struct crtc_position *position) 172872ada5f7SEric Cook { 172972ada5f7SEric Cook int i = 0; 173072ada5f7SEric Cook 173172ada5f7SEric Cook /* TODO: handle pipes > 1 173272ada5f7SEric Cook */ 173372ada5f7SEric Cook for (i = 0; i < num_pipes; i++) 17346b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position); 173572ada5f7SEric Cook } 173672ada5f7SEric Cook 17374562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 173894267b3dSSylvia Tsai int num_pipes, const struct dc_static_screen_events *events) 17394562236bSHarry Wentland { 17404562236bSHarry Wentland unsigned int i; 174194267b3dSSylvia Tsai unsigned int value = 0; 174294267b3dSSylvia Tsai 174394267b3dSSylvia Tsai if (events->overlay_update) 174494267b3dSSylvia Tsai value |= 0x100; 174594267b3dSSylvia Tsai if (events->surface_update) 174694267b3dSSylvia Tsai value |= 0x80; 174794267b3dSSylvia Tsai if (events->cursor_update) 174894267b3dSSylvia Tsai value |= 0x2; 1749ed8462acSCharlene Liu if (events->force_trigger) 1750ed8462acSCharlene Liu value |= 0x1; 17514562236bSHarry Wentland 1752c3aa1d67SBhawanpreet Lakha value |= 0x84; 1753c3aa1d67SBhawanpreet Lakha 17544562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 17556b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs-> 17566b670fa9SHarry Wentland set_static_screen_control(pipe_ctx[i]->stream_res.tg, value); 17574562236bSHarry Wentland } 17584562236bSHarry Wentland 17594562236bSHarry Wentland /* unit: in_khz before mode set, get pixel clock from context. ASIC register 1760fab55d61SDmytro Laktyushkin * may not be programmed yet 17614562236bSHarry Wentland */ 17624562236bSHarry Wentland static uint32_t get_max_pixel_clock_for_all_paths( 1763fb3466a4SBhawanpreet Lakha struct dc *dc, 1764fab55d61SDmytro Laktyushkin struct dc_state *context) 17654562236bSHarry Wentland { 17664562236bSHarry Wentland uint32_t max_pix_clk = 0; 17674562236bSHarry Wentland int i; 17684562236bSHarry Wentland 17694562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 17704562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 17714562236bSHarry Wentland 17724562236bSHarry Wentland if (pipe_ctx->stream == NULL) 17734562236bSHarry Wentland continue; 17744562236bSHarry Wentland 17754562236bSHarry Wentland /* do not check under lay */ 17764562236bSHarry Wentland if (pipe_ctx->top_pipe) 17774562236bSHarry Wentland continue; 17784562236bSHarry Wentland 177910688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk) 17804562236bSHarry Wentland max_pix_clk = 178110688217SHarry Wentland pipe_ctx->stream_res.pix_clk_params.requested_pix_clk; 17824562236bSHarry Wentland } 17834562236bSHarry Wentland 17844562236bSHarry Wentland return max_pix_clk; 17854562236bSHarry Wentland } 17864562236bSHarry Wentland 1787f6baff4dSHarry Wentland /* 1788690b5e39SRoman Li * Check if FBC can be enabled 1789690b5e39SRoman Li */ 17909c6569deSHarry Wentland static bool should_enable_fbc(struct dc *dc, 17913bc4aaa9SRoman Li struct dc_state *context, 17923bc4aaa9SRoman Li uint32_t *pipe_idx) 1793690b5e39SRoman Li { 17943bc4aaa9SRoman Li uint32_t i; 17953bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = NULL; 17963bc4aaa9SRoman Li struct resource_context *res_ctx = &context->res_ctx; 17973bc4aaa9SRoman Li 1798690b5e39SRoman Li 1799690b5e39SRoman Li ASSERT(dc->fbc_compressor); 1800690b5e39SRoman Li 1801690b5e39SRoman Li /* FBC memory should be allocated */ 1802690b5e39SRoman Li if (!dc->ctx->fbc_gpu_addr) 18039c6569deSHarry Wentland return false; 1804690b5e39SRoman Li 1805690b5e39SRoman Li /* Only supports single display */ 1806690b5e39SRoman Li if (context->stream_count != 1) 18079c6569deSHarry Wentland return false; 1808690b5e39SRoman Li 18093bc4aaa9SRoman Li for (i = 0; i < dc->res_pool->pipe_count; i++) { 18103bc4aaa9SRoman Li if (res_ctx->pipe_ctx[i].stream) { 18113bc4aaa9SRoman Li pipe_ctx = &res_ctx->pipe_ctx[i]; 18123bc4aaa9SRoman Li *pipe_idx = i; 18133bc4aaa9SRoman Li break; 18143bc4aaa9SRoman Li } 18153bc4aaa9SRoman Li } 18163bc4aaa9SRoman Li 18177a840773SRoman Li /* Pipe context should be found */ 18187a840773SRoman Li ASSERT(pipe_ctx); 18197a840773SRoman Li 1820690b5e39SRoman Li /* Only supports eDP */ 1821690b5e39SRoman Li if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP) 18229c6569deSHarry Wentland return false; 1823690b5e39SRoman Li 1824690b5e39SRoman Li /* PSR should not be enabled */ 1825690b5e39SRoman Li if (pipe_ctx->stream->sink->link->psr_enabled) 18269c6569deSHarry Wentland return false; 1827690b5e39SRoman Li 182893984bbcSShirish S /* Nothing to compress */ 182993984bbcSShirish S if (!pipe_ctx->plane_state) 18309c6569deSHarry Wentland return false; 183193984bbcSShirish S 183205230fa9SRoman Li /* Only for non-linear tiling */ 183305230fa9SRoman Li if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 18349c6569deSHarry Wentland return false; 183505230fa9SRoman Li 18369c6569deSHarry Wentland return true; 1837690b5e39SRoman Li } 1838690b5e39SRoman Li 1839690b5e39SRoman Li /* 1840690b5e39SRoman Li * Enable FBC 1841690b5e39SRoman Li */ 18429c6569deSHarry Wentland static void enable_fbc(struct dc *dc, 1843608ac7bbSJerry Zuo struct dc_state *context) 1844690b5e39SRoman Li { 18453bc4aaa9SRoman Li uint32_t pipe_idx = 0; 18463bc4aaa9SRoman Li 18473bc4aaa9SRoman Li if (should_enable_fbc(dc, context, &pipe_idx)) { 1848690b5e39SRoman Li /* Program GRPH COMPRESSED ADDRESS and PITCH */ 1849690b5e39SRoman Li struct compr_addr_and_pitch_params params = {0, 0, 0}; 1850690b5e39SRoman Li struct compressor *compr = dc->fbc_compressor; 18513bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 18523bc4aaa9SRoman Li 1853690b5e39SRoman Li 18549c6569deSHarry Wentland params.source_view_width = pipe_ctx->stream->timing.h_addressable; 18559c6569deSHarry Wentland params.source_view_height = pipe_ctx->stream->timing.v_addressable; 1856690b5e39SRoman Li 1857690b5e39SRoman Li compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 1858690b5e39SRoman Li 1859690b5e39SRoman Li compr->funcs->surface_address_and_pitch(compr, ¶ms); 1860690b5e39SRoman Li compr->funcs->set_fbc_invalidation_triggers(compr, 1); 1861690b5e39SRoman Li 1862690b5e39SRoman Li compr->funcs->enable_fbc(compr, ¶ms); 1863690b5e39SRoman Li } 1864690b5e39SRoman Li } 1865690b5e39SRoman Li 186654e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap( 1867fb3466a4SBhawanpreet Lakha struct dc *dc, 1868608ac7bbSJerry Zuo struct dc_state *context) 18694562236bSHarry Wentland { 18704562236bSHarry Wentland int i; 18714562236bSHarry Wentland 18724562236bSHarry Wentland /* Reset old context */ 18734562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 1874a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 18754562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 1876608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 18774562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 18784562236bSHarry Wentland 18794562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 18804562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 18814562236bSHarry Wentland * PHY when not already disabled. 18824562236bSHarry Wentland */ 18834562236bSHarry Wentland 18844562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 18854562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 18864562236bSHarry Wentland continue; 18874562236bSHarry Wentland 18884562236bSHarry Wentland if (!pipe_ctx->stream || 188954e8695eSDmytro Laktyushkin pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 189021e67d4dSHarry Wentland struct clock_source *old_clk = pipe_ctx_old->clock_source; 189121e67d4dSHarry Wentland 1892827f11e9SLeo (Sunpeng) Li /* Disable if new stream is null. O/w, if stream is 1893827f11e9SLeo (Sunpeng) Li * disabled already, no need to disable again. 1894827f11e9SLeo (Sunpeng) Li */ 1895827f11e9SLeo (Sunpeng) Li if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) 18964176664bSCharlene Liu core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); 1897d050f8edSHersen Wu 18986b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 18996b670fa9SHarry Wentland if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 190054e8695eSDmytro Laktyushkin dm_error("DC: failed to blank crtc!\n"); 190154e8695eSDmytro Laktyushkin BREAK_TO_DEBUGGER(); 190254e8695eSDmytro Laktyushkin } 19036b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); 190486a66c4eSHarry Wentland pipe_ctx_old->plane_res.mi->funcs->free_mem_input( 1905608ac7bbSJerry Zuo pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); 190654e8695eSDmytro Laktyushkin 1907ad8960a6SMikita Lipski if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx, 1908ad8960a6SMikita Lipski dc->res_pool, 1909ad8960a6SMikita Lipski old_clk)) 191021e67d4dSHarry Wentland old_clk->funcs->cs_power_down(old_clk); 191121e67d4dSHarry Wentland 19127f914a62SYongqiang Sun dc->hwss.disable_plane(dc, pipe_ctx_old); 191354e8695eSDmytro Laktyushkin 191454e8695eSDmytro Laktyushkin pipe_ctx_old->stream = NULL; 191554e8695eSDmytro Laktyushkin } 19164562236bSHarry Wentland } 19174562236bSHarry Wentland } 19184562236bSHarry Wentland 19191a05873fSAnthony Koo static void dce110_setup_audio_dto( 19201a05873fSAnthony Koo struct dc *dc, 19211a05873fSAnthony Koo struct dc_state *context) 19221a05873fSAnthony Koo { 19231a05873fSAnthony Koo int i; 19241a05873fSAnthony Koo 19251a05873fSAnthony Koo /* program audio wall clock. use HDMI as clock source if HDMI 19261a05873fSAnthony Koo * audio active. Otherwise, use DP as clock source 19271a05873fSAnthony Koo * first, loop to find any HDMI audio, if not, loop find DP audio 19281a05873fSAnthony Koo */ 19291a05873fSAnthony Koo /* Setup audio rate clock source */ 19301a05873fSAnthony Koo /* Issue: 19311a05873fSAnthony Koo * Audio lag happened on DP monitor when unplug a HDMI monitor 19321a05873fSAnthony Koo * 19331a05873fSAnthony Koo * Cause: 19341a05873fSAnthony Koo * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 19351a05873fSAnthony Koo * is set to either dto0 or dto1, audio should work fine. 19361a05873fSAnthony Koo * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 19371a05873fSAnthony Koo * set to dto0 will cause audio lag. 19381a05873fSAnthony Koo * 19391a05873fSAnthony Koo * Solution: 19401a05873fSAnthony Koo * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 19411a05873fSAnthony Koo * find first available pipe with audio, setup audio wall DTO per topology 19421a05873fSAnthony Koo * instead of per pipe. 19431a05873fSAnthony Koo */ 19441a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 19451a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 19461a05873fSAnthony Koo 19471a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 19481a05873fSAnthony Koo continue; 19491a05873fSAnthony Koo 19501a05873fSAnthony Koo if (pipe_ctx->top_pipe) 19511a05873fSAnthony Koo continue; 19521a05873fSAnthony Koo 19531a05873fSAnthony Koo if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 19541a05873fSAnthony Koo continue; 19551a05873fSAnthony Koo 19561a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 19571a05873fSAnthony Koo struct audio_output audio_output; 19581a05873fSAnthony Koo 19591a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 19601a05873fSAnthony Koo 19611a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 19621a05873fSAnthony Koo pipe_ctx->stream_res.audio, 19631a05873fSAnthony Koo pipe_ctx->stream->signal, 19641a05873fSAnthony Koo &audio_output.crtc_info, 19651a05873fSAnthony Koo &audio_output.pll_info); 19661a05873fSAnthony Koo break; 19671a05873fSAnthony Koo } 19681a05873fSAnthony Koo } 19691a05873fSAnthony Koo 19701a05873fSAnthony Koo /* no HDMI audio is found, try DP audio */ 19711a05873fSAnthony Koo if (i == dc->res_pool->pipe_count) { 19721a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 19731a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 19741a05873fSAnthony Koo 19751a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 19761a05873fSAnthony Koo continue; 19771a05873fSAnthony Koo 19781a05873fSAnthony Koo if (pipe_ctx->top_pipe) 19791a05873fSAnthony Koo continue; 19801a05873fSAnthony Koo 19811a05873fSAnthony Koo if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 19821a05873fSAnthony Koo continue; 19831a05873fSAnthony Koo 19841a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 19851a05873fSAnthony Koo struct audio_output audio_output; 19861a05873fSAnthony Koo 19871a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 19881a05873fSAnthony Koo 19891a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 19901a05873fSAnthony Koo pipe_ctx->stream_res.audio, 19911a05873fSAnthony Koo pipe_ctx->stream->signal, 19921a05873fSAnthony Koo &audio_output.crtc_info, 19931a05873fSAnthony Koo &audio_output.pll_info); 19941a05873fSAnthony Koo break; 19951a05873fSAnthony Koo } 19961a05873fSAnthony Koo } 19971a05873fSAnthony Koo } 19981a05873fSAnthony Koo } 1999cf437593SDmytro Laktyushkin 20004562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 2001fb3466a4SBhawanpreet Lakha struct dc *dc, 2002608ac7bbSJerry Zuo struct dc_state *context) 20034562236bSHarry Wentland { 20044562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 20054562236bSHarry Wentland enum dc_status status; 20064562236bSHarry Wentland int i; 20074562236bSHarry Wentland 20084562236bSHarry Wentland /* Reset old context */ 20094562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 20104562236bSHarry Wentland dc->hwss.reset_hw_ctx_wrap(dc, context); 20114562236bSHarry Wentland 20124562236bSHarry Wentland /* Skip applying if no targets */ 2013ab2541b6SAric Cyr if (context->stream_count <= 0) 20144562236bSHarry Wentland return DC_OK; 20154562236bSHarry Wentland 20164562236bSHarry Wentland /* Apply new context */ 20174562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 20184562236bSHarry Wentland 20194562236bSHarry Wentland /* below is for real asic only */ 2020a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 20214562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 2022608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 20234562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 20244562236bSHarry Wentland 20254562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 20264562236bSHarry Wentland continue; 20274562236bSHarry Wentland 20284562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 20294562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 20304562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 20314562236bSHarry Wentland pipe_ctx->clock_source, i); 20324562236bSHarry Wentland continue; 20334562236bSHarry Wentland } 20344562236bSHarry Wentland 20354562236bSHarry Wentland dc->hwss.enable_display_power_gating( 20364562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 20374562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 20384562236bSHarry Wentland } 20394562236bSHarry Wentland 20402f3bfb27SRoman Li if (dc->fbc_compressor) 20411663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 20425099114bSAlex Deucher 20431a05873fSAnthony Koo dce110_setup_audio_dto(dc, context); 2044ab8812a3SHersen Wu 2045a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 2046ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx_old = 2047608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 2048ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2049ab8812a3SHersen Wu 2050ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 2051ab8812a3SHersen Wu continue; 2052ab8812a3SHersen Wu 2053ab8812a3SHersen Wu if (pipe_ctx->stream == pipe_ctx_old->stream) 2054ab8812a3SHersen Wu continue; 2055ab8812a3SHersen Wu 20565b92d9d4SHarry Wentland if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 2057313bf4ffSYongqiang Sun continue; 2058313bf4ffSYongqiang Sun 2059ab8812a3SHersen Wu if (pipe_ctx->top_pipe) 2060ab8812a3SHersen Wu continue; 2061ab8812a3SHersen Wu 20624562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 20634562236bSHarry Wentland pipe_ctx, 20644562236bSHarry Wentland context, 20654562236bSHarry Wentland dc); 20664562236bSHarry Wentland 20674562236bSHarry Wentland if (DC_OK != status) 20684562236bSHarry Wentland return status; 20694562236bSHarry Wentland } 20704562236bSHarry Wentland 20714562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, false); 20724562236bSHarry Wentland 2073690b5e39SRoman Li if (dc->fbc_compressor) 2074690b5e39SRoman Li enable_fbc(dc, context); 2075690b5e39SRoman Li 20764562236bSHarry Wentland return DC_OK; 20774562236bSHarry Wentland } 20784562236bSHarry Wentland 20794562236bSHarry Wentland /******************************************************************************* 20804562236bSHarry Wentland * Front End programming 20814562236bSHarry Wentland ******************************************************************************/ 20824562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 20834562236bSHarry Wentland { 20844562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 20854562236bSHarry Wentland 20864562236bSHarry Wentland default_adjust.force_hw_default = false; 208734996173SHarry Wentland default_adjust.in_color_space = pipe_ctx->plane_state->color_space; 208834996173SHarry Wentland default_adjust.out_color_space = pipe_ctx->stream->output_color_space; 20894562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 20906702a9acSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 20914562236bSHarry Wentland 20924562236bSHarry Wentland /* display color depth */ 20934562236bSHarry Wentland default_adjust.color_depth = 20944fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.display_color_depth; 20954562236bSHarry Wentland 20964562236bSHarry Wentland /* Lb color depth */ 20976702a9acSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 20984562236bSHarry Wentland 209986a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 210086a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, &default_adjust); 21014562236bSHarry Wentland } 21024562236bSHarry Wentland 2103b06b7680SLeon Elazar 2104b06b7680SLeon Elazar /******************************************************************************* 2105b06b7680SLeon Elazar * In order to turn on/off specific surface we will program 2106b06b7680SLeon Elazar * Blender + CRTC 2107b06b7680SLeon Elazar * 2108b06b7680SLeon Elazar * In case that we have two surfaces and they have a different visibility 2109b06b7680SLeon Elazar * we can't turn off the CRTC since it will turn off the entire display 2110b06b7680SLeon Elazar * 2111b06b7680SLeon Elazar * |----------------------------------------------- | 2112b06b7680SLeon Elazar * |bottom pipe|curr pipe | | | 2113b06b7680SLeon Elazar * |Surface |Surface | Blender | CRCT | 2114b06b7680SLeon Elazar * |visibility |visibility | Configuration| | 2115b06b7680SLeon Elazar * |------------------------------------------------| 2116b06b7680SLeon Elazar * | off | off | CURRENT_PIPE | blank | 2117b06b7680SLeon Elazar * | off | on | CURRENT_PIPE | unblank | 2118b06b7680SLeon Elazar * | on | off | OTHER_PIPE | unblank | 2119b06b7680SLeon Elazar * | on | on | BLENDING | unblank | 2120b06b7680SLeon Elazar * -------------------------------------------------| 2121b06b7680SLeon Elazar * 2122b06b7680SLeon Elazar ******************************************************************************/ 2123fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc, 21244562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 21254562236bSHarry Wentland { 21264562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 2127b06b7680SLeon Elazar bool blank_target = false; 21284562236bSHarry Wentland 21294562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 2130b06b7680SLeon Elazar 2131b06b7680SLeon Elazar /* For now we are supporting only two pipes */ 2132b06b7680SLeon Elazar ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 2133b06b7680SLeon Elazar 21343be5262eSHarry Wentland if (pipe_ctx->bottom_pipe->plane_state->visible) { 21353be5262eSHarry Wentland if (pipe_ctx->plane_state->visible) 21364562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 21374562236bSHarry Wentland else 21384562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 2139b06b7680SLeon Elazar 21403be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2141b06b7680SLeon Elazar blank_target = true; 2142b06b7680SLeon Elazar 21433be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2144b06b7680SLeon Elazar blank_target = true; 2145b06b7680SLeon Elazar 2146e07f541fSYongqiang Sun dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode); 21476b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 2148b06b7680SLeon Elazar 21494562236bSHarry Wentland } 21504562236bSHarry Wentland 21511bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 21521bf56e62SZeyu Fan { 2153146a9f63SKrunoslav Kovac int i = 0; 21541bf56e62SZeyu Fan struct xfm_grph_csc_adjustment adjust; 21551bf56e62SZeyu Fan memset(&adjust, 0, sizeof(adjust)); 21561bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 21571bf56e62SZeyu Fan 21581bf56e62SZeyu Fan 21594fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 21601bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2161146a9f63SKrunoslav Kovac 2162146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2163146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2164146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 21651bf56e62SZeyu Fan } 21661bf56e62SZeyu Fan 216786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 21681bf56e62SZeyu Fan } 2169fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc, 21704562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 21714562236bSHarry Wentland { 21723be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 21734562236bSHarry Wentland 21743be5262eSHarry Wentland if (plane_state == NULL) 21754562236bSHarry Wentland return; 21764562236bSHarry Wentland 217786a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 217886a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 21793be5262eSHarry Wentland &plane_state->address, 21803be5262eSHarry Wentland plane_state->flip_immediate); 21814562236bSHarry Wentland 21823be5262eSHarry Wentland plane_state->status.requested_address = plane_state->address; 21834562236bSHarry Wentland } 21844562236bSHarry Wentland 2185f774b339SEric Yang static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 21864562236bSHarry Wentland { 21873be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 21884562236bSHarry Wentland 21893be5262eSHarry Wentland if (plane_state == NULL) 21904562236bSHarry Wentland return; 21914562236bSHarry Wentland 21923be5262eSHarry Wentland plane_state->status.is_flip_pending = 219386a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 219486a66c4eSHarry Wentland pipe_ctx->plane_res.mi); 21954562236bSHarry Wentland 21963be5262eSHarry Wentland if (plane_state->status.is_flip_pending && !plane_state->visible) 219786a66c4eSHarry Wentland pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address; 21984562236bSHarry Wentland 219986a66c4eSHarry Wentland plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 220086a66c4eSHarry Wentland if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 22016b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) { 22023be5262eSHarry Wentland plane_state->status.is_right_eye =\ 22036b670fa9SHarry Wentland !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 22047f5c22d1SVitaly Prosyak } 22054562236bSHarry Wentland } 22064562236bSHarry Wentland 2207fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc) 22084562236bSHarry Wentland { 22094562236bSHarry Wentland power_down_all_hw_blocks(dc); 22104562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 22114562236bSHarry Wentland } 22124562236bSHarry Wentland 22134562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 22144562236bSHarry Wentland struct dc_context *dc_ctx, 22154562236bSHarry Wentland struct timing_generator *tg) 22164562236bSHarry Wentland { 22174562236bSHarry Wentland bool rc = false; 22184562236bSHarry Wentland 22194562236bSHarry Wentland /* To avoid endless loop we wait at most 22204562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 22214562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 22224562236bSHarry Wentland uint32_t i; 22234562236bSHarry Wentland 22244562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 22254562236bSHarry Wentland 22264562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 22274562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 22284562236bSHarry Wentland break; 22294562236bSHarry Wentland } 22304562236bSHarry Wentland 22314562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 22324562236bSHarry Wentland rc = true; 22334562236bSHarry Wentland /* usually occurs at i=1 */ 22344562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 22354562236bSHarry Wentland i); 22364562236bSHarry Wentland break; 22374562236bSHarry Wentland } 22384562236bSHarry Wentland 22394562236bSHarry Wentland /* Wait for one frame. */ 22404562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 22414562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 22424562236bSHarry Wentland } 22434562236bSHarry Wentland 22444562236bSHarry Wentland if (false == rc) 22454562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 22464562236bSHarry Wentland 22474562236bSHarry Wentland return rc; 22484562236bSHarry Wentland } 22494562236bSHarry Wentland 22504562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 22514562236bSHarry Wentland static void dce110_enable_timing_synchronization( 2252fb3466a4SBhawanpreet Lakha struct dc *dc, 22534562236bSHarry Wentland int group_index, 22544562236bSHarry Wentland int group_size, 22554562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 22564562236bSHarry Wentland { 22574562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 22584562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 22594562236bSHarry Wentland int i; 22604562236bSHarry Wentland 22614562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 22624562236bSHarry Wentland 22634562236bSHarry Wentland /* Designate a single TG in the group as a master. 22644562236bSHarry Wentland * Since HW doesn't care which one, we always assign 22654562236bSHarry Wentland * the 1st one in the group. */ 22664562236bSHarry Wentland gsl_params.gsl_group = 0; 22676b670fa9SHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst; 22684562236bSHarry Wentland 22694562236bSHarry Wentland for (i = 0; i < group_size; i++) 22706b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 22716b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg, &gsl_params); 22724562236bSHarry Wentland 22734562236bSHarry Wentland /* Reset slave controllers on master VSync */ 22744562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 22754562236bSHarry Wentland 22764562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 22776b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( 2278fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2279fa2123dbSMikita Lipski gsl_params.gsl_group); 22804562236bSHarry Wentland 22814562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 22824562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 22836b670fa9SHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2284fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( 2285fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg); 22864562236bSHarry Wentland } 22874562236bSHarry Wentland 22884562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 22894562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 22904562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 22914562236bSHarry Wentland for (i = 0; i < group_size; i++) 22926b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 22934562236bSHarry Wentland 22944562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 22954562236bSHarry Wentland } 22964562236bSHarry Wentland 2297fa2123dbSMikita Lipski static void dce110_enable_per_frame_crtc_position_reset( 2298fa2123dbSMikita Lipski struct dc *dc, 2299fa2123dbSMikita Lipski int group_size, 2300fa2123dbSMikita Lipski struct pipe_ctx *grouped_pipes[]) 2301fa2123dbSMikita Lipski { 2302fa2123dbSMikita Lipski struct dc_context *dc_ctx = dc->ctx; 2303fa2123dbSMikita Lipski struct dcp_gsl_params gsl_params = { 0 }; 2304fa2123dbSMikita Lipski int i; 2305fa2123dbSMikita Lipski 2306fa2123dbSMikita Lipski gsl_params.gsl_group = 0; 2307fa2123dbSMikita Lipski gsl_params.gsl_master = grouped_pipes[0]->stream->triggered_crtc_reset.event_source->status.primary_otg_inst; 2308fa2123dbSMikita Lipski 2309fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2310fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 2311fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, &gsl_params); 2312fa2123dbSMikita Lipski 2313fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 2314fa2123dbSMikita Lipski 2315fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2316fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( 2317fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2318fa2123dbSMikita Lipski gsl_params.gsl_master, 2319fa2123dbSMikita Lipski &grouped_pipes[i]->stream->triggered_crtc_reset); 2320fa2123dbSMikita Lipski 2321fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 2322fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2323fa2123dbSMikita Lipski wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2324fa2123dbSMikita Lipski 2325fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2326fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 2327fa2123dbSMikita Lipski 2328fa2123dbSMikita Lipski } 2329fa2123dbSMikita Lipski 2330fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc) 23314562236bSHarry Wentland { 23324562236bSHarry Wentland int i; 23334562236bSHarry Wentland struct dc_bios *bp; 23344562236bSHarry Wentland struct transform *xfm; 23355e7773a2SAnthony Koo struct abm *abm; 23364562236bSHarry Wentland 23374562236bSHarry Wentland bp = dc->ctx->dc_bios; 23384562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 23394562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 23404562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 23414562236bSHarry Wentland 23424562236bSHarry Wentland dc->hwss.enable_display_power_gating( 23434562236bSHarry Wentland dc, i, bp, 23444562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 23454562236bSHarry Wentland dc->hwss.enable_display_power_gating( 23464562236bSHarry Wentland dc, i, bp, 23474562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 23484562236bSHarry Wentland dc->hwss.enable_display_pipe_clock_gating( 23494562236bSHarry Wentland dc->ctx, 23504562236bSHarry Wentland true); 23514562236bSHarry Wentland } 23524562236bSHarry Wentland 2353e166ad43SJulia Lawall dce_clock_gating_power_up(dc->hwseq, false); 23544562236bSHarry Wentland /***************************************/ 23554562236bSHarry Wentland 23564562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 23574562236bSHarry Wentland /****************************************/ 23584562236bSHarry Wentland /* Power up AND update implementation according to the 23594562236bSHarry Wentland * required signal (which may be different from the 23604562236bSHarry Wentland * default signal on connector). */ 2361d0778ebfSHarry Wentland struct dc_link *link = dc->links[i]; 2362069d418fSAndrew Jiang 2363069d418fSAndrew Jiang if (link->link_enc->connector.id == CONNECTOR_ID_EDP) 2364069d418fSAndrew Jiang dc->hwss.edp_power_control(link, true); 2365069d418fSAndrew Jiang 23664562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 23674562236bSHarry Wentland } 23684562236bSHarry Wentland 23694562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 23704562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 23714562236bSHarry Wentland 23724562236bSHarry Wentland tg->funcs->disable_vga(tg); 23734562236bSHarry Wentland 23744562236bSHarry Wentland /* Blank controller using driver code instead of 23754562236bSHarry Wentland * command table. */ 23764562236bSHarry Wentland tg->funcs->set_blank(tg, true); 23774b5e7d62SHersen Wu hwss_wait_for_blank_complete(tg); 23784562236bSHarry Wentland } 23794562236bSHarry Wentland 23804562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 23814562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 23824562236bSHarry Wentland audio->funcs->hw_init(audio); 23834562236bSHarry Wentland } 23845e7773a2SAnthony Koo 23855e7773a2SAnthony Koo abm = dc->res_pool->abm; 23866728b30cSAnthony Koo if (abm != NULL) { 23876728b30cSAnthony Koo abm->funcs->init_backlight(abm); 23885e7773a2SAnthony Koo abm->funcs->abm_init(abm); 23894562236bSHarry Wentland } 23905099114bSAlex Deucher 23912f3bfb27SRoman Li if (dc->fbc_compressor) 23921663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 2393690b5e39SRoman Li 23946728b30cSAnthony Koo } 23954562236bSHarry Wentland 239628f72454SJordan Lazare void dce110_fill_display_configs( 2397608ac7bbSJerry Zuo const struct dc_state *context, 2398cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg) 23994562236bSHarry Wentland { 2400cf437593SDmytro Laktyushkin int j; 2401cf437593SDmytro Laktyushkin int num_cfgs = 0; 2402cf437593SDmytro Laktyushkin 2403cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 2404cf437593SDmytro Laktyushkin int k; 2405cf437593SDmytro Laktyushkin 24060971c40eSHarry Wentland const struct dc_stream_state *stream = context->streams[j]; 2407cf437593SDmytro Laktyushkin struct dm_pp_single_disp_config *cfg = 2408cf437593SDmytro Laktyushkin &pp_display_cfg->disp_configs[num_cfgs]; 2409cf437593SDmytro Laktyushkin const struct pipe_ctx *pipe_ctx = NULL; 2410cf437593SDmytro Laktyushkin 2411cf437593SDmytro Laktyushkin for (k = 0; k < MAX_PIPES; k++) 2412cf437593SDmytro Laktyushkin if (stream == context->res_ctx.pipe_ctx[k].stream) { 2413cf437593SDmytro Laktyushkin pipe_ctx = &context->res_ctx.pipe_ctx[k]; 2414cf437593SDmytro Laktyushkin break; 24154562236bSHarry Wentland } 24164562236bSHarry Wentland 2417cf437593SDmytro Laktyushkin ASSERT(pipe_ctx != NULL); 2418cf437593SDmytro Laktyushkin 2419631aaa0aSHersen Wu /* only notify active stream */ 2420631aaa0aSHersen Wu if (stream->dpms_off) 2421631aaa0aSHersen Wu continue; 2422631aaa0aSHersen Wu 2423cf437593SDmytro Laktyushkin num_cfgs++; 2424cf437593SDmytro Laktyushkin cfg->signal = pipe_ctx->stream->signal; 2425e07f541fSYongqiang Sun cfg->pipe_idx = pipe_ctx->stream_res.tg->inst; 24264fa086b9SLeo (Sunpeng) Li cfg->src_height = stream->src.height; 24274fa086b9SLeo (Sunpeng) Li cfg->src_width = stream->src.width; 2428cf437593SDmytro Laktyushkin cfg->ddi_channel_mapping = 2429cf437593SDmytro Laktyushkin stream->sink->link->ddi_channel_mapping.raw; 2430cf437593SDmytro Laktyushkin cfg->transmitter = 2431cf437593SDmytro Laktyushkin stream->sink->link->link_enc->transmitter; 2432cf437593SDmytro Laktyushkin cfg->link_settings.lane_count = 2433d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.lane_count; 2434cf437593SDmytro Laktyushkin cfg->link_settings.link_rate = 2435d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.link_rate; 2436cf437593SDmytro Laktyushkin cfg->link_settings.link_spread = 2437d0778ebfSHarry Wentland stream->sink->link->cur_link_settings.link_spread; 2438cf437593SDmytro Laktyushkin cfg->sym_clock = stream->phy_pix_clk; 2439cf437593SDmytro Laktyushkin /* Round v_refresh*/ 24404fa086b9SLeo (Sunpeng) Li cfg->v_refresh = stream->timing.pix_clk_khz * 1000; 24414fa086b9SLeo (Sunpeng) Li cfg->v_refresh /= stream->timing.h_total; 24424fa086b9SLeo (Sunpeng) Li cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) 24434fa086b9SLeo (Sunpeng) Li / stream->timing.v_total; 2444cf437593SDmytro Laktyushkin } 2445cf437593SDmytro Laktyushkin 2446cf437593SDmytro Laktyushkin pp_display_cfg->display_count = num_cfgs; 2447cf437593SDmytro Laktyushkin } 2448cf437593SDmytro Laktyushkin 2449608ac7bbSJerry Zuo uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context) 2450cf437593SDmytro Laktyushkin { 2451cf437593SDmytro Laktyushkin uint8_t j; 2452cf437593SDmytro Laktyushkin uint32_t min_vertical_blank_time = -1; 2453cf437593SDmytro Laktyushkin 2454cf437593SDmytro Laktyushkin for (j = 0; j < context->stream_count; j++) { 24550971c40eSHarry Wentland struct dc_stream_state *stream = context->streams[j]; 2456cf437593SDmytro Laktyushkin uint32_t vertical_blank_in_pixels = 0; 2457cf437593SDmytro Laktyushkin uint32_t vertical_blank_time = 0; 2458cf437593SDmytro Laktyushkin 2459cf437593SDmytro Laktyushkin vertical_blank_in_pixels = stream->timing.h_total * 2460cf437593SDmytro Laktyushkin (stream->timing.v_total 2461cf437593SDmytro Laktyushkin - stream->timing.v_addressable); 2462cf437593SDmytro Laktyushkin 2463cf437593SDmytro Laktyushkin vertical_blank_time = vertical_blank_in_pixels 2464cf437593SDmytro Laktyushkin * 1000 / stream->timing.pix_clk_khz; 2465cf437593SDmytro Laktyushkin 2466cf437593SDmytro Laktyushkin if (min_vertical_blank_time > vertical_blank_time) 2467cf437593SDmytro Laktyushkin min_vertical_blank_time = vertical_blank_time; 2468cf437593SDmytro Laktyushkin } 2469cf437593SDmytro Laktyushkin 2470cf437593SDmytro Laktyushkin return min_vertical_blank_time; 2471cf437593SDmytro Laktyushkin } 2472cf437593SDmytro Laktyushkin 2473cf437593SDmytro Laktyushkin static int determine_sclk_from_bounding_box( 2474fb3466a4SBhawanpreet Lakha const struct dc *dc, 2475cf437593SDmytro Laktyushkin int required_sclk) 24764562236bSHarry Wentland { 24774562236bSHarry Wentland int i; 24784562236bSHarry Wentland 2479cf437593SDmytro Laktyushkin /* 2480cf437593SDmytro Laktyushkin * Some asics do not give us sclk levels, so we just report the actual 2481cf437593SDmytro Laktyushkin * required sclk 2482cf437593SDmytro Laktyushkin */ 2483cf437593SDmytro Laktyushkin if (dc->sclk_lvls.num_levels == 0) 2484cf437593SDmytro Laktyushkin return required_sclk; 24854562236bSHarry Wentland 2486cf437593SDmytro Laktyushkin for (i = 0; i < dc->sclk_lvls.num_levels; i++) { 2487cf437593SDmytro Laktyushkin if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk) 2488cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[i]; 2489cf437593SDmytro Laktyushkin } 2490cf437593SDmytro Laktyushkin /* 2491cf437593SDmytro Laktyushkin * even maximum level could not satisfy requirement, this 2492cf437593SDmytro Laktyushkin * is unexpected at this stage, should have been caught at 2493cf437593SDmytro Laktyushkin * validation time 2494cf437593SDmytro Laktyushkin */ 2495cf437593SDmytro Laktyushkin ASSERT(0); 2496cf437593SDmytro Laktyushkin return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1]; 24974562236bSHarry Wentland } 24984562236bSHarry Wentland 2499cf437593SDmytro Laktyushkin static void pplib_apply_display_requirements( 2500fb3466a4SBhawanpreet Lakha struct dc *dc, 2501608ac7bbSJerry Zuo struct dc_state *context) 2502cf437593SDmytro Laktyushkin { 2503cf437593SDmytro Laktyushkin struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; 2504cf437593SDmytro Laktyushkin 2505cf437593SDmytro Laktyushkin pp_display_cfg->all_displays_in_sync = 25069037d802SDmytro Laktyushkin context->bw.dce.all_displays_in_sync; 2507cf437593SDmytro Laktyushkin pp_display_cfg->nb_pstate_switch_disable = 25089037d802SDmytro Laktyushkin context->bw.dce.nbp_state_change_enable == false; 2509cf437593SDmytro Laktyushkin pp_display_cfg->cpu_cc6_disable = 25109037d802SDmytro Laktyushkin context->bw.dce.cpuc_state_change_enable == false; 2511cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_disable = 25129037d802SDmytro Laktyushkin context->bw.dce.cpup_state_change_enable == false; 2513cf437593SDmytro Laktyushkin pp_display_cfg->cpu_pstate_separation_time = 25149037d802SDmytro Laktyushkin context->bw.dce.blackout_recovery_time_us; 2515cf437593SDmytro Laktyushkin 25169037d802SDmytro Laktyushkin pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz 2517cf437593SDmytro Laktyushkin / MEMORY_TYPE_MULTIPLIER; 2518cf437593SDmytro Laktyushkin 2519cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( 2520cf437593SDmytro Laktyushkin dc, 25219037d802SDmytro Laktyushkin context->bw.dce.sclk_khz); 2522cf437593SDmytro Laktyushkin 2523cf437593SDmytro Laktyushkin pp_display_cfg->min_engine_clock_deep_sleep_khz 25249037d802SDmytro Laktyushkin = context->bw.dce.sclk_deep_sleep_khz; 2525cf437593SDmytro Laktyushkin 2526cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_us = 252728f72454SJordan Lazare dce110_get_min_vblank_time_us(context); 2528cf437593SDmytro Laktyushkin /* TODO: dce11.2*/ 2529cf437593SDmytro Laktyushkin pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; 2530cf437593SDmytro Laktyushkin 25315ae6fe57SNicholas Kazlauskas pp_display_cfg->disp_clk_khz = dc->res_pool->dccg->clks.dispclk_khz; 2532cf437593SDmytro Laktyushkin 253328f72454SJordan Lazare dce110_fill_display_configs(context, pp_display_cfg); 2534cf437593SDmytro Laktyushkin 2535cf437593SDmytro Laktyushkin /* TODO: is this still applicable?*/ 2536cf437593SDmytro Laktyushkin if (pp_display_cfg->display_count == 1) { 2537cf437593SDmytro Laktyushkin const struct dc_crtc_timing *timing = 25384fa086b9SLeo (Sunpeng) Li &context->streams[0]->timing; 2539cf437593SDmytro Laktyushkin 2540cf437593SDmytro Laktyushkin pp_display_cfg->crtc_index = 2541cf437593SDmytro Laktyushkin pp_display_cfg->disp_configs[0].pipe_idx; 2542cf437593SDmytro Laktyushkin pp_display_cfg->line_time_in_us = timing->h_total * 1000 2543cf437593SDmytro Laktyushkin / timing->pix_clk_khz; 2544cf437593SDmytro Laktyushkin } 2545cf437593SDmytro Laktyushkin 2546cf437593SDmytro Laktyushkin if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof( 2547cf437593SDmytro Laktyushkin struct dm_pp_display_configuration)) != 0) 2548cf437593SDmytro Laktyushkin dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); 2549cf437593SDmytro Laktyushkin 2550cf437593SDmytro Laktyushkin dc->prev_display_config = *pp_display_cfg; 2551cf437593SDmytro Laktyushkin } 2552cf437593SDmytro Laktyushkin 2553f358b39dSJerry (Fangzhi) Zuo void dce110_set_bandwidth( 2554fb3466a4SBhawanpreet Lakha struct dc *dc, 2555608ac7bbSJerry Zuo struct dc_state *context, 2556cf437593SDmytro Laktyushkin bool decrease_allowed) 2557cf437593SDmytro Laktyushkin { 2558fab55d61SDmytro Laktyushkin struct dc_clocks req_clks; 25595a83c932SNicholas Kazlauskas struct dccg *dccg = dc->res_pool->dccg; 2560fab55d61SDmytro Laktyushkin 25615ae6fe57SNicholas Kazlauskas req_clks.dispclk_khz = context->bw.dce.dispclk_khz; 2562fab55d61SDmytro Laktyushkin req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context); 2563fab55d61SDmytro Laktyushkin 2564fab55d61SDmytro Laktyushkin if (decrease_allowed) 25652180e7ccSDmytro Laktyushkin dce110_set_displaymarks(dc, context); 2566fab55d61SDmytro Laktyushkin else 2567fab55d61SDmytro Laktyushkin dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); 2568cf437593SDmytro Laktyushkin 25695a83c932SNicholas Kazlauskas if (dccg->funcs->update_dfs_bypass) 25705a83c932SNicholas Kazlauskas dccg->funcs->update_dfs_bypass( 25715a83c932SNicholas Kazlauskas dccg, 25725a83c932SNicholas Kazlauskas dc, 25735a83c932SNicholas Kazlauskas context, 25745a83c932SNicholas Kazlauskas req_clks.dispclk_khz); 25755a83c932SNicholas Kazlauskas 25765a83c932SNicholas Kazlauskas dccg->funcs->update_clocks( 25775a83c932SNicholas Kazlauskas dccg, 2578fab55d61SDmytro Laktyushkin &req_clks, 2579fab55d61SDmytro Laktyushkin decrease_allowed); 2580cf437593SDmytro Laktyushkin pplib_apply_display_requirements(dc, context); 25814562236bSHarry Wentland } 25824562236bSHarry Wentland 25834562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 2584fb3466a4SBhawanpreet Lakha struct dc *dc, struct pipe_ctx *pipe_ctx) 25854562236bSHarry Wentland { 258686a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 25874562236bSHarry Wentland struct pipe_ctx *old_pipe = NULL; 25883be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 25894562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 25904562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 259187ac8fb0SShirish S unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 25924562236bSHarry Wentland unsigned int i; 25935d4b05ddSBhawanpreet Lakha DC_LOGGER_INIT(); 25944562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 25954562236bSHarry Wentland 2596608ac7bbSJerry Zuo if (dc->current_state) 2597608ac7bbSJerry Zuo old_pipe = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; 25984562236bSHarry Wentland 25994562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 26004562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 26014562236bSHarry Wentland 2602e07f541fSYongqiang Sun dce_enable_fe_clock(dc->hwseq, mi->inst, true); 26034562236bSHarry Wentland 26044562236bSHarry Wentland set_default_colors(pipe_ctx); 26054fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 26064562236bSHarry Wentland == true) { 26074562236bSHarry Wentland tbl_entry.color_space = 26084fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 26094562236bSHarry Wentland 26104562236bSHarry Wentland for (i = 0; i < 12; i++) 26114562236bSHarry Wentland tbl_entry.regval[i] = 26124fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 26134562236bSHarry Wentland 261486a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 261586a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 26164562236bSHarry Wentland } 26174562236bSHarry Wentland 26184fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 26194562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2620146a9f63SKrunoslav Kovac 2621146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2622146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2623146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 26244562236bSHarry Wentland } 26254562236bSHarry Wentland 262686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 26274562236bSHarry Wentland 26286702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 2629c1473558SAndrey Grodzovsky 26304562236bSHarry Wentland program_scaler(dc, pipe_ctx); 26314562236bSHarry Wentland 263287ac8fb0SShirish S /* fbc not applicable on Underlay pipe */ 263387ac8fb0SShirish S if (dc->fbc_compressor && old_pipe->stream && 263487ac8fb0SShirish S pipe_ctx->pipe_idx != underlay_idx) { 2635e008b0bcSRoman Li if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 2636e008b0bcSRoman Li dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 2637e008b0bcSRoman Li else 2638e008b0bcSRoman Li enable_fbc(dc, dc->current_state); 2639e008b0bcSRoman Li } 2640e008b0bcSRoman Li 26414562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 26424562236bSHarry Wentland mi, 26433be5262eSHarry Wentland plane_state->format, 26443be5262eSHarry Wentland &plane_state->tiling_info, 26453be5262eSHarry Wentland &plane_state->plane_size, 26463be5262eSHarry Wentland plane_state->rotation, 2647624d7c47SYongqiang Sun NULL, 26484b28b76bSDmytro Laktyushkin false); 26494b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 26503be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 26514562236bSHarry Wentland 2652fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 26534562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 265486a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 26553be5262eSHarry Wentland plane_state->format, 26563be5262eSHarry Wentland &plane_state->tiling_info, 26573be5262eSHarry Wentland plane_state->rotation); 26584562236bSHarry Wentland 2659067c878aSYongqiang Sun /* Moved programming gamma from dc to hwss */ 2660405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update || 2661405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 2662405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.gamma_change) 2663a6114e85SHarry Wentland dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state); 2664405c50a0SAndrew Jiang 2665405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update) 2666a6114e85SHarry Wentland dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream); 2667067c878aSYongqiang Sun 26681296423bSBhawanpreet Lakha DC_LOG_SURFACE( 26693032deb5SBhawanpreet Lakha "Pipe:%d %p: addr hi:0x%x, " 26704562236bSHarry Wentland "addr low:0x%x, " 26714562236bSHarry Wentland "src: %d, %d, %d," 26724562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 26734562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 26744562236bSHarry Wentland pipe_ctx->pipe_idx, 26753032deb5SBhawanpreet Lakha (void *) pipe_ctx->plane_state, 26763be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.high_part, 26773be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.low_part, 26783be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.x, 26793be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.y, 26803be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.width, 26813be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.height, 26823be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.x, 26833be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.y, 26843be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.width, 26853be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.height, 26863be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.x, 26873be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.y, 26883be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.width, 26893be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.height); 26904562236bSHarry Wentland 26911296423bSBhawanpreet Lakha DC_LOG_SURFACE( 26924562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 26934562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 26944562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 26954562236bSHarry Wentland pipe_ctx->pipe_idx, 26966702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.width, 26976702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.height, 26986702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.x, 26996702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.y, 27006702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.width, 27016702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.height, 27026702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.x, 27036702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.y); 27044562236bSHarry Wentland } 27054562236bSHarry Wentland 27064562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 2707fb3466a4SBhawanpreet Lakha struct dc *dc, 27083e9ad616SEric Yang const struct dc_stream_state *stream, 27093e9ad616SEric Yang int num_planes, 2710608ac7bbSJerry Zuo struct dc_state *context) 27114562236bSHarry Wentland { 27122194e3aeSRoman Li int i; 27134562236bSHarry Wentland 27143e9ad616SEric Yang if (num_planes == 0) 27154562236bSHarry Wentland return; 27164562236bSHarry Wentland 27173e9ad616SEric Yang for (i = 0; i < dc->res_pool->pipe_count; i++) { 27183dc780ecSYongqiang Sun struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 27193dc780ecSYongqiang Sun struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 27203dc780ecSYongqiang Sun 27212194e3aeSRoman Li if (stream == pipe_ctx->stream) { 27223dc780ecSYongqiang Sun if (!pipe_ctx->top_pipe && 27233dc780ecSYongqiang Sun (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) 27243dc780ecSYongqiang Sun dc->hwss.pipe_control_lock(dc, pipe_ctx, true); 27253e9ad616SEric Yang } 27263e9ad616SEric Yang } 27273e9ad616SEric Yang 2728a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 27294562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 27304562236bSHarry Wentland 2731a2607aefSHarry Wentland if (pipe_ctx->stream != stream) 27324562236bSHarry Wentland continue; 27334562236bSHarry Wentland 27343b21b6d2SJerry Zuo /* Need to allocate mem before program front end for Fiji */ 27353b21b6d2SJerry Zuo pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 27363b21b6d2SJerry Zuo pipe_ctx->plane_res.mi, 27373b21b6d2SJerry Zuo pipe_ctx->stream->timing.h_total, 27383b21b6d2SJerry Zuo pipe_ctx->stream->timing.v_total, 27393b21b6d2SJerry Zuo pipe_ctx->stream->timing.pix_clk_khz, 27403b21b6d2SJerry Zuo context->stream_count); 27413b21b6d2SJerry Zuo 27424562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 27434f804817SYongqiang Sun 27444f804817SYongqiang Sun dc->hwss.update_plane_addr(dc, pipe_ctx); 27454f804817SYongqiang Sun 2746b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 27474562236bSHarry Wentland 27484562236bSHarry Wentland } 27493dc780ecSYongqiang Sun 27503dc780ecSYongqiang Sun for (i = 0; i < dc->res_pool->pipe_count; i++) { 27513dc780ecSYongqiang Sun struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 27523dc780ecSYongqiang Sun struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 27533dc780ecSYongqiang Sun 27543dc780ecSYongqiang Sun if ((stream == pipe_ctx->stream) && 27553dc780ecSYongqiang Sun (!pipe_ctx->top_pipe) && 27563dc780ecSYongqiang Sun (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) 27573dc780ecSYongqiang Sun dc->hwss.pipe_control_lock(dc, pipe_ctx, false); 27583dc780ecSYongqiang Sun } 27594562236bSHarry Wentland } 27604562236bSHarry Wentland 2761e6c258cbSYongqiang Sun static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) 27624562236bSHarry Wentland { 2763bc373a89SRoman Li int fe_idx = pipe_ctx->plane_res.mi ? 2764bc373a89SRoman Li pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx; 2765e6c258cbSYongqiang Sun 27667950f0f9SDmytro Laktyushkin /* Do not power down fe when stream is active on dce*/ 2767608ac7bbSJerry Zuo if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) 27684562236bSHarry Wentland return; 27694562236bSHarry Wentland 27704562236bSHarry Wentland dc->hwss.enable_display_power_gating( 2771cfe4645eSDmytro Laktyushkin dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 2772cfe4645eSDmytro Laktyushkin 2773cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 2774cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]); 27754562236bSHarry Wentland } 27764562236bSHarry Wentland 27776be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect( 2778fb3466a4SBhawanpreet Lakha struct dc *dc, 27796be425f3SEric Yang struct resource_pool *res_pool, 27806be425f3SEric Yang struct pipe_ctx *pipe_ctx) 2781b6762f0cSEric Yang { 2782b6762f0cSEric Yang /* do nothing*/ 2783b6762f0cSEric Yang } 2784b6762f0cSEric Yang 2785bdf9a1a0SYue Hin Lau static void program_csc_matrix(struct pipe_ctx *pipe_ctx, 2786bdf9a1a0SYue Hin Lau enum dc_color_space colorspace, 2787bdf9a1a0SYue Hin Lau uint16_t *matrix) 2788bdf9a1a0SYue Hin Lau { 2789bdf9a1a0SYue Hin Lau int i; 2790bdf9a1a0SYue Hin Lau struct out_csc_color_matrix tbl_entry; 2791bdf9a1a0SYue Hin Lau 2792bdf9a1a0SYue Hin Lau if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 2793bdf9a1a0SYue Hin Lau == true) { 2794bdf9a1a0SYue Hin Lau enum dc_color_space color_space = 2795bdf9a1a0SYue Hin Lau pipe_ctx->stream->output_color_space; 2796bdf9a1a0SYue Hin Lau 2797bdf9a1a0SYue Hin Lau //uint16_t matrix[12]; 2798bdf9a1a0SYue Hin Lau for (i = 0; i < 12; i++) 2799bdf9a1a0SYue Hin Lau tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; 2800bdf9a1a0SYue Hin Lau 2801bdf9a1a0SYue Hin Lau tbl_entry.color_space = color_space; 2802bdf9a1a0SYue Hin Lau //tbl_entry.regval = matrix; 280386a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry); 2804bdf9a1a0SYue Hin Lau } 2805bdf9a1a0SYue Hin Lau } 2806bdf9a1a0SYue Hin Lau 280733fd17d9SEric Yang void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) 280833fd17d9SEric Yang { 280933fd17d9SEric Yang struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; 281033fd17d9SEric Yang struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 281133fd17d9SEric Yang struct mem_input *mi = pipe_ctx->plane_res.mi; 281233fd17d9SEric Yang struct dc_cursor_mi_param param = { 281333fd17d9SEric Yang .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz, 281433fd17d9SEric Yang .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz, 281539a9f4d8SDmytro Laktyushkin .viewport = pipe_ctx->plane_res.scl_data.viewport, 281639a9f4d8SDmytro Laktyushkin .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, 281739a9f4d8SDmytro Laktyushkin .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, 281808ed681cSDmytro Laktyushkin .rotation = pipe_ctx->plane_state->rotation, 281908ed681cSDmytro Laktyushkin .mirror = pipe_ctx->plane_state->horizontal_mirror 282033fd17d9SEric Yang }; 282133fd17d9SEric Yang 282233fd17d9SEric Yang if (pipe_ctx->plane_state->address.type 282333fd17d9SEric Yang == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) 282433fd17d9SEric Yang pos_cpy.enable = false; 282533fd17d9SEric Yang 282633fd17d9SEric Yang if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 282733fd17d9SEric Yang pos_cpy.enable = false; 282833fd17d9SEric Yang 2829dc75dd70SRoman Li if (ipp->funcs->ipp_cursor_set_position) 283033fd17d9SEric Yang ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); 2831dc75dd70SRoman Li if (mi->funcs->set_cursor_position) 283233fd17d9SEric Yang mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); 283333fd17d9SEric Yang } 283433fd17d9SEric Yang 283533fd17d9SEric Yang void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) 283633fd17d9SEric Yang { 283733fd17d9SEric Yang struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; 283833fd17d9SEric Yang 2839d1aaad05SHarry Wentland if (pipe_ctx->plane_res.ipp && 2840d1aaad05SHarry Wentland pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) 284133fd17d9SEric Yang pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( 284233fd17d9SEric Yang pipe_ctx->plane_res.ipp, attributes); 284333fd17d9SEric Yang 2844d1aaad05SHarry Wentland if (pipe_ctx->plane_res.mi && 2845d1aaad05SHarry Wentland pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) 284633fd17d9SEric Yang pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( 284733fd17d9SEric Yang pipe_ctx->plane_res.mi, attributes); 284833fd17d9SEric Yang 2849d1aaad05SHarry Wentland if (pipe_ctx->plane_res.xfm && 2850d1aaad05SHarry Wentland pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) 285133fd17d9SEric Yang pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( 285233fd17d9SEric Yang pipe_ctx->plane_res.xfm, attributes); 285333fd17d9SEric Yang } 285433fd17d9SEric Yang 28556bf52028SHersen Wu static void ready_shared_resources(struct dc *dc, struct dc_state *context) {} 285641f97c07SHersen Wu 285741f97c07SHersen Wu static void optimize_shared_resources(struct dc *dc) {} 285841f97c07SHersen Wu 28594562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 28601bf56e62SZeyu Fan .program_gamut_remap = program_gamut_remap, 2861bdf9a1a0SYue Hin Lau .program_csc_matrix = program_csc_matrix, 28624562236bSHarry Wentland .init_hw = init_hw, 28634562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 28644562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 28654562236bSHarry Wentland .update_plane_addr = update_plane_addr, 28664562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 2867d7194cf6SAric Cyr .set_input_transfer_func = dce110_set_input_transfer_func, 286890e508baSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 28694562236bSHarry Wentland .power_down = dce110_power_down, 28704562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 28714562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 2872fa2123dbSMikita Lipski .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, 28734562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 28744562236bSHarry Wentland .enable_stream = dce110_enable_stream, 28754562236bSHarry Wentland .disable_stream = dce110_disable_stream, 28764562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 287741b49742SCharlene Liu .blank_stream = dce110_blank_stream, 28781a05873fSAnthony Koo .enable_audio_stream = dce110_enable_audio_stream, 28791a05873fSAnthony Koo .disable_audio_stream = dce110_disable_audio_stream, 28804562236bSHarry Wentland .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 28814562236bSHarry Wentland .enable_display_power_gating = dce110_enable_display_power_gating, 28827f914a62SYongqiang Sun .disable_plane = dce110_power_down_fe, 28834562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 28844562236bSHarry Wentland .set_bandwidth = dce110_set_bandwidth, 28854562236bSHarry Wentland .set_drr = set_drr, 288672ada5f7SEric Cook .get_position = get_position, 28874562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 288854e8695eSDmytro Laktyushkin .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 28893158223eSEric Bernstein .enable_stream_timing = dce110_enable_stream_timing, 289015e17335SCharlene Liu .setup_stereo = NULL, 289115e17335SCharlene Liu .set_avmute = dce110_set_avmute, 289241f97c07SHersen Wu .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 289341f97c07SHersen Wu .ready_shared_resources = ready_shared_resources, 289441f97c07SHersen Wu .optimize_shared_resources = optimize_shared_resources, 2895631aaa0aSHersen Wu .pplib_apply_display_requirements = pplib_apply_display_requirements, 289687401969SAndrew Jiang .edp_backlight_control = hwss_edp_backlight_control, 289787401969SAndrew Jiang .edp_power_control = hwss_edp_power_control, 2898904623eeSYongqiang Sun .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready, 289933fd17d9SEric Yang .set_cursor_position = dce110_set_cursor_position, 290033fd17d9SEric Yang .set_cursor_attribute = dce110_set_cursor_attribute 29014562236bSHarry Wentland }; 29024562236bSHarry Wentland 2903c13b408bSDave Airlie void dce110_hw_sequencer_construct(struct dc *dc) 29044562236bSHarry Wentland { 29054562236bSHarry Wentland dc->hwss = dce110_funcs; 29064562236bSHarry Wentland } 29074562236bSHarry Wentland 2908