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 */ 25c366be54SSam Ravnborg 26c366be54SSam Ravnborg #include <linux/delay.h> 27c366be54SSam Ravnborg 284562236bSHarry Wentland #include "dm_services.h" 294562236bSHarry Wentland #include "dc.h" 304562236bSHarry Wentland #include "dc_bios_types.h" 314562236bSHarry Wentland #include "core_types.h" 324562236bSHarry Wentland #include "core_status.h" 334562236bSHarry Wentland #include "resource.h" 344562236bSHarry Wentland #include "dm_helpers.h" 354562236bSHarry Wentland #include "dce110_hw_sequencer.h" 364562236bSHarry Wentland #include "dce110_timing_generator.h" 3798489c02SLeo (Sunpeng) Li #include "dce/dce_hwseq.h" 3887401969SAndrew Jiang #include "gpio_service_interface.h" 394562236bSHarry Wentland 401663ae1cSBhawanpreet Lakha #include "dce110_compressor.h" 411663ae1cSBhawanpreet Lakha 424562236bSHarry Wentland #include "bios/bios_parser_helper.h" 434562236bSHarry Wentland #include "timing_generator.h" 444562236bSHarry Wentland #include "mem_input.h" 454562236bSHarry Wentland #include "opp.h" 464562236bSHarry Wentland #include "ipp.h" 474562236bSHarry Wentland #include "transform.h" 484562236bSHarry Wentland #include "stream_encoder.h" 494562236bSHarry Wentland #include "link_encoder.h" 5087401969SAndrew Jiang #include "link_hwss.h" 514562236bSHarry Wentland #include "clock_source.h" 52dc88b4a6SEric Yang #include "clk_mgr.h" 535e7773a2SAnthony Koo #include "abm.h" 544562236bSHarry Wentland #include "audio.h" 5508b16886SZeyu Fan #include "reg_helper.h" 56d4caa72eSAnthony Koo #include "panel_cntl.h" 574562236bSHarry Wentland 584562236bSHarry Wentland /* include DCE11 register header files */ 594562236bSHarry Wentland #include "dce/dce_11_0_d.h" 604562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 61e266fdf6SVitaly Prosyak #include "custom_float.h" 624562236bSHarry Wentland 634cac1e6dSYongqiang Sun #include "atomfirmware.h" 644cac1e6dSYongqiang Sun 6578c77382SAnthony Koo #define GAMMA_HW_POINTS_NUM 256 6678c77382SAnthony Koo 6787401969SAndrew Jiang /* 6887401969SAndrew Jiang * All values are in milliseconds; 6987401969SAndrew Jiang * For eDP, after power-up/power/down, 7087401969SAndrew Jiang * 300/500 msec max. delay from LCDVCC to black video generation 7187401969SAndrew Jiang */ 7287401969SAndrew Jiang #define PANEL_POWER_UP_TIMEOUT 300 7387401969SAndrew Jiang #define PANEL_POWER_DOWN_TIMEOUT 500 7487401969SAndrew Jiang #define HPD_CHECK_INTERVAL 10 7596577cf8SHersen Wu #define OLED_POST_T7_DELAY 100 7696577cf8SHersen Wu #define OLED_PRE_T11_DELAY 150 7787401969SAndrew Jiang 785eefbc40SYue Hin Lau #define CTX \ 795eefbc40SYue Hin Lau hws->ctx 805d4b05ddSBhawanpreet Lakha 815d4b05ddSBhawanpreet Lakha #define DC_LOGGER_INIT() 825d4b05ddSBhawanpreet Lakha 835eefbc40SYue Hin Lau #define REG(reg)\ 845eefbc40SYue Hin Lau hws->regs->reg 855eefbc40SYue Hin Lau 865eefbc40SYue Hin Lau #undef FN 875eefbc40SYue Hin Lau #define FN(reg_name, field_name) \ 885eefbc40SYue Hin Lau hws->shifts->field_name, hws->masks->field_name 895eefbc40SYue Hin Lau 904562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 914562236bSHarry Wentland uint32_t crtc; 924562236bSHarry Wentland }; 934562236bSHarry Wentland 944562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 954562236bSHarry Wentland { 964562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 974562236bSHarry Wentland }, 984562236bSHarry Wentland { 994562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1004562236bSHarry Wentland }, 1014562236bSHarry Wentland { 1024562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1034562236bSHarry Wentland }, 1044562236bSHarry Wentland { 1054562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1064562236bSHarry Wentland } 1074562236bSHarry Wentland }; 1084562236bSHarry Wentland 1094562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 1104562236bSHarry Wentland (reg + reg_offsets[id].blnd) 1114562236bSHarry Wentland 1124562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 1134562236bSHarry Wentland (reg + reg_offsets[id].crtc) 1144562236bSHarry Wentland 1154562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 1164562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 1174562236bSHarry Wentland 1184562236bSHarry Wentland /******************************************************************************* 1194562236bSHarry Wentland * Private definitions 1204562236bSHarry Wentland ******************************************************************************/ 1214562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 1224562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 1234562236bSHarry Wentland { 1244562236bSHarry Wentland uint32_t addr; 1254562236bSHarry Wentland uint32_t value = 0; 1264562236bSHarry Wentland uint32_t chunk_int = 0; 1274562236bSHarry Wentland uint32_t chunk_mul = 0; 1284562236bSHarry Wentland 1294562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 1304562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1314562236bSHarry Wentland 1324562236bSHarry Wentland set_reg_field_value( 1334562236bSHarry Wentland value, 1344562236bSHarry Wentland 0, 1354562236bSHarry Wentland DVMM_PTE_CONTROL, 1364562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1374562236bSHarry Wentland 1384562236bSHarry Wentland set_reg_field_value( 1394562236bSHarry Wentland value, 1404562236bSHarry Wentland 1, 1414562236bSHarry Wentland DVMM_PTE_CONTROL, 1424562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1434562236bSHarry Wentland 1444562236bSHarry Wentland set_reg_field_value( 1454562236bSHarry Wentland value, 1464562236bSHarry Wentland 1, 1474562236bSHarry Wentland DVMM_PTE_CONTROL, 1484562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1494562236bSHarry Wentland 1504562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1514562236bSHarry Wentland 1524562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1534562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1544562236bSHarry Wentland 1554562236bSHarry Wentland chunk_int = get_reg_field_value( 1564562236bSHarry Wentland value, 1574562236bSHarry Wentland DVMM_PTE_REQ, 1584562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1594562236bSHarry Wentland 1604562236bSHarry Wentland chunk_mul = get_reg_field_value( 1614562236bSHarry Wentland value, 1624562236bSHarry Wentland DVMM_PTE_REQ, 1634562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1644562236bSHarry Wentland 1654562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1664562236bSHarry Wentland 1674562236bSHarry Wentland set_reg_field_value( 1684562236bSHarry Wentland value, 1694562236bSHarry Wentland 255, 1704562236bSHarry Wentland DVMM_PTE_REQ, 1714562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1724562236bSHarry Wentland 1734562236bSHarry Wentland set_reg_field_value( 1744562236bSHarry Wentland value, 1754562236bSHarry Wentland 4, 1764562236bSHarry Wentland DVMM_PTE_REQ, 1774562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1784562236bSHarry Wentland 1794562236bSHarry Wentland set_reg_field_value( 1804562236bSHarry Wentland value, 1814562236bSHarry Wentland 4, 1824562236bSHarry Wentland DVMM_PTE_REQ, 1834562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1844562236bSHarry Wentland 1854562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1864562236bSHarry Wentland } 1874562236bSHarry Wentland } 1884562236bSHarry Wentland /**************************************************************************/ 1894562236bSHarry Wentland 1904562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1914562236bSHarry Wentland struct dc_context *ctx, 1924562236bSHarry Wentland bool clock_gating) 1934562236bSHarry Wentland { 1944562236bSHarry Wentland /*TODO*/ 1954562236bSHarry Wentland } 1964562236bSHarry Wentland 1974562236bSHarry Wentland static bool dce110_enable_display_power_gating( 198fb3466a4SBhawanpreet Lakha struct dc *dc, 1994562236bSHarry Wentland uint8_t controller_id, 2004562236bSHarry Wentland struct dc_bios *dcb, 2014562236bSHarry Wentland enum pipe_gating_control power_gating) 2024562236bSHarry Wentland { 2034562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 2044562236bSHarry Wentland enum bp_pipe_control_action cntl; 2054562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 2064562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 2074562236bSHarry Wentland 2084562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 2094562236bSHarry Wentland return true; 2104562236bSHarry Wentland 2114562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 2124562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 2134562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 2144562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 2154562236bSHarry Wentland else 2164562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 2174562236bSHarry Wentland 2184562236bSHarry Wentland if (controller_id == underlay_idx) 2194562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 2204562236bSHarry Wentland 2214562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){ 2224562236bSHarry Wentland 2234562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 2244562236bSHarry Wentland dcb, controller_id + 1, cntl); 2254562236bSHarry Wentland 2264562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 2274562236bSHarry Wentland * by default when command table is called 2284562236bSHarry Wentland * 2294562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 2304562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 2314562236bSHarry Wentland * than 3. 2324562236bSHarry Wentland */ 2334562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 2344562236bSHarry Wentland dm_write_reg(ctx, 2354562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 2364562236bSHarry Wentland 0); 2374562236bSHarry Wentland } 2384562236bSHarry Wentland 2394562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2404562236bSHarry Wentland dce110_init_pte(ctx); 2414562236bSHarry Wentland 2424562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2434562236bSHarry Wentland return true; 2444562236bSHarry Wentland else 2454562236bSHarry Wentland return false; 2464562236bSHarry Wentland } 2474562236bSHarry Wentland 2484562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2493be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2504562236bSHarry Wentland { 2514562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2524562236bSHarry Wentland 2533be5262eSHarry Wentland switch (plane_state->format) { 2541352c779SNicholas Kazlauskas case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 2551352c779SNicholas Kazlauskas prescale_params->scale = 0x2082; 2561352c779SNicholas Kazlauskas break; 2574562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2588693049aSTony Cheng case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 2594562236bSHarry Wentland prescale_params->scale = 0x2020; 2604562236bSHarry Wentland break; 2614562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2624562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2634562236bSHarry Wentland prescale_params->scale = 0x2008; 2644562236bSHarry Wentland break; 2654562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 2664562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2674562236bSHarry Wentland prescale_params->scale = 0x2000; 2684562236bSHarry Wentland break; 2694562236bSHarry Wentland default: 2704562236bSHarry Wentland ASSERT(false); 271d7194cf6SAric Cyr break; 2724562236bSHarry Wentland } 2734562236bSHarry Wentland } 2744562236bSHarry Wentland 275a6114e85SHarry Wentland static bool 27678c77382SAnthony Koo dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 2773be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2784562236bSHarry Wentland { 27986a66c4eSHarry Wentland struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 2807b0c470fSLeo (Sunpeng) Li const struct dc_transfer_func *tf = NULL; 28190e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 28290e508baSAnthony Koo bool result = true; 28390e508baSAnthony Koo 28490e508baSAnthony Koo if (ipp == NULL) 28590e508baSAnthony Koo return false; 28690e508baSAnthony Koo 2873be5262eSHarry Wentland if (plane_state->in_transfer_func) 2883be5262eSHarry Wentland tf = plane_state->in_transfer_func; 28990e508baSAnthony Koo 2903be5262eSHarry Wentland build_prescale_params(&prescale_params, plane_state); 29190e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 29290e508baSAnthony Koo 29384ffa801SLeo (Sunpeng) Li if (plane_state->gamma_correction && 29484ffa801SLeo (Sunpeng) Li !plane_state->gamma_correction->is_identity && 29584ffa801SLeo (Sunpeng) Li dce_use_lut(plane_state->format)) 2963be5262eSHarry Wentland ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction); 297d7194cf6SAric Cyr 29890e508baSAnthony Koo if (tf == NULL) { 29990e508baSAnthony Koo /* Default case if no input transfer function specified */ 300a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 3017b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_PREDEFINED) { 3027b0c470fSLeo (Sunpeng) Li switch (tf->tf) { 30390e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 304a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 30590e508baSAnthony Koo break; 30690e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 307a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC); 30890e508baSAnthony Koo break; 30990e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 310a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 31190e508baSAnthony Koo break; 31290e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 31390e508baSAnthony Koo default: 31490e508baSAnthony Koo result = false; 315d7194cf6SAric Cyr break; 31690e508baSAnthony Koo } 3177b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_BYPASS) { 31870063a59SAmy Zhang ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 31990e508baSAnthony Koo } else { 32090e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 32190e508baSAnthony Koo result = false; 32290e508baSAnthony Koo } 32390e508baSAnthony Koo 32490e508baSAnthony Koo return result; 32590e508baSAnthony Koo } 32690e508baSAnthony Koo 327bd1be8e8SHarry Wentland static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted, 328fcd2f4bfSAmy Zhang struct curve_points *arr_points, 329fcd2f4bfSAmy Zhang uint32_t hw_points_num) 330fcd2f4bfSAmy Zhang { 331fcd2f4bfSAmy Zhang struct custom_float_format fmt; 332fcd2f4bfSAmy Zhang 333fcd2f4bfSAmy Zhang struct pwl_result_data *rgb = rgb_resulted; 334fcd2f4bfSAmy Zhang 335fcd2f4bfSAmy Zhang uint32_t i = 0; 336fcd2f4bfSAmy Zhang 337fcd2f4bfSAmy Zhang fmt.exponenta_bits = 6; 338fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 339fcd2f4bfSAmy Zhang fmt.sign = true; 340fcd2f4bfSAmy Zhang 341bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].x, &fmt, 342fcd2f4bfSAmy Zhang &arr_points[0].custom_float_x)) { 343fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 344fcd2f4bfSAmy Zhang return false; 345fcd2f4bfSAmy Zhang } 346fcd2f4bfSAmy Zhang 347bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].offset, &fmt, 348fcd2f4bfSAmy Zhang &arr_points[0].custom_float_offset)) { 349fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 350fcd2f4bfSAmy Zhang return false; 351fcd2f4bfSAmy Zhang } 352fcd2f4bfSAmy Zhang 353bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].slope, &fmt, 354fcd2f4bfSAmy Zhang &arr_points[0].custom_float_slope)) { 355fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 356fcd2f4bfSAmy Zhang return false; 357fcd2f4bfSAmy Zhang } 358fcd2f4bfSAmy Zhang 359fcd2f4bfSAmy Zhang fmt.mantissa_bits = 10; 360fcd2f4bfSAmy Zhang fmt.sign = false; 361fcd2f4bfSAmy Zhang 362bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].x, &fmt, 363fcd2f4bfSAmy Zhang &arr_points[1].custom_float_x)) { 364fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 365fcd2f4bfSAmy Zhang return false; 366fcd2f4bfSAmy Zhang } 367fcd2f4bfSAmy Zhang 368bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].y, &fmt, 369fcd2f4bfSAmy Zhang &arr_points[1].custom_float_y)) { 370fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 371fcd2f4bfSAmy Zhang return false; 372fcd2f4bfSAmy Zhang } 373fcd2f4bfSAmy Zhang 3744d06ccd0SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].slope, &fmt, 3754d06ccd0SHarry Wentland &arr_points[1].custom_float_slope)) { 376fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 377fcd2f4bfSAmy Zhang return false; 378fcd2f4bfSAmy Zhang } 379fcd2f4bfSAmy Zhang 380fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 381fcd2f4bfSAmy Zhang fmt.sign = true; 382fcd2f4bfSAmy Zhang 383fcd2f4bfSAmy Zhang while (i != hw_points_num) { 384bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->red, &fmt, 385fcd2f4bfSAmy Zhang &rgb->red_reg)) { 386fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 387fcd2f4bfSAmy Zhang return false; 388fcd2f4bfSAmy Zhang } 389fcd2f4bfSAmy Zhang 390bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->green, &fmt, 391fcd2f4bfSAmy Zhang &rgb->green_reg)) { 392fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 393fcd2f4bfSAmy Zhang return false; 394fcd2f4bfSAmy Zhang } 395fcd2f4bfSAmy Zhang 396bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->blue, &fmt, 397fcd2f4bfSAmy Zhang &rgb->blue_reg)) { 398fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 399fcd2f4bfSAmy Zhang return false; 400fcd2f4bfSAmy Zhang } 401fcd2f4bfSAmy Zhang 402bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_red, &fmt, 403fcd2f4bfSAmy Zhang &rgb->delta_red_reg)) { 404fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 405fcd2f4bfSAmy Zhang return false; 406fcd2f4bfSAmy Zhang } 407fcd2f4bfSAmy Zhang 408bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_green, &fmt, 409fcd2f4bfSAmy Zhang &rgb->delta_green_reg)) { 410fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 411fcd2f4bfSAmy Zhang return false; 412fcd2f4bfSAmy Zhang } 413fcd2f4bfSAmy Zhang 414bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_blue, &fmt, 415fcd2f4bfSAmy Zhang &rgb->delta_blue_reg)) { 416fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 417fcd2f4bfSAmy Zhang return false; 418fcd2f4bfSAmy Zhang } 419fcd2f4bfSAmy Zhang 420fcd2f4bfSAmy Zhang ++rgb; 421fcd2f4bfSAmy Zhang ++i; 422fcd2f4bfSAmy Zhang } 423fcd2f4bfSAmy Zhang 424fcd2f4bfSAmy Zhang return true; 425fcd2f4bfSAmy Zhang } 426fcd2f4bfSAmy Zhang 42708616da5SLeo (Sunpeng) Li #define MAX_LOW_POINT 25 4288f8372c7SKrunoslav Kovac #define NUMBER_REGIONS 16 4298f8372c7SKrunoslav Kovac #define NUMBER_SW_SEGMENTS 16 4308f8372c7SKrunoslav Kovac 431b310b081SHarry Wentland static bool 432b310b081SHarry Wentland dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, 433b310b081SHarry Wentland struct pwl_params *regamma_params) 434fcd2f4bfSAmy Zhang { 43523ae4f8eSAmy Zhang struct curve_points *arr_points; 43623ae4f8eSAmy Zhang struct pwl_result_data *rgb_resulted; 43723ae4f8eSAmy Zhang struct pwl_result_data *rgb; 43823ae4f8eSAmy Zhang struct pwl_result_data *rgb_plus_1; 439fcd2f4bfSAmy Zhang struct fixed31_32 y_r; 440fcd2f4bfSAmy Zhang struct fixed31_32 y_g; 441fcd2f4bfSAmy Zhang struct fixed31_32 y_b; 442fcd2f4bfSAmy Zhang struct fixed31_32 y1_min; 443fcd2f4bfSAmy Zhang struct fixed31_32 y3_max; 444fcd2f4bfSAmy Zhang 4458f8372c7SKrunoslav Kovac int32_t region_start, region_end; 4468f8372c7SKrunoslav Kovac uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points; 44723ae4f8eSAmy Zhang 448b310b081SHarry Wentland if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS) 44923ae4f8eSAmy Zhang return false; 45023ae4f8eSAmy Zhang 45123ae4f8eSAmy Zhang arr_points = regamma_params->arr_points; 45223ae4f8eSAmy Zhang rgb_resulted = regamma_params->rgb_resulted; 45323ae4f8eSAmy Zhang hw_points = 0; 454fcd2f4bfSAmy Zhang 455fcd2f4bfSAmy Zhang memset(regamma_params, 0, sizeof(struct pwl_params)); 456fcd2f4bfSAmy Zhang 457fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 458534db198SAmy Zhang /* 16 segments 459fcd2f4bfSAmy Zhang * segments are from 2^-11 to 2^5 460fcd2f4bfSAmy Zhang */ 46108616da5SLeo (Sunpeng) Li region_start = -11; 46208616da5SLeo (Sunpeng) Li region_end = region_start + NUMBER_REGIONS; 463fcd2f4bfSAmy Zhang 4648f8372c7SKrunoslav Kovac for (i = 0; i < NUMBER_REGIONS; i++) 4658f8372c7SKrunoslav Kovac seg_distr[i] = 4; 466534db198SAmy Zhang 467fcd2f4bfSAmy Zhang } else { 468534db198SAmy Zhang /* 10 segments 469fc6de1c5SLeo (Sunpeng) Li * segment is from 2^-10 to 2^1 470fc6de1c5SLeo (Sunpeng) Li * We include an extra segment for range [2^0, 2^1). This is to 471fc6de1c5SLeo (Sunpeng) Li * ensure that colors with normalized values of 1 don't miss the 472fc6de1c5SLeo (Sunpeng) Li * LUT. 473fcd2f4bfSAmy Zhang */ 4748f8372c7SKrunoslav Kovac region_start = -10; 475fc6de1c5SLeo (Sunpeng) Li region_end = 1; 476534db198SAmy Zhang 4778f8372c7SKrunoslav Kovac seg_distr[0] = 4; 478534db198SAmy Zhang seg_distr[1] = 4; 479534db198SAmy Zhang seg_distr[2] = 4; 480534db198SAmy Zhang seg_distr[3] = 4; 481534db198SAmy Zhang seg_distr[4] = 4; 482534db198SAmy Zhang seg_distr[5] = 4; 483534db198SAmy Zhang seg_distr[6] = 4; 484534db198SAmy Zhang seg_distr[7] = 4; 4858f8372c7SKrunoslav Kovac seg_distr[8] = 4; 4868f8372c7SKrunoslav Kovac seg_distr[9] = 4; 487fc6de1c5SLeo (Sunpeng) Li seg_distr[10] = 0; 488534db198SAmy Zhang seg_distr[11] = -1; 489534db198SAmy Zhang seg_distr[12] = -1; 490534db198SAmy Zhang seg_distr[13] = -1; 491534db198SAmy Zhang seg_distr[14] = -1; 492534db198SAmy Zhang seg_distr[15] = -1; 493fcd2f4bfSAmy Zhang } 494fcd2f4bfSAmy Zhang 495534db198SAmy Zhang for (k = 0; k < 16; k++) { 496534db198SAmy Zhang if (seg_distr[k] != -1) 497534db198SAmy Zhang hw_points += (1 << seg_distr[k]); 498534db198SAmy Zhang } 499534db198SAmy Zhang 500fcd2f4bfSAmy Zhang j = 0; 5018f8372c7SKrunoslav Kovac for (k = 0; k < (region_end - region_start); k++) { 502ec47734aSLeo (Sunpeng) Li increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 5038f8372c7SKrunoslav Kovac start_index = (region_start + k + MAX_LOW_POINT) * 5048f8372c7SKrunoslav Kovac NUMBER_SW_SEGMENTS; 5058f8372c7SKrunoslav Kovac for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 5068f8372c7SKrunoslav Kovac i += increment) { 507534db198SAmy Zhang if (j == hw_points - 1) 508fcd2f4bfSAmy Zhang break; 509fcd2f4bfSAmy Zhang rgb_resulted[j].red = output_tf->tf_pts.red[i]; 510fcd2f4bfSAmy Zhang rgb_resulted[j].green = output_tf->tf_pts.green[i]; 511fcd2f4bfSAmy Zhang rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 512fcd2f4bfSAmy Zhang j++; 513fcd2f4bfSAmy Zhang } 514534db198SAmy Zhang } 515534db198SAmy Zhang 516534db198SAmy Zhang /* last point */ 5178f8372c7SKrunoslav Kovac start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 518b310b081SHarry Wentland rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 519b310b081SHarry Wentland rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 520b310b081SHarry Wentland rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 521fcd2f4bfSAmy Zhang 522eb0e5154SDmytro Laktyushkin arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2), 523eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_start)); 524eb0e5154SDmytro Laktyushkin arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2), 525eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_end)); 526fcd2f4bfSAmy Zhang 527fcd2f4bfSAmy Zhang y_r = rgb_resulted[0].red; 528fcd2f4bfSAmy Zhang y_g = rgb_resulted[0].green; 529fcd2f4bfSAmy Zhang y_b = rgb_resulted[0].blue; 530fcd2f4bfSAmy Zhang 531eb0e5154SDmytro Laktyushkin y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b)); 532fcd2f4bfSAmy Zhang 533fcd2f4bfSAmy Zhang arr_points[0].y = y1_min; 534eb0e5154SDmytro Laktyushkin arr_points[0].slope = dc_fixpt_div(arr_points[0].y, 535fcd2f4bfSAmy Zhang arr_points[0].x); 536fcd2f4bfSAmy Zhang 537fcd2f4bfSAmy Zhang y_r = rgb_resulted[hw_points - 1].red; 538fcd2f4bfSAmy Zhang y_g = rgb_resulted[hw_points - 1].green; 539fcd2f4bfSAmy Zhang y_b = rgb_resulted[hw_points - 1].blue; 540fcd2f4bfSAmy Zhang 541fcd2f4bfSAmy Zhang /* see comment above, m_arrPoints[1].y should be the Y value for the 542fcd2f4bfSAmy Zhang * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 543fcd2f4bfSAmy Zhang */ 544eb0e5154SDmytro Laktyushkin y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b)); 545fcd2f4bfSAmy Zhang 546fcd2f4bfSAmy Zhang arr_points[1].y = y3_max; 547fcd2f4bfSAmy Zhang 548eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_zero; 549fcd2f4bfSAmy Zhang 550fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 551fcd2f4bfSAmy Zhang /* for PQ, we want to have a straight line from last HW X point, 552fcd2f4bfSAmy Zhang * and the slope to be such that we hit 1.0 at 10000 nits. 553fcd2f4bfSAmy Zhang */ 554eb0e5154SDmytro Laktyushkin const struct fixed31_32 end_value = dc_fixpt_from_int(125); 555fcd2f4bfSAmy Zhang 556eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_div( 557eb0e5154SDmytro Laktyushkin dc_fixpt_sub(dc_fixpt_one, arr_points[1].y), 558eb0e5154SDmytro Laktyushkin dc_fixpt_sub(end_value, arr_points[1].x)); 559fcd2f4bfSAmy Zhang } 560fcd2f4bfSAmy Zhang 561fcd2f4bfSAmy Zhang regamma_params->hw_points_num = hw_points; 562fcd2f4bfSAmy Zhang 56369133b89SAric Cyr k = 0; 56469133b89SAric Cyr for (i = 1; i < 16; i++) { 565534db198SAmy Zhang if (seg_distr[k] != -1) { 566b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 567534db198SAmy Zhang regamma_params->arr_curve_points[i].offset = 568b310b081SHarry Wentland regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 569fcd2f4bfSAmy Zhang } 57069133b89SAric Cyr k++; 571534db198SAmy Zhang } 572534db198SAmy Zhang 573534db198SAmy Zhang if (seg_distr[k] != -1) 574b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 575fcd2f4bfSAmy Zhang 57623ae4f8eSAmy Zhang rgb = rgb_resulted; 57723ae4f8eSAmy Zhang rgb_plus_1 = rgb_resulted + 1; 578fcd2f4bfSAmy Zhang 579fcd2f4bfSAmy Zhang i = 1; 580fcd2f4bfSAmy Zhang 581fcd2f4bfSAmy Zhang while (i != hw_points + 1) { 582eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) 583fcd2f4bfSAmy Zhang rgb_plus_1->red = rgb->red; 584eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) 585fcd2f4bfSAmy Zhang rgb_plus_1->green = rgb->green; 586eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) 587fcd2f4bfSAmy Zhang rgb_plus_1->blue = rgb->blue; 588fcd2f4bfSAmy Zhang 589eb0e5154SDmytro Laktyushkin rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); 590eb0e5154SDmytro Laktyushkin rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 591eb0e5154SDmytro Laktyushkin rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 592fcd2f4bfSAmy Zhang 593fcd2f4bfSAmy Zhang ++rgb_plus_1; 594fcd2f4bfSAmy Zhang ++rgb; 595fcd2f4bfSAmy Zhang ++i; 596fcd2f4bfSAmy Zhang } 597fcd2f4bfSAmy Zhang 598fcd2f4bfSAmy Zhang convert_to_custom_float(rgb_resulted, arr_points, hw_points); 599fcd2f4bfSAmy Zhang 600fcd2f4bfSAmy Zhang return true; 601fcd2f4bfSAmy Zhang } 602fcd2f4bfSAmy Zhang 603a6114e85SHarry Wentland static bool 60478c77382SAnthony Koo dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 6050971c40eSHarry Wentland const struct dc_stream_state *stream) 60690e508baSAnthony Koo { 60786a66c4eSHarry Wentland struct transform *xfm = pipe_ctx->plane_res.xfm; 6084562236bSHarry Wentland 6097a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, true); 6107a09f5beSYue Hin Lau xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 6114562236bSHarry Wentland 6124fa086b9SLeo (Sunpeng) Li if (stream->out_transfer_func && 613efd52204SHarry Wentland stream->out_transfer_func->type == TF_TYPE_PREDEFINED && 614efd52204SHarry Wentland stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) { 6157a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 616efd52204SHarry Wentland } else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func, 617efd52204SHarry Wentland &xfm->regamma_params)) { 6187a09f5beSYue Hin Lau xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 6197a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 6204562236bSHarry Wentland } else { 6217a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 6224562236bSHarry Wentland } 6234562236bSHarry Wentland 6247a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, false); 6254562236bSHarry Wentland 626cc0cb445SLeon Elazar return true; 6274562236bSHarry Wentland } 6284562236bSHarry Wentland 6294562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 6304562236bSHarry Wentland { 63102553f57SEric Bernstein bool is_hdmi_tmds; 6326f0db2dcSKrunoslav Kovac bool is_dp; 6336f0db2dcSKrunoslav Kovac 63486e2e1beSHersen Wu ASSERT(pipe_ctx->stream); 63586e2e1beSHersen Wu 6368e9c4c8cSHarry Wentland if (pipe_ctx->stream_res.stream_enc == NULL) 63786e2e1beSHersen Wu return; /* this is not root pipe */ 63886e2e1beSHersen Wu 63902553f57SEric Bernstein is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal); 6406f0db2dcSKrunoslav Kovac is_dp = dc_is_dp_signal(pipe_ctx->stream->signal); 6416f0db2dcSKrunoslav Kovac 64202553f57SEric Bernstein if (!is_hdmi_tmds && !is_dp) 6436f0db2dcSKrunoslav Kovac return; 6446f0db2dcSKrunoslav Kovac 64502553f57SEric Bernstein if (is_hdmi_tmds) 6468e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 6478e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 64896c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6496f0db2dcSKrunoslav Kovac else 6508e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 6518e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 65296c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6534562236bSHarry Wentland } 6544562236bSHarry Wentland 6554562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 6564562236bSHarry Wentland { 6574562236bSHarry Wentland enum dc_lane_count lane_count = 658ceb3dbb4SJun Lei pipe_ctx->stream->link->cur_link_settings.lane_count; 6594fa086b9SLeo (Sunpeng) Li struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 660ceb3dbb4SJun Lei struct dc_link *link = pipe_ctx->stream->link; 661f42ea55bSAnthony Koo const struct dc *dc = link->dc; 662f215a57dSEric Yang 6634562236bSHarry Wentland uint32_t active_total_with_borders; 6644562236bSHarry Wentland uint32_t early_control = 0; 6656b670fa9SHarry Wentland struct timing_generator *tg = pipe_ctx->stream_res.tg; 6664562236bSHarry Wentland 667f215a57dSEric Yang /* For MST, there are multiply stream go to only one link. 668f215a57dSEric Yang * connect DIG back_end to front_end while enable_stream and 669f215a57dSEric Yang * disconnect them during disable_stream 670f215a57dSEric Yang * BY this, it is logic clean to separate stream and link */ 671f215a57dSEric Yang link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 672f215a57dSEric Yang pipe_ctx->stream_res.stream_enc->id, true); 673f215a57dSEric Yang 674f42ea55bSAnthony Koo dc->hwss.update_info_frame(pipe_ctx); 675f215a57dSEric Yang 6764562236bSHarry Wentland /* enable early control to avoid corruption on DP monitor*/ 6774562236bSHarry Wentland active_total_with_borders = 6784562236bSHarry Wentland timing->h_addressable 6794562236bSHarry Wentland + timing->h_border_left 6804562236bSHarry Wentland + timing->h_border_right; 6814562236bSHarry Wentland 6824562236bSHarry Wentland if (lane_count != 0) 6834562236bSHarry Wentland early_control = active_total_with_borders % lane_count; 6844562236bSHarry Wentland 6854562236bSHarry Wentland if (early_control == 0) 6864562236bSHarry Wentland early_control = lane_count; 6874562236bSHarry Wentland 6884562236bSHarry Wentland tg->funcs->set_early_control(tg, early_control); 6894562236bSHarry Wentland 6904562236bSHarry Wentland /* enable audio only within mode set */ 691afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 6924562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 6938e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); 6944562236bSHarry Wentland } 6954562236bSHarry Wentland 696f215a57dSEric Yang 697f215a57dSEric Yang 6984562236bSHarry Wentland 6994562236bSHarry Wentland } 7004562236bSHarry Wentland 7015eefbc40SYue Hin Lau static enum bp_result link_transmitter_control( 70287401969SAndrew Jiang struct dc_bios *bios, 7035eefbc40SYue Hin Lau struct bp_transmitter_control *cntl) 7045eefbc40SYue Hin Lau { 7055eefbc40SYue Hin Lau enum bp_result result; 7065eefbc40SYue Hin Lau 70787401969SAndrew Jiang result = bios->funcs->transmitter_control(bios, cntl); 7085eefbc40SYue Hin Lau 7095eefbc40SYue Hin Lau return result; 7105eefbc40SYue Hin Lau } 7115eefbc40SYue Hin Lau 71287401969SAndrew Jiang /* 71387401969SAndrew Jiang * @brief 71487401969SAndrew Jiang * eDP only. 71587401969SAndrew Jiang */ 7168a31820bSMartin Leung void dce110_edp_wait_for_hpd_ready( 717069d418fSAndrew Jiang struct dc_link *link, 71887401969SAndrew Jiang bool power_up) 71987401969SAndrew Jiang { 720069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 721069d418fSAndrew Jiang struct graphics_object_id connector = link->link_enc->connector; 72287401969SAndrew Jiang struct gpio *hpd; 72387401969SAndrew Jiang bool edp_hpd_high = false; 72487401969SAndrew Jiang uint32_t time_elapsed = 0; 72587401969SAndrew Jiang uint32_t timeout = power_up ? 72687401969SAndrew Jiang PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; 72787401969SAndrew Jiang 72887401969SAndrew Jiang if (dal_graphics_object_id_get_connector_id(connector) 72987401969SAndrew Jiang != CONNECTOR_ID_EDP) { 73087401969SAndrew Jiang BREAK_TO_DEBUGGER(); 73187401969SAndrew Jiang return; 73287401969SAndrew Jiang } 73387401969SAndrew Jiang 73487401969SAndrew Jiang if (!power_up) 73587401969SAndrew Jiang /* 73687401969SAndrew Jiang * From KV, we will not HPD low after turning off VCC - 73787401969SAndrew Jiang * instead, we will check the SW timer in power_up(). 73887401969SAndrew Jiang */ 73987401969SAndrew Jiang return; 74087401969SAndrew Jiang 74187401969SAndrew Jiang /* 74287401969SAndrew Jiang * When we power on/off the eDP panel, 74387401969SAndrew Jiang * we need to wait until SENSE bit is high/low. 74487401969SAndrew Jiang */ 74587401969SAndrew Jiang 74687401969SAndrew Jiang /* obtain HPD */ 74787401969SAndrew Jiang /* TODO what to do with this? */ 74887401969SAndrew Jiang hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); 74987401969SAndrew Jiang 75087401969SAndrew Jiang if (!hpd) { 75187401969SAndrew Jiang BREAK_TO_DEBUGGER(); 75287401969SAndrew Jiang return; 75387401969SAndrew Jiang } 75487401969SAndrew Jiang 75587401969SAndrew Jiang dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); 75687401969SAndrew Jiang 75787401969SAndrew Jiang /* wait until timeout or panel detected */ 75887401969SAndrew Jiang 75987401969SAndrew Jiang do { 76087401969SAndrew Jiang uint32_t detected = 0; 76187401969SAndrew Jiang 76287401969SAndrew Jiang dal_gpio_get_value(hpd, &detected); 76387401969SAndrew Jiang 76487401969SAndrew Jiang if (!(detected ^ power_up)) { 76587401969SAndrew Jiang edp_hpd_high = true; 76687401969SAndrew Jiang break; 76787401969SAndrew Jiang } 76887401969SAndrew Jiang 76987401969SAndrew Jiang msleep(HPD_CHECK_INTERVAL); 77087401969SAndrew Jiang 77187401969SAndrew Jiang time_elapsed += HPD_CHECK_INTERVAL; 77287401969SAndrew Jiang } while (time_elapsed < timeout); 77387401969SAndrew Jiang 77487401969SAndrew Jiang dal_gpio_close(hpd); 77587401969SAndrew Jiang 77687401969SAndrew Jiang dal_gpio_destroy_irq(&hpd); 77787401969SAndrew Jiang 77887401969SAndrew Jiang if (false == edp_hpd_high) { 7791296423bSBhawanpreet Lakha DC_LOG_ERROR( 78087401969SAndrew Jiang "%s: wait timed out!\n", __func__); 78187401969SAndrew Jiang } 78287401969SAndrew Jiang } 78387401969SAndrew Jiang 7848a31820bSMartin Leung void dce110_edp_power_control( 785069d418fSAndrew Jiang struct dc_link *link, 78687401969SAndrew Jiang bool power_up) 78787401969SAndrew Jiang { 788069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 78987401969SAndrew Jiang struct bp_transmitter_control cntl = { 0 }; 79087401969SAndrew Jiang enum bp_result bp_result; 79187401969SAndrew Jiang 79287401969SAndrew Jiang 793069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 79487401969SAndrew Jiang != CONNECTOR_ID_EDP) { 79587401969SAndrew Jiang BREAK_TO_DEBUGGER(); 79687401969SAndrew Jiang return; 79787401969SAndrew Jiang } 79887401969SAndrew Jiang 799ffadb9d6SAnthony Koo if (!link->panel_cntl) 800904fb6e0SAnthony Koo return; 801904fb6e0SAnthony Koo 802d4caa72eSAnthony Koo if (power_up != 803d4caa72eSAnthony Koo link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) { 80487401969SAndrew Jiang /* Send VBIOS command to prompt eDP panel power */ 80578d5d04dSCharlene Liu if (power_up) { 80678d5d04dSCharlene Liu unsigned long long current_ts = dm_get_timestamp(ctx); 80778d5d04dSCharlene Liu unsigned long long duration_in_ms = 80893ed1814SHugo Hu div64_u64(dm_get_elapse_time_in_ns( 80978d5d04dSCharlene Liu ctx, 81078d5d04dSCharlene Liu current_ts, 81193ed1814SHugo Hu link->link_trace.time_stamp.edp_poweroff), 1000000); 81278d5d04dSCharlene Liu unsigned long long wait_time_ms = 0; 81378d5d04dSCharlene Liu 81478d5d04dSCharlene Liu /* max 500ms from LCDVDD off to on */ 8156c4fff06SYue Hin Lau unsigned long long edp_poweroff_time_ms = 500; 816ff587987SHugo Hu 8176c4fff06SYue Hin Lau if (link->local_sink != NULL) 8186c4fff06SYue Hin Lau edp_poweroff_time_ms = 8196c4fff06SYue Hin Lau 500 + link->local_sink->edid_caps.panel_patch.extra_t12_ms; 82078d5d04dSCharlene Liu if (link->link_trace.time_stamp.edp_poweroff == 0) 821ff587987SHugo Hu wait_time_ms = edp_poweroff_time_ms; 822ff587987SHugo Hu else if (duration_in_ms < edp_poweroff_time_ms) 823ff587987SHugo Hu wait_time_ms = edp_poweroff_time_ms - duration_in_ms; 82478d5d04dSCharlene Liu 82578d5d04dSCharlene Liu if (wait_time_ms) { 82678d5d04dSCharlene Liu msleep(wait_time_ms); 82778d5d04dSCharlene Liu dm_output_to_console("%s: wait %lld ms to power on eDP.\n", 82878d5d04dSCharlene Liu __func__, wait_time_ms); 82978d5d04dSCharlene Liu } 83078d5d04dSCharlene Liu 83178d5d04dSCharlene Liu } 83287401969SAndrew Jiang 8331296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 83487401969SAndrew Jiang "%s: Panel Power action: %s\n", 83587401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 83687401969SAndrew Jiang 83787401969SAndrew Jiang cntl.action = power_up ? 83887401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_ON : 83987401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_OFF; 840069d418fSAndrew Jiang cntl.transmitter = link->link_enc->transmitter; 841069d418fSAndrew Jiang cntl.connector_obj_id = link->link_enc->connector; 84287401969SAndrew Jiang cntl.coherent = false; 84387401969SAndrew Jiang cntl.lanes_number = LANE_COUNT_FOUR; 844069d418fSAndrew Jiang cntl.hpd_sel = link->link_enc->hpd_source; 8458a0e210cSChris Park 8468a0e210cSChris Park if (ctx->dc->ctx->dmub_srv && 8478a0e210cSChris Park ctx->dc->debug.dmub_command_table) { 8488a0e210cSChris Park if (cntl.action == TRANSMITTER_CONTROL_POWER_ON) 8498a0e210cSChris Park bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 8508a0e210cSChris Park LVTMA_CONTROL_POWER_ON); 8518a0e210cSChris Park else 8528a0e210cSChris Park bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 8538a0e210cSChris Park LVTMA_CONTROL_POWER_OFF); 8548a0e210cSChris Park } 8558a0e210cSChris Park 85687401969SAndrew Jiang bp_result = link_transmitter_control(ctx->dc_bios, &cntl); 85787401969SAndrew Jiang 85878d5d04dSCharlene Liu if (!power_up) 85978d5d04dSCharlene Liu /*save driver power off time stamp*/ 86078d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx); 86178d5d04dSCharlene Liu else 86278d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweron = dm_get_timestamp(ctx); 86378d5d04dSCharlene Liu 86487401969SAndrew Jiang if (bp_result != BP_RESULT_OK) 8651296423bSBhawanpreet Lakha DC_LOG_ERROR( 86687401969SAndrew Jiang "%s: Panel Power bp_result: %d\n", 86787401969SAndrew Jiang __func__, bp_result); 86887401969SAndrew Jiang } else { 8691296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 87087401969SAndrew Jiang "%s: Skipping Panel Power action: %s\n", 87187401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 87287401969SAndrew Jiang } 87387401969SAndrew Jiang } 8745eefbc40SYue Hin Lau 8755eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/ 8765eefbc40SYue Hin Lau /* 8775eefbc40SYue Hin Lau * @brief 8785eefbc40SYue Hin Lau * eDP only. Control the backlight of the eDP panel 8795eefbc40SYue Hin Lau */ 8808a31820bSMartin Leung void dce110_edp_backlight_control( 8815eefbc40SYue Hin Lau struct dc_link *link, 8825eefbc40SYue Hin Lau bool enable) 8835eefbc40SYue Hin Lau { 884069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 8855eefbc40SYue Hin Lau struct bp_transmitter_control cntl = { 0 }; 8865eefbc40SYue Hin Lau 887069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 8885eefbc40SYue Hin Lau != CONNECTOR_ID_EDP) { 8895eefbc40SYue Hin Lau BREAK_TO_DEBUGGER(); 8905eefbc40SYue Hin Lau return; 8915eefbc40SYue Hin Lau } 8925eefbc40SYue Hin Lau 893d4caa72eSAnthony Koo if (enable && link->panel_cntl && 894d4caa72eSAnthony Koo link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl)) { 8951296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 8965eefbc40SYue Hin Lau "%s: panel already powered up. Do nothing.\n", 8975eefbc40SYue Hin Lau __func__); 8985eefbc40SYue Hin Lau return; 8995eefbc40SYue Hin Lau } 9005eefbc40SYue Hin Lau 9015eefbc40SYue Hin Lau /* Send VBIOS command to control eDP panel backlight */ 9025eefbc40SYue Hin Lau 9031296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 9045eefbc40SYue Hin Lau "%s: backlight action: %s\n", 9055eefbc40SYue Hin Lau __func__, (enable ? "On":"Off")); 9065eefbc40SYue Hin Lau 9075eefbc40SYue Hin Lau cntl.action = enable ? 9085eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_ON : 9095eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_OFF; 91087401969SAndrew Jiang 9115eefbc40SYue Hin Lau /*cntl.engine_id = ctx->engine;*/ 9125eefbc40SYue Hin Lau cntl.transmitter = link->link_enc->transmitter; 9135eefbc40SYue Hin Lau cntl.connector_obj_id = link->link_enc->connector; 9145eefbc40SYue Hin Lau /*todo: unhardcode*/ 9155eefbc40SYue Hin Lau cntl.lanes_number = LANE_COUNT_FOUR; 9165eefbc40SYue Hin Lau cntl.hpd_sel = link->link_enc->hpd_source; 917cf1835f0SCharlene Liu cntl.signal = SIGNAL_TYPE_EDP; 9185eefbc40SYue Hin Lau 9195eefbc40SYue Hin Lau /* For eDP, the following delays might need to be considered 9205eefbc40SYue Hin Lau * after link training completed: 9215eefbc40SYue Hin Lau * idle period - min. accounts for required BS-Idle pattern, 9225eefbc40SYue Hin Lau * max. allows for source frame synchronization); 9235eefbc40SYue Hin Lau * 50 msec max. delay from valid video data from source 9245eefbc40SYue Hin Lau * to video on dislpay or backlight enable. 9255eefbc40SYue Hin Lau * 9265eefbc40SYue Hin Lau * Disable the delay for now. 9275eefbc40SYue Hin Lau * Enable it in the future if necessary. 9285eefbc40SYue Hin Lau */ 9295eefbc40SYue Hin Lau /* dc_service_sleep_in_milliseconds(50); */ 9305180d4a4SCharlene Liu /*edp 1.2*/ 9315180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 9325180d4a4SCharlene Liu edp_receiver_ready_T7(link); 9338a0e210cSChris Park 9348a0e210cSChris Park if (ctx->dc->ctx->dmub_srv && 9358a0e210cSChris Park ctx->dc->debug.dmub_command_table) { 9368a0e210cSChris Park if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 9378a0e210cSChris Park ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 9388a0e210cSChris Park LVTMA_CONTROL_LCD_BLON); 9398a0e210cSChris Park else 9408a0e210cSChris Park ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 9418a0e210cSChris Park LVTMA_CONTROL_LCD_BLOFF); 9428a0e210cSChris Park } 9438a0e210cSChris Park 944069d418fSAndrew Jiang link_transmitter_control(ctx->dc_bios, &cntl); 94596577cf8SHersen Wu 9468a0e210cSChris Park 9478a0e210cSChris Park 94896577cf8SHersen Wu if (enable && link->dpcd_sink_ext_caps.bits.oled) 94996577cf8SHersen Wu msleep(OLED_POST_T7_DELAY); 95096577cf8SHersen Wu 95196577cf8SHersen Wu if (link->dpcd_sink_ext_caps.bits.oled || 95296577cf8SHersen Wu link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || 95396577cf8SHersen Wu link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1) 95496577cf8SHersen Wu dc_link_backlight_enable_aux(link, enable); 95596577cf8SHersen Wu 95669b9723aSCharlene Liu /*edp 1.2*/ 9575180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) 95869b9723aSCharlene Liu edp_receiver_ready_T9(link); 95996577cf8SHersen Wu 96096577cf8SHersen Wu if (!enable && link->dpcd_sink_ext_caps.bits.oled) 96196577cf8SHersen Wu msleep(OLED_PRE_T11_DELAY); 9625eefbc40SYue Hin Lau } 9635eefbc40SYue Hin Lau 9641a05873fSAnthony Koo void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) 9654562236bSHarry Wentland { 9661a05873fSAnthony Koo /* notify audio driver for audio modes of monitor */ 9672b77dcc5SAnthony Koo struct dc *dc; 9681d0610bcSAlvin Lee struct clk_mgr *clk_mgr; 9691a05873fSAnthony Koo unsigned int i, num_audio = 1; 9701a05873fSAnthony Koo 9711d0610bcSAlvin Lee if (!pipe_ctx->stream) 9721d0610bcSAlvin Lee return; 9731d0610bcSAlvin Lee 9742b77dcc5SAnthony Koo dc = pipe_ctx->stream->ctx->dc; 9752b77dcc5SAnthony Koo clk_mgr = dc->clk_mgr; 9761d0610bcSAlvin Lee 9770a32df9cSEryk Brol if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true) 9780a32df9cSEryk Brol return; 9790a32df9cSEryk Brol 9801a05873fSAnthony Koo if (pipe_ctx->stream_res.audio) { 9811a05873fSAnthony Koo for (i = 0; i < MAX_PIPES; i++) { 9821a05873fSAnthony Koo /*current_state not updated yet*/ 9832b77dcc5SAnthony Koo if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) 9841a05873fSAnthony Koo num_audio++; 9851a05873fSAnthony Koo } 9861a05873fSAnthony Koo 9871a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); 9881a05873fSAnthony Koo 989170a2398SSu Sung Chung if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) 9901a05873fSAnthony Koo /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 991170a2398SSu Sung Chung clk_mgr->funcs->enable_pme_wa(clk_mgr); 9921a05873fSAnthony Koo /* un-mute audio */ 9931a05873fSAnthony Koo /* TODO: audio should be per stream rather than per link */ 9941a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 9951a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, false); 9960a32df9cSEryk Brol if (pipe_ctx->stream_res.audio) 9970a32df9cSEryk Brol pipe_ctx->stream_res.audio->enabled = true; 9981a05873fSAnthony Koo } 9991a05873fSAnthony Koo } 10001a05873fSAnthony Koo 100157430404SSu Sung Chung void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) 10021a05873fSAnthony Koo { 10031d0610bcSAlvin Lee struct dc *dc; 10041d0610bcSAlvin Lee struct clk_mgr *clk_mgr; 10051d0610bcSAlvin Lee 10061d0610bcSAlvin Lee if (!pipe_ctx || !pipe_ctx->stream) 10071d0610bcSAlvin Lee return; 10081d0610bcSAlvin Lee 10091d0610bcSAlvin Lee dc = pipe_ctx->stream->ctx->dc; 10101d0610bcSAlvin Lee clk_mgr = dc->clk_mgr; 10114562236bSHarry Wentland 10120a32df9cSEryk Brol if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false) 10130a32df9cSEryk Brol return; 10140a32df9cSEryk Brol 10152b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 10162b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc, true); 1017afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio) { 10183f52aa9fSNicholas Kazlauskas pipe_ctx->stream_res.audio->enabled = false; 10193f52aa9fSNicholas Kazlauskas 10204562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10218e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( 10228e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 10234562236bSHarry Wentland else 10248e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( 10258e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 102657430404SSu Sung Chung 1027170a2398SSu Sung Chung if (clk_mgr->funcs->enable_pme_wa) 1028070fe724SCharlene Liu /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1029170a2398SSu Sung Chung clk_mgr->funcs->enable_pme_wa(clk_mgr); 10304562236bSHarry Wentland 10314562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 10324562236bSHarry Wentland * add audio mode list change flag */ 10334562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 10344562236bSHarry Wentland * stream->stream_engine_id); 10354562236bSHarry Wentland */ 10364562236bSHarry Wentland } 10371a05873fSAnthony Koo } 10384562236bSHarry Wentland 103957430404SSu Sung Chung void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 10401a05873fSAnthony Koo { 10411a05873fSAnthony Koo struct dc_stream_state *stream = pipe_ctx->stream; 1042ceb3dbb4SJun Lei struct dc_link *link = stream->link; 10431a05873fSAnthony Koo struct dc *dc = pipe_ctx->stream->ctx->dc; 10441a05873fSAnthony Koo 1045ac42fd63SWenjing Liu if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { 10461a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 10471a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 1048ac42fd63SWenjing Liu pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute( 1049ac42fd63SWenjing Liu pipe_ctx->stream_res.stream_enc); 1050ac42fd63SWenjing Liu } 10511a05873fSAnthony Koo 10521a05873fSAnthony Koo if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10531a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 10541a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 10551a05873fSAnthony Koo 105657430404SSu Sung Chung dc->hwss.disable_audio_stream(pipe_ctx); 1057904623eeSYongqiang Sun 10584562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe( 10594562236bSHarry Wentland link->link_enc, 10608e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->id, 10614562236bSHarry Wentland false); 10624562236bSHarry Wentland 10634562236bSHarry Wentland } 10644562236bSHarry Wentland 10654562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 10664562236bSHarry Wentland struct dc_link_settings *link_settings) 10674562236bSHarry Wentland { 10684562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 106941b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 1070ceb3dbb4SJun Lei struct dc_link *link = stream->link; 1071f42ea55bSAnthony Koo struct dce_hwseq *hws = link->dc->hwseq; 10724562236bSHarry Wentland 10734562236bSHarry Wentland /* only 3 items below are used by unblank */ 10747fe538a4SCharlene Liu params.timing = pipe_ctx->stream->timing; 10754562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 107641b49742SCharlene Liu 107741b49742SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 10788e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); 107941b49742SCharlene Liu 108014d6f644SYongqiang Sun if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1081f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(link, true); 108214d6f644SYongqiang Sun } 108341b49742SCharlene Liu } 10842c850b7bSDmytro Laktyushkin 108541b49742SCharlene Liu void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 108641b49742SCharlene Liu { 108741b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 1088ceb3dbb4SJun Lei struct dc_link *link = stream->link; 1089f42ea55bSAnthony Koo struct dce_hwseq *hws = link->dc->hwseq; 109041b49742SCharlene Liu 1091ab892598SRoman Li if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1092f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(link, false); 10933ba01817SYongqiang Sun link->dc->hwss.set_abm_immediate_disable(pipe_ctx); 1094ab892598SRoman Li } 109541b49742SCharlene Liu 1096eec3303dSAric Cyr if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 109741b49742SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); 1098eec3303dSAric Cyr 1099eec3303dSAric Cyr /* 1100eec3303dSAric Cyr * After output is idle pattern some sinks need time to recognize the stream 1101eec3303dSAric Cyr * has changed or they enter protection state and hang. 1102eec3303dSAric Cyr */ 1103eec3303dSAric Cyr if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) 1104eec3303dSAric Cyr msleep(60); 1105eec3303dSAric Cyr } 1106eec3303dSAric Cyr 11074562236bSHarry Wentland } 11084562236bSHarry Wentland 110915e17335SCharlene Liu 111015e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 111115e17335SCharlene Liu { 11128e9c4c8cSHarry Wentland if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL) 11138e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 111415e17335SCharlene Liu } 111515e17335SCharlene Liu 11164562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 11174562236bSHarry Wentland { 11184562236bSHarry Wentland switch (crtc_id) { 11194562236bSHarry Wentland case CONTROLLER_ID_D0: 11204562236bSHarry Wentland return DTO_SOURCE_ID0; 11214562236bSHarry Wentland case CONTROLLER_ID_D1: 11224562236bSHarry Wentland return DTO_SOURCE_ID1; 11234562236bSHarry Wentland case CONTROLLER_ID_D2: 11244562236bSHarry Wentland return DTO_SOURCE_ID2; 11254562236bSHarry Wentland case CONTROLLER_ID_D3: 11264562236bSHarry Wentland return DTO_SOURCE_ID3; 11274562236bSHarry Wentland case CONTROLLER_ID_D4: 11284562236bSHarry Wentland return DTO_SOURCE_ID4; 11294562236bSHarry Wentland case CONTROLLER_ID_D5: 11304562236bSHarry Wentland return DTO_SOURCE_ID5; 11314562236bSHarry Wentland default: 11324562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 11334562236bSHarry Wentland } 11344562236bSHarry Wentland } 11354562236bSHarry Wentland 11364562236bSHarry Wentland static void build_audio_output( 1137ab8db3e1SAndrey Grodzovsky struct dc_state *state, 11384562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 11394562236bSHarry Wentland struct audio_output *audio_output) 11404562236bSHarry Wentland { 11410971c40eSHarry Wentland const struct dc_stream_state *stream = pipe_ctx->stream; 11428e9c4c8cSHarry Wentland audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id; 11434562236bSHarry Wentland 11444562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 11454562236bSHarry Wentland 11464562236bSHarry Wentland /* audio_crtc_info */ 11474562236bSHarry Wentland 11484562236bSHarry Wentland audio_output->crtc_info.h_total = 11494fa086b9SLeo (Sunpeng) Li stream->timing.h_total; 11504562236bSHarry Wentland 11514562236bSHarry Wentland /* 11524562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 11534562236bSHarry Wentland * need to specify actual active signal portion 11544562236bSHarry Wentland */ 11554562236bSHarry Wentland audio_output->crtc_info.h_active = 11564fa086b9SLeo (Sunpeng) Li stream->timing.h_addressable 11574fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_left 11584fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_right; 11594562236bSHarry Wentland 11604562236bSHarry Wentland audio_output->crtc_info.v_active = 11614fa086b9SLeo (Sunpeng) Li stream->timing.v_addressable 11624fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_top 11634fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_bottom; 11644562236bSHarry Wentland 11654562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 11664562236bSHarry Wentland 11674562236bSHarry Wentland audio_output->crtc_info.interlaced = 11684fa086b9SLeo (Sunpeng) Li stream->timing.flags.INTERLACE; 11694562236bSHarry Wentland 11704562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 117140fd9090SNevenko Stupar (stream->timing.pix_clk_100hz*100)/ 11724fa086b9SLeo (Sunpeng) Li (stream->timing.h_total*stream->timing.v_total); 11734562236bSHarry Wentland 11744562236bSHarry Wentland audio_output->crtc_info.color_depth = 11754fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth; 11764562236bSHarry Wentland 117740fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz = 117840fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 11794562236bSHarry Wentland 118040fd9090SNevenko Stupar audio_output->crtc_info.calculated_pixel_clock_100Hz = 118140fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 11824562236bSHarry Wentland 118387b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/ 11842166d9fbSCharlene Liu if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) && 118540fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz == 118640fd9090SNevenko Stupar (stream->timing.pix_clk_100hz)) { 118710688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 118840fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz = 118940fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz/2; 119040fd9090SNevenko Stupar audio_output->crtc_info.calculated_pixel_clock_100Hz = 119140fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2; 119287b58768SCharlene Liu 119387b58768SCharlene Liu } 119487b58768SCharlene Liu } 119587b58768SCharlene Liu 1196ed476602SAhzo if (state->clk_mgr && 1197ed476602SAhzo (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 1198ed476602SAhzo pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { 11994562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 12000de34efcSDmytro Laktyushkin state->clk_mgr->funcs->get_dp_ref_clk_frequency( 12010de34efcSDmytro Laktyushkin state->clk_mgr); 12024562236bSHarry Wentland } 12034562236bSHarry Wentland 12044562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 12054562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 12064562236bSHarry Wentland 12074562236bSHarry Wentland audio_output->pll_info.dto_source = 12084562236bSHarry Wentland translate_to_dto_source( 1209e07f541fSYongqiang Sun pipe_ctx->stream_res.tg->inst + 1); 12104562236bSHarry Wentland 12114562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 12124562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 12134562236bSHarry Wentland 12144562236bSHarry Wentland audio_output->pll_info.ss_percentage = 12154562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 12164562236bSHarry Wentland } 12174562236bSHarry Wentland 12184562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 12194562236bSHarry Wentland struct tg_color *color) 12204562236bSHarry Wentland { 12212a54bd6eSJerry (Fangzhi) Zuo uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4; 12224562236bSHarry Wentland 12236702a9acSHarry Wentland switch (pipe_ctx->plane_res.scl_data.format) { 12244562236bSHarry Wentland case PIXEL_FORMAT_ARGB8888: 12254562236bSHarry Wentland /* set boarder color to red */ 12264562236bSHarry Wentland color->color_r_cr = color_value; 12274562236bSHarry Wentland break; 12284562236bSHarry Wentland 12294562236bSHarry Wentland case PIXEL_FORMAT_ARGB2101010: 12304562236bSHarry Wentland /* set boarder color to blue */ 12314562236bSHarry Wentland color->color_b_cb = color_value; 12324562236bSHarry Wentland break; 123387449a90SAnthony Koo case PIXEL_FORMAT_420BPP8: 12344562236bSHarry Wentland /* set boarder color to green */ 12354562236bSHarry Wentland color->color_g_y = color_value; 12364562236bSHarry Wentland break; 123787449a90SAnthony Koo case PIXEL_FORMAT_420BPP10: 123887449a90SAnthony Koo /* set boarder color to yellow */ 123987449a90SAnthony Koo color->color_g_y = color_value; 124087449a90SAnthony Koo color->color_r_cr = color_value; 124187449a90SAnthony Koo break; 12424562236bSHarry Wentland case PIXEL_FORMAT_FP16: 12434562236bSHarry Wentland /* set boarder color to white */ 12444562236bSHarry Wentland color->color_r_cr = color_value; 12454562236bSHarry Wentland color->color_b_cb = color_value; 12464562236bSHarry Wentland color->color_g_y = color_value; 12474562236bSHarry Wentland break; 12484562236bSHarry Wentland default: 12494562236bSHarry Wentland break; 12504562236bSHarry Wentland } 12514562236bSHarry Wentland } 12524562236bSHarry Wentland 1253fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc, 12544562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 12554562236bSHarry Wentland { 12564562236bSHarry Wentland struct tg_color color = {0}; 12574562236bSHarry Wentland 1258b86a1aa3SBhawanpreet Lakha #if defined(CONFIG_DRM_AMD_DC_DCN) 1259ff5ef992SAlex Deucher /* TOFPGA */ 126086a66c4eSHarry Wentland if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) 1261ff5ef992SAlex Deucher return; 1262ff5ef992SAlex Deucher #endif 1263ff5ef992SAlex Deucher 1264bf53769dSGloria Li if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) 12654562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 12664562236bSHarry Wentland else 12674562236bSHarry Wentland color_space_to_black_color(dc, 12684fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space, 12694562236bSHarry Wentland &color); 12704562236bSHarry Wentland 127186a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 127286a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, 12736702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.depth, 12744562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 12754562236bSHarry Wentland 127612750d16SEric Yang if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) { 127712750d16SEric Yang /* 127812750d16SEric Yang * The way 420 is packed, 2 channels carry Y component, 1 channel 127912750d16SEric Yang * alternate between Cb and Cr, so both channels need the pixel 128012750d16SEric Yang * value for Y 128112750d16SEric Yang */ 128212750d16SEric Yang if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) 128312750d16SEric Yang color.color_r_cr = color.color_g_y; 128412750d16SEric Yang 12856b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 12866b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 12874562236bSHarry Wentland &color); 128812750d16SEric Yang } 12894562236bSHarry Wentland 129086a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 12916702a9acSHarry Wentland &pipe_ctx->plane_res.scl_data); 12924562236bSHarry Wentland } 12934562236bSHarry Wentland 12943158223eSEric Bernstein static enum dc_status dce110_enable_stream_timing( 12954562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1296608ac7bbSJerry Zuo struct dc_state *context, 1297fb3466a4SBhawanpreet Lakha struct dc *dc) 12984562236bSHarry Wentland { 12990971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1300608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 13014562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 13024562236bSHarry Wentland struct tg_color black_color = {0}; 13034562236bSHarry Wentland 13044562236bSHarry Wentland if (!pipe_ctx_old->stream) { 13054562236bSHarry Wentland 13064562236bSHarry Wentland /* program blank color */ 13074562236bSHarry Wentland color_space_to_black_color(dc, 13084fa086b9SLeo (Sunpeng) Li stream->output_color_space, &black_color); 13096b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank_color( 13106b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 13114562236bSHarry Wentland &black_color); 13124b5e7d62SHersen Wu 13134562236bSHarry Wentland /* 13144562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 13154562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 13164562236bSHarry Wentland */ 13176b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true); 13184562236bSHarry Wentland 13194562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 13204562236bSHarry Wentland pipe_ctx->clock_source, 132110688217SHarry Wentland &pipe_ctx->stream_res.pix_clk_params, 13224562236bSHarry Wentland &pipe_ctx->pll_settings)) { 13234562236bSHarry Wentland BREAK_TO_DEBUGGER(); 13244562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 13254562236bSHarry Wentland } 13264562236bSHarry Wentland 13276b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->program_timing( 13286b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 13294fa086b9SLeo (Sunpeng) Li &stream->timing, 1330e7e10c46SDmytro Laktyushkin 0, 1331e7e10c46SDmytro Laktyushkin 0, 1332e7e10c46SDmytro Laktyushkin 0, 1333e7e10c46SDmytro Laktyushkin 0, 1334e7e10c46SDmytro Laktyushkin pipe_ctx->stream->signal, 13354562236bSHarry Wentland true); 13364562236bSHarry Wentland } 13374562236bSHarry Wentland 13384562236bSHarry Wentland if (!pipe_ctx_old->stream) { 13396b670fa9SHarry Wentland if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc( 13406b670fa9SHarry Wentland pipe_ctx->stream_res.tg)) { 13414562236bSHarry Wentland BREAK_TO_DEBUGGER(); 13424562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 13434562236bSHarry Wentland } 13444562236bSHarry Wentland } 13454562236bSHarry Wentland 13464562236bSHarry Wentland return DC_OK; 13474562236bSHarry Wentland } 13484562236bSHarry Wentland 13494562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 13504562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1351608ac7bbSJerry Zuo struct dc_state *context, 1352fb3466a4SBhawanpreet Lakha struct dc *dc) 13534562236bSHarry Wentland { 13540971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 13559c0fb8d4SAnthony Koo struct drr_params params = {0}; 13569c0fb8d4SAnthony Koo unsigned int event_triggers = 0; 1357b1f6d01cSDmytro Laktyushkin struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; 1358f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 13594562236bSHarry Wentland 1360f42ea55bSAnthony Koo if (hws->funcs.disable_stream_gating) { 1361f42ea55bSAnthony Koo hws->funcs.disable_stream_gating(dc, pipe_ctx); 1362240d09d0SGary Kattan } 1363240d09d0SGary Kattan 13641a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 13651a05873fSAnthony Koo struct audio_output audio_output; 13661a05873fSAnthony Koo 13671a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 13681a05873fSAnthony Koo 13691a05873fSAnthony Koo if (dc_is_dp_signal(pipe_ctx->stream->signal)) 13701a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( 13711a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, 13721a05873fSAnthony Koo pipe_ctx->stream_res.audio->inst, 13731a05873fSAnthony Koo &pipe_ctx->stream->audio_info); 13741a05873fSAnthony Koo else 13751a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( 13761a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, 13771a05873fSAnthony Koo pipe_ctx->stream_res.audio->inst, 13781a05873fSAnthony Koo &pipe_ctx->stream->audio_info, 13791a05873fSAnthony Koo &audio_output.crtc_info); 13801a05873fSAnthony Koo 13811a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_configure( 13821a05873fSAnthony Koo pipe_ctx->stream_res.audio, 13831a05873fSAnthony Koo pipe_ctx->stream->signal, 13841a05873fSAnthony Koo &audio_output.crtc_info, 13851a05873fSAnthony Koo &pipe_ctx->stream->audio_info); 13861a05873fSAnthony Koo } 13871a05873fSAnthony Koo 13884562236bSHarry Wentland /* */ 1389d2d7885fSAnthony Koo /* Do not touch stream timing on seamless boot optimization. */ 1390d2d7885fSAnthony Koo if (!pipe_ctx->stream->apply_seamless_boot_optimization) 1391f42ea55bSAnthony Koo hws->funcs.enable_stream_timing(pipe_ctx, context, dc); 13924562236bSHarry Wentland 1393f42ea55bSAnthony Koo if (hws->funcs.setup_vupdate_interrupt) 1394f42ea55bSAnthony Koo hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx); 1395a122b62dSAnthony Koo 13969c0fb8d4SAnthony Koo params.vertical_total_min = stream->adjust.v_total_min; 13979c0fb8d4SAnthony Koo params.vertical_total_max = stream->adjust.v_total_max; 13989c0fb8d4SAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_drr) 13999c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg->funcs->set_drr( 14009c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg, ¶ms); 14019c0fb8d4SAnthony Koo 14029c0fb8d4SAnthony Koo // DRR should set trigger event to monitor surface update event 14039c0fb8d4SAnthony Koo if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0) 14049c0fb8d4SAnthony Koo event_triggers = 0x80; 14055b5abe95SAnthony Koo /* Event triggers and num frames initialized for DRR, but can be 14065b5abe95SAnthony Koo * later updated for PSR use. Note DRR trigger events are generated 14075b5abe95SAnthony Koo * regardless of whether num frames met. 14085b5abe95SAnthony Koo */ 14099c0fb8d4SAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control) 14109c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 14115b5abe95SAnthony Koo pipe_ctx->stream_res.tg, event_triggers, 2); 14129c0fb8d4SAnthony Koo 1413248cbed6SEric Bernstein if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) 1414d2c460e7Shersen wu pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( 1415d2c460e7Shersen wu pipe_ctx->stream_res.stream_enc, 1416d2c460e7Shersen wu pipe_ctx->stream_res.tg->inst); 1417aa9c4abeSNikola Cornij 1418f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1419f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp, 1420f0c4d997SCorbin McElhanney COLOR_SPACE_YCBCR601, 1421f0c4d997SCorbin McElhanney stream->timing.display_color_depth, 1422661a8cd9SDmytro Laktyushkin stream->signal); 14234562236bSHarry Wentland 1424a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1425a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 1426181a888fSCharlene Liu &stream->bit_depth_params, 1427181a888fSCharlene Liu &stream->clamping); 1428b1f6d01cSDmytro Laktyushkin while (odm_pipe) { 14297ed4e635SHarry Wentland odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion( 14307ed4e635SHarry Wentland odm_pipe->stream_res.opp, 14317ed4e635SHarry Wentland COLOR_SPACE_YCBCR601, 14327ed4e635SHarry Wentland stream->timing.display_color_depth, 14337ed4e635SHarry Wentland stream->signal); 14347ed4e635SHarry Wentland 14357ed4e635SHarry Wentland odm_pipe->stream_res.opp->funcs->opp_program_fmt( 14367ed4e635SHarry Wentland odm_pipe->stream_res.opp, 14377ed4e635SHarry Wentland &stream->bit_depth_params, 14387ed4e635SHarry Wentland &stream->clamping); 1439b1f6d01cSDmytro Laktyushkin odm_pipe = odm_pipe->next_odm_pipe; 14407ed4e635SHarry Wentland } 1441603767f9STony Cheng 14421e7e86c4SSamson Tam if (!stream->dpms_off) 1443ab8db3e1SAndrey Grodzovsky core_link_enable_stream(context, pipe_ctx); 14444562236bSHarry Wentland 14456702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 14464562236bSHarry Wentland 1447d1ebfdd8SWyatt Wood pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; 144894267b3dSSylvia Tsai 14494562236bSHarry Wentland return DC_OK; 14504562236bSHarry Wentland } 14514562236bSHarry Wentland 14524562236bSHarry Wentland /******************************************************************************/ 14534562236bSHarry Wentland 1454fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc) 14554562236bSHarry Wentland { 14564562236bSHarry Wentland int i; 1457b9b171ffSHersen Wu 1458b9b171ffSHersen Wu /* do not know BIOS back-front mapping, simply blank all. It will not 1459b9b171ffSHersen Wu * hurt for non-DP 1460b9b171ffSHersen Wu */ 1461b9b171ffSHersen Wu for (i = 0; i < dc->res_pool->stream_enc_count; i++) { 1462b9b171ffSHersen Wu dc->res_pool->stream_enc[i]->funcs->dp_blank( 1463b9b171ffSHersen Wu dc->res_pool->stream_enc[i]); 1464b9b171ffSHersen Wu } 1465b9b171ffSHersen Wu 14664562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 1467d4c2a96fSLewis Huang enum signal_type signal = dc->links[i]->connector_signal; 1468a0c38ebaSCharlene Liu 1469d4c2a96fSLewis Huang if ((signal == SIGNAL_TYPE_EDP) || 1470d4c2a96fSLewis Huang (signal == SIGNAL_TYPE_DISPLAY_PORT)) 1471a0c38ebaSCharlene Liu if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) 1472a0c38ebaSCharlene Liu dp_receiver_power_ctrl(dc->links[i], false); 1473a0c38ebaSCharlene Liu 14744338ffa8SSung Lee if (signal != SIGNAL_TYPE_EDP) 14754338ffa8SSung Lee signal = SIGNAL_TYPE_NONE; 14764338ffa8SSung Lee 14774562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 1478069d418fSAndrew Jiang dc->links[i]->link_enc, signal); 1479b56e90eaSPaul Hsieh 1480b56e90eaSPaul Hsieh dc->links[i]->link_status.link_active = false; 14814562236bSHarry Wentland } 14824562236bSHarry Wentland } 14834562236bSHarry Wentland 1484fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc) 14854562236bSHarry Wentland { 14864562236bSHarry Wentland int i; 14874562236bSHarry Wentland 14887f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 14894562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 14904562236bSHarry Wentland dc->res_pool->timing_generators[i]); 14914562236bSHarry Wentland } 14924562236bSHarry Wentland } 14934562236bSHarry Wentland 1494fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc) 14954562236bSHarry Wentland { 14964562236bSHarry Wentland int i; 14974562236bSHarry Wentland 14984562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 14994562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 15004562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 15014562236bSHarry Wentland 15024562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 15034562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 15044562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 15054562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 15064562236bSHarry Wentland } 15074562236bSHarry Wentland } 15084562236bSHarry Wentland 1509fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc) 15104562236bSHarry Wentland { 15114562236bSHarry Wentland power_down_encoders(dc); 15124562236bSHarry Wentland 15134562236bSHarry Wentland power_down_controllers(dc); 15144562236bSHarry Wentland 15154562236bSHarry Wentland power_down_clock_sources(dc); 15161663ae1cSBhawanpreet Lakha 15172f3bfb27SRoman Li if (dc->fbc_compressor) 15181663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 15194562236bSHarry Wentland } 15204562236bSHarry Wentland 15214562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 1522fb3466a4SBhawanpreet Lakha struct dc *dc) 15234562236bSHarry Wentland { 15244562236bSHarry Wentland int i; 15254562236bSHarry Wentland struct timing_generator *tg; 15264562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 15274562236bSHarry Wentland 15287f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 15294562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 15304562236bSHarry Wentland 15310a87425aSTony Cheng if (tg->funcs->disable_vga) 15324562236bSHarry Wentland tg->funcs->disable_vga(tg); 15337f93c1deSCharlene Liu } 15347f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->pipe_count; i++) { 15354562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 15364562236bSHarry Wentland * powergating. */ 15374562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 15384562236bSHarry Wentland true); 15394562236bSHarry Wentland 1540e6c258cbSYongqiang Sun dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i; 15417f914a62SYongqiang Sun dc->hwss.disable_plane(dc, 1542e6c258cbSYongqiang Sun &dc->current_state->res_ctx.pipe_ctx[i]); 15434562236bSHarry Wentland } 15444562236bSHarry Wentland } 15454562236bSHarry Wentland 15463de5aa81SSivapiriyanKumarasamy 15473de5aa81SSivapiriyanKumarasamy static struct dc_stream_state *get_edp_stream(struct dc_state *context) 15483de5aa81SSivapiriyanKumarasamy { 15493de5aa81SSivapiriyanKumarasamy int i; 15503de5aa81SSivapiriyanKumarasamy 15513de5aa81SSivapiriyanKumarasamy for (i = 0; i < context->stream_count; i++) { 15523de5aa81SSivapiriyanKumarasamy if (context->streams[i]->signal == SIGNAL_TYPE_EDP) 15533de5aa81SSivapiriyanKumarasamy return context->streams[i]; 15543de5aa81SSivapiriyanKumarasamy } 15553de5aa81SSivapiriyanKumarasamy return NULL; 15563de5aa81SSivapiriyanKumarasamy } 15573de5aa81SSivapiriyanKumarasamy 1558be4b289fSSivapiriyanKumarasamy static struct dc_link *get_edp_link_with_sink( 155925292028SYongqiang Sun struct dc *dc, 156025292028SYongqiang Sun struct dc_state *context) 156125292028SYongqiang Sun { 156225292028SYongqiang Sun int i; 156325292028SYongqiang Sun struct dc_link *link = NULL; 156425292028SYongqiang Sun 156525292028SYongqiang Sun /* check if there is an eDP panel not in use */ 156625292028SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 156725292028SYongqiang Sun if (dc->links[i]->local_sink && 156825292028SYongqiang Sun dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 156925292028SYongqiang Sun link = dc->links[i]; 157025292028SYongqiang Sun break; 157125292028SYongqiang Sun } 157225292028SYongqiang Sun } 157325292028SYongqiang Sun 157425292028SYongqiang Sun return link; 157525292028SYongqiang Sun } 157625292028SYongqiang Sun 15774562236bSHarry Wentland /** 15784562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 15794562236bSHarry Wentland * 1. Power down all DC HW blocks 15804562236bSHarry Wentland * 2. Disable VGA engine on all controllers 15814562236bSHarry Wentland * 3. Enable power gating for controller 15824562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 15834562236bSHarry Wentland */ 158425292028SYongqiang Sun void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 15854562236bSHarry Wentland { 1586d82f9942SAnthony Koo int i; 1587be4b289fSSivapiriyanKumarasamy struct dc_link *edp_link_with_sink = get_edp_link_with_sink(dc, context); 1588be4b289fSSivapiriyanKumarasamy struct dc_link *edp_link = get_edp_link(dc); 15893de5aa81SSivapiriyanKumarasamy struct dc_stream_state *edp_stream = NULL; 1590be4b289fSSivapiriyanKumarasamy bool can_apply_edp_fast_boot = false; 1591ce72741bSAnthony Koo bool can_apply_seamless_boot = false; 15923de5aa81SSivapiriyanKumarasamy bool keep_edp_vdd_on = false; 1593f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 1594ce72741bSAnthony Koo 1595f42ea55bSAnthony Koo if (hws->funcs.init_pipes) 1596f42ea55bSAnthony Koo hws->funcs.init_pipes(dc, context); 1597be4b289fSSivapiriyanKumarasamy 15983de5aa81SSivapiriyanKumarasamy edp_stream = get_edp_stream(context); 15993de5aa81SSivapiriyanKumarasamy 1600be4b289fSSivapiriyanKumarasamy // Check fastboot support, disable on DCE8 because of blank screens 1601be4b289fSSivapiriyanKumarasamy if (edp_link && dc->ctx->dce_version != DCE_VERSION_8_0 && 1602be4b289fSSivapiriyanKumarasamy dc->ctx->dce_version != DCE_VERSION_8_1 && 1603be4b289fSSivapiriyanKumarasamy dc->ctx->dce_version != DCE_VERSION_8_3) { 1604be4b289fSSivapiriyanKumarasamy 1605be4b289fSSivapiriyanKumarasamy // enable fastboot if backend is enabled on eDP 1606be4b289fSSivapiriyanKumarasamy if (edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc)) { 16073de5aa81SSivapiriyanKumarasamy /* Set optimization flag on eDP stream*/ 16083de5aa81SSivapiriyanKumarasamy if (edp_stream) { 16093de5aa81SSivapiriyanKumarasamy edp_stream->apply_edp_fast_boot_optimization = true; 1610be4b289fSSivapiriyanKumarasamy can_apply_edp_fast_boot = true; 1611be4b289fSSivapiriyanKumarasamy } 1612be4b289fSSivapiriyanKumarasamy } 16133de5aa81SSivapiriyanKumarasamy 16143de5aa81SSivapiriyanKumarasamy // We are trying to enable eDP, don't power down VDD 16153de5aa81SSivapiriyanKumarasamy if (edp_stream) 16163de5aa81SSivapiriyanKumarasamy keep_edp_vdd_on = true; 1617be4b289fSSivapiriyanKumarasamy } 1618be4b289fSSivapiriyanKumarasamy 1619be4b289fSSivapiriyanKumarasamy // Check seamless boot support 1620ce72741bSAnthony Koo for (i = 0; i < context->stream_count; i++) { 1621ce72741bSAnthony Koo if (context->streams[i]->apply_seamless_boot_optimization) { 1622ce72741bSAnthony Koo can_apply_seamless_boot = true; 1623ce72741bSAnthony Koo break; 1624ce72741bSAnthony Koo } 1625ce72741bSAnthony Koo } 16264cac1e6dSYongqiang Sun 1627be4b289fSSivapiriyanKumarasamy /* eDP should not have stream in resume from S4 and so even with VBios post 1628be4b289fSSivapiriyanKumarasamy * it should get turned off 16292c37e49aSYongqiang Sun */ 1630be4b289fSSivapiriyanKumarasamy if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) { 16313de5aa81SSivapiriyanKumarasamy if (edp_link_with_sink && !keep_edp_vdd_on) { 16324cac1e6dSYongqiang Sun /*turn off backlight before DP_blank and encoder powered down*/ 1633f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(edp_link_with_sink, false); 1634c5fc7f59SCharlene Liu } 1635c5fc7f59SCharlene Liu /*resume from S3, no vbios posting, no need to power down again*/ 163625292028SYongqiang Sun power_down_all_hw_blocks(dc); 16374562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 16383de5aa81SSivapiriyanKumarasamy if (edp_link_with_sink && !keep_edp_vdd_on) 1639be4b289fSSivapiriyanKumarasamy dc->hwss.edp_power_control(edp_link_with_sink, false); 1640c5fc7f59SCharlene Liu } 16414562236bSHarry Wentland bios_set_scratch_acc_mode_change(dc->ctx->dc_bios); 16424562236bSHarry Wentland } 16434562236bSHarry Wentland 16444562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 16454562236bSHarry Wentland struct bw_fixed blackout_duration, 16460971c40eSHarry Wentland const struct dc_stream_state *stream) 16474562236bSHarry Wentland { 16484562236bSHarry Wentland uint32_t total_dest_line_time_ns; 16494562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 16504562236bSHarry Wentland 16514562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 16524562236bSHarry Wentland 16534562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 1654380604e2SKen Chalmers (stream->timing.h_total * 10) / 1655380604e2SKen Chalmers stream->timing.pix_clk_100hz + 16564562236bSHarry Wentland pstate_blackout_duration_ns; 16574562236bSHarry Wentland 16584562236bSHarry Wentland return total_dest_line_time_ns; 16594562236bSHarry Wentland } 16604562236bSHarry Wentland 1661f774b339SEric Yang static void dce110_set_displaymarks( 1662fb3466a4SBhawanpreet Lakha const struct dc *dc, 1663608ac7bbSJerry Zuo struct dc_state *context) 16644562236bSHarry Wentland { 16654562236bSHarry Wentland uint8_t i, num_pipes; 16664562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 16674562236bSHarry Wentland 16684562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 16694562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 16704562236bSHarry Wentland uint32_t total_dest_line_time_ns; 16714562236bSHarry Wentland 16724562236bSHarry Wentland if (pipe_ctx->stream == NULL) 16734562236bSHarry Wentland continue; 16744562236bSHarry Wentland 16754562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 167677a4ea53SBhawanpreet Lakha dc->bw_vbios->blackout_duration, pipe_ctx->stream); 167786a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( 167886a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 1679813d20dcSAidan Wood context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 1680813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 1681813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes], 1682813d20dcSAidan Wood context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 16834562236bSHarry Wentland total_dest_line_time_ns); 16844562236bSHarry Wentland if (i == underlay_idx) { 16854562236bSHarry Wentland num_pipes++; 168686a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( 168786a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 1688813d20dcSAidan Wood context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 1689813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 1690813d20dcSAidan Wood context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 16914562236bSHarry Wentland total_dest_line_time_ns); 16924562236bSHarry Wentland } 16934562236bSHarry Wentland num_pipes++; 16944562236bSHarry Wentland } 16954562236bSHarry Wentland } 16964562236bSHarry Wentland 1697fab55d61SDmytro Laktyushkin void dce110_set_safe_displaymarks( 1698a2b8659dSTony Cheng struct resource_context *res_ctx, 1699a2b8659dSTony Cheng const struct resource_pool *pool) 17004562236bSHarry Wentland { 17014562236bSHarry Wentland int i; 1702a2b8659dSTony Cheng int underlay_idx = pool->underlay_pipe_index; 17039037d802SDmytro Laktyushkin struct dce_watermarks max_marks = { 17044562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 17059037d802SDmytro Laktyushkin struct dce_watermarks nbp_marks = { 17064562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 17073722c794SMikita Lipski struct dce_watermarks min_marks = { 0, 0, 0, 0}; 17084562236bSHarry Wentland 17094562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 17108feabd03SYue Hin Lau if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) 17114562236bSHarry Wentland continue; 17124562236bSHarry Wentland 171386a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 171486a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 17154562236bSHarry Wentland nbp_marks, 17164562236bSHarry Wentland max_marks, 17173722c794SMikita Lipski min_marks, 17184562236bSHarry Wentland max_marks, 17194562236bSHarry Wentland MAX_WATERMARK); 17208feabd03SYue Hin Lau 17214562236bSHarry Wentland if (i == underlay_idx) 172286a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 172386a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 17244562236bSHarry Wentland nbp_marks, 17254562236bSHarry Wentland max_marks, 17264562236bSHarry Wentland max_marks, 17274562236bSHarry Wentland MAX_WATERMARK); 17288feabd03SYue Hin Lau 17294562236bSHarry Wentland } 17304562236bSHarry Wentland } 17314562236bSHarry Wentland 17324562236bSHarry Wentland /******************************************************************************* 17334562236bSHarry Wentland * Public functions 17344562236bSHarry Wentland ******************************************************************************/ 17354562236bSHarry Wentland 17364562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 1737470e2ca5SBayan Zabihiyan int num_pipes, unsigned int vmin, unsigned int vmax, 1738470e2ca5SBayan Zabihiyan unsigned int vmid, unsigned int vmid_frame_number) 17394562236bSHarry Wentland { 17404562236bSHarry Wentland int i = 0; 17414562236bSHarry Wentland struct drr_params params = {0}; 174298e6436dSAnthony Koo // DRR should set trigger event to monitor surface update event 174398e6436dSAnthony Koo unsigned int event_triggers = 0x80; 17445b5abe95SAnthony Koo // Note DRR trigger events are generated regardless of whether num frames met. 17455b5abe95SAnthony Koo unsigned int num_frames = 2; 17464562236bSHarry Wentland 17474562236bSHarry Wentland params.vertical_total_max = vmax; 17484562236bSHarry Wentland params.vertical_total_min = vmin; 17494562236bSHarry Wentland 17504562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 175198e6436dSAnthony Koo * some GSL stuff. Static screen triggers may be programmed differently 175298e6436dSAnthony Koo * as well. 17534562236bSHarry Wentland */ 17544562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 175598e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_drr( 175698e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, ¶ms); 175798e6436dSAnthony Koo 175898e6436dSAnthony Koo if (vmax != 0 && vmin != 0) 175998e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( 176098e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, 17615b5abe95SAnthony Koo event_triggers, num_frames); 17624562236bSHarry Wentland } 17634562236bSHarry Wentland } 17644562236bSHarry Wentland 176572ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx, 176672ada5f7SEric Cook int num_pipes, 176772ada5f7SEric Cook struct crtc_position *position) 176872ada5f7SEric Cook { 176972ada5f7SEric Cook int i = 0; 177072ada5f7SEric Cook 177172ada5f7SEric Cook /* TODO: handle pipes > 1 177272ada5f7SEric Cook */ 177372ada5f7SEric Cook for (i = 0; i < num_pipes; i++) 17746b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position); 177572ada5f7SEric Cook } 177672ada5f7SEric Cook 17774562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 17785b5abe95SAnthony Koo int num_pipes, const struct dc_static_screen_params *params) 17794562236bSHarry Wentland { 17804562236bSHarry Wentland unsigned int i; 17815b5abe95SAnthony Koo unsigned int triggers = 0; 178294267b3dSSylvia Tsai 17835b5abe95SAnthony Koo if (params->triggers.overlay_update) 17845b5abe95SAnthony Koo triggers |= 0x100; 17855b5abe95SAnthony Koo if (params->triggers.surface_update) 17865b5abe95SAnthony Koo triggers |= 0x80; 17875b5abe95SAnthony Koo if (params->triggers.cursor_update) 17885b5abe95SAnthony Koo triggers |= 0x2; 17895b5abe95SAnthony Koo if (params->triggers.force_trigger) 17905b5abe95SAnthony Koo triggers |= 0x1; 17914562236bSHarry Wentland 1792593f79a2SAlex Deucher if (num_pipes) { 1793593f79a2SAlex Deucher struct dc *dc = pipe_ctx[0]->stream->ctx->dc; 1794593f79a2SAlex Deucher 1795593f79a2SAlex Deucher if (dc->fbc_compressor) 17965b5abe95SAnthony Koo triggers |= 0x84; 1797593f79a2SAlex Deucher } 1798c3aa1d67SBhawanpreet Lakha 17994562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 18006b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs-> 18015b5abe95SAnthony Koo set_static_screen_control(pipe_ctx[i]->stream_res.tg, 18025b5abe95SAnthony Koo triggers, params->num_frames); 18034562236bSHarry Wentland } 18044562236bSHarry Wentland 1805f6baff4dSHarry Wentland /* 1806690b5e39SRoman Li * Check if FBC can be enabled 1807690b5e39SRoman Li */ 18089c6569deSHarry Wentland static bool should_enable_fbc(struct dc *dc, 18093bc4aaa9SRoman Li struct dc_state *context, 18103bc4aaa9SRoman Li uint32_t *pipe_idx) 1811690b5e39SRoman Li { 18123bc4aaa9SRoman Li uint32_t i; 18133bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = NULL; 18143bc4aaa9SRoman Li struct resource_context *res_ctx = &context->res_ctx; 181565d38262Shersen wu unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 18163bc4aaa9SRoman Li 1817690b5e39SRoman Li 1818690b5e39SRoman Li ASSERT(dc->fbc_compressor); 1819690b5e39SRoman Li 1820690b5e39SRoman Li /* FBC memory should be allocated */ 1821690b5e39SRoman Li if (!dc->ctx->fbc_gpu_addr) 18229c6569deSHarry Wentland return false; 1823690b5e39SRoman Li 1824690b5e39SRoman Li /* Only supports single display */ 1825690b5e39SRoman Li if (context->stream_count != 1) 18269c6569deSHarry Wentland return false; 1827690b5e39SRoman Li 18283bc4aaa9SRoman Li for (i = 0; i < dc->res_pool->pipe_count; i++) { 18293bc4aaa9SRoman Li if (res_ctx->pipe_ctx[i].stream) { 183065d38262Shersen wu 18313bc4aaa9SRoman Li pipe_ctx = &res_ctx->pipe_ctx[i]; 183265d38262Shersen wu 183365d38262Shersen wu if (!pipe_ctx) 183465d38262Shersen wu continue; 183565d38262Shersen wu 183665d38262Shersen wu /* fbc not applicable on underlay pipe */ 183765d38262Shersen wu if (pipe_ctx->pipe_idx != underlay_idx) { 18383bc4aaa9SRoman Li *pipe_idx = i; 18393bc4aaa9SRoman Li break; 18403bc4aaa9SRoman Li } 18413bc4aaa9SRoman Li } 184265d38262Shersen wu } 18433bc4aaa9SRoman Li 184465d38262Shersen wu if (i == dc->res_pool->pipe_count) 184565d38262Shersen wu return false; 184665d38262Shersen wu 1847ceb3dbb4SJun Lei if (!pipe_ctx->stream->link) 184865d38262Shersen wu return false; 18497a840773SRoman Li 1850690b5e39SRoman Li /* Only supports eDP */ 1851ceb3dbb4SJun Lei if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP) 18529c6569deSHarry Wentland return false; 1853690b5e39SRoman Li 1854690b5e39SRoman Li /* PSR should not be enabled */ 1855d1ebfdd8SWyatt Wood if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled) 18569c6569deSHarry Wentland return false; 1857690b5e39SRoman Li 185893984bbcSShirish S /* Nothing to compress */ 185993984bbcSShirish S if (!pipe_ctx->plane_state) 18609c6569deSHarry Wentland return false; 186193984bbcSShirish S 186205230fa9SRoman Li /* Only for non-linear tiling */ 186305230fa9SRoman Li if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 18649c6569deSHarry Wentland return false; 186505230fa9SRoman Li 18669c6569deSHarry Wentland return true; 1867690b5e39SRoman Li } 1868690b5e39SRoman Li 1869690b5e39SRoman Li /* 1870690b5e39SRoman Li * Enable FBC 1871690b5e39SRoman Li */ 187265d38262Shersen wu static void enable_fbc( 187365d38262Shersen wu struct dc *dc, 1874608ac7bbSJerry Zuo struct dc_state *context) 1875690b5e39SRoman Li { 18763bc4aaa9SRoman Li uint32_t pipe_idx = 0; 18773bc4aaa9SRoman Li 18783bc4aaa9SRoman Li if (should_enable_fbc(dc, context, &pipe_idx)) { 1879690b5e39SRoman Li /* Program GRPH COMPRESSED ADDRESS and PITCH */ 1880690b5e39SRoman Li struct compr_addr_and_pitch_params params = {0, 0, 0}; 1881690b5e39SRoman Li struct compressor *compr = dc->fbc_compressor; 18823bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 18833bc4aaa9SRoman Li 18849c6569deSHarry Wentland params.source_view_width = pipe_ctx->stream->timing.h_addressable; 18859c6569deSHarry Wentland params.source_view_height = pipe_ctx->stream->timing.v_addressable; 188665d38262Shersen wu params.inst = pipe_ctx->stream_res.tg->inst; 1887690b5e39SRoman Li compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 1888690b5e39SRoman Li 1889690b5e39SRoman Li compr->funcs->surface_address_and_pitch(compr, ¶ms); 1890690b5e39SRoman Li compr->funcs->set_fbc_invalidation_triggers(compr, 1); 1891690b5e39SRoman Li 1892690b5e39SRoman Li compr->funcs->enable_fbc(compr, ¶ms); 1893690b5e39SRoman Li } 1894690b5e39SRoman Li } 1895690b5e39SRoman Li 189654e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap( 1897fb3466a4SBhawanpreet Lakha struct dc *dc, 1898608ac7bbSJerry Zuo struct dc_state *context) 18994562236bSHarry Wentland { 19004562236bSHarry Wentland int i; 19014562236bSHarry Wentland 19024562236bSHarry Wentland /* Reset old context */ 19034562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 1904a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 19054562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 1906608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 19074562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 19084562236bSHarry Wentland 19094562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 19104562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 19114562236bSHarry Wentland * PHY when not already disabled. 19124562236bSHarry Wentland */ 19134562236bSHarry Wentland 19144562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 19154562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 19164562236bSHarry Wentland continue; 19174562236bSHarry Wentland 19184562236bSHarry Wentland if (!pipe_ctx->stream || 191954e8695eSDmytro Laktyushkin pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 192021e67d4dSHarry Wentland struct clock_source *old_clk = pipe_ctx_old->clock_source; 192121e67d4dSHarry Wentland 1922827f11e9SLeo (Sunpeng) Li /* Disable if new stream is null. O/w, if stream is 1923827f11e9SLeo (Sunpeng) Li * disabled already, no need to disable again. 1924827f11e9SLeo (Sunpeng) Li */ 192557430404SSu Sung Chung if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) { 192657430404SSu Sung Chung core_link_disable_stream(pipe_ctx_old); 192757430404SSu Sung Chung 192857430404SSu Sung Chung /* free acquired resources*/ 192957430404SSu Sung Chung if (pipe_ctx_old->stream_res.audio) { 193057430404SSu Sung Chung /*disable az_endpoint*/ 193157430404SSu Sung Chung pipe_ctx_old->stream_res.audio->funcs-> 193257430404SSu Sung Chung az_disable(pipe_ctx_old->stream_res.audio); 193357430404SSu Sung Chung 193457430404SSu Sung Chung /*free audio*/ 193557430404SSu Sung Chung if (dc->caps.dynamic_audio == true) { 193657430404SSu Sung Chung /*we have to dynamic arbitrate the audio endpoints*/ 193757430404SSu Sung Chung /*we free the resource, need reset is_audio_acquired*/ 193857430404SSu Sung Chung update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, 193957430404SSu Sung Chung pipe_ctx_old->stream_res.audio, false); 194057430404SSu Sung Chung pipe_ctx_old->stream_res.audio = NULL; 194157430404SSu Sung Chung } 194257430404SSu Sung Chung } 194357430404SSu Sung Chung } 1944d050f8edSHersen Wu 19456b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 19466b670fa9SHarry Wentland if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 194754e8695eSDmytro Laktyushkin dm_error("DC: failed to blank crtc!\n"); 194854e8695eSDmytro Laktyushkin BREAK_TO_DEBUGGER(); 194954e8695eSDmytro Laktyushkin } 19506b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); 195186a66c4eSHarry Wentland pipe_ctx_old->plane_res.mi->funcs->free_mem_input( 1952608ac7bbSJerry Zuo pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); 195354e8695eSDmytro Laktyushkin 1954ad8960a6SMikita Lipski if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx, 1955ad8960a6SMikita Lipski dc->res_pool, 1956ad8960a6SMikita Lipski old_clk)) 195721e67d4dSHarry Wentland old_clk->funcs->cs_power_down(old_clk); 195821e67d4dSHarry Wentland 19597f914a62SYongqiang Sun dc->hwss.disable_plane(dc, pipe_ctx_old); 196054e8695eSDmytro Laktyushkin 196154e8695eSDmytro Laktyushkin pipe_ctx_old->stream = NULL; 196254e8695eSDmytro Laktyushkin } 19634562236bSHarry Wentland } 19644562236bSHarry Wentland } 19654562236bSHarry Wentland 19661a05873fSAnthony Koo static void dce110_setup_audio_dto( 19671a05873fSAnthony Koo struct dc *dc, 19681a05873fSAnthony Koo struct dc_state *context) 19691a05873fSAnthony Koo { 19701a05873fSAnthony Koo int i; 19711a05873fSAnthony Koo 19721a05873fSAnthony Koo /* program audio wall clock. use HDMI as clock source if HDMI 19731a05873fSAnthony Koo * audio active. Otherwise, use DP as clock source 19741a05873fSAnthony Koo * first, loop to find any HDMI audio, if not, loop find DP audio 19751a05873fSAnthony Koo */ 19761a05873fSAnthony Koo /* Setup audio rate clock source */ 19771a05873fSAnthony Koo /* Issue: 19781a05873fSAnthony Koo * Audio lag happened on DP monitor when unplug a HDMI monitor 19791a05873fSAnthony Koo * 19801a05873fSAnthony Koo * Cause: 19811a05873fSAnthony Koo * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 19821a05873fSAnthony Koo * is set to either dto0 or dto1, audio should work fine. 19831a05873fSAnthony Koo * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 19841a05873fSAnthony Koo * set to dto0 will cause audio lag. 19851a05873fSAnthony Koo * 19861a05873fSAnthony Koo * Solution: 19871a05873fSAnthony Koo * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 19881a05873fSAnthony Koo * find first available pipe with audio, setup audio wall DTO per topology 19891a05873fSAnthony Koo * instead of per pipe. 19901a05873fSAnthony Koo */ 19911a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 19921a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 19931a05873fSAnthony Koo 19941a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 19951a05873fSAnthony Koo continue; 19961a05873fSAnthony Koo 19971a05873fSAnthony Koo if (pipe_ctx->top_pipe) 19981a05873fSAnthony Koo continue; 19991a05873fSAnthony Koo if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 20001a05873fSAnthony Koo continue; 20011a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 20021a05873fSAnthony Koo struct audio_output audio_output; 20031a05873fSAnthony Koo 20041a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 20051a05873fSAnthony Koo 20061a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 20071a05873fSAnthony Koo pipe_ctx->stream_res.audio, 20081a05873fSAnthony Koo pipe_ctx->stream->signal, 20091a05873fSAnthony Koo &audio_output.crtc_info, 20101a05873fSAnthony Koo &audio_output.pll_info); 20111a05873fSAnthony Koo break; 20121a05873fSAnthony Koo } 20131a05873fSAnthony Koo } 20141a05873fSAnthony Koo 20151a05873fSAnthony Koo /* no HDMI audio is found, try DP audio */ 20161a05873fSAnthony Koo if (i == dc->res_pool->pipe_count) { 20171a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 20181a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 20191a05873fSAnthony Koo 20201a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 20211a05873fSAnthony Koo continue; 20221a05873fSAnthony Koo 20231a05873fSAnthony Koo if (pipe_ctx->top_pipe) 20241a05873fSAnthony Koo continue; 20251a05873fSAnthony Koo 20261a05873fSAnthony Koo if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 20271a05873fSAnthony Koo continue; 20281a05873fSAnthony Koo 20291a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 20301a05873fSAnthony Koo struct audio_output audio_output; 20311a05873fSAnthony Koo 20321a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 20331a05873fSAnthony Koo 20341a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 20351a05873fSAnthony Koo pipe_ctx->stream_res.audio, 20361a05873fSAnthony Koo pipe_ctx->stream->signal, 20371a05873fSAnthony Koo &audio_output.crtc_info, 20381a05873fSAnthony Koo &audio_output.pll_info); 20391a05873fSAnthony Koo break; 20401a05873fSAnthony Koo } 20411a05873fSAnthony Koo } 20421a05873fSAnthony Koo } 20431a05873fSAnthony Koo } 2044cf437593SDmytro Laktyushkin 20454562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 2046fb3466a4SBhawanpreet Lakha struct dc *dc, 2047608ac7bbSJerry Zuo struct dc_state *context) 20484562236bSHarry Wentland { 2049f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 20504562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 20514562236bSHarry Wentland enum dc_status status; 20524562236bSHarry Wentland int i; 20534562236bSHarry Wentland 20544562236bSHarry Wentland /* Reset old context */ 20554562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 2056f42ea55bSAnthony Koo hws->funcs.reset_hw_ctx_wrap(dc, context); 20574562236bSHarry Wentland 20584562236bSHarry Wentland /* Skip applying if no targets */ 2059ab2541b6SAric Cyr if (context->stream_count <= 0) 20604562236bSHarry Wentland return DC_OK; 20614562236bSHarry Wentland 20624562236bSHarry Wentland /* Apply new context */ 20634562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 20644562236bSHarry Wentland 20654562236bSHarry Wentland /* below is for real asic only */ 2066a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 20674562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 2068608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 20694562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 20704562236bSHarry Wentland 20714562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 20724562236bSHarry Wentland continue; 20734562236bSHarry Wentland 20744562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 20754562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 20764562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 20774562236bSHarry Wentland pipe_ctx->clock_source, i); 20784562236bSHarry Wentland continue; 20794562236bSHarry Wentland } 20804562236bSHarry Wentland 2081f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 20824562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 20834562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 20844562236bSHarry Wentland } 20854562236bSHarry Wentland 20862f3bfb27SRoman Li if (dc->fbc_compressor) 20871663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 20885099114bSAlex Deucher 20891a05873fSAnthony Koo dce110_setup_audio_dto(dc, context); 2090ab8812a3SHersen Wu 2091a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 2092ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx_old = 2093608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 2094ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2095ab8812a3SHersen Wu 2096ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 2097ab8812a3SHersen Wu continue; 2098ab8812a3SHersen Wu 2099eed928dcSCharlene Liu if (pipe_ctx->stream == pipe_ctx_old->stream && 2100eed928dcSCharlene Liu pipe_ctx->stream->link->link_state_valid) { 2101ab8812a3SHersen Wu continue; 2102eed928dcSCharlene Liu } 2103ab8812a3SHersen Wu 21045b92d9d4SHarry Wentland if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 2105313bf4ffSYongqiang Sun continue; 2106313bf4ffSYongqiang Sun 2107b1f6d01cSDmytro Laktyushkin if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) 2108ab8812a3SHersen Wu continue; 2109ab8812a3SHersen Wu 21104562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 21114562236bSHarry Wentland pipe_ctx, 21124562236bSHarry Wentland context, 21134562236bSHarry Wentland dc); 21144562236bSHarry Wentland 21154562236bSHarry Wentland if (DC_OK != status) 21164562236bSHarry Wentland return status; 21174562236bSHarry Wentland } 21184562236bSHarry Wentland 2119690b5e39SRoman Li if (dc->fbc_compressor) 212065d38262Shersen wu enable_fbc(dc, dc->current_state); 212165d38262Shersen wu 212265d38262Shersen wu dcb->funcs->set_scratch_critical_state(dcb, false); 2123690b5e39SRoman Li 21244562236bSHarry Wentland return DC_OK; 21254562236bSHarry Wentland } 21264562236bSHarry Wentland 21274562236bSHarry Wentland /******************************************************************************* 21284562236bSHarry Wentland * Front End programming 21294562236bSHarry Wentland ******************************************************************************/ 21304562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 21314562236bSHarry Wentland { 21324562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 21334562236bSHarry Wentland 21344562236bSHarry Wentland default_adjust.force_hw_default = false; 213534996173SHarry Wentland default_adjust.in_color_space = pipe_ctx->plane_state->color_space; 213634996173SHarry Wentland default_adjust.out_color_space = pipe_ctx->stream->output_color_space; 21374562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 21386702a9acSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 21394562236bSHarry Wentland 21404562236bSHarry Wentland /* display color depth */ 21414562236bSHarry Wentland default_adjust.color_depth = 21424fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.display_color_depth; 21434562236bSHarry Wentland 21444562236bSHarry Wentland /* Lb color depth */ 21456702a9acSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 21464562236bSHarry Wentland 214786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 214886a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, &default_adjust); 21494562236bSHarry Wentland } 21504562236bSHarry Wentland 2151b06b7680SLeon Elazar 2152b06b7680SLeon Elazar /******************************************************************************* 2153b06b7680SLeon Elazar * In order to turn on/off specific surface we will program 2154b06b7680SLeon Elazar * Blender + CRTC 2155b06b7680SLeon Elazar * 2156b06b7680SLeon Elazar * In case that we have two surfaces and they have a different visibility 2157b06b7680SLeon Elazar * we can't turn off the CRTC since it will turn off the entire display 2158b06b7680SLeon Elazar * 2159b06b7680SLeon Elazar * |----------------------------------------------- | 2160b06b7680SLeon Elazar * |bottom pipe|curr pipe | | | 2161b06b7680SLeon Elazar * |Surface |Surface | Blender | CRCT | 2162b06b7680SLeon Elazar * |visibility |visibility | Configuration| | 2163b06b7680SLeon Elazar * |------------------------------------------------| 2164b06b7680SLeon Elazar * | off | off | CURRENT_PIPE | blank | 2165b06b7680SLeon Elazar * | off | on | CURRENT_PIPE | unblank | 2166b06b7680SLeon Elazar * | on | off | OTHER_PIPE | unblank | 2167b06b7680SLeon Elazar * | on | on | BLENDING | unblank | 2168b06b7680SLeon Elazar * -------------------------------------------------| 2169b06b7680SLeon Elazar * 2170b06b7680SLeon Elazar ******************************************************************************/ 2171fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc, 21724562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 21734562236bSHarry Wentland { 21744562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 2175b06b7680SLeon Elazar bool blank_target = false; 21764562236bSHarry Wentland 21774562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 2178b06b7680SLeon Elazar 2179b06b7680SLeon Elazar /* For now we are supporting only two pipes */ 2180b06b7680SLeon Elazar ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 2181b06b7680SLeon Elazar 21823be5262eSHarry Wentland if (pipe_ctx->bottom_pipe->plane_state->visible) { 21833be5262eSHarry Wentland if (pipe_ctx->plane_state->visible) 21844562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 21854562236bSHarry Wentland else 21864562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 2187b06b7680SLeon Elazar 21883be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2189b06b7680SLeon Elazar blank_target = true; 2190b06b7680SLeon Elazar 21913be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2192b06b7680SLeon Elazar blank_target = true; 2193b06b7680SLeon Elazar 2194e07f541fSYongqiang Sun dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode); 21956b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 2196b06b7680SLeon Elazar 21974562236bSHarry Wentland } 21984562236bSHarry Wentland 21991bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 22001bf56e62SZeyu Fan { 2201146a9f63SKrunoslav Kovac int i = 0; 22021bf56e62SZeyu Fan struct xfm_grph_csc_adjustment adjust; 22031bf56e62SZeyu Fan memset(&adjust, 0, sizeof(adjust)); 22041bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 22051bf56e62SZeyu Fan 22061bf56e62SZeyu Fan 22074fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 22081bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2209146a9f63SKrunoslav Kovac 2210146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2211146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2212146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 22131bf56e62SZeyu Fan } 22141bf56e62SZeyu Fan 221586a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 22161bf56e62SZeyu Fan } 2217fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc, 22184562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 22194562236bSHarry Wentland { 22203be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 22214562236bSHarry Wentland 22223be5262eSHarry Wentland if (plane_state == NULL) 22234562236bSHarry Wentland return; 22244562236bSHarry Wentland 222586a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 222686a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 22273be5262eSHarry Wentland &plane_state->address, 22283be5262eSHarry Wentland plane_state->flip_immediate); 22294562236bSHarry Wentland 22303be5262eSHarry Wentland plane_state->status.requested_address = plane_state->address; 22314562236bSHarry Wentland } 22324562236bSHarry Wentland 2233f774b339SEric Yang static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 22344562236bSHarry Wentland { 22353be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 22364562236bSHarry Wentland 22373be5262eSHarry Wentland if (plane_state == NULL) 22384562236bSHarry Wentland return; 22394562236bSHarry Wentland 22403be5262eSHarry Wentland plane_state->status.is_flip_pending = 224186a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 224286a66c4eSHarry Wentland pipe_ctx->plane_res.mi); 22434562236bSHarry Wentland 22443be5262eSHarry Wentland if (plane_state->status.is_flip_pending && !plane_state->visible) 224586a66c4eSHarry Wentland pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address; 22464562236bSHarry Wentland 224786a66c4eSHarry Wentland plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 224886a66c4eSHarry Wentland if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 22496b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) { 22503be5262eSHarry Wentland plane_state->status.is_right_eye =\ 22516b670fa9SHarry Wentland !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 22527f5c22d1SVitaly Prosyak } 22534562236bSHarry Wentland } 22544562236bSHarry Wentland 2255fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc) 22564562236bSHarry Wentland { 22574562236bSHarry Wentland power_down_all_hw_blocks(dc); 22584562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 22594562236bSHarry Wentland } 22604562236bSHarry Wentland 22614562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 22624562236bSHarry Wentland struct dc_context *dc_ctx, 22634562236bSHarry Wentland struct timing_generator *tg) 22644562236bSHarry Wentland { 22654562236bSHarry Wentland bool rc = false; 22664562236bSHarry Wentland 22674562236bSHarry Wentland /* To avoid endless loop we wait at most 22684562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 22694562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 22704562236bSHarry Wentland uint32_t i; 22714562236bSHarry Wentland 22724562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 22734562236bSHarry Wentland 22744562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 22754562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 22764562236bSHarry Wentland break; 22774562236bSHarry Wentland } 22784562236bSHarry Wentland 22794562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 22804562236bSHarry Wentland rc = true; 22814562236bSHarry Wentland /* usually occurs at i=1 */ 22824562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 22834562236bSHarry Wentland i); 22844562236bSHarry Wentland break; 22854562236bSHarry Wentland } 22864562236bSHarry Wentland 22874562236bSHarry Wentland /* Wait for one frame. */ 22884562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 22894562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 22904562236bSHarry Wentland } 22914562236bSHarry Wentland 22924562236bSHarry Wentland if (false == rc) 22934562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 22944562236bSHarry Wentland 22954562236bSHarry Wentland return rc; 22964562236bSHarry Wentland } 22974562236bSHarry Wentland 22984562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 22994562236bSHarry Wentland static void dce110_enable_timing_synchronization( 2300fb3466a4SBhawanpreet Lakha struct dc *dc, 23014562236bSHarry Wentland int group_index, 23024562236bSHarry Wentland int group_size, 23034562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 23044562236bSHarry Wentland { 23054562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 23064562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 23074562236bSHarry Wentland int i; 23084562236bSHarry Wentland 23094562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 23104562236bSHarry Wentland 23114562236bSHarry Wentland /* Designate a single TG in the group as a master. 23124562236bSHarry Wentland * Since HW doesn't care which one, we always assign 23134562236bSHarry Wentland * the 1st one in the group. */ 23144562236bSHarry Wentland gsl_params.gsl_group = 0; 23156b670fa9SHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst; 23164562236bSHarry Wentland 23174562236bSHarry Wentland for (i = 0; i < group_size; i++) 23186b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 23196b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg, &gsl_params); 23204562236bSHarry Wentland 23214562236bSHarry Wentland /* Reset slave controllers on master VSync */ 23224562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 23234562236bSHarry Wentland 23244562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 23256b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( 2326fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2327fa2123dbSMikita Lipski gsl_params.gsl_group); 23284562236bSHarry Wentland 23294562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 23304562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 23316b670fa9SHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2332fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( 2333fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg); 23344562236bSHarry Wentland } 23354562236bSHarry Wentland 23364562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 23374562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 23384562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 23394562236bSHarry Wentland for (i = 0; i < group_size; i++) 23406b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 23414562236bSHarry Wentland 23424562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 23434562236bSHarry Wentland } 23444562236bSHarry Wentland 2345fa2123dbSMikita Lipski static void dce110_enable_per_frame_crtc_position_reset( 2346fa2123dbSMikita Lipski struct dc *dc, 2347fa2123dbSMikita Lipski int group_size, 2348fa2123dbSMikita Lipski struct pipe_ctx *grouped_pipes[]) 2349fa2123dbSMikita Lipski { 2350fa2123dbSMikita Lipski struct dc_context *dc_ctx = dc->ctx; 2351fa2123dbSMikita Lipski struct dcp_gsl_params gsl_params = { 0 }; 2352fa2123dbSMikita Lipski int i; 2353fa2123dbSMikita Lipski 2354fa2123dbSMikita Lipski gsl_params.gsl_group = 0; 235537cd85ceSDavid Francis gsl_params.gsl_master = 0; 2356fa2123dbSMikita Lipski 2357fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2358fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 2359fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, &gsl_params); 2360fa2123dbSMikita Lipski 2361fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 2362fa2123dbSMikita Lipski 2363fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2364fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( 2365fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2366fa2123dbSMikita Lipski gsl_params.gsl_master, 2367fa2123dbSMikita Lipski &grouped_pipes[i]->stream->triggered_crtc_reset); 2368fa2123dbSMikita Lipski 2369fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 2370fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2371fa2123dbSMikita Lipski wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2372fa2123dbSMikita Lipski 2373fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2374fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 2375fa2123dbSMikita Lipski 2376fa2123dbSMikita Lipski } 2377fa2123dbSMikita Lipski 2378fb55546eSAnthony Koo static void init_pipes(struct dc *dc, struct dc_state *context) 2379fb55546eSAnthony Koo { 2380fb55546eSAnthony Koo // Do nothing 2381fb55546eSAnthony Koo } 2382fb55546eSAnthony Koo 2383fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc) 23844562236bSHarry Wentland { 23854562236bSHarry Wentland int i; 23864562236bSHarry Wentland struct dc_bios *bp; 23874562236bSHarry Wentland struct transform *xfm; 23885e7773a2SAnthony Koo struct abm *abm; 238970d9e8cbSPaul Hsieh struct dmcu *dmcu; 2390f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 23913ba01817SYongqiang Sun uint32_t backlight = MAX_BACKLIGHT_LEVEL; 23924562236bSHarry Wentland 23934562236bSHarry Wentland bp = dc->ctx->dc_bios; 23944562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 23954562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 23964562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 23974562236bSHarry Wentland 2398f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 23994562236bSHarry Wentland dc, i, bp, 24004562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 2401f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 24024562236bSHarry Wentland dc, i, bp, 24034562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 2404f42ea55bSAnthony Koo hws->funcs.enable_display_pipe_clock_gating( 24054562236bSHarry Wentland dc->ctx, 24064562236bSHarry Wentland true); 24074562236bSHarry Wentland } 24084562236bSHarry Wentland 2409e166ad43SJulia Lawall dce_clock_gating_power_up(dc->hwseq, false); 24104562236bSHarry Wentland /***************************************/ 24114562236bSHarry Wentland 24124562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 24134562236bSHarry Wentland /****************************************/ 24144562236bSHarry Wentland /* Power up AND update implementation according to the 24154562236bSHarry Wentland * required signal (which may be different from the 24164562236bSHarry Wentland * default signal on connector). */ 2417d0778ebfSHarry Wentland struct dc_link *link = dc->links[i]; 2418069d418fSAndrew Jiang 24194562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 24204562236bSHarry Wentland } 24214562236bSHarry Wentland 24224562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 24234562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 24244562236bSHarry Wentland 24254562236bSHarry Wentland tg->funcs->disable_vga(tg); 24264562236bSHarry Wentland 24274562236bSHarry Wentland /* Blank controller using driver code instead of 24284562236bSHarry Wentland * command table. */ 24294562236bSHarry Wentland tg->funcs->set_blank(tg, true); 24304b5e7d62SHersen Wu hwss_wait_for_blank_complete(tg); 24314562236bSHarry Wentland } 24324562236bSHarry Wentland 24334562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 24344562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 24354562236bSHarry Wentland audio->funcs->hw_init(audio); 24364562236bSHarry Wentland } 24375e7773a2SAnthony Koo 24383ba01817SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 24393ba01817SYongqiang Sun struct dc_link *link = dc->links[i]; 24403ba01817SYongqiang Sun 24413ba01817SYongqiang Sun if (link->panel_cntl) 24423ba01817SYongqiang Sun backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); 24434562236bSHarry Wentland } 24445099114bSAlex Deucher 24453ba01817SYongqiang Sun abm = dc->res_pool->abm; 24463ba01817SYongqiang Sun if (abm != NULL) 24473ba01817SYongqiang Sun abm->funcs->abm_init(abm, backlight); 24483ba01817SYongqiang Sun 244970d9e8cbSPaul Hsieh dmcu = dc->res_pool->dmcu; 245070d9e8cbSPaul Hsieh if (dmcu != NULL && abm != NULL) 245170d9e8cbSPaul Hsieh abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu); 245270d9e8cbSPaul Hsieh 24532f3bfb27SRoman Li if (dc->fbc_compressor) 24541663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 2455690b5e39SRoman Li 24566728b30cSAnthony Koo } 24574562236bSHarry Wentland 24589566b675SDmytro Laktyushkin 24599566b675SDmytro Laktyushkin void dce110_prepare_bandwidth( 2460fb3466a4SBhawanpreet Lakha struct dc *dc, 24619566b675SDmytro Laktyushkin struct dc_state *context) 2462cf437593SDmytro Laktyushkin { 2463dc88b4a6SEric Yang struct clk_mgr *dccg = dc->clk_mgr; 2464fab55d61SDmytro Laktyushkin 2465fab55d61SDmytro Laktyushkin dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); 2466cf437593SDmytro Laktyushkin 24675a83c932SNicholas Kazlauskas dccg->funcs->update_clocks( 24685a83c932SNicholas Kazlauskas dccg, 246924f7dd7eSDmytro Laktyushkin context, 24709566b675SDmytro Laktyushkin false); 24719566b675SDmytro Laktyushkin } 24729566b675SDmytro Laktyushkin 24739566b675SDmytro Laktyushkin void dce110_optimize_bandwidth( 24749566b675SDmytro Laktyushkin struct dc *dc, 24759566b675SDmytro Laktyushkin struct dc_state *context) 24769566b675SDmytro Laktyushkin { 2477dc88b4a6SEric Yang struct clk_mgr *dccg = dc->clk_mgr; 24789566b675SDmytro Laktyushkin 24799566b675SDmytro Laktyushkin dce110_set_displaymarks(dc, context); 24809566b675SDmytro Laktyushkin 24819566b675SDmytro Laktyushkin dccg->funcs->update_clocks( 24829566b675SDmytro Laktyushkin dccg, 24839566b675SDmytro Laktyushkin context, 24849566b675SDmytro Laktyushkin true); 24854562236bSHarry Wentland } 24864562236bSHarry Wentland 24874562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 2488fb3466a4SBhawanpreet Lakha struct dc *dc, struct pipe_ctx *pipe_ctx) 24894562236bSHarry Wentland { 249086a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 24913be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 24924562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 24934562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 24944562236bSHarry Wentland unsigned int i; 2495f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 2496f42ea55bSAnthony Koo 24975d4b05ddSBhawanpreet Lakha DC_LOGGER_INIT(); 24984562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 24994562236bSHarry Wentland 25004562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 25014562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 25024562236bSHarry Wentland 2503e07f541fSYongqiang Sun dce_enable_fe_clock(dc->hwseq, mi->inst, true); 25044562236bSHarry Wentland 25054562236bSHarry Wentland set_default_colors(pipe_ctx); 25064fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 25074562236bSHarry Wentland == true) { 25084562236bSHarry Wentland tbl_entry.color_space = 25094fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 25104562236bSHarry Wentland 25114562236bSHarry Wentland for (i = 0; i < 12; i++) 25124562236bSHarry Wentland tbl_entry.regval[i] = 25134fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 25144562236bSHarry Wentland 251586a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 251686a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 25174562236bSHarry Wentland } 25184562236bSHarry Wentland 25194fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 25204562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2521146a9f63SKrunoslav Kovac 2522146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2523146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2524146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 25254562236bSHarry Wentland } 25264562236bSHarry Wentland 252786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 25284562236bSHarry Wentland 25296702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 2530c1473558SAndrey Grodzovsky 25314562236bSHarry Wentland program_scaler(dc, pipe_ctx); 25324562236bSHarry Wentland 25334562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 25344562236bSHarry Wentland mi, 25353be5262eSHarry Wentland plane_state->format, 25363be5262eSHarry Wentland &plane_state->tiling_info, 25373be5262eSHarry Wentland &plane_state->plane_size, 25383be5262eSHarry Wentland plane_state->rotation, 2539624d7c47SYongqiang Sun NULL, 25404b28b76bSDmytro Laktyushkin false); 25414b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 25423be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 25434562236bSHarry Wentland 2544fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 25454562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 254686a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 25473be5262eSHarry Wentland plane_state->format, 25483be5262eSHarry Wentland &plane_state->tiling_info, 25493be5262eSHarry Wentland plane_state->rotation); 25504562236bSHarry Wentland 2551067c878aSYongqiang Sun /* Moved programming gamma from dc to hwss */ 2552405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update || 2553405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 2554405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.gamma_change) 2555f42ea55bSAnthony Koo hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); 2556405c50a0SAndrew Jiang 2557405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update) 2558f42ea55bSAnthony Koo hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream); 2559067c878aSYongqiang Sun 25601296423bSBhawanpreet Lakha DC_LOG_SURFACE( 25613032deb5SBhawanpreet Lakha "Pipe:%d %p: addr hi:0x%x, " 25624562236bSHarry Wentland "addr low:0x%x, " 25634562236bSHarry Wentland "src: %d, %d, %d," 25644562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 25654562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 25664562236bSHarry Wentland pipe_ctx->pipe_idx, 25673032deb5SBhawanpreet Lakha (void *) pipe_ctx->plane_state, 25683be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.high_part, 25693be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.low_part, 25703be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.x, 25713be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.y, 25723be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.width, 25733be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.height, 25743be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.x, 25753be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.y, 25763be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.width, 25773be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.height, 25783be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.x, 25793be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.y, 25803be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.width, 25813be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.height); 25824562236bSHarry Wentland 25831296423bSBhawanpreet Lakha DC_LOG_SURFACE( 25844562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 25854562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 25864562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 25874562236bSHarry Wentland pipe_ctx->pipe_idx, 25886702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.width, 25896702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.height, 25906702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.x, 25916702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.y, 25926702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.width, 25936702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.height, 25946702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.x, 25956702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.y); 25964562236bSHarry Wentland } 25974562236bSHarry Wentland 25984562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 2599fb3466a4SBhawanpreet Lakha struct dc *dc, 26003e9ad616SEric Yang const struct dc_stream_state *stream, 26013e9ad616SEric Yang int num_planes, 2602608ac7bbSJerry Zuo struct dc_state *context) 26034562236bSHarry Wentland { 26042194e3aeSRoman Li int i; 26054562236bSHarry Wentland 26063e9ad616SEric Yang if (num_planes == 0) 26074562236bSHarry Wentland return; 26084562236bSHarry Wentland 260965d38262Shersen wu if (dc->fbc_compressor) 261065d38262Shersen wu dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 261165d38262Shersen wu 26123e9ad616SEric Yang for (i = 0; i < dc->res_pool->pipe_count; i++) { 26133dc780ecSYongqiang Sun struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 26144562236bSHarry Wentland 2615a2607aefSHarry Wentland if (pipe_ctx->stream != stream) 26164562236bSHarry Wentland continue; 26174562236bSHarry Wentland 26183b21b6d2SJerry Zuo /* Need to allocate mem before program front end for Fiji */ 26193b21b6d2SJerry Zuo pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 26203b21b6d2SJerry Zuo pipe_ctx->plane_res.mi, 26213b21b6d2SJerry Zuo pipe_ctx->stream->timing.h_total, 26223b21b6d2SJerry Zuo pipe_ctx->stream->timing.v_total, 2623380604e2SKen Chalmers pipe_ctx->stream->timing.pix_clk_100hz / 10, 26243b21b6d2SJerry Zuo context->stream_count); 26253b21b6d2SJerry Zuo 26264562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 26274f804817SYongqiang Sun 26284f804817SYongqiang Sun dc->hwss.update_plane_addr(dc, pipe_ctx); 26294f804817SYongqiang Sun 2630b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 26314562236bSHarry Wentland 26324562236bSHarry Wentland } 26333dc780ecSYongqiang Sun 263465d38262Shersen wu if (dc->fbc_compressor) 263512a8bd88SShirish S enable_fbc(dc, context); 26364562236bSHarry Wentland } 26374562236bSHarry Wentland 2638bbf5f6c3SAnthony Koo static void dce110_post_unlock_program_front_end( 2639bbf5f6c3SAnthony Koo struct dc *dc, 2640bbf5f6c3SAnthony Koo struct dc_state *context) 2641bbf5f6c3SAnthony Koo { 2642bbf5f6c3SAnthony Koo } 2643009114f6SAnthony Koo 2644e6c258cbSYongqiang Sun static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) 26454562236bSHarry Wentland { 2646f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 2647bc373a89SRoman Li int fe_idx = pipe_ctx->plane_res.mi ? 2648bc373a89SRoman Li pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx; 2649e6c258cbSYongqiang Sun 26507950f0f9SDmytro Laktyushkin /* Do not power down fe when stream is active on dce*/ 2651608ac7bbSJerry Zuo if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) 26524562236bSHarry Wentland return; 26534562236bSHarry Wentland 2654f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 2655cfe4645eSDmytro Laktyushkin dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 2656cfe4645eSDmytro Laktyushkin 2657cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 2658cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]); 26594562236bSHarry Wentland } 26604562236bSHarry Wentland 26616be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect( 2662fb3466a4SBhawanpreet Lakha struct dc *dc, 26636be425f3SEric Yang struct resource_pool *res_pool, 26646be425f3SEric Yang struct pipe_ctx *pipe_ctx) 2665b6762f0cSEric Yang { 2666b6762f0cSEric Yang /* do nothing*/ 2667b6762f0cSEric Yang } 2668b6762f0cSEric Yang 26694bd0dc68SJoshua Aberback static void program_output_csc(struct dc *dc, 26704bd0dc68SJoshua Aberback struct pipe_ctx *pipe_ctx, 26714bd0dc68SJoshua Aberback enum dc_color_space colorspace, 26724bd0dc68SJoshua Aberback uint16_t *matrix, 26734bd0dc68SJoshua Aberback int opp_id) 26744bd0dc68SJoshua Aberback { 26754bd0dc68SJoshua Aberback int i; 26764bd0dc68SJoshua Aberback struct out_csc_color_matrix tbl_entry; 26774bd0dc68SJoshua Aberback 26784bd0dc68SJoshua Aberback if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { 26794bd0dc68SJoshua Aberback enum dc_color_space color_space = pipe_ctx->stream->output_color_space; 26804bd0dc68SJoshua Aberback 26814bd0dc68SJoshua Aberback for (i = 0; i < 12; i++) 26824bd0dc68SJoshua Aberback tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; 26834bd0dc68SJoshua Aberback 26844bd0dc68SJoshua Aberback tbl_entry.color_space = color_space; 26854bd0dc68SJoshua Aberback 26864bd0dc68SJoshua Aberback pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment( 26874bd0dc68SJoshua Aberback pipe_ctx->plane_res.xfm, &tbl_entry); 26884bd0dc68SJoshua Aberback } 26894bd0dc68SJoshua Aberback } 26904bd0dc68SJoshua Aberback 269133fd17d9SEric Yang void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) 269233fd17d9SEric Yang { 269333fd17d9SEric Yang struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; 269433fd17d9SEric Yang struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 269533fd17d9SEric Yang struct mem_input *mi = pipe_ctx->plane_res.mi; 269633fd17d9SEric Yang struct dc_cursor_mi_param param = { 2697380604e2SKen Chalmers .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10, 269833d7598dSJun Lei .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz, 269939a9f4d8SDmytro Laktyushkin .viewport = pipe_ctx->plane_res.scl_data.viewport, 270039a9f4d8SDmytro Laktyushkin .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, 270139a9f4d8SDmytro Laktyushkin .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, 270208ed681cSDmytro Laktyushkin .rotation = pipe_ctx->plane_state->rotation, 270308ed681cSDmytro Laktyushkin .mirror = pipe_ctx->plane_state->horizontal_mirror 270433fd17d9SEric Yang }; 270533fd17d9SEric Yang 270603a4059bSNicholas Kazlauskas /** 270703a4059bSNicholas Kazlauskas * If the cursor's source viewport is clipped then we need to 270803a4059bSNicholas Kazlauskas * translate the cursor to appear in the correct position on 270903a4059bSNicholas Kazlauskas * the screen. 271003a4059bSNicholas Kazlauskas * 271103a4059bSNicholas Kazlauskas * This translation isn't affected by scaling so it needs to be 271203a4059bSNicholas Kazlauskas * done *after* we adjust the position for the scale factor. 2713033baeeeSNicholas Kazlauskas * 2714033baeeeSNicholas Kazlauskas * This is only done by opt-in for now since there are still 2715033baeeeSNicholas Kazlauskas * some usecases like tiled display that might enable the 2716033baeeeSNicholas Kazlauskas * cursor on both streams while expecting dc to clip it. 271703a4059bSNicholas Kazlauskas */ 2718033baeeeSNicholas Kazlauskas if (pos_cpy.translate_by_source) { 271903a4059bSNicholas Kazlauskas pos_cpy.x += pipe_ctx->plane_state->src_rect.x; 272003a4059bSNicholas Kazlauskas pos_cpy.y += pipe_ctx->plane_state->src_rect.y; 2721033baeeeSNicholas Kazlauskas } 272203a4059bSNicholas Kazlauskas 272333fd17d9SEric Yang if (pipe_ctx->plane_state->address.type 272433fd17d9SEric Yang == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) 272533fd17d9SEric Yang pos_cpy.enable = false; 272633fd17d9SEric Yang 272733fd17d9SEric Yang if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 272833fd17d9SEric Yang pos_cpy.enable = false; 272933fd17d9SEric Yang 2730dc75dd70SRoman Li if (ipp->funcs->ipp_cursor_set_position) 273133fd17d9SEric Yang ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); 2732dc75dd70SRoman Li if (mi->funcs->set_cursor_position) 273333fd17d9SEric Yang mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); 273433fd17d9SEric Yang } 273533fd17d9SEric Yang 273633fd17d9SEric Yang void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) 273733fd17d9SEric Yang { 273833fd17d9SEric Yang struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; 273933fd17d9SEric Yang 2740d1aaad05SHarry Wentland if (pipe_ctx->plane_res.ipp && 2741d1aaad05SHarry Wentland pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) 274233fd17d9SEric Yang pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( 274333fd17d9SEric Yang pipe_ctx->plane_res.ipp, attributes); 274433fd17d9SEric Yang 2745d1aaad05SHarry Wentland if (pipe_ctx->plane_res.mi && 2746d1aaad05SHarry Wentland pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) 274733fd17d9SEric Yang pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( 274833fd17d9SEric Yang pipe_ctx->plane_res.mi, attributes); 274933fd17d9SEric Yang 2750d1aaad05SHarry Wentland if (pipe_ctx->plane_res.xfm && 2751d1aaad05SHarry Wentland pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) 275233fd17d9SEric Yang pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( 275333fd17d9SEric Yang pipe_ctx->plane_res.xfm, attributes); 275433fd17d9SEric Yang } 275533fd17d9SEric Yang 27564b0e95d1SYongqiang Sun bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, 27574b0e95d1SYongqiang Sun uint32_t backlight_pwm_u16_16, 27584b0e95d1SYongqiang Sun uint32_t frame_ramp) 27594b0e95d1SYongqiang Sun { 27604b0e95d1SYongqiang Sun struct dc_link *link = pipe_ctx->stream->link; 27614b0e95d1SYongqiang Sun struct dc *dc = link->ctx->dc; 27624b0e95d1SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 27633ba01817SYongqiang Sun struct panel_cntl *panel_cntl = link->panel_cntl; 27644b0e95d1SYongqiang Sun struct dmcu *dmcu = dc->res_pool->dmcu; 27654b0e95d1SYongqiang Sun bool fw_set_brightness = true; 27664b0e95d1SYongqiang Sun /* DMCU -1 for all controller id values, 27674b0e95d1SYongqiang Sun * therefore +1 here 27684b0e95d1SYongqiang Sun */ 27694b0e95d1SYongqiang Sun uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1; 27704b0e95d1SYongqiang Sun 27713ba01817SYongqiang Sun if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL)) 27724b0e95d1SYongqiang Sun return false; 27734b0e95d1SYongqiang Sun 27744b0e95d1SYongqiang Sun if (dmcu) 27754b0e95d1SYongqiang Sun fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); 27764b0e95d1SYongqiang Sun 27773ba01817SYongqiang Sun if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight) 27783ba01817SYongqiang Sun panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16); 27793ba01817SYongqiang Sun else 27804b0e95d1SYongqiang Sun abm->funcs->set_backlight_level_pwm( 27814b0e95d1SYongqiang Sun abm, 27824b0e95d1SYongqiang Sun backlight_pwm_u16_16, 27834b0e95d1SYongqiang Sun frame_ramp, 27844b0e95d1SYongqiang Sun controller_id, 27853ba01817SYongqiang Sun link->panel_cntl->inst); 27864b0e95d1SYongqiang Sun 27874b0e95d1SYongqiang Sun return true; 27884b0e95d1SYongqiang Sun } 27894b0e95d1SYongqiang Sun 27903ba01817SYongqiang Sun void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx) 27913ba01817SYongqiang Sun { 27923ba01817SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 27933ba01817SYongqiang Sun struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 27943ba01817SYongqiang Sun 27953ba01817SYongqiang Sun if (abm) 27963ba01817SYongqiang Sun abm->funcs->set_abm_immediate_disable(abm, 27973ba01817SYongqiang Sun pipe_ctx->stream->link->panel_cntl->inst); 27983ba01817SYongqiang Sun 27993ba01817SYongqiang Sun if (panel_cntl) 28003ba01817SYongqiang Sun panel_cntl->funcs->store_backlight_level(panel_cntl); 28013ba01817SYongqiang Sun } 28023ba01817SYongqiang Sun 2803474ac4a8SYongqiang Sun void dce110_set_pipe(struct pipe_ctx *pipe_ctx) 2804474ac4a8SYongqiang Sun { 2805474ac4a8SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 2806474ac4a8SYongqiang Sun struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 2807474ac4a8SYongqiang Sun uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1; 2808474ac4a8SYongqiang Sun 2809474ac4a8SYongqiang Sun if (abm && panel_cntl) 2810474ac4a8SYongqiang Sun abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst); 2811474ac4a8SYongqiang Sun } 2812474ac4a8SYongqiang Sun 28134562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 28141bf56e62SZeyu Fan .program_gamut_remap = program_gamut_remap, 28154bd0dc68SJoshua Aberback .program_output_csc = program_output_csc, 28164562236bSHarry Wentland .init_hw = init_hw, 28174562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 28184562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 2819bbf5f6c3SAnthony Koo .post_unlock_program_front_end = dce110_post_unlock_program_front_end, 28204562236bSHarry Wentland .update_plane_addr = update_plane_addr, 28214562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 28224562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 28234562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 2824fa2123dbSMikita Lipski .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, 28254562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 28264562236bSHarry Wentland .enable_stream = dce110_enable_stream, 28274562236bSHarry Wentland .disable_stream = dce110_disable_stream, 28284562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 282941b49742SCharlene Liu .blank_stream = dce110_blank_stream, 28301a05873fSAnthony Koo .enable_audio_stream = dce110_enable_audio_stream, 28311a05873fSAnthony Koo .disable_audio_stream = dce110_disable_audio_stream, 28327f914a62SYongqiang Sun .disable_plane = dce110_power_down_fe, 28334562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 2834009114f6SAnthony Koo .interdependent_update_lock = NULL, 28351e461c37SAric Cyr .cursor_lock = dce_pipe_control_lock, 28369566b675SDmytro Laktyushkin .prepare_bandwidth = dce110_prepare_bandwidth, 28379566b675SDmytro Laktyushkin .optimize_bandwidth = dce110_optimize_bandwidth, 28384562236bSHarry Wentland .set_drr = set_drr, 283972ada5f7SEric Cook .get_position = get_position, 28404562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 284115e17335SCharlene Liu .setup_stereo = NULL, 284215e17335SCharlene Liu .set_avmute = dce110_set_avmute, 284341f97c07SHersen Wu .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 28448a31820bSMartin Leung .edp_power_control = dce110_edp_power_control, 28458a31820bSMartin Leung .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, 284633fd17d9SEric Yang .set_cursor_position = dce110_set_cursor_position, 28474b0e95d1SYongqiang Sun .set_cursor_attribute = dce110_set_cursor_attribute, 28484b0e95d1SYongqiang Sun .set_backlight_level = dce110_set_backlight_level, 28493ba01817SYongqiang Sun .set_abm_immediate_disable = dce110_set_abm_immediate_disable, 2850474ac4a8SYongqiang Sun .set_pipe = dce110_set_pipe, 28514562236bSHarry Wentland }; 28524562236bSHarry Wentland 2853f42ea55bSAnthony Koo static const struct hwseq_private_funcs dce110_private_funcs = { 2854f42ea55bSAnthony Koo .init_pipes = init_pipes, 2855f42ea55bSAnthony Koo .update_plane_addr = update_plane_addr, 2856f42ea55bSAnthony Koo .set_input_transfer_func = dce110_set_input_transfer_func, 2857f42ea55bSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 2858f42ea55bSAnthony Koo .power_down = dce110_power_down, 2859f42ea55bSAnthony Koo .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 2860f42ea55bSAnthony Koo .enable_display_power_gating = dce110_enable_display_power_gating, 2861f42ea55bSAnthony Koo .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 2862f42ea55bSAnthony Koo .enable_stream_timing = dce110_enable_stream_timing, 2863f42ea55bSAnthony Koo .disable_stream_gating = NULL, 2864f42ea55bSAnthony Koo .enable_stream_gating = NULL, 2865f42ea55bSAnthony Koo .edp_backlight_control = dce110_edp_backlight_control, 2866f42ea55bSAnthony Koo }; 2867f42ea55bSAnthony Koo 2868c13b408bSDave Airlie void dce110_hw_sequencer_construct(struct dc *dc) 28694562236bSHarry Wentland { 28704562236bSHarry Wentland dc->hwss = dce110_funcs; 2871f42ea55bSAnthony Koo dc->hwseq->funcs = dce110_private_funcs; 28724562236bSHarry Wentland } 28734562236bSHarry Wentland 2874