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 264562236bSHarry Wentland #include "dm_services.h" 274562236bSHarry Wentland #include "dc.h" 284562236bSHarry Wentland #include "dc_bios_types.h" 294562236bSHarry Wentland #include "core_types.h" 304562236bSHarry Wentland #include "core_status.h" 314562236bSHarry Wentland #include "resource.h" 324562236bSHarry Wentland #include "dm_helpers.h" 334562236bSHarry Wentland #include "dce110_timing_generator.h" 3498489c02SLeo (Sunpeng) Li #include "dce/dce_hwseq.h" 3587401969SAndrew Jiang #include "gpio_service_interface.h" 364562236bSHarry Wentland 371663ae1cSBhawanpreet Lakha #include "dce110_compressor.h" 381663ae1cSBhawanpreet Lakha 394562236bSHarry Wentland #include "bios/bios_parser_helper.h" 404562236bSHarry Wentland #include "timing_generator.h" 414562236bSHarry Wentland #include "mem_input.h" 424562236bSHarry Wentland #include "opp.h" 434562236bSHarry Wentland #include "ipp.h" 444562236bSHarry Wentland #include "transform.h" 454562236bSHarry Wentland #include "stream_encoder.h" 464562236bSHarry Wentland #include "link_encoder.h" 4764d283cbSJimmy Kizito #include "link_enc_cfg.h" 4887401969SAndrew Jiang #include "link_hwss.h" 494370f72eSWenjing Liu #include "link.h" 5064b1d0e8SNicholas Kazlauskas #include "dccg.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" 573550d622SLeo (Hanghong) Ma #include "dpcd_defs.h" 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 65a76eb7d3SLee Jones #include "dcn10/dcn10_hw_sequencer.h" 666e4a14ccSLee Jones 6764cf26f0SIsabella Basso #include "dce110_hw_sequencer.h" 6864cf26f0SIsabella Basso 6978c77382SAnthony Koo #define GAMMA_HW_POINTS_NUM 256 7078c77382SAnthony Koo 7187401969SAndrew Jiang /* 7287401969SAndrew Jiang * All values are in milliseconds; 7387401969SAndrew Jiang * For eDP, after power-up/power/down, 7487401969SAndrew Jiang * 300/500 msec max. delay from LCDVCC to black video generation 7587401969SAndrew Jiang */ 7687401969SAndrew Jiang #define PANEL_POWER_UP_TIMEOUT 300 7787401969SAndrew Jiang #define PANEL_POWER_DOWN_TIMEOUT 500 7887401969SAndrew Jiang #define HPD_CHECK_INTERVAL 10 7996577cf8SHersen Wu #define OLED_POST_T7_DELAY 100 8096577cf8SHersen Wu #define OLED_PRE_T11_DELAY 150 8187401969SAndrew Jiang 825eefbc40SYue Hin Lau #define CTX \ 835eefbc40SYue Hin Lau hws->ctx 845d4b05ddSBhawanpreet Lakha 855d4b05ddSBhawanpreet Lakha #define DC_LOGGER_INIT() 865d4b05ddSBhawanpreet Lakha 875eefbc40SYue Hin Lau #define REG(reg)\ 885eefbc40SYue Hin Lau hws->regs->reg 895eefbc40SYue Hin Lau 905eefbc40SYue Hin Lau #undef FN 915eefbc40SYue Hin Lau #define FN(reg_name, field_name) \ 925eefbc40SYue Hin Lau hws->shifts->field_name, hws->masks->field_name 935eefbc40SYue Hin Lau 944562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 954562236bSHarry Wentland uint32_t crtc; 964562236bSHarry Wentland }; 974562236bSHarry Wentland 984562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 994562236bSHarry Wentland { 1004562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1014562236bSHarry Wentland }, 1024562236bSHarry Wentland { 1034562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1044562236bSHarry Wentland }, 1054562236bSHarry Wentland { 1064562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1074562236bSHarry Wentland }, 1084562236bSHarry Wentland { 1094562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1104562236bSHarry Wentland } 1114562236bSHarry Wentland }; 1124562236bSHarry Wentland 1134562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 1144562236bSHarry Wentland (reg + reg_offsets[id].blnd) 1154562236bSHarry Wentland 1164562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 1174562236bSHarry Wentland (reg + reg_offsets[id].crtc) 1184562236bSHarry Wentland 1194562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 1204562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 1214562236bSHarry Wentland 1224562236bSHarry Wentland /******************************************************************************* 1234562236bSHarry Wentland * Private definitions 1244562236bSHarry Wentland ******************************************************************************/ 1254562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 1264562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 1274562236bSHarry Wentland { 1284562236bSHarry Wentland uint32_t addr; 1294562236bSHarry Wentland uint32_t value = 0; 1304562236bSHarry Wentland uint32_t chunk_int = 0; 1314562236bSHarry Wentland uint32_t chunk_mul = 0; 1324562236bSHarry Wentland 1334562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 1344562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1354562236bSHarry Wentland 1364562236bSHarry Wentland set_reg_field_value( 1374562236bSHarry Wentland value, 1384562236bSHarry Wentland 0, 1394562236bSHarry Wentland DVMM_PTE_CONTROL, 1404562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1414562236bSHarry Wentland 1424562236bSHarry Wentland set_reg_field_value( 1434562236bSHarry Wentland value, 1444562236bSHarry Wentland 1, 1454562236bSHarry Wentland DVMM_PTE_CONTROL, 1464562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1474562236bSHarry Wentland 1484562236bSHarry Wentland set_reg_field_value( 1494562236bSHarry Wentland value, 1504562236bSHarry Wentland 1, 1514562236bSHarry Wentland DVMM_PTE_CONTROL, 1524562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1534562236bSHarry Wentland 1544562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1554562236bSHarry Wentland 1564562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1574562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1584562236bSHarry Wentland 1594562236bSHarry Wentland chunk_int = get_reg_field_value( 1604562236bSHarry Wentland value, 1614562236bSHarry Wentland DVMM_PTE_REQ, 1624562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1634562236bSHarry Wentland 1644562236bSHarry Wentland chunk_mul = get_reg_field_value( 1654562236bSHarry Wentland value, 1664562236bSHarry Wentland DVMM_PTE_REQ, 1674562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1684562236bSHarry Wentland 1694562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1704562236bSHarry Wentland 1714562236bSHarry Wentland set_reg_field_value( 1724562236bSHarry Wentland value, 1734562236bSHarry Wentland 255, 1744562236bSHarry Wentland DVMM_PTE_REQ, 1754562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1764562236bSHarry Wentland 1774562236bSHarry Wentland set_reg_field_value( 1784562236bSHarry Wentland value, 1794562236bSHarry Wentland 4, 1804562236bSHarry Wentland DVMM_PTE_REQ, 1814562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1824562236bSHarry Wentland 1834562236bSHarry Wentland set_reg_field_value( 1844562236bSHarry Wentland value, 1854562236bSHarry Wentland 4, 1864562236bSHarry Wentland DVMM_PTE_REQ, 1874562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1884562236bSHarry Wentland 1894562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1904562236bSHarry Wentland } 1914562236bSHarry Wentland } 1924562236bSHarry Wentland /**************************************************************************/ 1934562236bSHarry Wentland 1944562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1954562236bSHarry Wentland struct dc_context *ctx, 1964562236bSHarry Wentland bool clock_gating) 1974562236bSHarry Wentland { 1984562236bSHarry Wentland /*TODO*/ 1994562236bSHarry Wentland } 2004562236bSHarry Wentland 2014562236bSHarry Wentland static bool dce110_enable_display_power_gating( 202fb3466a4SBhawanpreet Lakha struct dc *dc, 2034562236bSHarry Wentland uint8_t controller_id, 2044562236bSHarry Wentland struct dc_bios *dcb, 2054562236bSHarry Wentland enum pipe_gating_control power_gating) 2064562236bSHarry Wentland { 2074562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 2084562236bSHarry Wentland enum bp_pipe_control_action cntl; 2094562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 2104562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 2114562236bSHarry Wentland 2124562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 2134562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 2144562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 2154562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 2164562236bSHarry Wentland else 2174562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 2184562236bSHarry Wentland 2194562236bSHarry Wentland if (controller_id == underlay_idx) 2204562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 2214562236bSHarry Wentland 2224562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) { 2234562236bSHarry Wentland 2244562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 2254562236bSHarry Wentland dcb, controller_id + 1, cntl); 2264562236bSHarry Wentland 2274562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 2284562236bSHarry Wentland * by default when command table is called 2294562236bSHarry Wentland * 2304562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 2314562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 2324562236bSHarry Wentland * than 3. 2334562236bSHarry Wentland */ 2344562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 2354562236bSHarry Wentland dm_write_reg(ctx, 2364562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 2374562236bSHarry Wentland 0); 2384562236bSHarry Wentland } 2394562236bSHarry Wentland 2404562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2414562236bSHarry Wentland dce110_init_pte(ctx); 2424562236bSHarry Wentland 2434562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2444562236bSHarry Wentland return true; 2454562236bSHarry Wentland else 2464562236bSHarry Wentland return false; 2474562236bSHarry Wentland } 2484562236bSHarry Wentland 2494562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2503be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2514562236bSHarry Wentland { 2524562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2534562236bSHarry Wentland 2543be5262eSHarry Wentland switch (plane_state->format) { 2551352c779SNicholas Kazlauskas case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 2561352c779SNicholas Kazlauskas prescale_params->scale = 0x2082; 2571352c779SNicholas Kazlauskas break; 2584562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2598693049aSTony Cheng case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 2604562236bSHarry Wentland prescale_params->scale = 0x2020; 2614562236bSHarry Wentland break; 2624562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2634562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2644562236bSHarry Wentland prescale_params->scale = 0x2008; 2654562236bSHarry Wentland break; 2664562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 267050cd3d6SMario Kleiner case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: 2684562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2694562236bSHarry Wentland prescale_params->scale = 0x2000; 2704562236bSHarry Wentland break; 2714562236bSHarry Wentland default: 2724562236bSHarry Wentland ASSERT(false); 273d7194cf6SAric Cyr break; 2744562236bSHarry Wentland } 2754562236bSHarry Wentland } 2764562236bSHarry Wentland 277a6114e85SHarry Wentland static bool 27878c77382SAnthony Koo dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 2793be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2804562236bSHarry Wentland { 28186a66c4eSHarry Wentland struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 2827b0c470fSLeo (Sunpeng) Li const struct dc_transfer_func *tf = NULL; 28390e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 28490e508baSAnthony Koo bool result = true; 28590e508baSAnthony Koo 28690e508baSAnthony Koo if (ipp == NULL) 28790e508baSAnthony Koo return false; 28890e508baSAnthony Koo 2893be5262eSHarry Wentland if (plane_state->in_transfer_func) 2903be5262eSHarry Wentland tf = plane_state->in_transfer_func; 29190e508baSAnthony Koo 2923be5262eSHarry Wentland build_prescale_params(&prescale_params, plane_state); 29390e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 29490e508baSAnthony Koo 29584ffa801SLeo (Sunpeng) Li if (plane_state->gamma_correction && 29684ffa801SLeo (Sunpeng) Li !plane_state->gamma_correction->is_identity && 29784ffa801SLeo (Sunpeng) Li dce_use_lut(plane_state->format)) 2983be5262eSHarry Wentland ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction); 299d7194cf6SAric Cyr 30090e508baSAnthony Koo if (tf == NULL) { 30190e508baSAnthony Koo /* Default case if no input transfer function specified */ 302a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 3037b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_PREDEFINED) { 3047b0c470fSLeo (Sunpeng) Li switch (tf->tf) { 30590e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 306a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 30790e508baSAnthony Koo break; 30890e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 309a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC); 31090e508baSAnthony Koo break; 31190e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 312a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 31390e508baSAnthony Koo break; 31490e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 31590e508baSAnthony Koo default: 31690e508baSAnthony Koo result = false; 317d7194cf6SAric Cyr break; 31890e508baSAnthony Koo } 3197b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_BYPASS) { 32070063a59SAmy Zhang ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 32190e508baSAnthony Koo } else { 32290e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 32390e508baSAnthony Koo result = false; 32490e508baSAnthony Koo } 32590e508baSAnthony Koo 32690e508baSAnthony Koo return result; 32790e508baSAnthony Koo } 32890e508baSAnthony Koo 329bd1be8e8SHarry Wentland static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted, 330fcd2f4bfSAmy Zhang struct curve_points *arr_points, 331fcd2f4bfSAmy Zhang uint32_t hw_points_num) 332fcd2f4bfSAmy Zhang { 333fcd2f4bfSAmy Zhang struct custom_float_format fmt; 334fcd2f4bfSAmy Zhang 335fcd2f4bfSAmy Zhang struct pwl_result_data *rgb = rgb_resulted; 336fcd2f4bfSAmy Zhang 337fcd2f4bfSAmy Zhang uint32_t i = 0; 338fcd2f4bfSAmy Zhang 339fcd2f4bfSAmy Zhang fmt.exponenta_bits = 6; 340fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 341fcd2f4bfSAmy Zhang fmt.sign = true; 342fcd2f4bfSAmy Zhang 343bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].x, &fmt, 344fcd2f4bfSAmy Zhang &arr_points[0].custom_float_x)) { 345fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 346fcd2f4bfSAmy Zhang return false; 347fcd2f4bfSAmy Zhang } 348fcd2f4bfSAmy Zhang 349bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].offset, &fmt, 350fcd2f4bfSAmy Zhang &arr_points[0].custom_float_offset)) { 351fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 352fcd2f4bfSAmy Zhang return false; 353fcd2f4bfSAmy Zhang } 354fcd2f4bfSAmy Zhang 355bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].slope, &fmt, 356fcd2f4bfSAmy Zhang &arr_points[0].custom_float_slope)) { 357fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 358fcd2f4bfSAmy Zhang return false; 359fcd2f4bfSAmy Zhang } 360fcd2f4bfSAmy Zhang 361fcd2f4bfSAmy Zhang fmt.mantissa_bits = 10; 362fcd2f4bfSAmy Zhang fmt.sign = false; 363fcd2f4bfSAmy Zhang 364bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].x, &fmt, 365fcd2f4bfSAmy Zhang &arr_points[1].custom_float_x)) { 366fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 367fcd2f4bfSAmy Zhang return false; 368fcd2f4bfSAmy Zhang } 369fcd2f4bfSAmy Zhang 370bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].y, &fmt, 371fcd2f4bfSAmy Zhang &arr_points[1].custom_float_y)) { 372fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 373fcd2f4bfSAmy Zhang return false; 374fcd2f4bfSAmy Zhang } 375fcd2f4bfSAmy Zhang 3764d06ccd0SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].slope, &fmt, 3774d06ccd0SHarry Wentland &arr_points[1].custom_float_slope)) { 378fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 379fcd2f4bfSAmy Zhang return false; 380fcd2f4bfSAmy Zhang } 381fcd2f4bfSAmy Zhang 382fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 383fcd2f4bfSAmy Zhang fmt.sign = true; 384fcd2f4bfSAmy Zhang 385fcd2f4bfSAmy Zhang while (i != hw_points_num) { 386bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->red, &fmt, 387fcd2f4bfSAmy Zhang &rgb->red_reg)) { 388fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 389fcd2f4bfSAmy Zhang return false; 390fcd2f4bfSAmy Zhang } 391fcd2f4bfSAmy Zhang 392bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->green, &fmt, 393fcd2f4bfSAmy Zhang &rgb->green_reg)) { 394fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 395fcd2f4bfSAmy Zhang return false; 396fcd2f4bfSAmy Zhang } 397fcd2f4bfSAmy Zhang 398bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->blue, &fmt, 399fcd2f4bfSAmy Zhang &rgb->blue_reg)) { 400fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 401fcd2f4bfSAmy Zhang return false; 402fcd2f4bfSAmy Zhang } 403fcd2f4bfSAmy Zhang 404bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_red, &fmt, 405fcd2f4bfSAmy Zhang &rgb->delta_red_reg)) { 406fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 407fcd2f4bfSAmy Zhang return false; 408fcd2f4bfSAmy Zhang } 409fcd2f4bfSAmy Zhang 410bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_green, &fmt, 411fcd2f4bfSAmy Zhang &rgb->delta_green_reg)) { 412fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 413fcd2f4bfSAmy Zhang return false; 414fcd2f4bfSAmy Zhang } 415fcd2f4bfSAmy Zhang 416bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_blue, &fmt, 417fcd2f4bfSAmy Zhang &rgb->delta_blue_reg)) { 418fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 419fcd2f4bfSAmy Zhang return false; 420fcd2f4bfSAmy Zhang } 421fcd2f4bfSAmy Zhang 422fcd2f4bfSAmy Zhang ++rgb; 423fcd2f4bfSAmy Zhang ++i; 424fcd2f4bfSAmy Zhang } 425fcd2f4bfSAmy Zhang 426fcd2f4bfSAmy Zhang return true; 427fcd2f4bfSAmy Zhang } 428fcd2f4bfSAmy Zhang 42908616da5SLeo (Sunpeng) Li #define MAX_LOW_POINT 25 4308f8372c7SKrunoslav Kovac #define NUMBER_REGIONS 16 4318f8372c7SKrunoslav Kovac #define NUMBER_SW_SEGMENTS 16 4328f8372c7SKrunoslav Kovac 433b310b081SHarry Wentland static bool 434b310b081SHarry Wentland dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, 435b310b081SHarry Wentland struct pwl_params *regamma_params) 436fcd2f4bfSAmy Zhang { 43723ae4f8eSAmy Zhang struct curve_points *arr_points; 43823ae4f8eSAmy Zhang struct pwl_result_data *rgb_resulted; 43923ae4f8eSAmy Zhang struct pwl_result_data *rgb; 44023ae4f8eSAmy Zhang struct pwl_result_data *rgb_plus_1; 441fcd2f4bfSAmy Zhang struct fixed31_32 y_r; 442fcd2f4bfSAmy Zhang struct fixed31_32 y_g; 443fcd2f4bfSAmy Zhang struct fixed31_32 y_b; 444fcd2f4bfSAmy Zhang struct fixed31_32 y1_min; 445fcd2f4bfSAmy Zhang struct fixed31_32 y3_max; 446fcd2f4bfSAmy Zhang 4478f8372c7SKrunoslav Kovac int32_t region_start, region_end; 4488f8372c7SKrunoslav Kovac uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points; 44923ae4f8eSAmy Zhang 450b310b081SHarry Wentland if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS) 45123ae4f8eSAmy Zhang return false; 45223ae4f8eSAmy Zhang 45323ae4f8eSAmy Zhang arr_points = regamma_params->arr_points; 45423ae4f8eSAmy Zhang rgb_resulted = regamma_params->rgb_resulted; 45523ae4f8eSAmy Zhang hw_points = 0; 456fcd2f4bfSAmy Zhang 457fcd2f4bfSAmy Zhang memset(regamma_params, 0, sizeof(struct pwl_params)); 458fcd2f4bfSAmy Zhang 459fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 460534db198SAmy Zhang /* 16 segments 461fcd2f4bfSAmy Zhang * segments are from 2^-11 to 2^5 462fcd2f4bfSAmy Zhang */ 46308616da5SLeo (Sunpeng) Li region_start = -11; 46408616da5SLeo (Sunpeng) Li region_end = region_start + NUMBER_REGIONS; 465fcd2f4bfSAmy Zhang 4668f8372c7SKrunoslav Kovac for (i = 0; i < NUMBER_REGIONS; i++) 4678f8372c7SKrunoslav Kovac seg_distr[i] = 4; 468534db198SAmy Zhang 469fcd2f4bfSAmy Zhang } else { 470534db198SAmy Zhang /* 10 segments 471fc6de1c5SLeo (Sunpeng) Li * segment is from 2^-10 to 2^1 472fc6de1c5SLeo (Sunpeng) Li * We include an extra segment for range [2^0, 2^1). This is to 473fc6de1c5SLeo (Sunpeng) Li * ensure that colors with normalized values of 1 don't miss the 474fc6de1c5SLeo (Sunpeng) Li * LUT. 475fcd2f4bfSAmy Zhang */ 4768f8372c7SKrunoslav Kovac region_start = -10; 477fc6de1c5SLeo (Sunpeng) Li region_end = 1; 478534db198SAmy Zhang 4798f8372c7SKrunoslav Kovac seg_distr[0] = 4; 480534db198SAmy Zhang seg_distr[1] = 4; 481534db198SAmy Zhang seg_distr[2] = 4; 482534db198SAmy Zhang seg_distr[3] = 4; 483534db198SAmy Zhang seg_distr[4] = 4; 484534db198SAmy Zhang seg_distr[5] = 4; 485534db198SAmy Zhang seg_distr[6] = 4; 486534db198SAmy Zhang seg_distr[7] = 4; 4878f8372c7SKrunoslav Kovac seg_distr[8] = 4; 4888f8372c7SKrunoslav Kovac seg_distr[9] = 4; 489fc6de1c5SLeo (Sunpeng) Li seg_distr[10] = 0; 490534db198SAmy Zhang seg_distr[11] = -1; 491534db198SAmy Zhang seg_distr[12] = -1; 492534db198SAmy Zhang seg_distr[13] = -1; 493534db198SAmy Zhang seg_distr[14] = -1; 494534db198SAmy Zhang seg_distr[15] = -1; 495fcd2f4bfSAmy Zhang } 496fcd2f4bfSAmy Zhang 497534db198SAmy Zhang for (k = 0; k < 16; k++) { 498534db198SAmy Zhang if (seg_distr[k] != -1) 499534db198SAmy Zhang hw_points += (1 << seg_distr[k]); 500534db198SAmy Zhang } 501534db198SAmy Zhang 502fcd2f4bfSAmy Zhang j = 0; 5038f8372c7SKrunoslav Kovac for (k = 0; k < (region_end - region_start); k++) { 504ec47734aSLeo (Sunpeng) Li increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 5058f8372c7SKrunoslav Kovac start_index = (region_start + k + MAX_LOW_POINT) * 5068f8372c7SKrunoslav Kovac NUMBER_SW_SEGMENTS; 5078f8372c7SKrunoslav Kovac for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 5088f8372c7SKrunoslav Kovac i += increment) { 509534db198SAmy Zhang if (j == hw_points - 1) 510fcd2f4bfSAmy Zhang break; 511fcd2f4bfSAmy Zhang rgb_resulted[j].red = output_tf->tf_pts.red[i]; 512fcd2f4bfSAmy Zhang rgb_resulted[j].green = output_tf->tf_pts.green[i]; 513fcd2f4bfSAmy Zhang rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 514fcd2f4bfSAmy Zhang j++; 515fcd2f4bfSAmy Zhang } 516534db198SAmy Zhang } 517534db198SAmy Zhang 518534db198SAmy Zhang /* last point */ 5198f8372c7SKrunoslav Kovac start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 520b310b081SHarry Wentland rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 521b310b081SHarry Wentland rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 522b310b081SHarry Wentland rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 523fcd2f4bfSAmy Zhang 524eb0e5154SDmytro Laktyushkin arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2), 525eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_start)); 526eb0e5154SDmytro Laktyushkin arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2), 527eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_end)); 528fcd2f4bfSAmy Zhang 529fcd2f4bfSAmy Zhang y_r = rgb_resulted[0].red; 530fcd2f4bfSAmy Zhang y_g = rgb_resulted[0].green; 531fcd2f4bfSAmy Zhang y_b = rgb_resulted[0].blue; 532fcd2f4bfSAmy Zhang 533eb0e5154SDmytro Laktyushkin y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b)); 534fcd2f4bfSAmy Zhang 535fcd2f4bfSAmy Zhang arr_points[0].y = y1_min; 536eb0e5154SDmytro Laktyushkin arr_points[0].slope = dc_fixpt_div(arr_points[0].y, 537fcd2f4bfSAmy Zhang arr_points[0].x); 538fcd2f4bfSAmy Zhang 539fcd2f4bfSAmy Zhang y_r = rgb_resulted[hw_points - 1].red; 540fcd2f4bfSAmy Zhang y_g = rgb_resulted[hw_points - 1].green; 541fcd2f4bfSAmy Zhang y_b = rgb_resulted[hw_points - 1].blue; 542fcd2f4bfSAmy Zhang 543fcd2f4bfSAmy Zhang /* see comment above, m_arrPoints[1].y should be the Y value for the 544fcd2f4bfSAmy Zhang * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 545fcd2f4bfSAmy Zhang */ 546eb0e5154SDmytro Laktyushkin y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b)); 547fcd2f4bfSAmy Zhang 548fcd2f4bfSAmy Zhang arr_points[1].y = y3_max; 549fcd2f4bfSAmy Zhang 550eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_zero; 551fcd2f4bfSAmy Zhang 552fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 553fcd2f4bfSAmy Zhang /* for PQ, we want to have a straight line from last HW X point, 554fcd2f4bfSAmy Zhang * and the slope to be such that we hit 1.0 at 10000 nits. 555fcd2f4bfSAmy Zhang */ 556eb0e5154SDmytro Laktyushkin const struct fixed31_32 end_value = dc_fixpt_from_int(125); 557fcd2f4bfSAmy Zhang 558eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_div( 559eb0e5154SDmytro Laktyushkin dc_fixpt_sub(dc_fixpt_one, arr_points[1].y), 560eb0e5154SDmytro Laktyushkin dc_fixpt_sub(end_value, arr_points[1].x)); 561fcd2f4bfSAmy Zhang } 562fcd2f4bfSAmy Zhang 563fcd2f4bfSAmy Zhang regamma_params->hw_points_num = hw_points; 564fcd2f4bfSAmy Zhang 56569133b89SAric Cyr k = 0; 56669133b89SAric Cyr for (i = 1; i < 16; i++) { 567534db198SAmy Zhang if (seg_distr[k] != -1) { 568b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 569534db198SAmy Zhang regamma_params->arr_curve_points[i].offset = 570b310b081SHarry Wentland regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 571fcd2f4bfSAmy Zhang } 57269133b89SAric Cyr k++; 573534db198SAmy Zhang } 574534db198SAmy Zhang 575534db198SAmy Zhang if (seg_distr[k] != -1) 576b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 577fcd2f4bfSAmy Zhang 57823ae4f8eSAmy Zhang rgb = rgb_resulted; 57923ae4f8eSAmy Zhang rgb_plus_1 = rgb_resulted + 1; 580fcd2f4bfSAmy Zhang 581fcd2f4bfSAmy Zhang i = 1; 582fcd2f4bfSAmy Zhang 583fcd2f4bfSAmy Zhang while (i != hw_points + 1) { 584eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) 585fcd2f4bfSAmy Zhang rgb_plus_1->red = rgb->red; 586eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) 587fcd2f4bfSAmy Zhang rgb_plus_1->green = rgb->green; 588eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) 589fcd2f4bfSAmy Zhang rgb_plus_1->blue = rgb->blue; 590fcd2f4bfSAmy Zhang 591eb0e5154SDmytro Laktyushkin rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); 592eb0e5154SDmytro Laktyushkin rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 593eb0e5154SDmytro Laktyushkin rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 594fcd2f4bfSAmy Zhang 595fcd2f4bfSAmy Zhang ++rgb_plus_1; 596fcd2f4bfSAmy Zhang ++rgb; 597fcd2f4bfSAmy Zhang ++i; 598fcd2f4bfSAmy Zhang } 599fcd2f4bfSAmy Zhang 600fcd2f4bfSAmy Zhang convert_to_custom_float(rgb_resulted, arr_points, hw_points); 601fcd2f4bfSAmy Zhang 602fcd2f4bfSAmy Zhang return true; 603fcd2f4bfSAmy Zhang } 604fcd2f4bfSAmy Zhang 605a6114e85SHarry Wentland static bool 60678c77382SAnthony Koo dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 6070971c40eSHarry Wentland const struct dc_stream_state *stream) 60890e508baSAnthony Koo { 60986a66c4eSHarry Wentland struct transform *xfm = pipe_ctx->plane_res.xfm; 6104562236bSHarry Wentland 6117a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, true); 6127a09f5beSYue Hin Lau xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 6134562236bSHarry Wentland 6144fa086b9SLeo (Sunpeng) Li if (stream->out_transfer_func && 615efd52204SHarry Wentland stream->out_transfer_func->type == TF_TYPE_PREDEFINED && 616efd52204SHarry Wentland stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) { 6177a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 618efd52204SHarry Wentland } else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func, 619efd52204SHarry Wentland &xfm->regamma_params)) { 6207a09f5beSYue Hin Lau xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 6217a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 6224562236bSHarry Wentland } else { 6237a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 6244562236bSHarry Wentland } 6254562236bSHarry Wentland 6267a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, false); 6274562236bSHarry Wentland 628cc0cb445SLeon Elazar return true; 6294562236bSHarry Wentland } 6304562236bSHarry Wentland 6314562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 6324562236bSHarry Wentland { 63302553f57SEric Bernstein bool is_hdmi_tmds; 6346f0db2dcSKrunoslav Kovac bool is_dp; 6356f0db2dcSKrunoslav Kovac 63686e2e1beSHersen Wu ASSERT(pipe_ctx->stream); 63786e2e1beSHersen Wu 6388e9c4c8cSHarry Wentland if (pipe_ctx->stream_res.stream_enc == NULL) 63986e2e1beSHersen Wu return; /* this is not root pipe */ 64086e2e1beSHersen Wu 64102553f57SEric Bernstein is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal); 6426f0db2dcSKrunoslav Kovac is_dp = dc_is_dp_signal(pipe_ctx->stream->signal); 6436f0db2dcSKrunoslav Kovac 64402553f57SEric Bernstein if (!is_hdmi_tmds && !is_dp) 6456f0db2dcSKrunoslav Kovac return; 6466f0db2dcSKrunoslav Kovac 64702553f57SEric Bernstein if (is_hdmi_tmds) 6488e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 6498e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 65096c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 651e95afc1cSSung Joon Kim else { 652e95afc1cSSung Joon Kim if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num) 653e95afc1cSSung Joon Kim pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num( 654e95afc1cSSung Joon Kim pipe_ctx->stream_res.stream_enc, 655e95afc1cSSung Joon Kim &pipe_ctx->stream_res.encoder_info_frame); 656e95afc1cSSung Joon Kim 6578e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 6588e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 65996c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6604562236bSHarry Wentland } 661e95afc1cSSung Joon Kim } 6624562236bSHarry Wentland 6634562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 6644562236bSHarry Wentland { 6654562236bSHarry Wentland enum dc_lane_count lane_count = 666ceb3dbb4SJun Lei pipe_ctx->stream->link->cur_link_settings.lane_count; 6674fa086b9SLeo (Sunpeng) Li struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 668ceb3dbb4SJun Lei struct dc_link *link = pipe_ctx->stream->link; 669f42ea55bSAnthony Koo const struct dc *dc = link->dc; 6709d8033d6SWenjing Liu const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); 6714562236bSHarry Wentland uint32_t active_total_with_borders; 6724562236bSHarry Wentland uint32_t early_control = 0; 6736b670fa9SHarry Wentland struct timing_generator *tg = pipe_ctx->stream_res.tg; 6744562236bSHarry Wentland 6759d8033d6SWenjing Liu link_hwss->setup_stream_encoder(pipe_ctx); 676f215a57dSEric Yang 677f42ea55bSAnthony Koo dc->hwss.update_info_frame(pipe_ctx); 678f215a57dSEric Yang 6794562236bSHarry Wentland /* enable early control to avoid corruption on DP monitor*/ 6804562236bSHarry Wentland active_total_with_borders = 6814562236bSHarry Wentland timing->h_addressable 6824562236bSHarry Wentland + timing->h_border_left 6834562236bSHarry Wentland + timing->h_border_right; 6844562236bSHarry Wentland 6854562236bSHarry Wentland if (lane_count != 0) 6864562236bSHarry Wentland early_control = active_total_with_borders % lane_count; 6874562236bSHarry Wentland 6884562236bSHarry Wentland if (early_control == 0) 6894562236bSHarry Wentland early_control = lane_count; 6904562236bSHarry Wentland 6914562236bSHarry Wentland tg->funcs->set_early_control(tg, early_control); 6924562236bSHarry Wentland } 6934562236bSHarry Wentland 6945eefbc40SYue Hin Lau static enum bp_result link_transmitter_control( 69587401969SAndrew Jiang struct dc_bios *bios, 6965eefbc40SYue Hin Lau struct bp_transmitter_control *cntl) 6975eefbc40SYue Hin Lau { 6985eefbc40SYue Hin Lau enum bp_result result; 6995eefbc40SYue Hin Lau 70087401969SAndrew Jiang result = bios->funcs->transmitter_control(bios, cntl); 7015eefbc40SYue Hin Lau 7025eefbc40SYue Hin Lau return result; 7035eefbc40SYue Hin Lau } 7045eefbc40SYue Hin Lau 70587401969SAndrew Jiang /* 70687401969SAndrew Jiang * @brief 70787401969SAndrew Jiang * eDP only. 70887401969SAndrew Jiang */ 7098a31820bSMartin Leung void dce110_edp_wait_for_hpd_ready( 710069d418fSAndrew Jiang struct dc_link *link, 71187401969SAndrew Jiang bool power_up) 71287401969SAndrew Jiang { 713069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 714069d418fSAndrew Jiang struct graphics_object_id connector = link->link_enc->connector; 71587401969SAndrew Jiang struct gpio *hpd; 71687401969SAndrew Jiang bool edp_hpd_high = false; 71787401969SAndrew Jiang uint32_t time_elapsed = 0; 71887401969SAndrew Jiang uint32_t timeout = power_up ? 71987401969SAndrew Jiang PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; 72087401969SAndrew Jiang 72187401969SAndrew Jiang if (dal_graphics_object_id_get_connector_id(connector) 72287401969SAndrew Jiang != CONNECTOR_ID_EDP) { 72387401969SAndrew Jiang BREAK_TO_DEBUGGER(); 72487401969SAndrew Jiang return; 72587401969SAndrew Jiang } 72687401969SAndrew Jiang 72787401969SAndrew Jiang if (!power_up) 72887401969SAndrew Jiang /* 72987401969SAndrew Jiang * From KV, we will not HPD low after turning off VCC - 73087401969SAndrew Jiang * instead, we will check the SW timer in power_up(). 73187401969SAndrew Jiang */ 73287401969SAndrew Jiang return; 73387401969SAndrew Jiang 73487401969SAndrew Jiang /* 73587401969SAndrew Jiang * When we power on/off the eDP panel, 73687401969SAndrew Jiang * we need to wait until SENSE bit is high/low. 73787401969SAndrew Jiang */ 73887401969SAndrew Jiang 73987401969SAndrew Jiang /* obtain HPD */ 74087401969SAndrew Jiang /* TODO what to do with this? */ 74198ce7d32SWenjing Liu hpd = ctx->dc->link_srv->get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); 74287401969SAndrew Jiang 74387401969SAndrew Jiang if (!hpd) { 74487401969SAndrew Jiang BREAK_TO_DEBUGGER(); 74587401969SAndrew Jiang return; 74687401969SAndrew Jiang } 74787401969SAndrew Jiang 748eccff6cdSIan Chen if (link != NULL) { 749eccff6cdSIan Chen if (link->panel_config.pps.extra_t3_ms > 0) { 750eccff6cdSIan Chen int extra_t3_in_ms = link->panel_config.pps.extra_t3_ms; 7516798d042SLewis Huang 7526798d042SLewis Huang msleep(extra_t3_in_ms); 7536798d042SLewis Huang } 7546798d042SLewis Huang } 7556798d042SLewis Huang 75687401969SAndrew Jiang dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); 75787401969SAndrew Jiang 75887401969SAndrew Jiang /* wait until timeout or panel detected */ 75987401969SAndrew Jiang 76087401969SAndrew Jiang do { 76187401969SAndrew Jiang uint32_t detected = 0; 76287401969SAndrew Jiang 76387401969SAndrew Jiang dal_gpio_get_value(hpd, &detected); 76487401969SAndrew Jiang 76587401969SAndrew Jiang if (!(detected ^ power_up)) { 76687401969SAndrew Jiang edp_hpd_high = true; 76787401969SAndrew Jiang break; 76887401969SAndrew Jiang } 76987401969SAndrew Jiang 77087401969SAndrew Jiang msleep(HPD_CHECK_INTERVAL); 77187401969SAndrew Jiang 77287401969SAndrew Jiang time_elapsed += HPD_CHECK_INTERVAL; 77387401969SAndrew Jiang } while (time_elapsed < timeout); 77487401969SAndrew Jiang 77587401969SAndrew Jiang dal_gpio_close(hpd); 77687401969SAndrew Jiang 77787401969SAndrew Jiang dal_gpio_destroy_irq(&hpd); 77887401969SAndrew Jiang 7796d9b6dceSHamza Mahfooz /* ensure that the panel is detected */ 78041519dc4SMario Limonciello if (!edp_hpd_high) 78141519dc4SMario Limonciello DC_LOG_DC("%s: wait timed out!\n", __func__); 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; 791*71be0f67SLewis Huang uint8_t pwrseq_instance; 79287401969SAndrew Jiang 79387401969SAndrew Jiang 794069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 79587401969SAndrew Jiang != CONNECTOR_ID_EDP) { 79687401969SAndrew Jiang BREAK_TO_DEBUGGER(); 79787401969SAndrew Jiang return; 79887401969SAndrew Jiang } 79987401969SAndrew Jiang 800ffadb9d6SAnthony Koo if (!link->panel_cntl) 801904fb6e0SAnthony Koo return; 802d4caa72eSAnthony Koo if (power_up != 803d4caa72eSAnthony Koo link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) { 804172c9b77SAshley Thomas 80578d5d04dSCharlene Liu unsigned long long current_ts = dm_get_timestamp(ctx); 806172c9b77SAshley Thomas unsigned long long time_since_edp_poweroff_ms = 80793ed1814SHugo Hu div64_u64(dm_get_elapse_time_in_ns( 80878d5d04dSCharlene Liu ctx, 80978d5d04dSCharlene Liu current_ts, 81098ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000); 811172c9b77SAshley Thomas unsigned long long time_since_edp_poweron_ms = 812172c9b77SAshley Thomas div64_u64(dm_get_elapse_time_in_ns( 813172c9b77SAshley Thomas ctx, 814172c9b77SAshley Thomas current_ts, 81598ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)), 1000000); 816172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 817172c9b77SAshley Thomas "%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu", 818172c9b77SAshley Thomas __func__, 819172c9b77SAshley Thomas power_up, 820172c9b77SAshley Thomas current_ts, 82198ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link), 82298ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link), 823172c9b77SAshley Thomas time_since_edp_poweroff_ms, 824172c9b77SAshley Thomas time_since_edp_poweron_ms); 82578d5d04dSCharlene Liu 826172c9b77SAshley Thomas /* Send VBIOS command to prompt eDP panel power */ 827172c9b77SAshley Thomas if (power_up) { 828172c9b77SAshley Thomas /* edp requires a min of 500ms from LCDVDD off to on */ 829172c9b77SAshley Thomas unsigned long long remaining_min_edp_poweroff_time_ms = 500; 830ff587987SHugo Hu 831172c9b77SAshley Thomas /* add time defined by a patch, if any (usually patch extra_t12_ms is 0) */ 8326c4fff06SYue Hin Lau if (link->local_sink != NULL) 833172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms += 834eccff6cdSIan Chen link->panel_config.pps.extra_t12_ms; 83578d5d04dSCharlene Liu 836172c9b77SAshley Thomas /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */ 83798ce7d32SWenjing Liu if (ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) { 838172c9b77SAshley Thomas if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms) 839172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms = 840172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms; 841172c9b77SAshley Thomas else 842172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms = 0; 84378d5d04dSCharlene Liu } 84478d5d04dSCharlene Liu 845172c9b77SAshley Thomas if (remaining_min_edp_poweroff_time_ms) { 846172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 847172c9b77SAshley Thomas "%s: remaining_min_edp_poweroff_time_ms=%llu: begin wait.\n", 848172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 849172c9b77SAshley Thomas msleep(remaining_min_edp_poweroff_time_ms); 850172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 851172c9b77SAshley Thomas "%s: remaining_min_edp_poweroff_time_ms=%llu: end wait.\n", 852172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 853172c9b77SAshley Thomas dm_output_to_console("%s: wait %lld ms to power on eDP.\n", 854172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 855172c9b77SAshley Thomas } else { 856172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 857172c9b77SAshley Thomas "%s: remaining_min_edp_poweroff_time_ms=%llu: no wait required.\n", 858172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 859172c9b77SAshley Thomas } 86078d5d04dSCharlene Liu } 86187401969SAndrew Jiang 8621296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 863172c9b77SAshley Thomas "%s: BEGIN: Panel Power action: %s\n", 86487401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 86587401969SAndrew Jiang 86687401969SAndrew Jiang cntl.action = power_up ? 86787401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_ON : 86887401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_OFF; 869069d418fSAndrew Jiang cntl.transmitter = link->link_enc->transmitter; 870069d418fSAndrew Jiang cntl.connector_obj_id = link->link_enc->connector; 87187401969SAndrew Jiang cntl.coherent = false; 87287401969SAndrew Jiang cntl.lanes_number = LANE_COUNT_FOUR; 873069d418fSAndrew Jiang cntl.hpd_sel = link->link_enc->hpd_source; 874*71be0f67SLewis Huang pwrseq_instance = link->panel_cntl->pwrseq_inst; 8758a0e210cSChris Park 8768a0e210cSChris Park if (ctx->dc->ctx->dmub_srv && 8778a0e210cSChris Park ctx->dc->debug.dmub_command_table) { 8783351ce5dSTony Tascioglu 8793351ce5dSTony Tascioglu if (cntl.action == TRANSMITTER_CONTROL_POWER_ON) { 8808a0e210cSChris Park bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 88106ddcee4SJake Wang LVTMA_CONTROL_POWER_ON, 882*71be0f67SLewis Huang pwrseq_instance, link->link_powered_externally); 8833351ce5dSTony Tascioglu } else { 8848a0e210cSChris Park bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 88506ddcee4SJake Wang LVTMA_CONTROL_POWER_OFF, 886*71be0f67SLewis Huang pwrseq_instance, link->link_powered_externally); 8873351ce5dSTony Tascioglu } 8888a0e210cSChris Park } 8898a0e210cSChris Park 89087401969SAndrew Jiang bp_result = link_transmitter_control(ctx->dc_bios, &cntl); 89187401969SAndrew Jiang 892172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 893172c9b77SAshley Thomas "%s: END: Panel Power action: %s bp_result=%u\n", 894172c9b77SAshley Thomas __func__, (power_up ? "On":"Off"), 895172c9b77SAshley Thomas bp_result); 896172c9b77SAshley Thomas 89798ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_set_edp_power_timestamp(link, power_up); 89878d5d04dSCharlene Liu 899172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 900172c9b77SAshley Thomas "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n", 901172c9b77SAshley Thomas __func__, 90298ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link), 90398ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)); 904172c9b77SAshley Thomas 90587401969SAndrew Jiang if (bp_result != BP_RESULT_OK) 9061296423bSBhawanpreet Lakha DC_LOG_ERROR( 90787401969SAndrew Jiang "%s: Panel Power bp_result: %d\n", 90887401969SAndrew Jiang __func__, bp_result); 90987401969SAndrew Jiang } else { 9101296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 91187401969SAndrew Jiang "%s: Skipping Panel Power action: %s\n", 91287401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 91387401969SAndrew Jiang } 91487401969SAndrew Jiang } 9155eefbc40SYue Hin Lau 916cf3a2627SJun Lei void dce110_edp_wait_for_T12( 917cf3a2627SJun Lei struct dc_link *link) 918cf3a2627SJun Lei { 919cf3a2627SJun Lei struct dc_context *ctx = link->ctx; 920cf3a2627SJun Lei 921cf3a2627SJun Lei if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 922cf3a2627SJun Lei != CONNECTOR_ID_EDP) { 923cf3a2627SJun Lei BREAK_TO_DEBUGGER(); 924cf3a2627SJun Lei return; 925cf3a2627SJun Lei } 926cf3a2627SJun Lei 927cf3a2627SJun Lei if (!link->panel_cntl) 928cf3a2627SJun Lei return; 929cf3a2627SJun Lei 930cf3a2627SJun Lei if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) && 93198ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) { 932cf3a2627SJun Lei unsigned int t12_duration = 500; // Default T12 as per spec 933cf3a2627SJun Lei unsigned long long current_ts = dm_get_timestamp(ctx); 934cf3a2627SJun Lei unsigned long long time_since_edp_poweroff_ms = 935cf3a2627SJun Lei div64_u64(dm_get_elapse_time_in_ns( 936cf3a2627SJun Lei ctx, 937cf3a2627SJun Lei current_ts, 93898ce7d32SWenjing Liu ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000); 939cf3a2627SJun Lei 940eccff6cdSIan Chen t12_duration += link->panel_config.pps.extra_t12_ms; // Add extra T12 941cf3a2627SJun Lei 942cf3a2627SJun Lei if (time_since_edp_poweroff_ms < t12_duration) 943cf3a2627SJun Lei msleep(t12_duration - time_since_edp_poweroff_ms); 944cf3a2627SJun Lei } 945cf3a2627SJun Lei } 9465eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/ 9475eefbc40SYue Hin Lau /* 9485eefbc40SYue Hin Lau * @brief 9495eefbc40SYue Hin Lau * eDP only. Control the backlight of the eDP panel 9505eefbc40SYue Hin Lau */ 9518a31820bSMartin Leung void dce110_edp_backlight_control( 9525eefbc40SYue Hin Lau struct dc_link *link, 9535eefbc40SYue Hin Lau bool enable) 9545eefbc40SYue Hin Lau { 955069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 9565eefbc40SYue Hin Lau struct bp_transmitter_control cntl = { 0 }; 957*71be0f67SLewis Huang uint8_t pwrseq_instance; 958eccff6cdSIan Chen unsigned int pre_T11_delay = OLED_PRE_T11_DELAY; 959eccff6cdSIan Chen unsigned int post_T7_delay = OLED_POST_T7_DELAY; 9605eefbc40SYue Hin Lau 961069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 9625eefbc40SYue Hin Lau != CONNECTOR_ID_EDP) { 9635eefbc40SYue Hin Lau BREAK_TO_DEBUGGER(); 9645eefbc40SYue Hin Lau return; 9655eefbc40SYue Hin Lau } 9665eefbc40SYue Hin Lau 967f5b2c10bSSwapnil Patel if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled || 968f5b2c10bSSwapnil Patel link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || 969f5b2c10bSSwapnil Patel link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { 970014427adSSherry bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); 971014427adSSherry 972014427adSSherry if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { 9731296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 974014427adSSherry "%s: panel already powered up/off. Do nothing.\n", 9755eefbc40SYue Hin Lau __func__); 9765eefbc40SYue Hin Lau return; 9775eefbc40SYue Hin Lau } 978014427adSSherry } 9795eefbc40SYue Hin Lau 9805eefbc40SYue Hin Lau /* Send VBIOS command to control eDP panel backlight */ 9815eefbc40SYue Hin Lau 9821296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 9835eefbc40SYue Hin Lau "%s: backlight action: %s\n", 9845eefbc40SYue Hin Lau __func__, (enable ? "On":"Off")); 9855eefbc40SYue Hin Lau 9865eefbc40SYue Hin Lau cntl.action = enable ? 9875eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_ON : 9885eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_OFF; 98987401969SAndrew Jiang 9905eefbc40SYue Hin Lau /*cntl.engine_id = ctx->engine;*/ 9915eefbc40SYue Hin Lau cntl.transmitter = link->link_enc->transmitter; 9925eefbc40SYue Hin Lau cntl.connector_obj_id = link->link_enc->connector; 9935eefbc40SYue Hin Lau /*todo: unhardcode*/ 9945eefbc40SYue Hin Lau cntl.lanes_number = LANE_COUNT_FOUR; 9955eefbc40SYue Hin Lau cntl.hpd_sel = link->link_enc->hpd_source; 996cf1835f0SCharlene Liu cntl.signal = SIGNAL_TYPE_EDP; 9975eefbc40SYue Hin Lau 9985eefbc40SYue Hin Lau /* For eDP, the following delays might need to be considered 9995eefbc40SYue Hin Lau * after link training completed: 10005eefbc40SYue Hin Lau * idle period - min. accounts for required BS-Idle pattern, 10015eefbc40SYue Hin Lau * max. allows for source frame synchronization); 10025eefbc40SYue Hin Lau * 50 msec max. delay from valid video data from source 10035eefbc40SYue Hin Lau * to video on dislpay or backlight enable. 10045eefbc40SYue Hin Lau * 10055eefbc40SYue Hin Lau * Disable the delay for now. 10065eefbc40SYue Hin Lau * Enable it in the future if necessary. 10075eefbc40SYue Hin Lau */ 10085eefbc40SYue Hin Lau /* dc_service_sleep_in_milliseconds(50); */ 10095180d4a4SCharlene Liu /*edp 1.2*/ 1010*71be0f67SLewis Huang pwrseq_instance = link->panel_cntl->pwrseq_inst; 1011a5148245SZhan Liu 1012a5148245SZhan Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) { 1013a5148245SZhan Liu if (!link->dc->config.edp_no_power_sequencing) 1014a5148245SZhan Liu /* 1015a5148245SZhan Liu * Sometimes, DP receiver chip power-controlled externally by an 1016a5148245SZhan Liu * Embedded Controller could be treated and used as eDP, 1017a5148245SZhan Liu * if it drives mobile display. In this case, 1018a5148245SZhan Liu * we shouldn't be doing power-sequencing, hence we can skip 1019a5148245SZhan Liu * waiting for T7-ready. 1020a5148245SZhan Liu */ 102198ce7d32SWenjing Liu ctx->dc->link_srv->edp_receiver_ready_T7(link); 1022a5148245SZhan Liu else 1023a5148245SZhan Liu DC_LOG_DC("edp_receiver_ready_T7 skipped\n"); 1024a5148245SZhan Liu } 10258a0e210cSChris Park 1026e0886e1fSTony Tascioglu /* Setting link_powered_externally will bypass delays in the backlight 1027e0886e1fSTony Tascioglu * as they are not required if the link is being powered by a different 1028e0886e1fSTony Tascioglu * source. 1029e0886e1fSTony Tascioglu */ 10308a0e210cSChris Park if (ctx->dc->ctx->dmub_srv && 10318a0e210cSChris Park ctx->dc->debug.dmub_command_table) { 10328a0e210cSChris Park if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 10338a0e210cSChris Park ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 103406ddcee4SJake Wang LVTMA_CONTROL_LCD_BLON, 1035*71be0f67SLewis Huang pwrseq_instance, link->link_powered_externally); 10368a0e210cSChris Park else 10378a0e210cSChris Park ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 103806ddcee4SJake Wang LVTMA_CONTROL_LCD_BLOFF, 1039*71be0f67SLewis Huang pwrseq_instance, link->link_powered_externally); 10408a0e210cSChris Park } 10418a0e210cSChris Park 1042069d418fSAndrew Jiang link_transmitter_control(ctx->dc_bios, &cntl); 104396577cf8SHersen Wu 1044eccff6cdSIan Chen if (enable && link->dpcd_sink_ext_caps.bits.oled) { 1045eccff6cdSIan Chen post_T7_delay += link->panel_config.pps.extra_post_t7_ms; 1046eccff6cdSIan Chen msleep(post_T7_delay); 1047eccff6cdSIan Chen } 104896577cf8SHersen Wu 104996577cf8SHersen Wu if (link->dpcd_sink_ext_caps.bits.oled || 105096577cf8SHersen Wu link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || 105196577cf8SHersen Wu link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1) 105298ce7d32SWenjing Liu ctx->dc->link_srv->edp_backlight_enable_aux(link, enable); 105396577cf8SHersen Wu 105469b9723aSCharlene Liu /*edp 1.2*/ 1055a5148245SZhan Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) { 1056a5148245SZhan Liu if (!link->dc->config.edp_no_power_sequencing) 1057a5148245SZhan Liu /* 1058a5148245SZhan Liu * Sometimes, DP receiver chip power-controlled externally by an 1059a5148245SZhan Liu * Embedded Controller could be treated and used as eDP, 1060a5148245SZhan Liu * if it drives mobile display. In this case, 1061a5148245SZhan Liu * we shouldn't be doing power-sequencing, hence we can skip 1062a5148245SZhan Liu * waiting for T9-ready. 1063a5148245SZhan Liu */ 106498ce7d32SWenjing Liu ctx->dc->link_srv->edp_add_delay_for_T9(link); 1065a5148245SZhan Liu else 1066a5148245SZhan Liu DC_LOG_DC("edp_receiver_ready_T9 skipped\n"); 1067a5148245SZhan Liu } 106896577cf8SHersen Wu 1069eccff6cdSIan Chen if (!enable && link->dpcd_sink_ext_caps.bits.oled) { 1070eccff6cdSIan Chen pre_T11_delay += link->panel_config.pps.extra_pre_t11_ms; 1071eccff6cdSIan Chen msleep(pre_T11_delay); 1072eccff6cdSIan Chen } 10735eefbc40SYue Hin Lau } 10745eefbc40SYue Hin Lau 10751a05873fSAnthony Koo void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) 10764562236bSHarry Wentland { 10771a05873fSAnthony Koo /* notify audio driver for audio modes of monitor */ 10782b77dcc5SAnthony Koo struct dc *dc; 10791d0610bcSAlvin Lee struct clk_mgr *clk_mgr; 10801a05873fSAnthony Koo unsigned int i, num_audio = 1; 108114e2739cSWenjing Liu const struct link_hwss *link_hwss; 10821a05873fSAnthony Koo 10831d0610bcSAlvin Lee if (!pipe_ctx->stream) 10841d0610bcSAlvin Lee return; 10851d0610bcSAlvin Lee 10862b77dcc5SAnthony Koo dc = pipe_ctx->stream->ctx->dc; 10872b77dcc5SAnthony Koo clk_mgr = dc->clk_mgr; 108814e2739cSWenjing Liu link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res); 10891d0610bcSAlvin Lee 10900a32df9cSEryk Brol if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true) 10910a32df9cSEryk Brol return; 10920a32df9cSEryk Brol 10931a05873fSAnthony Koo if (pipe_ctx->stream_res.audio) { 10941a05873fSAnthony Koo for (i = 0; i < MAX_PIPES; i++) { 10951a05873fSAnthony Koo /*current_state not updated yet*/ 10962b77dcc5SAnthony Koo if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) 10971a05873fSAnthony Koo num_audio++; 10981a05873fSAnthony Koo } 10991a05873fSAnthony Koo 11001a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); 11011a05873fSAnthony Koo 1102170a2398SSu Sung Chung if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) 11031a05873fSAnthony Koo /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1104170a2398SSu Sung Chung clk_mgr->funcs->enable_pme_wa(clk_mgr); 110514e2739cSWenjing Liu 110614e2739cSWenjing Liu link_hwss->enable_audio_packet(pipe_ctx); 110714e2739cSWenjing Liu 11080a32df9cSEryk Brol if (pipe_ctx->stream_res.audio) 11090a32df9cSEryk Brol pipe_ctx->stream_res.audio->enabled = true; 11101a05873fSAnthony Koo } 11111a05873fSAnthony Koo } 11121a05873fSAnthony Koo 111357430404SSu Sung Chung void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) 11141a05873fSAnthony Koo { 11151d0610bcSAlvin Lee struct dc *dc; 11161d0610bcSAlvin Lee struct clk_mgr *clk_mgr; 111714e2739cSWenjing Liu const struct link_hwss *link_hwss; 11181d0610bcSAlvin Lee 11191d0610bcSAlvin Lee if (!pipe_ctx || !pipe_ctx->stream) 11201d0610bcSAlvin Lee return; 11211d0610bcSAlvin Lee 11221d0610bcSAlvin Lee dc = pipe_ctx->stream->ctx->dc; 11231d0610bcSAlvin Lee clk_mgr = dc->clk_mgr; 112414e2739cSWenjing Liu link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res); 11254562236bSHarry Wentland 11260a32df9cSEryk Brol if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false) 11270a32df9cSEryk Brol return; 11280a32df9cSEryk Brol 112914e2739cSWenjing Liu link_hwss->disable_audio_packet(pipe_ctx); 113014e2739cSWenjing Liu 1131afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio) { 11323f52aa9fSNicholas Kazlauskas pipe_ctx->stream_res.audio->enabled = false; 11333f52aa9fSNicholas Kazlauskas 1134170a2398SSu Sung Chung if (clk_mgr->funcs->enable_pme_wa) 1135070fe724SCharlene Liu /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1136170a2398SSu Sung Chung clk_mgr->funcs->enable_pme_wa(clk_mgr); 11374562236bSHarry Wentland 11384562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 11394562236bSHarry Wentland * add audio mode list change flag */ 11404562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 11414562236bSHarry Wentland * stream->stream_engine_id); 11424562236bSHarry Wentland */ 11434562236bSHarry Wentland } 11441a05873fSAnthony Koo } 11454562236bSHarry Wentland 114657430404SSu Sung Chung void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 11471a05873fSAnthony Koo { 11481a05873fSAnthony Koo struct dc_stream_state *stream = pipe_ctx->stream; 1149ceb3dbb4SJun Lei struct dc_link *link = stream->link; 11501a05873fSAnthony Koo struct dc *dc = pipe_ctx->stream->ctx->dc; 11519d8033d6SWenjing Liu const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); 11527462475eSWenjing Liu struct dccg *dccg = dc->res_pool->dccg; 11537462475eSWenjing Liu struct timing_generator *tg = pipe_ctx->stream_res.tg; 11547462475eSWenjing Liu struct dtbclk_dto_params dto_params = {0}; 11557462475eSWenjing Liu int dp_hpo_inst; 1156ec4b70dbSTaimur Hassan struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); 1157927e784cSTaimur Hassan struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; 11581a05873fSAnthony Koo 1159ac42fd63SWenjing Liu if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { 11601a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 11611a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 1162ac42fd63SWenjing Liu pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute( 1163ac42fd63SWenjing Liu pipe_ctx->stream_res.stream_enc); 1164ac42fd63SWenjing Liu } 11651a05873fSAnthony Koo 116698ce7d32SWenjing Liu if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 1167f01ee019SFangzhi Zuo pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets( 1168f01ee019SFangzhi Zuo pipe_ctx->stream_res.hpo_dp_stream_enc); 1169f01ee019SFangzhi Zuo } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) 11701a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 11711a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 11721a05873fSAnthony Koo 117357430404SSu Sung Chung dc->hwss.disable_audio_stream(pipe_ctx); 1174904623eeSYongqiang Sun 11759d8033d6SWenjing Liu link_hwss->reset_stream_encoder(pipe_ctx); 117664d283cbSJimmy Kizito 117798ce7d32SWenjing Liu if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 11787462475eSWenjing Liu dto_params.otg_inst = tg->inst; 11797462475eSWenjing Liu dto_params.timing = &pipe_ctx->stream->timing; 11807462475eSWenjing Liu dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; 11816f6583e5SMuhammad Ahmed if (dccg) { 11827462475eSWenjing Liu dccg->funcs->set_dtbclk_dto(dccg, &dto_params); 11837462475eSWenjing Liu dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); 11847462475eSWenjing Liu dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); 11856f6583e5SMuhammad Ahmed } 11866f6583e5SMuhammad Ahmed } else if (dccg && dccg->funcs->disable_symclk_se) { 1187ec4b70dbSTaimur Hassan dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, 1188ec4b70dbSTaimur Hassan link_enc->transmitter - TRANSMITTER_UNIPHY_A); 11896f6583e5SMuhammad Ahmed } 11907462475eSWenjing Liu 119198ce7d32SWenjing Liu if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 11929d8033d6SWenjing Liu /* TODO: This looks like a bug to me as we are disabling HPO IO when 11939d8033d6SWenjing Liu * we are just disabling a single HPO stream. Shouldn't we disable HPO 11949d8033d6SWenjing Liu * HW control only when HPOs for all streams are disabled? 11959d8033d6SWenjing Liu */ 11969d8033d6SWenjing Liu if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control) 11979d8033d6SWenjing Liu pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control( 11989d8033d6SWenjing Liu pipe_ctx->stream->ctx->dc->hwseq, false); 1199f01ee019SFangzhi Zuo } 12004562236bSHarry Wentland } 12014562236bSHarry Wentland 12024562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 12034562236bSHarry Wentland struct dc_link_settings *link_settings) 12044562236bSHarry Wentland { 12054562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 120641b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 1207ceb3dbb4SJun Lei struct dc_link *link = stream->link; 1208f42ea55bSAnthony Koo struct dce_hwseq *hws = link->dc->hwseq; 12094562236bSHarry Wentland 12104562236bSHarry Wentland /* only 3 items below are used by unblank */ 12117fe538a4SCharlene Liu params.timing = pipe_ctx->stream->timing; 12124562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 121341b49742SCharlene Liu 121441b49742SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 12153550d622SLeo (Hanghong) Ma pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); 121641b49742SCharlene Liu 121714d6f644SYongqiang Sun if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1218f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(link, true); 121914d6f644SYongqiang Sun } 122041b49742SCharlene Liu } 12212c850b7bSDmytro Laktyushkin 122241b49742SCharlene Liu void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 122341b49742SCharlene Liu { 122441b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 1225ceb3dbb4SJun Lei struct dc_link *link = stream->link; 1226f42ea55bSAnthony Koo struct dce_hwseq *hws = link->dc->hwseq; 122741b49742SCharlene Liu 1228ab892598SRoman Li if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1229a8728dbbSIan Chen if (!link->skip_implict_edp_power_control) 1230f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(link, false); 12313ba01817SYongqiang Sun link->dc->hwss.set_abm_immediate_disable(pipe_ctx); 1232ab892598SRoman Li } 123341b49742SCharlene Liu 123498ce7d32SWenjing Liu if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 1235f01ee019SFangzhi Zuo /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */ 1236f01ee019SFangzhi Zuo pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank( 1237f01ee019SFangzhi Zuo pipe_ctx->stream_res.hpo_dp_stream_enc); 1238f01ee019SFangzhi Zuo } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 12393550d622SLeo (Hanghong) Ma pipe_ctx->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc); 1240eec3303dSAric Cyr 12413a372bedSHugo Hu if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) { 1242eec3303dSAric Cyr /* 1243eec3303dSAric Cyr * After output is idle pattern some sinks need time to recognize the stream 1244eec3303dSAric Cyr * has changed or they enter protection state and hang. 1245eec3303dSAric Cyr */ 1246eec3303dSAric Cyr msleep(60); 1247a8201902SLeung, Martin } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) { 1248a8201902SLeung, Martin if (!link->dc->config.edp_no_power_sequencing) { 1249a8201902SLeung, Martin /* 1250a8201902SLeung, Martin * Sometimes, DP receiver chip power-controlled externally by an 1251a8201902SLeung, Martin * Embedded Controller could be treated and used as eDP, 1252a8201902SLeung, Martin * if it drives mobile display. In this case, 1253a8201902SLeung, Martin * we shouldn't be doing power-sequencing, hence we can skip 1254a8201902SLeung, Martin * waiting for T9-ready. 1255a8201902SLeung, Martin */ 125698ce7d32SWenjing Liu link->dc->link_srv->edp_receiver_ready_T9(link); 1257eec3303dSAric Cyr } 1258a8201902SLeung, Martin } 1259a8201902SLeung, Martin } 1260eec3303dSAric Cyr 12614562236bSHarry Wentland } 12624562236bSHarry Wentland 126315e17335SCharlene Liu 126415e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 126515e17335SCharlene Liu { 12668e9c4c8cSHarry Wentland if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL) 12678e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 126815e17335SCharlene Liu } 126915e17335SCharlene Liu 12704562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 12714562236bSHarry Wentland { 12724562236bSHarry Wentland switch (crtc_id) { 12734562236bSHarry Wentland case CONTROLLER_ID_D0: 12744562236bSHarry Wentland return DTO_SOURCE_ID0; 12754562236bSHarry Wentland case CONTROLLER_ID_D1: 12764562236bSHarry Wentland return DTO_SOURCE_ID1; 12774562236bSHarry Wentland case CONTROLLER_ID_D2: 12784562236bSHarry Wentland return DTO_SOURCE_ID2; 12794562236bSHarry Wentland case CONTROLLER_ID_D3: 12804562236bSHarry Wentland return DTO_SOURCE_ID3; 12814562236bSHarry Wentland case CONTROLLER_ID_D4: 12824562236bSHarry Wentland return DTO_SOURCE_ID4; 12834562236bSHarry Wentland case CONTROLLER_ID_D5: 12844562236bSHarry Wentland return DTO_SOURCE_ID5; 12854562236bSHarry Wentland default: 12864562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 12874562236bSHarry Wentland } 12884562236bSHarry Wentland } 12894562236bSHarry Wentland 12904562236bSHarry Wentland static void build_audio_output( 1291ab8db3e1SAndrey Grodzovsky struct dc_state *state, 12924562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 12934562236bSHarry Wentland struct audio_output *audio_output) 12944562236bSHarry Wentland { 12950971c40eSHarry Wentland const struct dc_stream_state *stream = pipe_ctx->stream; 12968e9c4c8cSHarry Wentland audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id; 12974562236bSHarry Wentland 12984562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 12994562236bSHarry Wentland 13004562236bSHarry Wentland /* audio_crtc_info */ 13014562236bSHarry Wentland 13024562236bSHarry Wentland audio_output->crtc_info.h_total = 13034fa086b9SLeo (Sunpeng) Li stream->timing.h_total; 13044562236bSHarry Wentland 13054562236bSHarry Wentland /* 13064562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 13074562236bSHarry Wentland * need to specify actual active signal portion 13084562236bSHarry Wentland */ 13094562236bSHarry Wentland audio_output->crtc_info.h_active = 13104fa086b9SLeo (Sunpeng) Li stream->timing.h_addressable 13114fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_left 13124fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_right; 13134562236bSHarry Wentland 13144562236bSHarry Wentland audio_output->crtc_info.v_active = 13154fa086b9SLeo (Sunpeng) Li stream->timing.v_addressable 13164fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_top 13174fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_bottom; 13184562236bSHarry Wentland 13194562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 13204562236bSHarry Wentland 13214562236bSHarry Wentland audio_output->crtc_info.interlaced = 13224fa086b9SLeo (Sunpeng) Li stream->timing.flags.INTERLACE; 13234562236bSHarry Wentland 13244562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 132540fd9090SNevenko Stupar (stream->timing.pix_clk_100hz*100)/ 13264fa086b9SLeo (Sunpeng) Li (stream->timing.h_total*stream->timing.v_total); 13274562236bSHarry Wentland 13284562236bSHarry Wentland audio_output->crtc_info.color_depth = 13294fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth; 13304562236bSHarry Wentland 133140fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz = 133240fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 13334562236bSHarry Wentland 133440fd9090SNevenko Stupar audio_output->crtc_info.calculated_pixel_clock_100Hz = 133540fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 13364562236bSHarry Wentland 133787b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/ 13382166d9fbSCharlene Liu if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) && 133940fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz == 134040fd9090SNevenko Stupar (stream->timing.pix_clk_100hz)) { 134110688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 134240fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz = 134340fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz/2; 134440fd9090SNevenko Stupar audio_output->crtc_info.calculated_pixel_clock_100Hz = 134540fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2; 134687b58768SCharlene Liu 134787b58768SCharlene Liu } 134887b58768SCharlene Liu } 134987b58768SCharlene Liu 1350ed476602SAhzo if (state->clk_mgr && 1351ed476602SAhzo (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 1352ed476602SAhzo pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { 13534562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 13540de34efcSDmytro Laktyushkin state->clk_mgr->funcs->get_dp_ref_clk_frequency( 13550de34efcSDmytro Laktyushkin state->clk_mgr); 13564562236bSHarry Wentland } 13574562236bSHarry Wentland 13584562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 13594562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 13604562236bSHarry Wentland 13614562236bSHarry Wentland audio_output->pll_info.dto_source = 13624562236bSHarry Wentland translate_to_dto_source( 1363e07f541fSYongqiang Sun pipe_ctx->stream_res.tg->inst + 1); 13644562236bSHarry Wentland 13654562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 13664562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 13674562236bSHarry Wentland 13684562236bSHarry Wentland audio_output->pll_info.ss_percentage = 13694562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 13704562236bSHarry Wentland } 13714562236bSHarry Wentland 1372fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc, 13734562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 13744562236bSHarry Wentland { 13754562236bSHarry Wentland struct tg_color color = {0}; 13764562236bSHarry Wentland 1377ff5ef992SAlex Deucher /* TOFPGA */ 137886a66c4eSHarry Wentland if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) 1379ff5ef992SAlex Deucher return; 1380ff5ef992SAlex Deucher 1381bf53769dSGloria Li if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) 13824562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 13834562236bSHarry Wentland else 13844562236bSHarry Wentland color_space_to_black_color(dc, 13854fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space, 13864562236bSHarry Wentland &color); 13874562236bSHarry Wentland 138886a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 138986a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, 13906702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.depth, 13914562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 13924562236bSHarry Wentland 139312750d16SEric Yang if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) { 139412750d16SEric Yang /* 139512750d16SEric Yang * The way 420 is packed, 2 channels carry Y component, 1 channel 139612750d16SEric Yang * alternate between Cb and Cr, so both channels need the pixel 139712750d16SEric Yang * value for Y 139812750d16SEric Yang */ 139912750d16SEric Yang if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) 140012750d16SEric Yang color.color_r_cr = color.color_g_y; 140112750d16SEric Yang 14026b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 14036b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 14044562236bSHarry Wentland &color); 140512750d16SEric Yang } 14064562236bSHarry Wentland 140786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 14086702a9acSHarry Wentland &pipe_ctx->plane_res.scl_data); 14094562236bSHarry Wentland } 14104562236bSHarry Wentland 14113158223eSEric Bernstein static enum dc_status dce110_enable_stream_timing( 14124562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1413608ac7bbSJerry Zuo struct dc_state *context, 1414fb3466a4SBhawanpreet Lakha struct dc *dc) 14154562236bSHarry Wentland { 14160971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1417608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 14184562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 14194562236bSHarry Wentland struct tg_color black_color = {0}; 14204562236bSHarry Wentland 14214562236bSHarry Wentland if (!pipe_ctx_old->stream) { 14224562236bSHarry Wentland 14234562236bSHarry Wentland /* program blank color */ 14244562236bSHarry Wentland color_space_to_black_color(dc, 14254fa086b9SLeo (Sunpeng) Li stream->output_color_space, &black_color); 14266b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank_color( 14276b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 14284562236bSHarry Wentland &black_color); 14294b5e7d62SHersen Wu 14304562236bSHarry Wentland /* 14314562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 14324562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 14334562236bSHarry Wentland */ 14346b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true); 14354562236bSHarry Wentland 14364562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 14374562236bSHarry Wentland pipe_ctx->clock_source, 143810688217SHarry Wentland &pipe_ctx->stream_res.pix_clk_params, 143998ce7d32SWenjing Liu dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), 14404562236bSHarry Wentland &pipe_ctx->pll_settings)) { 14414562236bSHarry Wentland BREAK_TO_DEBUGGER(); 14424562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 14434562236bSHarry Wentland } 14444562236bSHarry Wentland 14459c75891fSWenjing Liu if (dc_is_hdmi_tmds_signal(stream->signal)) { 14469c75891fSWenjing Liu stream->link->phy_state.symclk_ref_cnts.otg = 1; 14479c75891fSWenjing Liu if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF) 14489c75891fSWenjing Liu stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF; 14499c75891fSWenjing Liu else 14509c75891fSWenjing Liu stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 14519c75891fSWenjing Liu } 14529c75891fSWenjing Liu 14536b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->program_timing( 14546b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 14554fa086b9SLeo (Sunpeng) Li &stream->timing, 1456e7e10c46SDmytro Laktyushkin 0, 1457e7e10c46SDmytro Laktyushkin 0, 1458e7e10c46SDmytro Laktyushkin 0, 1459e7e10c46SDmytro Laktyushkin 0, 1460e7e10c46SDmytro Laktyushkin pipe_ctx->stream->signal, 14614562236bSHarry Wentland true); 14624562236bSHarry Wentland } 14634562236bSHarry Wentland 14644562236bSHarry Wentland if (!pipe_ctx_old->stream) { 14656b670fa9SHarry Wentland if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc( 14666b670fa9SHarry Wentland pipe_ctx->stream_res.tg)) { 14674562236bSHarry Wentland BREAK_TO_DEBUGGER(); 14684562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 14694562236bSHarry Wentland } 14704562236bSHarry Wentland } 14714562236bSHarry Wentland 14724562236bSHarry Wentland return DC_OK; 14734562236bSHarry Wentland } 14744562236bSHarry Wentland 14754562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 14764562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1477608ac7bbSJerry Zuo struct dc_state *context, 1478fb3466a4SBhawanpreet Lakha struct dc *dc) 14794562236bSHarry Wentland { 14800971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 14813550d622SLeo (Hanghong) Ma struct dc_link *link = stream->link; 14829c0fb8d4SAnthony Koo struct drr_params params = {0}; 14839c0fb8d4SAnthony Koo unsigned int event_triggers = 0; 1484b1f6d01cSDmytro Laktyushkin struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; 1485f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 1486c859181cSWenjing Liu const struct link_hwss *link_hwss = get_link_hwss( 1487c859181cSWenjing Liu link, &pipe_ctx->link_res); 1488c859181cSWenjing Liu 14894562236bSHarry Wentland 1490f42ea55bSAnthony Koo if (hws->funcs.disable_stream_gating) { 1491f42ea55bSAnthony Koo hws->funcs.disable_stream_gating(dc, pipe_ctx); 1492240d09d0SGary Kattan } 1493240d09d0SGary Kattan 14941a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 14951a05873fSAnthony Koo struct audio_output audio_output; 14961a05873fSAnthony Koo 14971a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 14981a05873fSAnthony Koo 1499c859181cSWenjing Liu link_hwss->setup_audio_output(pipe_ctx, &audio_output, 1500c859181cSWenjing Liu pipe_ctx->stream_res.audio->inst); 15011a05873fSAnthony Koo 15021a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_configure( 15031a05873fSAnthony Koo pipe_ctx->stream_res.audio, 15041a05873fSAnthony Koo pipe_ctx->stream->signal, 15051a05873fSAnthony Koo &audio_output.crtc_info, 15061a05873fSAnthony Koo &pipe_ctx->stream->audio_info); 15071a05873fSAnthony Koo } 15081a05873fSAnthony Koo 1509a896f870SMeenakshikumar Somasundaram /* make sure no pipes syncd to the pipe being enabled */ 1510a896f870SMeenakshikumar Somasundaram if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic) 1511a896f870SMeenakshikumar Somasundaram check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx); 1512a896f870SMeenakshikumar Somasundaram 1513f70b88b9SWesley Chalmers pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1514f70b88b9SWesley Chalmers pipe_ctx->stream_res.opp, 1515f70b88b9SWesley Chalmers &stream->bit_depth_params, 1516f70b88b9SWesley Chalmers &stream->clamping); 1517f70b88b9SWesley Chalmers 1518f70b88b9SWesley Chalmers pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1519f70b88b9SWesley Chalmers pipe_ctx->stream_res.opp, 1520f70b88b9SWesley Chalmers COLOR_SPACE_YCBCR601, 1521f70b88b9SWesley Chalmers stream->timing.display_color_depth, 1522f70b88b9SWesley Chalmers stream->signal); 1523f70b88b9SWesley Chalmers 1524f70b88b9SWesley Chalmers while (odm_pipe) { 1525f70b88b9SWesley Chalmers odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion( 1526f70b88b9SWesley Chalmers odm_pipe->stream_res.opp, 1527f70b88b9SWesley Chalmers COLOR_SPACE_YCBCR601, 1528f70b88b9SWesley Chalmers stream->timing.display_color_depth, 1529f70b88b9SWesley Chalmers stream->signal); 1530f70b88b9SWesley Chalmers 1531f70b88b9SWesley Chalmers odm_pipe->stream_res.opp->funcs->opp_program_fmt( 1532f70b88b9SWesley Chalmers odm_pipe->stream_res.opp, 1533f70b88b9SWesley Chalmers &stream->bit_depth_params, 1534f70b88b9SWesley Chalmers &stream->clamping); 1535f70b88b9SWesley Chalmers odm_pipe = odm_pipe->next_odm_pipe; 1536f70b88b9SWesley Chalmers } 1537f70b88b9SWesley Chalmers 1538f01ee019SFangzhi Zuo /* DCN3.1 FPGA Workaround 1539f01ee019SFangzhi Zuo * Need to enable HPO DP Stream Encoder before setting OTG master enable. 1540f01ee019SFangzhi Zuo * To do so, move calling function enable_stream_timing to only be done AFTER calling 1541f01ee019SFangzhi Zuo * function core_link_enable_stream 1542f01ee019SFangzhi Zuo */ 154398ce7d32SWenjing Liu if (!(hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx))) 15444562236bSHarry Wentland /* */ 1545d2d7885fSAnthony Koo /* Do not touch stream timing on seamless boot optimization. */ 1546d2d7885fSAnthony Koo if (!pipe_ctx->stream->apply_seamless_boot_optimization) 1547f42ea55bSAnthony Koo hws->funcs.enable_stream_timing(pipe_ctx, context, dc); 15484562236bSHarry Wentland 1549f42ea55bSAnthony Koo if (hws->funcs.setup_vupdate_interrupt) 1550f42ea55bSAnthony Koo hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx); 1551a122b62dSAnthony Koo 15529c0fb8d4SAnthony Koo params.vertical_total_min = stream->adjust.v_total_min; 15539c0fb8d4SAnthony Koo params.vertical_total_max = stream->adjust.v_total_max; 15549c0fb8d4SAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_drr) 15559c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg->funcs->set_drr( 15569c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg, ¶ms); 15579c0fb8d4SAnthony Koo 15589c0fb8d4SAnthony Koo // DRR should set trigger event to monitor surface update event 15599c0fb8d4SAnthony Koo if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0) 15609c0fb8d4SAnthony Koo event_triggers = 0x80; 15615b5abe95SAnthony Koo /* Event triggers and num frames initialized for DRR, but can be 15625b5abe95SAnthony Koo * later updated for PSR use. Note DRR trigger events are generated 15635b5abe95SAnthony Koo * regardless of whether num frames met. 15645b5abe95SAnthony Koo */ 15659c0fb8d4SAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control) 15669c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 15675b5abe95SAnthony Koo pipe_ctx->stream_res.tg, event_triggers, 2); 15689c0fb8d4SAnthony Koo 1569248cbed6SEric Bernstein if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) 1570d2c460e7Shersen wu pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( 1571d2c460e7Shersen wu pipe_ctx->stream_res.stream_enc, 1572d2c460e7Shersen wu pipe_ctx->stream_res.tg->inst); 1573aa9c4abeSNikola Cornij 15743550d622SLeo (Hanghong) Ma if (dc_is_dp_signal(pipe_ctx->stream->signal)) 157598ce7d32SWenjing Liu dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG); 15763550d622SLeo (Hanghong) Ma 15779c75891fSWenjing Liu if (!stream->dpms_off) 157898ce7d32SWenjing Liu dc->link_srv->set_dpms_on(context, pipe_ctx); 15794562236bSHarry Wentland 1580f01ee019SFangzhi Zuo /* DCN3.1 FPGA Workaround 1581f01ee019SFangzhi Zuo * Need to enable HPO DP Stream Encoder before setting OTG master enable. 1582f01ee019SFangzhi Zuo * To do so, move calling function enable_stream_timing to only be done AFTER calling 1583f01ee019SFangzhi Zuo * function core_link_enable_stream 1584f01ee019SFangzhi Zuo */ 158598ce7d32SWenjing Liu if (hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 1586f01ee019SFangzhi Zuo if (!pipe_ctx->stream->apply_seamless_boot_optimization) 1587f01ee019SFangzhi Zuo hws->funcs.enable_stream_timing(pipe_ctx, context, dc); 1588f01ee019SFangzhi Zuo } 1589f01ee019SFangzhi Zuo 1590b83e1ba9SMagali Lemes pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL; 15914562236bSHarry Wentland 1592bf29274dSAlvin Lee /* Phantom and main stream share the same link (because the stream 1593bf29274dSAlvin Lee * is constructed with the same sink). Make sure not to override 1594bf29274dSAlvin Lee * and link programming on the main. 1595bf29274dSAlvin Lee */ 1596bf29274dSAlvin Lee if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) { 1597d1ebfdd8SWyatt Wood pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; 1598c84f5123SBhawanpreet Lakha pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false; 1599bf29274dSAlvin Lee } 16004562236bSHarry Wentland return DC_OK; 16014562236bSHarry Wentland } 16024562236bSHarry Wentland 16034562236bSHarry Wentland /******************************************************************************/ 16044562236bSHarry Wentland 1605fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc) 16064562236bSHarry Wentland { 1607ebd1e719SLeo (Hanghong) Ma int i; 1608b9b171ffSHersen Wu 16094562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 1610d4c2a96fSLewis Huang enum signal_type signal = dc->links[i]->connector_signal; 1611a0c38ebaSCharlene Liu 161298ce7d32SWenjing Liu dc->link_srv->blank_dp_stream(dc->links[i], false); 1613c494e579SAgustin Gutierrez 16144338ffa8SSung Lee if (signal != SIGNAL_TYPE_EDP) 16154338ffa8SSung Lee signal = SIGNAL_TYPE_NONE; 16164338ffa8SSung Lee 161764d283cbSJimmy Kizito if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY) 16184562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 1619069d418fSAndrew Jiang dc->links[i]->link_enc, signal); 1620b56e90eaSPaul Hsieh 1621b56e90eaSPaul Hsieh dc->links[i]->link_status.link_active = false; 162207920450SJoshua Aberback memset(&dc->links[i]->cur_link_settings, 0, 162307920450SJoshua Aberback sizeof(dc->links[i]->cur_link_settings)); 16244562236bSHarry Wentland } 16254562236bSHarry Wentland } 16264562236bSHarry Wentland 1627fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc) 16284562236bSHarry Wentland { 16294562236bSHarry Wentland int i; 16304562236bSHarry Wentland 16317f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 16324562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 16334562236bSHarry Wentland dc->res_pool->timing_generators[i]); 16344562236bSHarry Wentland } 16354562236bSHarry Wentland } 16364562236bSHarry Wentland 1637fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc) 16384562236bSHarry Wentland { 16394562236bSHarry Wentland int i; 16404562236bSHarry Wentland 16414562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 16424562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 16434562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 16444562236bSHarry Wentland 16454562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 16464562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 16474562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 16484562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 16494562236bSHarry Wentland } 16504562236bSHarry Wentland } 16514562236bSHarry Wentland 1652fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc) 16534562236bSHarry Wentland { 16544562236bSHarry Wentland power_down_encoders(dc); 16554562236bSHarry Wentland 16564562236bSHarry Wentland power_down_controllers(dc); 16574562236bSHarry Wentland 16584562236bSHarry Wentland power_down_clock_sources(dc); 16591663ae1cSBhawanpreet Lakha 16602f3bfb27SRoman Li if (dc->fbc_compressor) 16611663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 16624562236bSHarry Wentland } 16634562236bSHarry Wentland 16644562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 1665fb3466a4SBhawanpreet Lakha struct dc *dc) 16664562236bSHarry Wentland { 16674562236bSHarry Wentland int i; 16684562236bSHarry Wentland struct timing_generator *tg; 16694562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 16704562236bSHarry Wentland 16717f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 16724562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 16734562236bSHarry Wentland 16740a87425aSTony Cheng if (tg->funcs->disable_vga) 16754562236bSHarry Wentland tg->funcs->disable_vga(tg); 16767f93c1deSCharlene Liu } 16777f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->pipe_count; i++) { 16784562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 16794562236bSHarry Wentland * powergating. */ 16804562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 16814562236bSHarry Wentland true); 16824562236bSHarry Wentland 1683e6c258cbSYongqiang Sun dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i; 16847f914a62SYongqiang Sun dc->hwss.disable_plane(dc, 1685e6c258cbSYongqiang Sun &dc->current_state->res_ctx.pipe_ctx[i]); 16864562236bSHarry Wentland } 16874562236bSHarry Wentland } 16884562236bSHarry Wentland 16893de5aa81SSivapiriyanKumarasamy 169045a1261bSJake Wang static void get_edp_streams(struct dc_state *context, 169145a1261bSJake Wang struct dc_stream_state **edp_streams, 169245a1261bSJake Wang int *edp_stream_num) 16933de5aa81SSivapiriyanKumarasamy { 16943de5aa81SSivapiriyanKumarasamy int i; 16953de5aa81SSivapiriyanKumarasamy 169645a1261bSJake Wang *edp_stream_num = 0; 16973de5aa81SSivapiriyanKumarasamy for (i = 0; i < context->stream_count; i++) { 169845a1261bSJake Wang if (context->streams[i]->signal == SIGNAL_TYPE_EDP) { 169945a1261bSJake Wang edp_streams[*edp_stream_num] = context->streams[i]; 170045a1261bSJake Wang if (++(*edp_stream_num) == MAX_NUM_EDP) 170145a1261bSJake Wang return; 17023de5aa81SSivapiriyanKumarasamy } 170345a1261bSJake Wang } 17043de5aa81SSivapiriyanKumarasamy } 17053de5aa81SSivapiriyanKumarasamy 170645a1261bSJake Wang static void get_edp_links_with_sink( 170725292028SYongqiang Sun struct dc *dc, 170845a1261bSJake Wang struct dc_link **edp_links_with_sink, 170945a1261bSJake Wang int *edp_with_sink_num) 171025292028SYongqiang Sun { 171125292028SYongqiang Sun int i; 171225292028SYongqiang Sun 171325292028SYongqiang Sun /* check if there is an eDP panel not in use */ 171445a1261bSJake Wang *edp_with_sink_num = 0; 171525292028SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 171625292028SYongqiang Sun if (dc->links[i]->local_sink && 171725292028SYongqiang Sun dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 171845a1261bSJake Wang edp_links_with_sink[*edp_with_sink_num] = dc->links[i]; 171945a1261bSJake Wang if (++(*edp_with_sink_num) == MAX_NUM_EDP) 172045a1261bSJake Wang return; 172125292028SYongqiang Sun } 172225292028SYongqiang Sun } 172325292028SYongqiang Sun } 172425292028SYongqiang Sun 17251c17952eSLee Jones /* 17264562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 17274562236bSHarry Wentland * 1. Power down all DC HW blocks 17284562236bSHarry Wentland * 2. Disable VGA engine on all controllers 17294562236bSHarry Wentland * 3. Enable power gating for controller 17304562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 17314562236bSHarry Wentland */ 173225292028SYongqiang Sun void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 17334562236bSHarry Wentland { 173445a1261bSJake Wang struct dc_link *edp_links_with_sink[MAX_NUM_EDP]; 173545a1261bSJake Wang struct dc_link *edp_links[MAX_NUM_EDP]; 173645a1261bSJake Wang struct dc_stream_state *edp_streams[MAX_NUM_EDP]; 173745a1261bSJake Wang struct dc_link *edp_link_with_sink = NULL; 173845a1261bSJake Wang struct dc_link *edp_link = NULL; 173945a1261bSJake Wang struct dce_hwseq *hws = dc->hwseq; 174045a1261bSJake Wang int edp_with_sink_num; 174145a1261bSJake Wang int edp_num; 174245a1261bSJake Wang int edp_stream_num; 174345a1261bSJake Wang int i; 1744be4b289fSSivapiriyanKumarasamy bool can_apply_edp_fast_boot = false; 1745ce72741bSAnthony Koo bool can_apply_seamless_boot = false; 17463de5aa81SSivapiriyanKumarasamy bool keep_edp_vdd_on = false; 17470eda55caSMichael Strauss DC_LOGGER_INIT(); 17480eda55caSMichael Strauss 174945a1261bSJake Wang 175045a1261bSJake Wang get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num); 17517ae1dbe6SWenjing Liu dc_get_edp_links(dc, edp_links, &edp_num); 1752ce72741bSAnthony Koo 1753f42ea55bSAnthony Koo if (hws->funcs.init_pipes) 1754f42ea55bSAnthony Koo hws->funcs.init_pipes(dc, context); 1755be4b289fSSivapiriyanKumarasamy 175645a1261bSJake Wang get_edp_streams(context, edp_streams, &edp_stream_num); 17573de5aa81SSivapiriyanKumarasamy 1758be4b289fSSivapiriyanKumarasamy // Check fastboot support, disable on DCE8 because of blank screens 1759b9957475SBrandon Syu if (edp_num && edp_stream_num && dc->ctx->dce_version != DCE_VERSION_8_0 && 1760be4b289fSSivapiriyanKumarasamy dc->ctx->dce_version != DCE_VERSION_8_1 && 1761be4b289fSSivapiriyanKumarasamy dc->ctx->dce_version != DCE_VERSION_8_3) { 176245a1261bSJake Wang for (i = 0; i < edp_num; i++) { 176345a1261bSJake Wang edp_link = edp_links[i]; 1764b9957475SBrandon Syu if (edp_link != edp_streams[0]->link) 1765b9957475SBrandon Syu continue; 1766be4b289fSSivapiriyanKumarasamy // enable fastboot if backend is enabled on eDP 17674fe38194SMario Limonciello if (edp_link->link_enc->funcs->is_dig_enabled && 17684fe38194SMario Limonciello edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && 17694fe38194SMario Limonciello edp_link->link_status.link_active) { 17702b36afc6SMario Limonciello struct dc_stream_state *edp_stream = edp_streams[0]; 17712b36afc6SMario Limonciello 177298ea24e6SPaul Hsieh can_apply_edp_fast_boot = dc_validate_boot_timing(dc, 177398ea24e6SPaul Hsieh edp_stream->sink, &edp_stream->timing); 1774f9fc6f39SMichael Strauss edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot; 17750eda55caSMichael Strauss if (can_apply_edp_fast_boot) 17760eda55caSMichael Strauss DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n"); 1777f9fc6f39SMichael Strauss 177845a1261bSJake Wang break; 1779be4b289fSSivapiriyanKumarasamy } 1780be4b289fSSivapiriyanKumarasamy } 17814dd905fdSMario Limonciello // We are trying to enable eDP, don't power down VDD 17824dd905fdSMario Limonciello if (can_apply_edp_fast_boot) 17833de5aa81SSivapiriyanKumarasamy keep_edp_vdd_on = true; 1784be4b289fSSivapiriyanKumarasamy } 1785be4b289fSSivapiriyanKumarasamy 1786be4b289fSSivapiriyanKumarasamy // Check seamless boot support 1787ce72741bSAnthony Koo for (i = 0; i < context->stream_count; i++) { 1788ce72741bSAnthony Koo if (context->streams[i]->apply_seamless_boot_optimization) { 1789ce72741bSAnthony Koo can_apply_seamless_boot = true; 1790ce72741bSAnthony Koo break; 1791ce72741bSAnthony Koo } 1792ce72741bSAnthony Koo } 17934cac1e6dSYongqiang Sun 1794be4b289fSSivapiriyanKumarasamy /* eDP should not have stream in resume from S4 and so even with VBios post 1795be4b289fSSivapiriyanKumarasamy * it should get turned off 17962c37e49aSYongqiang Sun */ 179745a1261bSJake Wang if (edp_with_sink_num) 179845a1261bSJake Wang edp_link_with_sink = edp_links_with_sink[0]; 179945a1261bSJake Wang 1800be4b289fSSivapiriyanKumarasamy if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) { 18013de5aa81SSivapiriyanKumarasamy if (edp_link_with_sink && !keep_edp_vdd_on) { 18024cac1e6dSYongqiang Sun /*turn off backlight before DP_blank and encoder powered down*/ 1803f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(edp_link_with_sink, false); 1804c5fc7f59SCharlene Liu } 1805c5fc7f59SCharlene Liu /*resume from S3, no vbios posting, no need to power down again*/ 18064012e091SLeo Chen clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); 18074012e091SLeo Chen 180825292028SYongqiang Sun power_down_all_hw_blocks(dc); 18094562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 18103de5aa81SSivapiriyanKumarasamy if (edp_link_with_sink && !keep_edp_vdd_on) 1811be4b289fSSivapiriyanKumarasamy dc->hwss.edp_power_control(edp_link_with_sink, false); 18124012e091SLeo Chen clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); 1813c5fc7f59SCharlene Liu } 18141c5ea40cSYao Wang1 bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); 18154562236bSHarry Wentland } 18164562236bSHarry Wentland 18174562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 18184562236bSHarry Wentland struct bw_fixed blackout_duration, 18190971c40eSHarry Wentland const struct dc_stream_state *stream) 18204562236bSHarry Wentland { 18214562236bSHarry Wentland uint32_t total_dest_line_time_ns; 18224562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 18234562236bSHarry Wentland 18244562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 18254562236bSHarry Wentland 18264562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 1827380604e2SKen Chalmers (stream->timing.h_total * 10) / 1828380604e2SKen Chalmers stream->timing.pix_clk_100hz + 18294562236bSHarry Wentland pstate_blackout_duration_ns; 18304562236bSHarry Wentland 18314562236bSHarry Wentland return total_dest_line_time_ns; 18324562236bSHarry Wentland } 18334562236bSHarry Wentland 1834f774b339SEric Yang static void dce110_set_displaymarks( 1835fb3466a4SBhawanpreet Lakha const struct dc *dc, 1836608ac7bbSJerry Zuo struct dc_state *context) 18374562236bSHarry Wentland { 18384562236bSHarry Wentland uint8_t i, num_pipes; 18394562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 18404562236bSHarry Wentland 18414562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 18424562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 18434562236bSHarry Wentland uint32_t total_dest_line_time_ns; 18444562236bSHarry Wentland 18454562236bSHarry Wentland if (pipe_ctx->stream == NULL) 18464562236bSHarry Wentland continue; 18474562236bSHarry Wentland 18484562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 184977a4ea53SBhawanpreet Lakha dc->bw_vbios->blackout_duration, pipe_ctx->stream); 185086a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( 185186a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 1852813d20dcSAidan Wood context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 1853813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 1854813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes], 1855813d20dcSAidan Wood context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 18564562236bSHarry Wentland total_dest_line_time_ns); 18574562236bSHarry Wentland if (i == underlay_idx) { 18584562236bSHarry Wentland num_pipes++; 185986a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( 186086a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 1861813d20dcSAidan Wood context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 1862813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 1863813d20dcSAidan Wood context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 18644562236bSHarry Wentland total_dest_line_time_ns); 18654562236bSHarry Wentland } 18664562236bSHarry Wentland num_pipes++; 18674562236bSHarry Wentland } 18684562236bSHarry Wentland } 18694562236bSHarry Wentland 1870fab55d61SDmytro Laktyushkin void dce110_set_safe_displaymarks( 1871a2b8659dSTony Cheng struct resource_context *res_ctx, 1872a2b8659dSTony Cheng const struct resource_pool *pool) 18734562236bSHarry Wentland { 18744562236bSHarry Wentland int i; 1875a2b8659dSTony Cheng int underlay_idx = pool->underlay_pipe_index; 18769037d802SDmytro Laktyushkin struct dce_watermarks max_marks = { 18774562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 18789037d802SDmytro Laktyushkin struct dce_watermarks nbp_marks = { 18794562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 18803722c794SMikita Lipski struct dce_watermarks min_marks = { 0, 0, 0, 0}; 18814562236bSHarry Wentland 18824562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 18838feabd03SYue Hin Lau if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) 18844562236bSHarry Wentland continue; 18854562236bSHarry Wentland 188686a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 188786a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 18884562236bSHarry Wentland nbp_marks, 18894562236bSHarry Wentland max_marks, 18903722c794SMikita Lipski min_marks, 18914562236bSHarry Wentland max_marks, 18924562236bSHarry Wentland MAX_WATERMARK); 18938feabd03SYue Hin Lau 18944562236bSHarry Wentland if (i == underlay_idx) 189586a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 189686a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 18974562236bSHarry Wentland nbp_marks, 18984562236bSHarry Wentland max_marks, 18994562236bSHarry Wentland max_marks, 19004562236bSHarry Wentland MAX_WATERMARK); 19018feabd03SYue Hin Lau 19024562236bSHarry Wentland } 19034562236bSHarry Wentland } 19044562236bSHarry Wentland 19054562236bSHarry Wentland /******************************************************************************* 19064562236bSHarry Wentland * Public functions 19074562236bSHarry Wentland ******************************************************************************/ 19084562236bSHarry Wentland 19094562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 191049c70eceSAlvin Lee int num_pipes, struct dc_crtc_timing_adjust adjust) 19114562236bSHarry Wentland { 19124562236bSHarry Wentland int i = 0; 19134562236bSHarry Wentland struct drr_params params = {0}; 191498e6436dSAnthony Koo // DRR should set trigger event to monitor surface update event 191598e6436dSAnthony Koo unsigned int event_triggers = 0x80; 19165b5abe95SAnthony Koo // Note DRR trigger events are generated regardless of whether num frames met. 19175b5abe95SAnthony Koo unsigned int num_frames = 2; 19184562236bSHarry Wentland 191949c70eceSAlvin Lee params.vertical_total_max = adjust.v_total_max; 192049c70eceSAlvin Lee params.vertical_total_min = adjust.v_total_min; 19214562236bSHarry Wentland 19224562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 192398e6436dSAnthony Koo * some GSL stuff. Static screen triggers may be programmed differently 192498e6436dSAnthony Koo * as well. 19254562236bSHarry Wentland */ 19264562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 192798e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_drr( 192898e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, ¶ms); 192998e6436dSAnthony Koo 193049c70eceSAlvin Lee if (adjust.v_total_max != 0 && adjust.v_total_min != 0) 193198e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( 193298e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, 19335b5abe95SAnthony Koo event_triggers, num_frames); 19344562236bSHarry Wentland } 19354562236bSHarry Wentland } 19364562236bSHarry Wentland 193772ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx, 193872ada5f7SEric Cook int num_pipes, 193972ada5f7SEric Cook struct crtc_position *position) 194072ada5f7SEric Cook { 194172ada5f7SEric Cook int i = 0; 194272ada5f7SEric Cook 194372ada5f7SEric Cook /* TODO: handle pipes > 1 194472ada5f7SEric Cook */ 194572ada5f7SEric Cook for (i = 0; i < num_pipes; i++) 19466b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position); 194772ada5f7SEric Cook } 194872ada5f7SEric Cook 19494562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 19505b5abe95SAnthony Koo int num_pipes, const struct dc_static_screen_params *params) 19514562236bSHarry Wentland { 19524562236bSHarry Wentland unsigned int i; 19535b5abe95SAnthony Koo unsigned int triggers = 0; 195494267b3dSSylvia Tsai 19555b5abe95SAnthony Koo if (params->triggers.overlay_update) 19565b5abe95SAnthony Koo triggers |= 0x100; 19575b5abe95SAnthony Koo if (params->triggers.surface_update) 19585b5abe95SAnthony Koo triggers |= 0x80; 19595b5abe95SAnthony Koo if (params->triggers.cursor_update) 19605b5abe95SAnthony Koo triggers |= 0x2; 19615b5abe95SAnthony Koo if (params->triggers.force_trigger) 19625b5abe95SAnthony Koo triggers |= 0x1; 19634562236bSHarry Wentland 1964593f79a2SAlex Deucher if (num_pipes) { 1965593f79a2SAlex Deucher struct dc *dc = pipe_ctx[0]->stream->ctx->dc; 1966593f79a2SAlex Deucher 1967593f79a2SAlex Deucher if (dc->fbc_compressor) 19685b5abe95SAnthony Koo triggers |= 0x84; 1969593f79a2SAlex Deucher } 1970c3aa1d67SBhawanpreet Lakha 19714562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 19726b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs-> 19735b5abe95SAnthony Koo set_static_screen_control(pipe_ctx[i]->stream_res.tg, 19745b5abe95SAnthony Koo triggers, params->num_frames); 19754562236bSHarry Wentland } 19764562236bSHarry Wentland 1977f6baff4dSHarry Wentland /* 1978690b5e39SRoman Li * Check if FBC can be enabled 1979690b5e39SRoman Li */ 19809c6569deSHarry Wentland static bool should_enable_fbc(struct dc *dc, 19813bc4aaa9SRoman Li struct dc_state *context, 19823bc4aaa9SRoman Li uint32_t *pipe_idx) 1983690b5e39SRoman Li { 19843bc4aaa9SRoman Li uint32_t i; 19853bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = NULL; 19863bc4aaa9SRoman Li struct resource_context *res_ctx = &context->res_ctx; 198765d38262Shersen wu unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 19883bc4aaa9SRoman Li 1989690b5e39SRoman Li 1990690b5e39SRoman Li ASSERT(dc->fbc_compressor); 1991690b5e39SRoman Li 1992690b5e39SRoman Li /* FBC memory should be allocated */ 1993690b5e39SRoman Li if (!dc->ctx->fbc_gpu_addr) 19949c6569deSHarry Wentland return false; 1995690b5e39SRoman Li 1996690b5e39SRoman Li /* Only supports single display */ 1997690b5e39SRoman Li if (context->stream_count != 1) 19989c6569deSHarry Wentland return false; 1999690b5e39SRoman Li 20003bc4aaa9SRoman Li for (i = 0; i < dc->res_pool->pipe_count; i++) { 20013bc4aaa9SRoman Li if (res_ctx->pipe_ctx[i].stream) { 200265d38262Shersen wu 20033bc4aaa9SRoman Li pipe_ctx = &res_ctx->pipe_ctx[i]; 200465d38262Shersen wu 200565d38262Shersen wu if (!pipe_ctx) 200665d38262Shersen wu continue; 200765d38262Shersen wu 200865d38262Shersen wu /* fbc not applicable on underlay pipe */ 200965d38262Shersen wu if (pipe_ctx->pipe_idx != underlay_idx) { 20103bc4aaa9SRoman Li *pipe_idx = i; 20113bc4aaa9SRoman Li break; 20123bc4aaa9SRoman Li } 20133bc4aaa9SRoman Li } 201465d38262Shersen wu } 20153bc4aaa9SRoman Li 201665d38262Shersen wu if (i == dc->res_pool->pipe_count) 201765d38262Shersen wu return false; 201865d38262Shersen wu 2019ceb3dbb4SJun Lei if (!pipe_ctx->stream->link) 202065d38262Shersen wu return false; 20217a840773SRoman Li 2022690b5e39SRoman Li /* Only supports eDP */ 2023ceb3dbb4SJun Lei if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP) 20249c6569deSHarry Wentland return false; 2025690b5e39SRoman Li 2026690b5e39SRoman Li /* PSR should not be enabled */ 2027d1ebfdd8SWyatt Wood if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled) 20289c6569deSHarry Wentland return false; 2029690b5e39SRoman Li 2030c84f5123SBhawanpreet Lakha /* Replay should not be enabled */ 2031c84f5123SBhawanpreet Lakha if (pipe_ctx->stream->link->replay_settings.replay_feature_enabled) 2032c84f5123SBhawanpreet Lakha return false; 2033c84f5123SBhawanpreet Lakha 203493984bbcSShirish S /* Nothing to compress */ 203593984bbcSShirish S if (!pipe_ctx->plane_state) 20369c6569deSHarry Wentland return false; 203793984bbcSShirish S 203805230fa9SRoman Li /* Only for non-linear tiling */ 203905230fa9SRoman Li if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 20409c6569deSHarry Wentland return false; 204105230fa9SRoman Li 20429c6569deSHarry Wentland return true; 2043690b5e39SRoman Li } 2044690b5e39SRoman Li 2045690b5e39SRoman Li /* 2046690b5e39SRoman Li * Enable FBC 2047690b5e39SRoman Li */ 204865d38262Shersen wu static void enable_fbc( 204965d38262Shersen wu struct dc *dc, 2050608ac7bbSJerry Zuo struct dc_state *context) 2051690b5e39SRoman Li { 20523bc4aaa9SRoman Li uint32_t pipe_idx = 0; 20533bc4aaa9SRoman Li 20543bc4aaa9SRoman Li if (should_enable_fbc(dc, context, &pipe_idx)) { 2055690b5e39SRoman Li /* Program GRPH COMPRESSED ADDRESS and PITCH */ 2056690b5e39SRoman Li struct compr_addr_and_pitch_params params = {0, 0, 0}; 2057690b5e39SRoman Li struct compressor *compr = dc->fbc_compressor; 20583bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 20593bc4aaa9SRoman Li 20609c6569deSHarry Wentland params.source_view_width = pipe_ctx->stream->timing.h_addressable; 20619c6569deSHarry Wentland params.source_view_height = pipe_ctx->stream->timing.v_addressable; 206265d38262Shersen wu params.inst = pipe_ctx->stream_res.tg->inst; 2063690b5e39SRoman Li compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 2064690b5e39SRoman Li 2065690b5e39SRoman Li compr->funcs->surface_address_and_pitch(compr, ¶ms); 2066690b5e39SRoman Li compr->funcs->set_fbc_invalidation_triggers(compr, 1); 2067690b5e39SRoman Li 2068690b5e39SRoman Li compr->funcs->enable_fbc(compr, ¶ms); 2069690b5e39SRoman Li } 2070690b5e39SRoman Li } 2071690b5e39SRoman Li 207254e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap( 2073fb3466a4SBhawanpreet Lakha struct dc *dc, 2074608ac7bbSJerry Zuo struct dc_state *context) 20754562236bSHarry Wentland { 20764562236bSHarry Wentland int i; 20774562236bSHarry Wentland 20784562236bSHarry Wentland /* Reset old context */ 20794562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 2080a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 20814562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 2082608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 20834562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 20844562236bSHarry Wentland 20854562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 20864562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 20874562236bSHarry Wentland * PHY when not already disabled. 20884562236bSHarry Wentland */ 20894562236bSHarry Wentland 20904562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 20914562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 20924562236bSHarry Wentland continue; 20934562236bSHarry Wentland 20944562236bSHarry Wentland if (!pipe_ctx->stream || 209554e8695eSDmytro Laktyushkin pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 209621e67d4dSHarry Wentland struct clock_source *old_clk = pipe_ctx_old->clock_source; 209721e67d4dSHarry Wentland 2098827f11e9SLeo (Sunpeng) Li /* Disable if new stream is null. O/w, if stream is 2099827f11e9SLeo (Sunpeng) Li * disabled already, no need to disable again. 2100827f11e9SLeo (Sunpeng) Li */ 210157430404SSu Sung Chung if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) { 210298ce7d32SWenjing Liu dc->link_srv->set_dpms_off(pipe_ctx_old); 210357430404SSu Sung Chung 210457430404SSu Sung Chung /* free acquired resources*/ 210557430404SSu Sung Chung if (pipe_ctx_old->stream_res.audio) { 210657430404SSu Sung Chung /*disable az_endpoint*/ 210757430404SSu Sung Chung pipe_ctx_old->stream_res.audio->funcs-> 210857430404SSu Sung Chung az_disable(pipe_ctx_old->stream_res.audio); 210957430404SSu Sung Chung 211057430404SSu Sung Chung /*free audio*/ 211157430404SSu Sung Chung if (dc->caps.dynamic_audio == true) { 211257430404SSu Sung Chung /*we have to dynamic arbitrate the audio endpoints*/ 211357430404SSu Sung Chung /*we free the resource, need reset is_audio_acquired*/ 211457430404SSu Sung Chung update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, 211557430404SSu Sung Chung pipe_ctx_old->stream_res.audio, false); 211657430404SSu Sung Chung pipe_ctx_old->stream_res.audio = NULL; 211757430404SSu Sung Chung } 211857430404SSu Sung Chung } 211957430404SSu Sung Chung } 2120d050f8edSHersen Wu 21216b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 21226b670fa9SHarry Wentland if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 212354e8695eSDmytro Laktyushkin dm_error("DC: failed to blank crtc!\n"); 212454e8695eSDmytro Laktyushkin BREAK_TO_DEBUGGER(); 212554e8695eSDmytro Laktyushkin } 21266b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); 21279c75891fSWenjing Liu pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; 212886a66c4eSHarry Wentland pipe_ctx_old->plane_res.mi->funcs->free_mem_input( 2129608ac7bbSJerry Zuo pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); 213054e8695eSDmytro Laktyushkin 2131ad8960a6SMikita Lipski if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx, 2132ad8960a6SMikita Lipski dc->res_pool, 2133ad8960a6SMikita Lipski old_clk)) 213421e67d4dSHarry Wentland old_clk->funcs->cs_power_down(old_clk); 213521e67d4dSHarry Wentland 21367f914a62SYongqiang Sun dc->hwss.disable_plane(dc, pipe_ctx_old); 213754e8695eSDmytro Laktyushkin 213854e8695eSDmytro Laktyushkin pipe_ctx_old->stream = NULL; 213954e8695eSDmytro Laktyushkin } 21404562236bSHarry Wentland } 21414562236bSHarry Wentland } 21424562236bSHarry Wentland 21431a05873fSAnthony Koo static void dce110_setup_audio_dto( 21441a05873fSAnthony Koo struct dc *dc, 21451a05873fSAnthony Koo struct dc_state *context) 21461a05873fSAnthony Koo { 21471a05873fSAnthony Koo int i; 21481a05873fSAnthony Koo 21491a05873fSAnthony Koo /* program audio wall clock. use HDMI as clock source if HDMI 21501a05873fSAnthony Koo * audio active. Otherwise, use DP as clock source 21511a05873fSAnthony Koo * first, loop to find any HDMI audio, if not, loop find DP audio 21521a05873fSAnthony Koo */ 21531a05873fSAnthony Koo /* Setup audio rate clock source */ 21541a05873fSAnthony Koo /* Issue: 21551a05873fSAnthony Koo * Audio lag happened on DP monitor when unplug a HDMI monitor 21561a05873fSAnthony Koo * 21571a05873fSAnthony Koo * Cause: 21581a05873fSAnthony Koo * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 21591a05873fSAnthony Koo * is set to either dto0 or dto1, audio should work fine. 21601a05873fSAnthony Koo * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 21611a05873fSAnthony Koo * set to dto0 will cause audio lag. 21621a05873fSAnthony Koo * 21631a05873fSAnthony Koo * Solution: 21641a05873fSAnthony Koo * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 21651a05873fSAnthony Koo * find first available pipe with audio, setup audio wall DTO per topology 21661a05873fSAnthony Koo * instead of per pipe. 21671a05873fSAnthony Koo */ 21681a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 21691a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 21701a05873fSAnthony Koo 21711a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 21721a05873fSAnthony Koo continue; 21731a05873fSAnthony Koo 21741a05873fSAnthony Koo if (pipe_ctx->top_pipe) 21751a05873fSAnthony Koo continue; 21761a05873fSAnthony Koo if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 21771a05873fSAnthony Koo continue; 21781f21390eSAric Cyr if (pipe_ctx->stream_res.audio != NULL) { 21791a05873fSAnthony Koo struct audio_output audio_output; 21801a05873fSAnthony Koo 21811a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 21821a05873fSAnthony Koo 218364b1d0e8SNicholas Kazlauskas if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) { 2184136788ccSAurabindo Pillai struct dtbclk_dto_params dto_params = {0}; 218564b1d0e8SNicholas Kazlauskas 21863e211f23SAlvin Lee dc->res_pool->dccg->funcs->set_audio_dtbclk_dto( 21873e211f23SAlvin Lee dc->res_pool->dccg, &dto_params); 21883e211f23SAlvin Lee 21891a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 21901a05873fSAnthony Koo pipe_ctx->stream_res.audio, 21911a05873fSAnthony Koo pipe_ctx->stream->signal, 21921a05873fSAnthony Koo &audio_output.crtc_info, 21931a05873fSAnthony Koo &audio_output.pll_info); 219464b1d0e8SNicholas Kazlauskas } else 219564b1d0e8SNicholas Kazlauskas pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 219664b1d0e8SNicholas Kazlauskas pipe_ctx->stream_res.audio, 219764b1d0e8SNicholas Kazlauskas pipe_ctx->stream->signal, 219864b1d0e8SNicholas Kazlauskas &audio_output.crtc_info, 219964b1d0e8SNicholas Kazlauskas &audio_output.pll_info); 22001a05873fSAnthony Koo break; 22011a05873fSAnthony Koo } 22021a05873fSAnthony Koo } 22031a05873fSAnthony Koo 22041a05873fSAnthony Koo /* no HDMI audio is found, try DP audio */ 22051a05873fSAnthony Koo if (i == dc->res_pool->pipe_count) { 22061a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 22071a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 22081a05873fSAnthony Koo 22091a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 22101a05873fSAnthony Koo continue; 22111a05873fSAnthony Koo 22121a05873fSAnthony Koo if (pipe_ctx->top_pipe) 22131a05873fSAnthony Koo continue; 22141a05873fSAnthony Koo 22151a05873fSAnthony Koo if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 22161a05873fSAnthony Koo continue; 22171a05873fSAnthony Koo 22181f21390eSAric Cyr if (pipe_ctx->stream_res.audio != NULL) { 22191a05873fSAnthony Koo struct audio_output audio_output; 22201a05873fSAnthony Koo 22211a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 22221a05873fSAnthony Koo 22231a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 22241a05873fSAnthony Koo pipe_ctx->stream_res.audio, 22251a05873fSAnthony Koo pipe_ctx->stream->signal, 22261a05873fSAnthony Koo &audio_output.crtc_info, 22271a05873fSAnthony Koo &audio_output.pll_info); 22281a05873fSAnthony Koo break; 22291a05873fSAnthony Koo } 22301a05873fSAnthony Koo } 22311a05873fSAnthony Koo } 22321a05873fSAnthony Koo } 2233cf437593SDmytro Laktyushkin 22344562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 2235fb3466a4SBhawanpreet Lakha struct dc *dc, 2236608ac7bbSJerry Zuo struct dc_state *context) 22374562236bSHarry Wentland { 2238f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 22394562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 22404562236bSHarry Wentland enum dc_status status; 22414562236bSHarry Wentland int i; 22424562236bSHarry Wentland 2243a896f870SMeenakshikumar Somasundaram /* reset syncd pipes from disabled pipes */ 2244a896f870SMeenakshikumar Somasundaram if (dc->config.use_pipe_ctx_sync_logic) 2245a896f870SMeenakshikumar Somasundaram reset_syncd_pipes_from_disabled_pipes(dc, context); 2246a896f870SMeenakshikumar Somasundaram 22474562236bSHarry Wentland /* Reset old context */ 22484562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 2249f42ea55bSAnthony Koo hws->funcs.reset_hw_ctx_wrap(dc, context); 22504562236bSHarry Wentland 22514562236bSHarry Wentland /* Skip applying if no targets */ 2252ab2541b6SAric Cyr if (context->stream_count <= 0) 22534562236bSHarry Wentland return DC_OK; 22544562236bSHarry Wentland 22554562236bSHarry Wentland /* Apply new context */ 22564562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 22574562236bSHarry Wentland 22584562236bSHarry Wentland /* below is for real asic only */ 2259a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 22604562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 2261608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 22624562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 22634562236bSHarry Wentland 22644562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 22654562236bSHarry Wentland continue; 22664562236bSHarry Wentland 22674562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 22684562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 22694562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 22704562236bSHarry Wentland pipe_ctx->clock_source, i); 22714562236bSHarry Wentland continue; 22724562236bSHarry Wentland } 22734562236bSHarry Wentland 2274f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 22754562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 22764562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 22774562236bSHarry Wentland } 22784562236bSHarry Wentland 22792f3bfb27SRoman Li if (dc->fbc_compressor) 22801663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 22815099114bSAlex Deucher 22821a05873fSAnthony Koo dce110_setup_audio_dto(dc, context); 2283ab8812a3SHersen Wu 2284a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 2285ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx_old = 2286608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 2287ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2288ab8812a3SHersen Wu 2289ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 2290ab8812a3SHersen Wu continue; 2291ab8812a3SHersen Wu 2292eed928dcSCharlene Liu if (pipe_ctx->stream == pipe_ctx_old->stream && 2293eed928dcSCharlene Liu pipe_ctx->stream->link->link_state_valid) { 2294ab8812a3SHersen Wu continue; 2295eed928dcSCharlene Liu } 2296ab8812a3SHersen Wu 22975b92d9d4SHarry Wentland if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 2298313bf4ffSYongqiang Sun continue; 2299313bf4ffSYongqiang Sun 2300b1f6d01cSDmytro Laktyushkin if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) 2301ab8812a3SHersen Wu continue; 2302ab8812a3SHersen Wu 23034562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 23044562236bSHarry Wentland pipe_ctx, 23054562236bSHarry Wentland context, 23064562236bSHarry Wentland dc); 23074562236bSHarry Wentland 23084562236bSHarry Wentland if (DC_OK != status) 23094562236bSHarry Wentland return status; 23103e8d74cbSSaaem Rizvi 23119f173a80SArnd Bergmann #ifdef CONFIG_DRM_AMD_DC_FP 23123e8d74cbSSaaem Rizvi if (hws->funcs.resync_fifo_dccg_dio) 23133e8d74cbSSaaem Rizvi hws->funcs.resync_fifo_dccg_dio(hws, dc, context); 23149f173a80SArnd Bergmann #endif 23154562236bSHarry Wentland } 23164562236bSHarry Wentland 2317690b5e39SRoman Li if (dc->fbc_compressor) 231865d38262Shersen wu enable_fbc(dc, dc->current_state); 231965d38262Shersen wu 232065d38262Shersen wu dcb->funcs->set_scratch_critical_state(dcb, false); 2321690b5e39SRoman Li 23224562236bSHarry Wentland return DC_OK; 23234562236bSHarry Wentland } 23244562236bSHarry Wentland 23254562236bSHarry Wentland /******************************************************************************* 23264562236bSHarry Wentland * Front End programming 23274562236bSHarry Wentland ******************************************************************************/ 23284562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 23294562236bSHarry Wentland { 23304562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 23314562236bSHarry Wentland 23324562236bSHarry Wentland default_adjust.force_hw_default = false; 233334996173SHarry Wentland default_adjust.in_color_space = pipe_ctx->plane_state->color_space; 233434996173SHarry Wentland default_adjust.out_color_space = pipe_ctx->stream->output_color_space; 23354562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 23366702a9acSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 23374562236bSHarry Wentland 23384562236bSHarry Wentland /* display color depth */ 23394562236bSHarry Wentland default_adjust.color_depth = 23404fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.display_color_depth; 23414562236bSHarry Wentland 23424562236bSHarry Wentland /* Lb color depth */ 23436702a9acSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 23444562236bSHarry Wentland 234586a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 234686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, &default_adjust); 23474562236bSHarry Wentland } 23484562236bSHarry Wentland 2349b06b7680SLeon Elazar 2350b06b7680SLeon Elazar /******************************************************************************* 2351b06b7680SLeon Elazar * In order to turn on/off specific surface we will program 2352b06b7680SLeon Elazar * Blender + CRTC 2353b06b7680SLeon Elazar * 2354b06b7680SLeon Elazar * In case that we have two surfaces and they have a different visibility 2355b06b7680SLeon Elazar * we can't turn off the CRTC since it will turn off the entire display 2356b06b7680SLeon Elazar * 2357b06b7680SLeon Elazar * |----------------------------------------------- | 2358b06b7680SLeon Elazar * |bottom pipe|curr pipe | | | 2359b06b7680SLeon Elazar * |Surface |Surface | Blender | CRCT | 2360b06b7680SLeon Elazar * |visibility |visibility | Configuration| | 2361b06b7680SLeon Elazar * |------------------------------------------------| 2362b06b7680SLeon Elazar * | off | off | CURRENT_PIPE | blank | 2363b06b7680SLeon Elazar * | off | on | CURRENT_PIPE | unblank | 2364b06b7680SLeon Elazar * | on | off | OTHER_PIPE | unblank | 2365b06b7680SLeon Elazar * | on | on | BLENDING | unblank | 2366b06b7680SLeon Elazar * -------------------------------------------------| 2367b06b7680SLeon Elazar * 2368b06b7680SLeon Elazar ******************************************************************************/ 2369fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc, 23704562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 23714562236bSHarry Wentland { 23724562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 2373b06b7680SLeon Elazar bool blank_target = false; 23744562236bSHarry Wentland 23754562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 2376b06b7680SLeon Elazar 2377b06b7680SLeon Elazar /* For now we are supporting only two pipes */ 2378b06b7680SLeon Elazar ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 2379b06b7680SLeon Elazar 23803be5262eSHarry Wentland if (pipe_ctx->bottom_pipe->plane_state->visible) { 23813be5262eSHarry Wentland if (pipe_ctx->plane_state->visible) 23824562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 23834562236bSHarry Wentland else 23844562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 2385b06b7680SLeon Elazar 23863be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2387b06b7680SLeon Elazar blank_target = true; 2388b06b7680SLeon Elazar 23893be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2390b06b7680SLeon Elazar blank_target = true; 2391b06b7680SLeon Elazar 2392e07f541fSYongqiang Sun dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode); 23936b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 2394b06b7680SLeon Elazar 23954562236bSHarry Wentland } 23964562236bSHarry Wentland 23971bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 23981bf56e62SZeyu Fan { 2399146a9f63SKrunoslav Kovac int i = 0; 24001bf56e62SZeyu Fan struct xfm_grph_csc_adjustment adjust; 24011bf56e62SZeyu Fan memset(&adjust, 0, sizeof(adjust)); 24021bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 24031bf56e62SZeyu Fan 24041bf56e62SZeyu Fan 24054fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 24061bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2407146a9f63SKrunoslav Kovac 2408146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2409146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2410146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 24111bf56e62SZeyu Fan } 24121bf56e62SZeyu Fan 241386a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 24141bf56e62SZeyu Fan } 2415fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc, 24164562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 24174562236bSHarry Wentland { 24183be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 24194562236bSHarry Wentland 24203be5262eSHarry Wentland if (plane_state == NULL) 24214562236bSHarry Wentland return; 24224562236bSHarry Wentland 242386a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 242486a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 24253be5262eSHarry Wentland &plane_state->address, 24263be5262eSHarry Wentland plane_state->flip_immediate); 24274562236bSHarry Wentland 24283be5262eSHarry Wentland plane_state->status.requested_address = plane_state->address; 24294562236bSHarry Wentland } 24304562236bSHarry Wentland 2431f774b339SEric Yang static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 24324562236bSHarry Wentland { 24333be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 24344562236bSHarry Wentland 24353be5262eSHarry Wentland if (plane_state == NULL) 24364562236bSHarry Wentland return; 24374562236bSHarry Wentland 24383be5262eSHarry Wentland plane_state->status.is_flip_pending = 243986a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 244086a66c4eSHarry Wentland pipe_ctx->plane_res.mi); 24414562236bSHarry Wentland 24423be5262eSHarry Wentland if (plane_state->status.is_flip_pending && !plane_state->visible) 244386a66c4eSHarry Wentland pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address; 24444562236bSHarry Wentland 244586a66c4eSHarry Wentland plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 244686a66c4eSHarry Wentland if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 24476b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) { 24483be5262eSHarry Wentland plane_state->status.is_right_eye =\ 24496b670fa9SHarry Wentland !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 24507f5c22d1SVitaly Prosyak } 24514562236bSHarry Wentland } 24524562236bSHarry Wentland 2453fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc) 24544562236bSHarry Wentland { 24554562236bSHarry Wentland power_down_all_hw_blocks(dc); 24564562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 24574562236bSHarry Wentland } 24584562236bSHarry Wentland 24594562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 24604562236bSHarry Wentland struct dc_context *dc_ctx, 24614562236bSHarry Wentland struct timing_generator *tg) 24624562236bSHarry Wentland { 24634562236bSHarry Wentland bool rc = false; 24644562236bSHarry Wentland 24654562236bSHarry Wentland /* To avoid endless loop we wait at most 24664562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 24674562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 24684562236bSHarry Wentland uint32_t i; 24694562236bSHarry Wentland 24704562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 24714562236bSHarry Wentland 24724562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 24734562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 24744562236bSHarry Wentland break; 24754562236bSHarry Wentland } 24764562236bSHarry Wentland 24774562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 24784562236bSHarry Wentland rc = true; 24794562236bSHarry Wentland /* usually occurs at i=1 */ 24804562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 24814562236bSHarry Wentland i); 24824562236bSHarry Wentland break; 24834562236bSHarry Wentland } 24844562236bSHarry Wentland 24854562236bSHarry Wentland /* Wait for one frame. */ 24864562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 24874562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 24884562236bSHarry Wentland } 24894562236bSHarry Wentland 24904562236bSHarry Wentland if (false == rc) 24914562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 24924562236bSHarry Wentland 24934562236bSHarry Wentland return rc; 24944562236bSHarry Wentland } 24954562236bSHarry Wentland 24964562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 24974562236bSHarry Wentland static void dce110_enable_timing_synchronization( 2498fb3466a4SBhawanpreet Lakha struct dc *dc, 24994562236bSHarry Wentland int group_index, 25004562236bSHarry Wentland int group_size, 25014562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 25024562236bSHarry Wentland { 25034562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 25044562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 25054562236bSHarry Wentland int i; 25064562236bSHarry Wentland 25074562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 25084562236bSHarry Wentland 25094562236bSHarry Wentland /* Designate a single TG in the group as a master. 25104562236bSHarry Wentland * Since HW doesn't care which one, we always assign 25114562236bSHarry Wentland * the 1st one in the group. */ 25124562236bSHarry Wentland gsl_params.gsl_group = 0; 25136b670fa9SHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst; 25144562236bSHarry Wentland 25154562236bSHarry Wentland for (i = 0; i < group_size; i++) 25166b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 25176b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg, &gsl_params); 25184562236bSHarry Wentland 25194562236bSHarry Wentland /* Reset slave controllers on master VSync */ 25204562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 25214562236bSHarry Wentland 25224562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 25236b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( 2524fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2525fa2123dbSMikita Lipski gsl_params.gsl_group); 25264562236bSHarry Wentland 25274562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 25284562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 25296b670fa9SHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2530fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( 2531fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg); 25324562236bSHarry Wentland } 25334562236bSHarry Wentland 25344562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 25354562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 25364562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 25374562236bSHarry Wentland for (i = 0; i < group_size; i++) 25386b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 25394562236bSHarry Wentland 25404562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 25414562236bSHarry Wentland } 25424562236bSHarry Wentland 2543fa2123dbSMikita Lipski static void dce110_enable_per_frame_crtc_position_reset( 2544fa2123dbSMikita Lipski struct dc *dc, 2545fa2123dbSMikita Lipski int group_size, 2546fa2123dbSMikita Lipski struct pipe_ctx *grouped_pipes[]) 2547fa2123dbSMikita Lipski { 2548fa2123dbSMikita Lipski struct dc_context *dc_ctx = dc->ctx; 2549fa2123dbSMikita Lipski struct dcp_gsl_params gsl_params = { 0 }; 2550fa2123dbSMikita Lipski int i; 2551fa2123dbSMikita Lipski 2552fa2123dbSMikita Lipski gsl_params.gsl_group = 0; 255337cd85ceSDavid Francis gsl_params.gsl_master = 0; 2554fa2123dbSMikita Lipski 2555fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2556fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 2557fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, &gsl_params); 2558fa2123dbSMikita Lipski 2559fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 2560fa2123dbSMikita Lipski 2561fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2562fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( 2563fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2564fa2123dbSMikita Lipski gsl_params.gsl_master, 2565fa2123dbSMikita Lipski &grouped_pipes[i]->stream->triggered_crtc_reset); 2566fa2123dbSMikita Lipski 2567fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 2568fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2569fa2123dbSMikita Lipski wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2570fa2123dbSMikita Lipski 2571fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2572fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 2573fa2123dbSMikita Lipski 2574fa2123dbSMikita Lipski } 2575fa2123dbSMikita Lipski 2576fb55546eSAnthony Koo static void init_pipes(struct dc *dc, struct dc_state *context) 2577fb55546eSAnthony Koo { 2578fb55546eSAnthony Koo // Do nothing 2579fb55546eSAnthony Koo } 2580fb55546eSAnthony Koo 2581fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc) 25824562236bSHarry Wentland { 25834562236bSHarry Wentland int i; 25844562236bSHarry Wentland struct dc_bios *bp; 25854562236bSHarry Wentland struct transform *xfm; 25865e7773a2SAnthony Koo struct abm *abm; 258770d9e8cbSPaul Hsieh struct dmcu *dmcu; 2588f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 25893ba01817SYongqiang Sun uint32_t backlight = MAX_BACKLIGHT_LEVEL; 25904562236bSHarry Wentland 25914562236bSHarry Wentland bp = dc->ctx->dc_bios; 25924562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 25934562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 25944562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 25954562236bSHarry Wentland 2596f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 25974562236bSHarry Wentland dc, i, bp, 25984562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 2599f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 26004562236bSHarry Wentland dc, i, bp, 26014562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 2602f42ea55bSAnthony Koo hws->funcs.enable_display_pipe_clock_gating( 26034562236bSHarry Wentland dc->ctx, 26044562236bSHarry Wentland true); 26054562236bSHarry Wentland } 26064562236bSHarry Wentland 2607e166ad43SJulia Lawall dce_clock_gating_power_up(dc->hwseq, false); 26084562236bSHarry Wentland /***************************************/ 26094562236bSHarry Wentland 26104562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 26114562236bSHarry Wentland /****************************************/ 26124562236bSHarry Wentland /* Power up AND update implementation according to the 26134562236bSHarry Wentland * required signal (which may be different from the 26144562236bSHarry Wentland * default signal on connector). */ 2615d0778ebfSHarry Wentland struct dc_link *link = dc->links[i]; 2616069d418fSAndrew Jiang 26174562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 26184562236bSHarry Wentland } 26194562236bSHarry Wentland 26204562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 26214562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 26224562236bSHarry Wentland 26234562236bSHarry Wentland tg->funcs->disable_vga(tg); 26244562236bSHarry Wentland 26254562236bSHarry Wentland /* Blank controller using driver code instead of 26264562236bSHarry Wentland * command table. */ 26274562236bSHarry Wentland tg->funcs->set_blank(tg, true); 26284b5e7d62SHersen Wu hwss_wait_for_blank_complete(tg); 26294562236bSHarry Wentland } 26304562236bSHarry Wentland 26314562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 26324562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 26334562236bSHarry Wentland audio->funcs->hw_init(audio); 26344562236bSHarry Wentland } 26355e7773a2SAnthony Koo 26363ba01817SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 26373ba01817SYongqiang Sun struct dc_link *link = dc->links[i]; 26383ba01817SYongqiang Sun 26393ba01817SYongqiang Sun if (link->panel_cntl) 26403ba01817SYongqiang Sun backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); 26414562236bSHarry Wentland } 26425099114bSAlex Deucher 26433ba01817SYongqiang Sun abm = dc->res_pool->abm; 26443ba01817SYongqiang Sun if (abm != NULL) 26453ba01817SYongqiang Sun abm->funcs->abm_init(abm, backlight); 26463ba01817SYongqiang Sun 264770d9e8cbSPaul Hsieh dmcu = dc->res_pool->dmcu; 264870d9e8cbSPaul Hsieh if (dmcu != NULL && abm != NULL) 264970d9e8cbSPaul Hsieh abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu); 265070d9e8cbSPaul Hsieh 26512f3bfb27SRoman Li if (dc->fbc_compressor) 26521663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 2653690b5e39SRoman Li 26546728b30cSAnthony Koo } 26554562236bSHarry Wentland 26569566b675SDmytro Laktyushkin 26579566b675SDmytro Laktyushkin void dce110_prepare_bandwidth( 2658fb3466a4SBhawanpreet Lakha struct dc *dc, 26599566b675SDmytro Laktyushkin struct dc_state *context) 2660cf437593SDmytro Laktyushkin { 2661dc88b4a6SEric Yang struct clk_mgr *dccg = dc->clk_mgr; 2662fab55d61SDmytro Laktyushkin 2663fab55d61SDmytro Laktyushkin dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); 26646f6583e5SMuhammad Ahmed if (dccg) 26655a83c932SNicholas Kazlauskas dccg->funcs->update_clocks( 26665a83c932SNicholas Kazlauskas dccg, 266724f7dd7eSDmytro Laktyushkin context, 26689566b675SDmytro Laktyushkin false); 26699566b675SDmytro Laktyushkin } 26709566b675SDmytro Laktyushkin 26719566b675SDmytro Laktyushkin void dce110_optimize_bandwidth( 26729566b675SDmytro Laktyushkin struct dc *dc, 26739566b675SDmytro Laktyushkin struct dc_state *context) 26749566b675SDmytro Laktyushkin { 2675dc88b4a6SEric Yang struct clk_mgr *dccg = dc->clk_mgr; 26769566b675SDmytro Laktyushkin 26779566b675SDmytro Laktyushkin dce110_set_displaymarks(dc, context); 26789566b675SDmytro Laktyushkin 26796f6583e5SMuhammad Ahmed if (dccg) 26809566b675SDmytro Laktyushkin dccg->funcs->update_clocks( 26819566b675SDmytro Laktyushkin dccg, 26829566b675SDmytro Laktyushkin context, 26839566b675SDmytro Laktyushkin true); 26844562236bSHarry Wentland } 26854562236bSHarry Wentland 26864562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 2687fb3466a4SBhawanpreet Lakha struct dc *dc, struct pipe_ctx *pipe_ctx) 26884562236bSHarry Wentland { 268986a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 26903be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 26914562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 26924562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 26934562236bSHarry Wentland unsigned int i; 2694f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 2695f42ea55bSAnthony Koo 26965d4b05ddSBhawanpreet Lakha DC_LOGGER_INIT(); 26974562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 26984562236bSHarry Wentland 26994562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 27004562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 27014562236bSHarry Wentland 2702e07f541fSYongqiang Sun dce_enable_fe_clock(dc->hwseq, mi->inst, true); 27034562236bSHarry Wentland 27044562236bSHarry Wentland set_default_colors(pipe_ctx); 27054fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 27064562236bSHarry Wentland == true) { 27074562236bSHarry Wentland tbl_entry.color_space = 27084fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 27094562236bSHarry Wentland 27104562236bSHarry Wentland for (i = 0; i < 12; i++) 27114562236bSHarry Wentland tbl_entry.regval[i] = 27124fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 27134562236bSHarry Wentland 271486a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 271586a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 27164562236bSHarry Wentland } 27174562236bSHarry Wentland 27184fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 27194562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2720146a9f63SKrunoslav Kovac 2721146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2722146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2723146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 27244562236bSHarry Wentland } 27254562236bSHarry Wentland 272686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 27274562236bSHarry Wentland 2728b83e1ba9SMagali Lemes pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL; 2729c1473558SAndrey Grodzovsky 27304562236bSHarry Wentland program_scaler(dc, pipe_ctx); 27314562236bSHarry Wentland 27324562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 27334562236bSHarry Wentland mi, 27343be5262eSHarry Wentland plane_state->format, 27353be5262eSHarry Wentland &plane_state->tiling_info, 27363be5262eSHarry Wentland &plane_state->plane_size, 27373be5262eSHarry Wentland plane_state->rotation, 2738624d7c47SYongqiang Sun NULL, 27394b28b76bSDmytro Laktyushkin false); 27404b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 27413be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 27424562236bSHarry Wentland 2743fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 27444562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 274586a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 27463be5262eSHarry Wentland plane_state->format, 27473be5262eSHarry Wentland &plane_state->tiling_info, 27483be5262eSHarry Wentland plane_state->rotation); 27494562236bSHarry Wentland 2750067c878aSYongqiang Sun /* Moved programming gamma from dc to hwss */ 2751405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update || 2752405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 2753405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.gamma_change) 2754f42ea55bSAnthony Koo hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); 2755405c50a0SAndrew Jiang 2756405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update) 2757f42ea55bSAnthony Koo hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream); 2758067c878aSYongqiang Sun 27591296423bSBhawanpreet Lakha DC_LOG_SURFACE( 27603032deb5SBhawanpreet Lakha "Pipe:%d %p: addr hi:0x%x, " 27614562236bSHarry Wentland "addr low:0x%x, " 27624562236bSHarry Wentland "src: %d, %d, %d," 27634562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 27644562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 27654562236bSHarry Wentland pipe_ctx->pipe_idx, 27663032deb5SBhawanpreet Lakha (void *) pipe_ctx->plane_state, 27673be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.high_part, 27683be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.low_part, 27693be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.x, 27703be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.y, 27713be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.width, 27723be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.height, 27733be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.x, 27743be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.y, 27753be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.width, 27763be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.height, 27773be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.x, 27783be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.y, 27793be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.width, 27803be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.height); 27814562236bSHarry Wentland 27821296423bSBhawanpreet Lakha DC_LOG_SURFACE( 27834562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 27844562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 27854562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 27864562236bSHarry Wentland pipe_ctx->pipe_idx, 27876702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.width, 27886702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.height, 27896702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.x, 27906702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.y, 27916702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.width, 27926702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.height, 27936702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.x, 27946702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.y); 27954562236bSHarry Wentland } 27964562236bSHarry Wentland 27974562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 2798fb3466a4SBhawanpreet Lakha struct dc *dc, 27993e9ad616SEric Yang const struct dc_stream_state *stream, 28003e9ad616SEric Yang int num_planes, 2801608ac7bbSJerry Zuo struct dc_state *context) 28024562236bSHarry Wentland { 28032194e3aeSRoman Li int i; 28044562236bSHarry Wentland 28053e9ad616SEric Yang if (num_planes == 0) 28064562236bSHarry Wentland return; 28074562236bSHarry Wentland 280865d38262Shersen wu if (dc->fbc_compressor) 280965d38262Shersen wu dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 281065d38262Shersen wu 28113e9ad616SEric Yang for (i = 0; i < dc->res_pool->pipe_count; i++) { 28123dc780ecSYongqiang Sun struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 28134562236bSHarry Wentland 2814a2607aefSHarry Wentland if (pipe_ctx->stream != stream) 28154562236bSHarry Wentland continue; 28164562236bSHarry Wentland 28173b21b6d2SJerry Zuo /* Need to allocate mem before program front end for Fiji */ 28183b21b6d2SJerry Zuo pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 28193b21b6d2SJerry Zuo pipe_ctx->plane_res.mi, 28203b21b6d2SJerry Zuo pipe_ctx->stream->timing.h_total, 28213b21b6d2SJerry Zuo pipe_ctx->stream->timing.v_total, 2822380604e2SKen Chalmers pipe_ctx->stream->timing.pix_clk_100hz / 10, 28233b21b6d2SJerry Zuo context->stream_count); 28243b21b6d2SJerry Zuo 28254562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 28264f804817SYongqiang Sun 28274f804817SYongqiang Sun dc->hwss.update_plane_addr(dc, pipe_ctx); 28284f804817SYongqiang Sun 2829b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 28304562236bSHarry Wentland 28314562236bSHarry Wentland } 28323dc780ecSYongqiang Sun 283365d38262Shersen wu if (dc->fbc_compressor) 283412a8bd88SShirish S enable_fbc(dc, context); 28354562236bSHarry Wentland } 28364562236bSHarry Wentland 2837bbf5f6c3SAnthony Koo static void dce110_post_unlock_program_front_end( 2838bbf5f6c3SAnthony Koo struct dc *dc, 2839bbf5f6c3SAnthony Koo struct dc_state *context) 2840bbf5f6c3SAnthony Koo { 2841bbf5f6c3SAnthony Koo } 2842009114f6SAnthony Koo 2843e6c258cbSYongqiang Sun static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) 28444562236bSHarry Wentland { 2845f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 2846bc373a89SRoman Li int fe_idx = pipe_ctx->plane_res.mi ? 2847bc373a89SRoman Li pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx; 2848e6c258cbSYongqiang Sun 28497950f0f9SDmytro Laktyushkin /* Do not power down fe when stream is active on dce*/ 2850608ac7bbSJerry Zuo if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) 28514562236bSHarry Wentland return; 28524562236bSHarry Wentland 2853f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 2854cfe4645eSDmytro Laktyushkin dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 2855cfe4645eSDmytro Laktyushkin 2856cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 2857cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]); 28584562236bSHarry Wentland } 28594562236bSHarry Wentland 28606be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect( 2861fb3466a4SBhawanpreet Lakha struct dc *dc, 28626be425f3SEric Yang struct resource_pool *res_pool, 28636be425f3SEric Yang struct pipe_ctx *pipe_ctx) 2864b6762f0cSEric Yang { 2865b6762f0cSEric Yang /* do nothing*/ 2866b6762f0cSEric Yang } 2867b6762f0cSEric Yang 28684bd0dc68SJoshua Aberback static void program_output_csc(struct dc *dc, 28694bd0dc68SJoshua Aberback struct pipe_ctx *pipe_ctx, 28704bd0dc68SJoshua Aberback enum dc_color_space colorspace, 28714bd0dc68SJoshua Aberback uint16_t *matrix, 28724bd0dc68SJoshua Aberback int opp_id) 28734bd0dc68SJoshua Aberback { 28744bd0dc68SJoshua Aberback int i; 28754bd0dc68SJoshua Aberback struct out_csc_color_matrix tbl_entry; 28764bd0dc68SJoshua Aberback 28774bd0dc68SJoshua Aberback if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { 28784bd0dc68SJoshua Aberback enum dc_color_space color_space = pipe_ctx->stream->output_color_space; 28794bd0dc68SJoshua Aberback 28804bd0dc68SJoshua Aberback for (i = 0; i < 12; i++) 28814bd0dc68SJoshua Aberback tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; 28824bd0dc68SJoshua Aberback 28834bd0dc68SJoshua Aberback tbl_entry.color_space = color_space; 28844bd0dc68SJoshua Aberback 28854bd0dc68SJoshua Aberback pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment( 28864bd0dc68SJoshua Aberback pipe_ctx->plane_res.xfm, &tbl_entry); 28874bd0dc68SJoshua Aberback } 28884bd0dc68SJoshua Aberback } 28894bd0dc68SJoshua Aberback 2890faf0389fSJason Yan static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) 289133fd17d9SEric Yang { 289233fd17d9SEric Yang struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; 289333fd17d9SEric Yang struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 289433fd17d9SEric Yang struct mem_input *mi = pipe_ctx->plane_res.mi; 289533fd17d9SEric Yang struct dc_cursor_mi_param param = { 2896380604e2SKen Chalmers .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10, 289733d7598dSJun Lei .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz, 289839a9f4d8SDmytro Laktyushkin .viewport = pipe_ctx->plane_res.scl_data.viewport, 289939a9f4d8SDmytro Laktyushkin .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, 290039a9f4d8SDmytro Laktyushkin .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, 290108ed681cSDmytro Laktyushkin .rotation = pipe_ctx->plane_state->rotation, 290208ed681cSDmytro Laktyushkin .mirror = pipe_ctx->plane_state->horizontal_mirror 290333fd17d9SEric Yang }; 290433fd17d9SEric Yang 290503a4059bSNicholas Kazlauskas /** 290603a4059bSNicholas Kazlauskas * If the cursor's source viewport is clipped then we need to 290703a4059bSNicholas Kazlauskas * translate the cursor to appear in the correct position on 290803a4059bSNicholas Kazlauskas * the screen. 290903a4059bSNicholas Kazlauskas * 291003a4059bSNicholas Kazlauskas * This translation isn't affected by scaling so it needs to be 291103a4059bSNicholas Kazlauskas * done *after* we adjust the position for the scale factor. 2912033baeeeSNicholas Kazlauskas * 2913033baeeeSNicholas Kazlauskas * This is only done by opt-in for now since there are still 2914033baeeeSNicholas Kazlauskas * some usecases like tiled display that might enable the 2915033baeeeSNicholas Kazlauskas * cursor on both streams while expecting dc to clip it. 291603a4059bSNicholas Kazlauskas */ 2917033baeeeSNicholas Kazlauskas if (pos_cpy.translate_by_source) { 291803a4059bSNicholas Kazlauskas pos_cpy.x += pipe_ctx->plane_state->src_rect.x; 291903a4059bSNicholas Kazlauskas pos_cpy.y += pipe_ctx->plane_state->src_rect.y; 2920033baeeeSNicholas Kazlauskas } 292103a4059bSNicholas Kazlauskas 292233fd17d9SEric Yang if (pipe_ctx->plane_state->address.type 292333fd17d9SEric Yang == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) 292433fd17d9SEric Yang pos_cpy.enable = false; 292533fd17d9SEric Yang 292633fd17d9SEric Yang if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 292733fd17d9SEric Yang pos_cpy.enable = false; 292833fd17d9SEric Yang 2929dc75dd70SRoman Li if (ipp->funcs->ipp_cursor_set_position) 293033fd17d9SEric Yang ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); 2931dc75dd70SRoman Li if (mi->funcs->set_cursor_position) 293233fd17d9SEric Yang mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); 293333fd17d9SEric Yang } 293433fd17d9SEric Yang 2935faf0389fSJason Yan static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) 293633fd17d9SEric Yang { 293733fd17d9SEric Yang struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; 293833fd17d9SEric Yang 2939d1aaad05SHarry Wentland if (pipe_ctx->plane_res.ipp && 2940d1aaad05SHarry Wentland pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) 294133fd17d9SEric Yang pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( 294233fd17d9SEric Yang pipe_ctx->plane_res.ipp, attributes); 294333fd17d9SEric Yang 2944d1aaad05SHarry Wentland if (pipe_ctx->plane_res.mi && 2945d1aaad05SHarry Wentland pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) 294633fd17d9SEric Yang pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( 294733fd17d9SEric Yang pipe_ctx->plane_res.mi, attributes); 294833fd17d9SEric Yang 2949d1aaad05SHarry Wentland if (pipe_ctx->plane_res.xfm && 2950d1aaad05SHarry Wentland pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) 295133fd17d9SEric Yang pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( 295233fd17d9SEric Yang pipe_ctx->plane_res.xfm, attributes); 295333fd17d9SEric Yang } 295433fd17d9SEric Yang 29554b0e95d1SYongqiang Sun bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, 29564b0e95d1SYongqiang Sun uint32_t backlight_pwm_u16_16, 29574b0e95d1SYongqiang Sun uint32_t frame_ramp) 29584b0e95d1SYongqiang Sun { 29594b0e95d1SYongqiang Sun struct dc_link *link = pipe_ctx->stream->link; 29604b0e95d1SYongqiang Sun struct dc *dc = link->ctx->dc; 29614b0e95d1SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 29623ba01817SYongqiang Sun struct panel_cntl *panel_cntl = link->panel_cntl; 29634b0e95d1SYongqiang Sun struct dmcu *dmcu = dc->res_pool->dmcu; 29644b0e95d1SYongqiang Sun bool fw_set_brightness = true; 29654b0e95d1SYongqiang Sun /* DMCU -1 for all controller id values, 29664b0e95d1SYongqiang Sun * therefore +1 here 29674b0e95d1SYongqiang Sun */ 29684b0e95d1SYongqiang Sun uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1; 29694b0e95d1SYongqiang Sun 29703ba01817SYongqiang Sun if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL)) 29714b0e95d1SYongqiang Sun return false; 29724b0e95d1SYongqiang Sun 29734b0e95d1SYongqiang Sun if (dmcu) 29744b0e95d1SYongqiang Sun fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); 29754b0e95d1SYongqiang Sun 29763ba01817SYongqiang Sun if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight) 29773ba01817SYongqiang Sun panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16); 29783ba01817SYongqiang Sun else 29794b0e95d1SYongqiang Sun abm->funcs->set_backlight_level_pwm( 29804b0e95d1SYongqiang Sun abm, 29814b0e95d1SYongqiang Sun backlight_pwm_u16_16, 29824b0e95d1SYongqiang Sun frame_ramp, 29834b0e95d1SYongqiang Sun controller_id, 29843ba01817SYongqiang Sun link->panel_cntl->inst); 29854b0e95d1SYongqiang Sun 29864b0e95d1SYongqiang Sun return true; 29874b0e95d1SYongqiang Sun } 29884b0e95d1SYongqiang Sun 29893ba01817SYongqiang Sun void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx) 29903ba01817SYongqiang Sun { 29913ba01817SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 29923ba01817SYongqiang Sun struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 29933ba01817SYongqiang Sun 29943ba01817SYongqiang Sun if (abm) 29953ba01817SYongqiang Sun abm->funcs->set_abm_immediate_disable(abm, 29963ba01817SYongqiang Sun pipe_ctx->stream->link->panel_cntl->inst); 29973ba01817SYongqiang Sun 29983ba01817SYongqiang Sun if (panel_cntl) 29993ba01817SYongqiang Sun panel_cntl->funcs->store_backlight_level(panel_cntl); 30003ba01817SYongqiang Sun } 30013ba01817SYongqiang Sun 3002474ac4a8SYongqiang Sun void dce110_set_pipe(struct pipe_ctx *pipe_ctx) 3003474ac4a8SYongqiang Sun { 3004474ac4a8SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 3005474ac4a8SYongqiang Sun struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 3006474ac4a8SYongqiang Sun uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1; 3007474ac4a8SYongqiang Sun 3008474ac4a8SYongqiang Sun if (abm && panel_cntl) 3009474ac4a8SYongqiang Sun abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst); 3010474ac4a8SYongqiang Sun } 3011474ac4a8SYongqiang Sun 30129c75891fSWenjing Liu void dce110_enable_lvds_link_output(struct dc_link *link, 30139c75891fSWenjing Liu const struct link_resource *link_res, 30149c75891fSWenjing Liu enum clock_source_id clock_source, 30159c75891fSWenjing Liu uint32_t pixel_clock) 30169c75891fSWenjing Liu { 30179c75891fSWenjing Liu link->link_enc->funcs->enable_lvds_output( 30189c75891fSWenjing Liu link->link_enc, 30199c75891fSWenjing Liu clock_source, 30209c75891fSWenjing Liu pixel_clock); 30219c75891fSWenjing Liu link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 30229c75891fSWenjing Liu } 30239c75891fSWenjing Liu 30249c75891fSWenjing Liu void dce110_enable_tmds_link_output(struct dc_link *link, 30259c75891fSWenjing Liu const struct link_resource *link_res, 30269c75891fSWenjing Liu enum signal_type signal, 30279c75891fSWenjing Liu enum clock_source_id clock_source, 30289c75891fSWenjing Liu enum dc_color_depth color_depth, 30299c75891fSWenjing Liu uint32_t pixel_clock) 30309c75891fSWenjing Liu { 30319c75891fSWenjing Liu link->link_enc->funcs->enable_tmds_output( 30329c75891fSWenjing Liu link->link_enc, 30339c75891fSWenjing Liu clock_source, 30349c75891fSWenjing Liu color_depth, 30359c75891fSWenjing Liu signal, 30369c75891fSWenjing Liu pixel_clock); 30379c75891fSWenjing Liu link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 30389c75891fSWenjing Liu } 30399c75891fSWenjing Liu 30409c75891fSWenjing Liu void dce110_enable_dp_link_output( 30419c75891fSWenjing Liu struct dc_link *link, 30429c75891fSWenjing Liu const struct link_resource *link_res, 30439c75891fSWenjing Liu enum signal_type signal, 30449c75891fSWenjing Liu enum clock_source_id clock_source, 30459c75891fSWenjing Liu const struct dc_link_settings *link_settings) 30469c75891fSWenjing Liu { 30479c75891fSWenjing Liu struct dc *dc = link->ctx->dc; 30489c75891fSWenjing Liu struct dmcu *dmcu = dc->res_pool->dmcu; 30499c75891fSWenjing Liu struct pipe_ctx *pipes = 30509c75891fSWenjing Liu link->dc->current_state->res_ctx.pipe_ctx; 30519c75891fSWenjing Liu struct clock_source *dp_cs = 30529c75891fSWenjing Liu link->dc->res_pool->dp_clock_source; 30539c75891fSWenjing Liu const struct link_hwss *link_hwss = get_link_hwss(link, link_res); 30549c75891fSWenjing Liu unsigned int i; 30559c75891fSWenjing Liu 3056a6c0c9f5SJingwen Zhu /* 3057a6c0c9f5SJingwen Zhu * Add the logic to extract BOTH power up and power down sequences 3058a6c0c9f5SJingwen Zhu * from enable/disable link output and only call edp panel control 3059a6c0c9f5SJingwen Zhu * in enable_link_dp and disable_link_dp once. 3060a6c0c9f5SJingwen Zhu */ 30619c75891fSWenjing Liu if (link->connector_signal == SIGNAL_TYPE_EDP) { 30629c75891fSWenjing Liu link->dc->hwss.edp_wait_for_hpd_ready(link, true); 30639c75891fSWenjing Liu } 30649c75891fSWenjing Liu 30659c75891fSWenjing Liu /* If the current pixel clock source is not DTO(happens after 30669c75891fSWenjing Liu * switching from HDMI passive dongle to DP on the same connector), 30679c75891fSWenjing Liu * switch the pixel clock source to DTO. 30689c75891fSWenjing Liu */ 30699c75891fSWenjing Liu 30709c75891fSWenjing Liu for (i = 0; i < MAX_PIPES; i++) { 30719c75891fSWenjing Liu if (pipes[i].stream != NULL && 30729c75891fSWenjing Liu pipes[i].stream->link == link) { 30739c75891fSWenjing Liu if (pipes[i].clock_source != NULL && 30749c75891fSWenjing Liu pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) { 30759c75891fSWenjing Liu pipes[i].clock_source = dp_cs; 30769c75891fSWenjing Liu pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz = 30779c75891fSWenjing Liu pipes[i].stream->timing.pix_clk_100hz; 30789c75891fSWenjing Liu pipes[i].clock_source->funcs->program_pix_clk( 30799c75891fSWenjing Liu pipes[i].clock_source, 30809c75891fSWenjing Liu &pipes[i].stream_res.pix_clk_params, 308198ce7d32SWenjing Liu dc->link_srv->dp_get_encoding_format(link_settings), 30829c75891fSWenjing Liu &pipes[i].pll_settings); 30839c75891fSWenjing Liu } 30849c75891fSWenjing Liu } 30859c75891fSWenjing Liu } 30869c75891fSWenjing Liu 308798ce7d32SWenjing Liu if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) { 30889c75891fSWenjing Liu if (dc->clk_mgr->funcs->notify_link_rate_change) 30899c75891fSWenjing Liu dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); 30909c75891fSWenjing Liu } 30919c75891fSWenjing Liu 30929c75891fSWenjing Liu if (dmcu != NULL && dmcu->funcs->lock_phy) 30939c75891fSWenjing Liu dmcu->funcs->lock_phy(dmcu); 30949c75891fSWenjing Liu 30959c75891fSWenjing Liu if (link_hwss->ext.enable_dp_link_output) 30969c75891fSWenjing Liu link_hwss->ext.enable_dp_link_output(link, link_res, signal, 30979c75891fSWenjing Liu clock_source, link_settings); 30989c75891fSWenjing Liu 30999c75891fSWenjing Liu link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 31009c75891fSWenjing Liu 31019c75891fSWenjing Liu if (dmcu != NULL && dmcu->funcs->unlock_phy) 31029c75891fSWenjing Liu dmcu->funcs->unlock_phy(dmcu); 31039c75891fSWenjing Liu 310498ce7d32SWenjing Liu dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY); 31059c75891fSWenjing Liu } 31069c75891fSWenjing Liu 31079c75891fSWenjing Liu void dce110_disable_link_output(struct dc_link *link, 31089c75891fSWenjing Liu const struct link_resource *link_res, 31099c75891fSWenjing Liu enum signal_type signal) 31109c75891fSWenjing Liu { 31119c75891fSWenjing Liu struct dc *dc = link->ctx->dc; 31129c75891fSWenjing Liu const struct link_hwss *link_hwss = get_link_hwss(link, link_res); 31139c75891fSWenjing Liu struct dmcu *dmcu = dc->res_pool->dmcu; 31149c75891fSWenjing Liu 31159c75891fSWenjing Liu if (signal == SIGNAL_TYPE_EDP && 31169c75891fSWenjing Liu link->dc->hwss.edp_backlight_control) 31179c75891fSWenjing Liu link->dc->hwss.edp_backlight_control(link, false); 311841da5fd2SWenjing Liu else if (dmcu != NULL && dmcu->funcs->lock_phy) 31199c75891fSWenjing Liu dmcu->funcs->lock_phy(dmcu); 31209c75891fSWenjing Liu 31219c75891fSWenjing Liu link_hwss->disable_link_output(link, link_res, signal); 31229c75891fSWenjing Liu link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF; 3123a6c0c9f5SJingwen Zhu /* 3124a6c0c9f5SJingwen Zhu * Add the logic to extract BOTH power up and power down sequences 3125a6c0c9f5SJingwen Zhu * from enable/disable link output and only call edp panel control 3126a6c0c9f5SJingwen Zhu * in enable_link_dp and disable_link_dp once. 3127a6c0c9f5SJingwen Zhu */ 3128a6c0c9f5SJingwen Zhu if (dmcu != NULL && dmcu->funcs->lock_phy) 31299c75891fSWenjing Liu dmcu->funcs->unlock_phy(dmcu); 313098ce7d32SWenjing Liu dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); 31319c75891fSWenjing Liu } 31329c75891fSWenjing Liu 31334562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 31341bf56e62SZeyu Fan .program_gamut_remap = program_gamut_remap, 31354bd0dc68SJoshua Aberback .program_output_csc = program_output_csc, 31364562236bSHarry Wentland .init_hw = init_hw, 31374562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 31384562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 3139bbf5f6c3SAnthony Koo .post_unlock_program_front_end = dce110_post_unlock_program_front_end, 31404562236bSHarry Wentland .update_plane_addr = update_plane_addr, 31414562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 31424562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 31434562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 3144fa2123dbSMikita Lipski .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, 31454562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 31464562236bSHarry Wentland .enable_stream = dce110_enable_stream, 31474562236bSHarry Wentland .disable_stream = dce110_disable_stream, 31484562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 314941b49742SCharlene Liu .blank_stream = dce110_blank_stream, 31501a05873fSAnthony Koo .enable_audio_stream = dce110_enable_audio_stream, 31511a05873fSAnthony Koo .disable_audio_stream = dce110_disable_audio_stream, 31527f914a62SYongqiang Sun .disable_plane = dce110_power_down_fe, 31534562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 3154009114f6SAnthony Koo .interdependent_update_lock = NULL, 31551e461c37SAric Cyr .cursor_lock = dce_pipe_control_lock, 31569566b675SDmytro Laktyushkin .prepare_bandwidth = dce110_prepare_bandwidth, 31579566b675SDmytro Laktyushkin .optimize_bandwidth = dce110_optimize_bandwidth, 31584562236bSHarry Wentland .set_drr = set_drr, 315972ada5f7SEric Cook .get_position = get_position, 31604562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 316115e17335SCharlene Liu .setup_stereo = NULL, 316215e17335SCharlene Liu .set_avmute = dce110_set_avmute, 316341f97c07SHersen Wu .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 3164099303e9SPeikang Zhang .edp_backlight_control = dce110_edp_backlight_control, 31658a31820bSMartin Leung .edp_power_control = dce110_edp_power_control, 31668a31820bSMartin Leung .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, 316733fd17d9SEric Yang .set_cursor_position = dce110_set_cursor_position, 31684b0e95d1SYongqiang Sun .set_cursor_attribute = dce110_set_cursor_attribute, 31694b0e95d1SYongqiang Sun .set_backlight_level = dce110_set_backlight_level, 31703ba01817SYongqiang Sun .set_abm_immediate_disable = dce110_set_abm_immediate_disable, 3171474ac4a8SYongqiang Sun .set_pipe = dce110_set_pipe, 31729c75891fSWenjing Liu .enable_lvds_link_output = dce110_enable_lvds_link_output, 31739c75891fSWenjing Liu .enable_tmds_link_output = dce110_enable_tmds_link_output, 31749c75891fSWenjing Liu .enable_dp_link_output = dce110_enable_dp_link_output, 31759c75891fSWenjing Liu .disable_link_output = dce110_disable_link_output, 31764562236bSHarry Wentland }; 31774562236bSHarry Wentland 3178f42ea55bSAnthony Koo static const struct hwseq_private_funcs dce110_private_funcs = { 3179f42ea55bSAnthony Koo .init_pipes = init_pipes, 3180f42ea55bSAnthony Koo .update_plane_addr = update_plane_addr, 3181f42ea55bSAnthony Koo .set_input_transfer_func = dce110_set_input_transfer_func, 3182f42ea55bSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 3183f42ea55bSAnthony Koo .power_down = dce110_power_down, 3184f42ea55bSAnthony Koo .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 3185f42ea55bSAnthony Koo .enable_display_power_gating = dce110_enable_display_power_gating, 3186f42ea55bSAnthony Koo .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 3187f42ea55bSAnthony Koo .enable_stream_timing = dce110_enable_stream_timing, 3188f42ea55bSAnthony Koo .disable_stream_gating = NULL, 3189f42ea55bSAnthony Koo .enable_stream_gating = NULL, 3190f42ea55bSAnthony Koo .edp_backlight_control = dce110_edp_backlight_control, 3191f42ea55bSAnthony Koo }; 3192f42ea55bSAnthony Koo 3193c13b408bSDave Airlie void dce110_hw_sequencer_construct(struct dc *dc) 31944562236bSHarry Wentland { 31954562236bSHarry Wentland dc->hwss = dce110_funcs; 3196f42ea55bSAnthony Koo dc->hwseq->funcs = dce110_private_funcs; 31974562236bSHarry Wentland } 31984562236bSHarry Wentland 3199