14562236bSHarry Wentland /* 24562236bSHarry Wentland * Copyright 2015 Advanced Micro Devices, Inc. 34562236bSHarry Wentland * 44562236bSHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a 54562236bSHarry Wentland * copy of this software and associated documentation files (the "Software"), 64562236bSHarry Wentland * to deal in the Software without restriction, including without limitation 74562236bSHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 84562236bSHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the 94562236bSHarry Wentland * Software is furnished to do so, subject to the following conditions: 104562236bSHarry Wentland * 114562236bSHarry Wentland * The above copyright notice and this permission notice shall be included in 124562236bSHarry Wentland * all copies or substantial portions of the Software. 134562236bSHarry Wentland * 144562236bSHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 154562236bSHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 164562236bSHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 174562236bSHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 184562236bSHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 194562236bSHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 204562236bSHarry Wentland * OTHER DEALINGS IN THE SOFTWARE. 214562236bSHarry Wentland * 224562236bSHarry Wentland * Authors: AMD 234562236bSHarry Wentland * 244562236bSHarry Wentland */ 25c366be54SSam Ravnborg 26c366be54SSam Ravnborg #include <linux/delay.h> 27c366be54SSam Ravnborg 284562236bSHarry Wentland #include "dm_services.h" 294562236bSHarry Wentland #include "dc.h" 304562236bSHarry Wentland #include "dc_bios_types.h" 314562236bSHarry Wentland #include "core_types.h" 324562236bSHarry Wentland #include "core_status.h" 334562236bSHarry Wentland #include "resource.h" 344562236bSHarry Wentland #include "dm_helpers.h" 354562236bSHarry Wentland #include "dce110_hw_sequencer.h" 364562236bSHarry Wentland #include "dce110_timing_generator.h" 3798489c02SLeo (Sunpeng) Li #include "dce/dce_hwseq.h" 3887401969SAndrew Jiang #include "gpio_service_interface.h" 394562236bSHarry Wentland 401663ae1cSBhawanpreet Lakha #include "dce110_compressor.h" 411663ae1cSBhawanpreet Lakha 424562236bSHarry Wentland #include "bios/bios_parser_helper.h" 434562236bSHarry Wentland #include "timing_generator.h" 444562236bSHarry Wentland #include "mem_input.h" 454562236bSHarry Wentland #include "opp.h" 464562236bSHarry Wentland #include "ipp.h" 474562236bSHarry Wentland #include "transform.h" 484562236bSHarry Wentland #include "stream_encoder.h" 494562236bSHarry Wentland #include "link_encoder.h" 5087401969SAndrew Jiang #include "link_hwss.h" 51f9fc6f39SMichael Strauss #include "dc_link_dp.h" 524562236bSHarry Wentland #include "clock_source.h" 53dc88b4a6SEric Yang #include "clk_mgr.h" 545e7773a2SAnthony Koo #include "abm.h" 554562236bSHarry Wentland #include "audio.h" 5608b16886SZeyu Fan #include "reg_helper.h" 57d4caa72eSAnthony Koo #include "panel_cntl.h" 584562236bSHarry Wentland 594562236bSHarry Wentland /* include DCE11 register header files */ 604562236bSHarry Wentland #include "dce/dce_11_0_d.h" 614562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 62e266fdf6SVitaly Prosyak #include "custom_float.h" 634562236bSHarry Wentland 644cac1e6dSYongqiang Sun #include "atomfirmware.h" 654cac1e6dSYongqiang Sun 66*6e4a14ccSLee Jones #include "dce110_hw_sequencer.h" 67*6e4a14ccSLee Jones 6878c77382SAnthony Koo #define GAMMA_HW_POINTS_NUM 256 6978c77382SAnthony Koo 7087401969SAndrew Jiang /* 7187401969SAndrew Jiang * All values are in milliseconds; 7287401969SAndrew Jiang * For eDP, after power-up/power/down, 7387401969SAndrew Jiang * 300/500 msec max. delay from LCDVCC to black video generation 7487401969SAndrew Jiang */ 7587401969SAndrew Jiang #define PANEL_POWER_UP_TIMEOUT 300 7687401969SAndrew Jiang #define PANEL_POWER_DOWN_TIMEOUT 500 7787401969SAndrew Jiang #define HPD_CHECK_INTERVAL 10 7896577cf8SHersen Wu #define OLED_POST_T7_DELAY 100 7996577cf8SHersen Wu #define OLED_PRE_T11_DELAY 150 8087401969SAndrew Jiang 815eefbc40SYue Hin Lau #define CTX \ 825eefbc40SYue Hin Lau hws->ctx 835d4b05ddSBhawanpreet Lakha 845d4b05ddSBhawanpreet Lakha #define DC_LOGGER_INIT() 855d4b05ddSBhawanpreet Lakha 865eefbc40SYue Hin Lau #define REG(reg)\ 875eefbc40SYue Hin Lau hws->regs->reg 885eefbc40SYue Hin Lau 895eefbc40SYue Hin Lau #undef FN 905eefbc40SYue Hin Lau #define FN(reg_name, field_name) \ 915eefbc40SYue Hin Lau hws->shifts->field_name, hws->masks->field_name 925eefbc40SYue Hin Lau 934562236bSHarry Wentland struct dce110_hw_seq_reg_offsets { 944562236bSHarry Wentland uint32_t crtc; 954562236bSHarry Wentland }; 964562236bSHarry Wentland 974562236bSHarry Wentland static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 984562236bSHarry Wentland { 994562236bSHarry Wentland .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1004562236bSHarry Wentland }, 1014562236bSHarry Wentland { 1024562236bSHarry Wentland .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1034562236bSHarry Wentland }, 1044562236bSHarry Wentland { 1054562236bSHarry Wentland .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1064562236bSHarry Wentland }, 1074562236bSHarry Wentland { 1084562236bSHarry Wentland .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 1094562236bSHarry Wentland } 1104562236bSHarry Wentland }; 1114562236bSHarry Wentland 1124562236bSHarry Wentland #define HW_REG_BLND(reg, id)\ 1134562236bSHarry Wentland (reg + reg_offsets[id].blnd) 1144562236bSHarry Wentland 1154562236bSHarry Wentland #define HW_REG_CRTC(reg, id)\ 1164562236bSHarry Wentland (reg + reg_offsets[id].crtc) 1174562236bSHarry Wentland 1184562236bSHarry Wentland #define MAX_WATERMARK 0xFFFF 1194562236bSHarry Wentland #define SAFE_NBP_MARK 0x7FFF 1204562236bSHarry Wentland 1214562236bSHarry Wentland /******************************************************************************* 1224562236bSHarry Wentland * Private definitions 1234562236bSHarry Wentland ******************************************************************************/ 1244562236bSHarry Wentland /***************************PIPE_CONTROL***********************************/ 1254562236bSHarry Wentland static void dce110_init_pte(struct dc_context *ctx) 1264562236bSHarry Wentland { 1274562236bSHarry Wentland uint32_t addr; 1284562236bSHarry Wentland uint32_t value = 0; 1294562236bSHarry Wentland uint32_t chunk_int = 0; 1304562236bSHarry Wentland uint32_t chunk_mul = 0; 1314562236bSHarry Wentland 1324562236bSHarry Wentland addr = mmUNP_DVMM_PTE_CONTROL; 1334562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1344562236bSHarry Wentland 1354562236bSHarry Wentland set_reg_field_value( 1364562236bSHarry Wentland value, 1374562236bSHarry Wentland 0, 1384562236bSHarry Wentland DVMM_PTE_CONTROL, 1394562236bSHarry Wentland DVMM_USE_SINGLE_PTE); 1404562236bSHarry Wentland 1414562236bSHarry Wentland set_reg_field_value( 1424562236bSHarry Wentland value, 1434562236bSHarry Wentland 1, 1444562236bSHarry Wentland DVMM_PTE_CONTROL, 1454562236bSHarry Wentland DVMM_PTE_BUFFER_MODE0); 1464562236bSHarry Wentland 1474562236bSHarry Wentland set_reg_field_value( 1484562236bSHarry Wentland value, 1494562236bSHarry Wentland 1, 1504562236bSHarry Wentland DVMM_PTE_CONTROL, 1514562236bSHarry Wentland DVMM_PTE_BUFFER_MODE1); 1524562236bSHarry Wentland 1534562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1544562236bSHarry Wentland 1554562236bSHarry Wentland addr = mmDVMM_PTE_REQ; 1564562236bSHarry Wentland value = dm_read_reg(ctx, addr); 1574562236bSHarry Wentland 1584562236bSHarry Wentland chunk_int = get_reg_field_value( 1594562236bSHarry Wentland value, 1604562236bSHarry Wentland DVMM_PTE_REQ, 1614562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1624562236bSHarry Wentland 1634562236bSHarry Wentland chunk_mul = get_reg_field_value( 1644562236bSHarry Wentland value, 1654562236bSHarry Wentland DVMM_PTE_REQ, 1664562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1674562236bSHarry Wentland 1684562236bSHarry Wentland if (chunk_int != 0x4 || chunk_mul != 0x4) { 1694562236bSHarry Wentland 1704562236bSHarry Wentland set_reg_field_value( 1714562236bSHarry Wentland value, 1724562236bSHarry Wentland 255, 1734562236bSHarry Wentland DVMM_PTE_REQ, 1744562236bSHarry Wentland MAX_PTEREQ_TO_ISSUE); 1754562236bSHarry Wentland 1764562236bSHarry Wentland set_reg_field_value( 1774562236bSHarry Wentland value, 1784562236bSHarry Wentland 4, 1794562236bSHarry Wentland DVMM_PTE_REQ, 1804562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_INT); 1814562236bSHarry Wentland 1824562236bSHarry Wentland set_reg_field_value( 1834562236bSHarry Wentland value, 1844562236bSHarry Wentland 4, 1854562236bSHarry Wentland DVMM_PTE_REQ, 1864562236bSHarry Wentland HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 1874562236bSHarry Wentland 1884562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1894562236bSHarry Wentland } 1904562236bSHarry Wentland } 1914562236bSHarry Wentland /**************************************************************************/ 1924562236bSHarry Wentland 1934562236bSHarry Wentland static void enable_display_pipe_clock_gating( 1944562236bSHarry Wentland struct dc_context *ctx, 1954562236bSHarry Wentland bool clock_gating) 1964562236bSHarry Wentland { 1974562236bSHarry Wentland /*TODO*/ 1984562236bSHarry Wentland } 1994562236bSHarry Wentland 2004562236bSHarry Wentland static bool dce110_enable_display_power_gating( 201fb3466a4SBhawanpreet Lakha struct dc *dc, 2024562236bSHarry Wentland uint8_t controller_id, 2034562236bSHarry Wentland struct dc_bios *dcb, 2044562236bSHarry Wentland enum pipe_gating_control power_gating) 2054562236bSHarry Wentland { 2064562236bSHarry Wentland enum bp_result bp_result = BP_RESULT_OK; 2074562236bSHarry Wentland enum bp_pipe_control_action cntl; 2084562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 2094562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 2104562236bSHarry Wentland 2114562236bSHarry Wentland if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 2124562236bSHarry Wentland return true; 2134562236bSHarry Wentland 2144562236bSHarry Wentland if (power_gating == PIPE_GATING_CONTROL_INIT) 2154562236bSHarry Wentland cntl = ASIC_PIPE_INIT; 2164562236bSHarry Wentland else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 2174562236bSHarry Wentland cntl = ASIC_PIPE_ENABLE; 2184562236bSHarry Wentland else 2194562236bSHarry Wentland cntl = ASIC_PIPE_DISABLE; 2204562236bSHarry Wentland 2214562236bSHarry Wentland if (controller_id == underlay_idx) 2224562236bSHarry Wentland controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 2234562236bSHarry Wentland 2244562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0){ 2254562236bSHarry Wentland 2264562236bSHarry Wentland bp_result = dcb->funcs->enable_disp_power_gating( 2274562236bSHarry Wentland dcb, controller_id + 1, cntl); 2284562236bSHarry Wentland 2294562236bSHarry Wentland /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 2304562236bSHarry Wentland * by default when command table is called 2314562236bSHarry Wentland * 2324562236bSHarry Wentland * Bios parser accepts controller_id = 6 as indicative of 2334562236bSHarry Wentland * underlay pipe in dce110. But we do not support more 2344562236bSHarry Wentland * than 3. 2354562236bSHarry Wentland */ 2364562236bSHarry Wentland if (controller_id < CONTROLLER_ID_MAX - 1) 2374562236bSHarry Wentland dm_write_reg(ctx, 2384562236bSHarry Wentland HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 2394562236bSHarry Wentland 0); 2404562236bSHarry Wentland } 2414562236bSHarry Wentland 2424562236bSHarry Wentland if (power_gating != PIPE_GATING_CONTROL_ENABLE) 2434562236bSHarry Wentland dce110_init_pte(ctx); 2444562236bSHarry Wentland 2454562236bSHarry Wentland if (bp_result == BP_RESULT_OK) 2464562236bSHarry Wentland return true; 2474562236bSHarry Wentland else 2484562236bSHarry Wentland return false; 2494562236bSHarry Wentland } 2504562236bSHarry Wentland 2514562236bSHarry Wentland static void build_prescale_params(struct ipp_prescale_params *prescale_params, 2523be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2534562236bSHarry Wentland { 2544562236bSHarry Wentland prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 2554562236bSHarry Wentland 2563be5262eSHarry Wentland switch (plane_state->format) { 2571352c779SNicholas Kazlauskas case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 2581352c779SNicholas Kazlauskas prescale_params->scale = 0x2082; 2591352c779SNicholas Kazlauskas break; 2604562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 2618693049aSTony Cheng case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 2624562236bSHarry Wentland prescale_params->scale = 0x2020; 2634562236bSHarry Wentland break; 2644562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 2654562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 2664562236bSHarry Wentland prescale_params->scale = 0x2008; 2674562236bSHarry Wentland break; 2684562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 2694562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 2704562236bSHarry Wentland prescale_params->scale = 0x2000; 2714562236bSHarry Wentland break; 2724562236bSHarry Wentland default: 2734562236bSHarry Wentland ASSERT(false); 274d7194cf6SAric Cyr break; 2754562236bSHarry Wentland } 2764562236bSHarry Wentland } 2774562236bSHarry Wentland 278a6114e85SHarry Wentland static bool 27978c77382SAnthony Koo dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 2803be5262eSHarry Wentland const struct dc_plane_state *plane_state) 2814562236bSHarry Wentland { 28286a66c4eSHarry Wentland struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 2837b0c470fSLeo (Sunpeng) Li const struct dc_transfer_func *tf = NULL; 28490e508baSAnthony Koo struct ipp_prescale_params prescale_params = { 0 }; 28590e508baSAnthony Koo bool result = true; 28690e508baSAnthony Koo 28790e508baSAnthony Koo if (ipp == NULL) 28890e508baSAnthony Koo return false; 28990e508baSAnthony Koo 2903be5262eSHarry Wentland if (plane_state->in_transfer_func) 2913be5262eSHarry Wentland tf = plane_state->in_transfer_func; 29290e508baSAnthony Koo 2933be5262eSHarry Wentland build_prescale_params(&prescale_params, plane_state); 29490e508baSAnthony Koo ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 29590e508baSAnthony Koo 29684ffa801SLeo (Sunpeng) Li if (plane_state->gamma_correction && 29784ffa801SLeo (Sunpeng) Li !plane_state->gamma_correction->is_identity && 29884ffa801SLeo (Sunpeng) Li dce_use_lut(plane_state->format)) 2993be5262eSHarry Wentland ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction); 300d7194cf6SAric Cyr 30190e508baSAnthony Koo if (tf == NULL) { 30290e508baSAnthony Koo /* Default case if no input transfer function specified */ 303a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 3047b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_PREDEFINED) { 3057b0c470fSLeo (Sunpeng) Li switch (tf->tf) { 30690e508baSAnthony Koo case TRANSFER_FUNCTION_SRGB: 307a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 30890e508baSAnthony Koo break; 30990e508baSAnthony Koo case TRANSFER_FUNCTION_BT709: 310a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC); 31190e508baSAnthony Koo break; 31290e508baSAnthony Koo case TRANSFER_FUNCTION_LINEAR: 313a6114e85SHarry Wentland ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 31490e508baSAnthony Koo break; 31590e508baSAnthony Koo case TRANSFER_FUNCTION_PQ: 31690e508baSAnthony Koo default: 31790e508baSAnthony Koo result = false; 318d7194cf6SAric Cyr break; 31990e508baSAnthony Koo } 3207b0c470fSLeo (Sunpeng) Li } else if (tf->type == TF_TYPE_BYPASS) { 32170063a59SAmy Zhang ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 32290e508baSAnthony Koo } else { 32390e508baSAnthony Koo /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 32490e508baSAnthony Koo result = false; 32590e508baSAnthony Koo } 32690e508baSAnthony Koo 32790e508baSAnthony Koo return result; 32890e508baSAnthony Koo } 32990e508baSAnthony Koo 330bd1be8e8SHarry Wentland static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted, 331fcd2f4bfSAmy Zhang struct curve_points *arr_points, 332fcd2f4bfSAmy Zhang uint32_t hw_points_num) 333fcd2f4bfSAmy Zhang { 334fcd2f4bfSAmy Zhang struct custom_float_format fmt; 335fcd2f4bfSAmy Zhang 336fcd2f4bfSAmy Zhang struct pwl_result_data *rgb = rgb_resulted; 337fcd2f4bfSAmy Zhang 338fcd2f4bfSAmy Zhang uint32_t i = 0; 339fcd2f4bfSAmy Zhang 340fcd2f4bfSAmy Zhang fmt.exponenta_bits = 6; 341fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 342fcd2f4bfSAmy Zhang fmt.sign = true; 343fcd2f4bfSAmy Zhang 344bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].x, &fmt, 345fcd2f4bfSAmy Zhang &arr_points[0].custom_float_x)) { 346fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 347fcd2f4bfSAmy Zhang return false; 348fcd2f4bfSAmy Zhang } 349fcd2f4bfSAmy Zhang 350bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].offset, &fmt, 351fcd2f4bfSAmy Zhang &arr_points[0].custom_float_offset)) { 352fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 353fcd2f4bfSAmy Zhang return false; 354fcd2f4bfSAmy Zhang } 355fcd2f4bfSAmy Zhang 356bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[0].slope, &fmt, 357fcd2f4bfSAmy Zhang &arr_points[0].custom_float_slope)) { 358fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 359fcd2f4bfSAmy Zhang return false; 360fcd2f4bfSAmy Zhang } 361fcd2f4bfSAmy Zhang 362fcd2f4bfSAmy Zhang fmt.mantissa_bits = 10; 363fcd2f4bfSAmy Zhang fmt.sign = false; 364fcd2f4bfSAmy Zhang 365bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].x, &fmt, 366fcd2f4bfSAmy Zhang &arr_points[1].custom_float_x)) { 367fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 368fcd2f4bfSAmy Zhang return false; 369fcd2f4bfSAmy Zhang } 370fcd2f4bfSAmy Zhang 371bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].y, &fmt, 372fcd2f4bfSAmy Zhang &arr_points[1].custom_float_y)) { 373fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 374fcd2f4bfSAmy Zhang return false; 375fcd2f4bfSAmy Zhang } 376fcd2f4bfSAmy Zhang 3774d06ccd0SHarry Wentland if (!convert_to_custom_float_format(arr_points[1].slope, &fmt, 3784d06ccd0SHarry Wentland &arr_points[1].custom_float_slope)) { 379fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 380fcd2f4bfSAmy Zhang return false; 381fcd2f4bfSAmy Zhang } 382fcd2f4bfSAmy Zhang 383fcd2f4bfSAmy Zhang fmt.mantissa_bits = 12; 384fcd2f4bfSAmy Zhang fmt.sign = true; 385fcd2f4bfSAmy Zhang 386fcd2f4bfSAmy Zhang while (i != hw_points_num) { 387bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->red, &fmt, 388fcd2f4bfSAmy Zhang &rgb->red_reg)) { 389fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 390fcd2f4bfSAmy Zhang return false; 391fcd2f4bfSAmy Zhang } 392fcd2f4bfSAmy Zhang 393bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->green, &fmt, 394fcd2f4bfSAmy Zhang &rgb->green_reg)) { 395fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 396fcd2f4bfSAmy Zhang return false; 397fcd2f4bfSAmy Zhang } 398fcd2f4bfSAmy Zhang 399bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->blue, &fmt, 400fcd2f4bfSAmy Zhang &rgb->blue_reg)) { 401fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 402fcd2f4bfSAmy Zhang return false; 403fcd2f4bfSAmy Zhang } 404fcd2f4bfSAmy Zhang 405bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_red, &fmt, 406fcd2f4bfSAmy Zhang &rgb->delta_red_reg)) { 407fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 408fcd2f4bfSAmy Zhang return false; 409fcd2f4bfSAmy Zhang } 410fcd2f4bfSAmy Zhang 411bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_green, &fmt, 412fcd2f4bfSAmy Zhang &rgb->delta_green_reg)) { 413fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 414fcd2f4bfSAmy Zhang return false; 415fcd2f4bfSAmy Zhang } 416fcd2f4bfSAmy Zhang 417bd1be8e8SHarry Wentland if (!convert_to_custom_float_format(rgb->delta_blue, &fmt, 418fcd2f4bfSAmy Zhang &rgb->delta_blue_reg)) { 419fcd2f4bfSAmy Zhang BREAK_TO_DEBUGGER(); 420fcd2f4bfSAmy Zhang return false; 421fcd2f4bfSAmy Zhang } 422fcd2f4bfSAmy Zhang 423fcd2f4bfSAmy Zhang ++rgb; 424fcd2f4bfSAmy Zhang ++i; 425fcd2f4bfSAmy Zhang } 426fcd2f4bfSAmy Zhang 427fcd2f4bfSAmy Zhang return true; 428fcd2f4bfSAmy Zhang } 429fcd2f4bfSAmy Zhang 43008616da5SLeo (Sunpeng) Li #define MAX_LOW_POINT 25 4318f8372c7SKrunoslav Kovac #define NUMBER_REGIONS 16 4328f8372c7SKrunoslav Kovac #define NUMBER_SW_SEGMENTS 16 4338f8372c7SKrunoslav Kovac 434b310b081SHarry Wentland static bool 435b310b081SHarry Wentland dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, 436b310b081SHarry Wentland struct pwl_params *regamma_params) 437fcd2f4bfSAmy Zhang { 43823ae4f8eSAmy Zhang struct curve_points *arr_points; 43923ae4f8eSAmy Zhang struct pwl_result_data *rgb_resulted; 44023ae4f8eSAmy Zhang struct pwl_result_data *rgb; 44123ae4f8eSAmy Zhang struct pwl_result_data *rgb_plus_1; 442fcd2f4bfSAmy Zhang struct fixed31_32 y_r; 443fcd2f4bfSAmy Zhang struct fixed31_32 y_g; 444fcd2f4bfSAmy Zhang struct fixed31_32 y_b; 445fcd2f4bfSAmy Zhang struct fixed31_32 y1_min; 446fcd2f4bfSAmy Zhang struct fixed31_32 y3_max; 447fcd2f4bfSAmy Zhang 4488f8372c7SKrunoslav Kovac int32_t region_start, region_end; 4498f8372c7SKrunoslav Kovac uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points; 45023ae4f8eSAmy Zhang 451b310b081SHarry Wentland if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS) 45223ae4f8eSAmy Zhang return false; 45323ae4f8eSAmy Zhang 45423ae4f8eSAmy Zhang arr_points = regamma_params->arr_points; 45523ae4f8eSAmy Zhang rgb_resulted = regamma_params->rgb_resulted; 45623ae4f8eSAmy Zhang hw_points = 0; 457fcd2f4bfSAmy Zhang 458fcd2f4bfSAmy Zhang memset(regamma_params, 0, sizeof(struct pwl_params)); 459fcd2f4bfSAmy Zhang 460fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 461534db198SAmy Zhang /* 16 segments 462fcd2f4bfSAmy Zhang * segments are from 2^-11 to 2^5 463fcd2f4bfSAmy Zhang */ 46408616da5SLeo (Sunpeng) Li region_start = -11; 46508616da5SLeo (Sunpeng) Li region_end = region_start + NUMBER_REGIONS; 466fcd2f4bfSAmy Zhang 4678f8372c7SKrunoslav Kovac for (i = 0; i < NUMBER_REGIONS; i++) 4688f8372c7SKrunoslav Kovac seg_distr[i] = 4; 469534db198SAmy Zhang 470fcd2f4bfSAmy Zhang } else { 471534db198SAmy Zhang /* 10 segments 472fc6de1c5SLeo (Sunpeng) Li * segment is from 2^-10 to 2^1 473fc6de1c5SLeo (Sunpeng) Li * We include an extra segment for range [2^0, 2^1). This is to 474fc6de1c5SLeo (Sunpeng) Li * ensure that colors with normalized values of 1 don't miss the 475fc6de1c5SLeo (Sunpeng) Li * LUT. 476fcd2f4bfSAmy Zhang */ 4778f8372c7SKrunoslav Kovac region_start = -10; 478fc6de1c5SLeo (Sunpeng) Li region_end = 1; 479534db198SAmy Zhang 4808f8372c7SKrunoslav Kovac seg_distr[0] = 4; 481534db198SAmy Zhang seg_distr[1] = 4; 482534db198SAmy Zhang seg_distr[2] = 4; 483534db198SAmy Zhang seg_distr[3] = 4; 484534db198SAmy Zhang seg_distr[4] = 4; 485534db198SAmy Zhang seg_distr[5] = 4; 486534db198SAmy Zhang seg_distr[6] = 4; 487534db198SAmy Zhang seg_distr[7] = 4; 4888f8372c7SKrunoslav Kovac seg_distr[8] = 4; 4898f8372c7SKrunoslav Kovac seg_distr[9] = 4; 490fc6de1c5SLeo (Sunpeng) Li seg_distr[10] = 0; 491534db198SAmy Zhang seg_distr[11] = -1; 492534db198SAmy Zhang seg_distr[12] = -1; 493534db198SAmy Zhang seg_distr[13] = -1; 494534db198SAmy Zhang seg_distr[14] = -1; 495534db198SAmy Zhang seg_distr[15] = -1; 496fcd2f4bfSAmy Zhang } 497fcd2f4bfSAmy Zhang 498534db198SAmy Zhang for (k = 0; k < 16; k++) { 499534db198SAmy Zhang if (seg_distr[k] != -1) 500534db198SAmy Zhang hw_points += (1 << seg_distr[k]); 501534db198SAmy Zhang } 502534db198SAmy Zhang 503fcd2f4bfSAmy Zhang j = 0; 5048f8372c7SKrunoslav Kovac for (k = 0; k < (region_end - region_start); k++) { 505ec47734aSLeo (Sunpeng) Li increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 5068f8372c7SKrunoslav Kovac start_index = (region_start + k + MAX_LOW_POINT) * 5078f8372c7SKrunoslav Kovac NUMBER_SW_SEGMENTS; 5088f8372c7SKrunoslav Kovac for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 5098f8372c7SKrunoslav Kovac i += increment) { 510534db198SAmy Zhang if (j == hw_points - 1) 511fcd2f4bfSAmy Zhang break; 512fcd2f4bfSAmy Zhang rgb_resulted[j].red = output_tf->tf_pts.red[i]; 513fcd2f4bfSAmy Zhang rgb_resulted[j].green = output_tf->tf_pts.green[i]; 514fcd2f4bfSAmy Zhang rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 515fcd2f4bfSAmy Zhang j++; 516fcd2f4bfSAmy Zhang } 517534db198SAmy Zhang } 518534db198SAmy Zhang 519534db198SAmy Zhang /* last point */ 5208f8372c7SKrunoslav Kovac start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 521b310b081SHarry Wentland rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 522b310b081SHarry Wentland rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 523b310b081SHarry Wentland rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 524fcd2f4bfSAmy Zhang 525eb0e5154SDmytro Laktyushkin arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2), 526eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_start)); 527eb0e5154SDmytro Laktyushkin arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2), 528eb0e5154SDmytro Laktyushkin dc_fixpt_from_int(region_end)); 529fcd2f4bfSAmy Zhang 530fcd2f4bfSAmy Zhang y_r = rgb_resulted[0].red; 531fcd2f4bfSAmy Zhang y_g = rgb_resulted[0].green; 532fcd2f4bfSAmy Zhang y_b = rgb_resulted[0].blue; 533fcd2f4bfSAmy Zhang 534eb0e5154SDmytro Laktyushkin y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b)); 535fcd2f4bfSAmy Zhang 536fcd2f4bfSAmy Zhang arr_points[0].y = y1_min; 537eb0e5154SDmytro Laktyushkin arr_points[0].slope = dc_fixpt_div(arr_points[0].y, 538fcd2f4bfSAmy Zhang arr_points[0].x); 539fcd2f4bfSAmy Zhang 540fcd2f4bfSAmy Zhang y_r = rgb_resulted[hw_points - 1].red; 541fcd2f4bfSAmy Zhang y_g = rgb_resulted[hw_points - 1].green; 542fcd2f4bfSAmy Zhang y_b = rgb_resulted[hw_points - 1].blue; 543fcd2f4bfSAmy Zhang 544fcd2f4bfSAmy Zhang /* see comment above, m_arrPoints[1].y should be the Y value for the 545fcd2f4bfSAmy Zhang * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 546fcd2f4bfSAmy Zhang */ 547eb0e5154SDmytro Laktyushkin y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b)); 548fcd2f4bfSAmy Zhang 549fcd2f4bfSAmy Zhang arr_points[1].y = y3_max; 550fcd2f4bfSAmy Zhang 551eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_zero; 552fcd2f4bfSAmy Zhang 553fcd2f4bfSAmy Zhang if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 554fcd2f4bfSAmy Zhang /* for PQ, we want to have a straight line from last HW X point, 555fcd2f4bfSAmy Zhang * and the slope to be such that we hit 1.0 at 10000 nits. 556fcd2f4bfSAmy Zhang */ 557eb0e5154SDmytro Laktyushkin const struct fixed31_32 end_value = dc_fixpt_from_int(125); 558fcd2f4bfSAmy Zhang 559eb0e5154SDmytro Laktyushkin arr_points[1].slope = dc_fixpt_div( 560eb0e5154SDmytro Laktyushkin dc_fixpt_sub(dc_fixpt_one, arr_points[1].y), 561eb0e5154SDmytro Laktyushkin dc_fixpt_sub(end_value, arr_points[1].x)); 562fcd2f4bfSAmy Zhang } 563fcd2f4bfSAmy Zhang 564fcd2f4bfSAmy Zhang regamma_params->hw_points_num = hw_points; 565fcd2f4bfSAmy Zhang 56669133b89SAric Cyr k = 0; 56769133b89SAric Cyr for (i = 1; i < 16; i++) { 568534db198SAmy Zhang if (seg_distr[k] != -1) { 569b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 570534db198SAmy Zhang regamma_params->arr_curve_points[i].offset = 571b310b081SHarry Wentland regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 572fcd2f4bfSAmy Zhang } 57369133b89SAric Cyr k++; 574534db198SAmy Zhang } 575534db198SAmy Zhang 576534db198SAmy Zhang if (seg_distr[k] != -1) 577b310b081SHarry Wentland regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 578fcd2f4bfSAmy Zhang 57923ae4f8eSAmy Zhang rgb = rgb_resulted; 58023ae4f8eSAmy Zhang rgb_plus_1 = rgb_resulted + 1; 581fcd2f4bfSAmy Zhang 582fcd2f4bfSAmy Zhang i = 1; 583fcd2f4bfSAmy Zhang 584fcd2f4bfSAmy Zhang while (i != hw_points + 1) { 585eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) 586fcd2f4bfSAmy Zhang rgb_plus_1->red = rgb->red; 587eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) 588fcd2f4bfSAmy Zhang rgb_plus_1->green = rgb->green; 589eb0e5154SDmytro Laktyushkin if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) 590fcd2f4bfSAmy Zhang rgb_plus_1->blue = rgb->blue; 591fcd2f4bfSAmy Zhang 592eb0e5154SDmytro Laktyushkin rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); 593eb0e5154SDmytro Laktyushkin rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 594eb0e5154SDmytro Laktyushkin rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 595fcd2f4bfSAmy Zhang 596fcd2f4bfSAmy Zhang ++rgb_plus_1; 597fcd2f4bfSAmy Zhang ++rgb; 598fcd2f4bfSAmy Zhang ++i; 599fcd2f4bfSAmy Zhang } 600fcd2f4bfSAmy Zhang 601fcd2f4bfSAmy Zhang convert_to_custom_float(rgb_resulted, arr_points, hw_points); 602fcd2f4bfSAmy Zhang 603fcd2f4bfSAmy Zhang return true; 604fcd2f4bfSAmy Zhang } 605fcd2f4bfSAmy Zhang 606a6114e85SHarry Wentland static bool 60778c77382SAnthony Koo dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 6080971c40eSHarry Wentland const struct dc_stream_state *stream) 60990e508baSAnthony Koo { 61086a66c4eSHarry Wentland struct transform *xfm = pipe_ctx->plane_res.xfm; 6114562236bSHarry Wentland 6127a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, true); 6137a09f5beSYue Hin Lau xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 6144562236bSHarry Wentland 6154fa086b9SLeo (Sunpeng) Li if (stream->out_transfer_func && 616efd52204SHarry Wentland stream->out_transfer_func->type == TF_TYPE_PREDEFINED && 617efd52204SHarry Wentland stream->out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) { 6187a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 619efd52204SHarry Wentland } else if (dce110_translate_regamma_to_hw_format(stream->out_transfer_func, 620efd52204SHarry Wentland &xfm->regamma_params)) { 6217a09f5beSYue Hin Lau xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 6227a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 6234562236bSHarry Wentland } else { 6247a09f5beSYue Hin Lau xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 6254562236bSHarry Wentland } 6264562236bSHarry Wentland 6277a09f5beSYue Hin Lau xfm->funcs->opp_power_on_regamma_lut(xfm, false); 6284562236bSHarry Wentland 629cc0cb445SLeon Elazar return true; 6304562236bSHarry Wentland } 6314562236bSHarry Wentland 6324562236bSHarry Wentland void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 6334562236bSHarry Wentland { 63402553f57SEric Bernstein bool is_hdmi_tmds; 6356f0db2dcSKrunoslav Kovac bool is_dp; 6366f0db2dcSKrunoslav Kovac 63786e2e1beSHersen Wu ASSERT(pipe_ctx->stream); 63886e2e1beSHersen Wu 6398e9c4c8cSHarry Wentland if (pipe_ctx->stream_res.stream_enc == NULL) 64086e2e1beSHersen Wu return; /* this is not root pipe */ 64186e2e1beSHersen Wu 64202553f57SEric Bernstein is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal); 6436f0db2dcSKrunoslav Kovac is_dp = dc_is_dp_signal(pipe_ctx->stream->signal); 6446f0db2dcSKrunoslav Kovac 64502553f57SEric Bernstein if (!is_hdmi_tmds && !is_dp) 6466f0db2dcSKrunoslav Kovac return; 6476f0db2dcSKrunoslav Kovac 64802553f57SEric Bernstein if (is_hdmi_tmds) 6498e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 6508e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 65196c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6526f0db2dcSKrunoslav Kovac else 6538e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 6548e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc, 65596c50c0dSHarry Wentland &pipe_ctx->stream_res.encoder_info_frame); 6564562236bSHarry Wentland } 6574562236bSHarry Wentland 6584562236bSHarry Wentland void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 6594562236bSHarry Wentland { 6604562236bSHarry Wentland enum dc_lane_count lane_count = 661ceb3dbb4SJun Lei pipe_ctx->stream->link->cur_link_settings.lane_count; 6624fa086b9SLeo (Sunpeng) Li struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 663ceb3dbb4SJun Lei struct dc_link *link = pipe_ctx->stream->link; 664f42ea55bSAnthony Koo const struct dc *dc = link->dc; 665f215a57dSEric Yang 6664562236bSHarry Wentland uint32_t active_total_with_borders; 6674562236bSHarry Wentland uint32_t early_control = 0; 6686b670fa9SHarry Wentland struct timing_generator *tg = pipe_ctx->stream_res.tg; 6694562236bSHarry Wentland 670f215a57dSEric Yang /* For MST, there are multiply stream go to only one link. 671f215a57dSEric Yang * connect DIG back_end to front_end while enable_stream and 672f215a57dSEric Yang * disconnect them during disable_stream 673f215a57dSEric Yang * BY this, it is logic clean to separate stream and link */ 674f215a57dSEric Yang link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, 675f215a57dSEric Yang pipe_ctx->stream_res.stream_enc->id, true); 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 /* enable audio only within mode set */ 694afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio != NULL) { 6954562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 6968e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); 6974562236bSHarry Wentland } 6984562236bSHarry Wentland 699f215a57dSEric Yang 700f215a57dSEric Yang 7014562236bSHarry Wentland 7024562236bSHarry Wentland } 7034562236bSHarry Wentland 7045eefbc40SYue Hin Lau static enum bp_result link_transmitter_control( 70587401969SAndrew Jiang struct dc_bios *bios, 7065eefbc40SYue Hin Lau struct bp_transmitter_control *cntl) 7075eefbc40SYue Hin Lau { 7085eefbc40SYue Hin Lau enum bp_result result; 7095eefbc40SYue Hin Lau 71087401969SAndrew Jiang result = bios->funcs->transmitter_control(bios, cntl); 7115eefbc40SYue Hin Lau 7125eefbc40SYue Hin Lau return result; 7135eefbc40SYue Hin Lau } 7145eefbc40SYue Hin Lau 71587401969SAndrew Jiang /* 71687401969SAndrew Jiang * @brief 71787401969SAndrew Jiang * eDP only. 71887401969SAndrew Jiang */ 7198a31820bSMartin Leung void dce110_edp_wait_for_hpd_ready( 720069d418fSAndrew Jiang struct dc_link *link, 72187401969SAndrew Jiang bool power_up) 72287401969SAndrew Jiang { 723069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 724069d418fSAndrew Jiang struct graphics_object_id connector = link->link_enc->connector; 72587401969SAndrew Jiang struct gpio *hpd; 7266798d042SLewis Huang struct dc_sink *sink = link->local_sink; 72787401969SAndrew Jiang bool edp_hpd_high = false; 72887401969SAndrew Jiang uint32_t time_elapsed = 0; 72987401969SAndrew Jiang uint32_t timeout = power_up ? 73087401969SAndrew Jiang PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; 73187401969SAndrew Jiang 73287401969SAndrew Jiang if (dal_graphics_object_id_get_connector_id(connector) 73387401969SAndrew Jiang != CONNECTOR_ID_EDP) { 73487401969SAndrew Jiang BREAK_TO_DEBUGGER(); 73587401969SAndrew Jiang return; 73687401969SAndrew Jiang } 73787401969SAndrew Jiang 73887401969SAndrew Jiang if (!power_up) 73987401969SAndrew Jiang /* 74087401969SAndrew Jiang * From KV, we will not HPD low after turning off VCC - 74187401969SAndrew Jiang * instead, we will check the SW timer in power_up(). 74287401969SAndrew Jiang */ 74387401969SAndrew Jiang return; 74487401969SAndrew Jiang 74587401969SAndrew Jiang /* 74687401969SAndrew Jiang * When we power on/off the eDP panel, 74787401969SAndrew Jiang * we need to wait until SENSE bit is high/low. 74887401969SAndrew Jiang */ 74987401969SAndrew Jiang 75087401969SAndrew Jiang /* obtain HPD */ 75187401969SAndrew Jiang /* TODO what to do with this? */ 75287401969SAndrew Jiang hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); 75387401969SAndrew Jiang 75487401969SAndrew Jiang if (!hpd) { 75587401969SAndrew Jiang BREAK_TO_DEBUGGER(); 75687401969SAndrew Jiang return; 75787401969SAndrew Jiang } 75887401969SAndrew Jiang 7596798d042SLewis Huang if (sink != NULL) { 7606798d042SLewis Huang if (sink->edid_caps.panel_patch.extra_t3_ms > 0) { 7616798d042SLewis Huang int extra_t3_in_ms = sink->edid_caps.panel_patch.extra_t3_ms; 7626798d042SLewis Huang 7636798d042SLewis Huang msleep(extra_t3_in_ms); 7646798d042SLewis Huang } 7656798d042SLewis Huang } 7666798d042SLewis Huang 76787401969SAndrew Jiang dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); 76887401969SAndrew Jiang 76987401969SAndrew Jiang /* wait until timeout or panel detected */ 77087401969SAndrew Jiang 77187401969SAndrew Jiang do { 77287401969SAndrew Jiang uint32_t detected = 0; 77387401969SAndrew Jiang 77487401969SAndrew Jiang dal_gpio_get_value(hpd, &detected); 77587401969SAndrew Jiang 77687401969SAndrew Jiang if (!(detected ^ power_up)) { 77787401969SAndrew Jiang edp_hpd_high = true; 77887401969SAndrew Jiang break; 77987401969SAndrew Jiang } 78087401969SAndrew Jiang 78187401969SAndrew Jiang msleep(HPD_CHECK_INTERVAL); 78287401969SAndrew Jiang 78387401969SAndrew Jiang time_elapsed += HPD_CHECK_INTERVAL; 78487401969SAndrew Jiang } while (time_elapsed < timeout); 78587401969SAndrew Jiang 78687401969SAndrew Jiang dal_gpio_close(hpd); 78787401969SAndrew Jiang 78887401969SAndrew Jiang dal_gpio_destroy_irq(&hpd); 78987401969SAndrew Jiang 79087401969SAndrew Jiang if (false == edp_hpd_high) { 7911296423bSBhawanpreet Lakha DC_LOG_ERROR( 79287401969SAndrew Jiang "%s: wait timed out!\n", __func__); 79387401969SAndrew Jiang } 79487401969SAndrew Jiang } 79587401969SAndrew Jiang 7968a31820bSMartin Leung void dce110_edp_power_control( 797069d418fSAndrew Jiang struct dc_link *link, 79887401969SAndrew Jiang bool power_up) 79987401969SAndrew Jiang { 800069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 80187401969SAndrew Jiang struct bp_transmitter_control cntl = { 0 }; 80287401969SAndrew Jiang enum bp_result bp_result; 80306ddcee4SJake Wang uint8_t panel_instance; 80487401969SAndrew Jiang 80587401969SAndrew Jiang 806069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 80787401969SAndrew Jiang != CONNECTOR_ID_EDP) { 80887401969SAndrew Jiang BREAK_TO_DEBUGGER(); 80987401969SAndrew Jiang return; 81087401969SAndrew Jiang } 81187401969SAndrew Jiang 812ffadb9d6SAnthony Koo if (!link->panel_cntl) 813904fb6e0SAnthony Koo return; 814d4caa72eSAnthony Koo if (power_up != 815d4caa72eSAnthony Koo link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) { 816172c9b77SAshley Thomas 81778d5d04dSCharlene Liu unsigned long long current_ts = dm_get_timestamp(ctx); 818172c9b77SAshley Thomas unsigned long long time_since_edp_poweroff_ms = 81993ed1814SHugo Hu div64_u64(dm_get_elapse_time_in_ns( 82078d5d04dSCharlene Liu ctx, 82178d5d04dSCharlene Liu current_ts, 82293ed1814SHugo Hu link->link_trace.time_stamp.edp_poweroff), 1000000); 823172c9b77SAshley Thomas unsigned long long time_since_edp_poweron_ms = 824172c9b77SAshley Thomas div64_u64(dm_get_elapse_time_in_ns( 825172c9b77SAshley Thomas ctx, 826172c9b77SAshley Thomas current_ts, 827172c9b77SAshley Thomas link->link_trace.time_stamp.edp_poweron), 1000000); 828172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 829172c9b77SAshley 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", 830172c9b77SAshley Thomas __func__, 831172c9b77SAshley Thomas power_up, 832172c9b77SAshley Thomas current_ts, 833172c9b77SAshley Thomas link->link_trace.time_stamp.edp_poweroff, 834172c9b77SAshley Thomas link->link_trace.time_stamp.edp_poweron, 835172c9b77SAshley Thomas time_since_edp_poweroff_ms, 836172c9b77SAshley Thomas time_since_edp_poweron_ms); 83778d5d04dSCharlene Liu 838172c9b77SAshley Thomas /* Send VBIOS command to prompt eDP panel power */ 839172c9b77SAshley Thomas if (power_up) { 840172c9b77SAshley Thomas /* edp requires a min of 500ms from LCDVDD off to on */ 841172c9b77SAshley Thomas unsigned long long remaining_min_edp_poweroff_time_ms = 500; 842ff587987SHugo Hu 843172c9b77SAshley Thomas /* add time defined by a patch, if any (usually patch extra_t12_ms is 0) */ 8446c4fff06SYue Hin Lau if (link->local_sink != NULL) 845172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms += 846172c9b77SAshley Thomas link->local_sink->edid_caps.panel_patch.extra_t12_ms; 84778d5d04dSCharlene Liu 848172c9b77SAshley Thomas /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */ 849172c9b77SAshley Thomas if (link->link_trace.time_stamp.edp_poweroff != 0) { 850172c9b77SAshley Thomas if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms) 851172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms = 852172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms; 853172c9b77SAshley Thomas else 854172c9b77SAshley Thomas remaining_min_edp_poweroff_time_ms = 0; 85578d5d04dSCharlene Liu } 85678d5d04dSCharlene Liu 857172c9b77SAshley Thomas if (remaining_min_edp_poweroff_time_ms) { 858172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 859172c9b77SAshley Thomas "%s: remaining_min_edp_poweroff_time_ms=%llu: begin wait.\n", 860172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 861172c9b77SAshley Thomas msleep(remaining_min_edp_poweroff_time_ms); 862172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 863172c9b77SAshley Thomas "%s: remaining_min_edp_poweroff_time_ms=%llu: end wait.\n", 864172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 865172c9b77SAshley Thomas dm_output_to_console("%s: wait %lld ms to power on eDP.\n", 866172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 867172c9b77SAshley Thomas } else { 868172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 869172c9b77SAshley Thomas "%s: remaining_min_edp_poweroff_time_ms=%llu: no wait required.\n", 870172c9b77SAshley Thomas __func__, remaining_min_edp_poweroff_time_ms); 871172c9b77SAshley Thomas } 87278d5d04dSCharlene Liu } 87387401969SAndrew Jiang 8741296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 875172c9b77SAshley Thomas "%s: BEGIN: Panel Power action: %s\n", 87687401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 87787401969SAndrew Jiang 87887401969SAndrew Jiang cntl.action = power_up ? 87987401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_ON : 88087401969SAndrew Jiang TRANSMITTER_CONTROL_POWER_OFF; 881069d418fSAndrew Jiang cntl.transmitter = link->link_enc->transmitter; 882069d418fSAndrew Jiang cntl.connector_obj_id = link->link_enc->connector; 88387401969SAndrew Jiang cntl.coherent = false; 88487401969SAndrew Jiang cntl.lanes_number = LANE_COUNT_FOUR; 885069d418fSAndrew Jiang cntl.hpd_sel = link->link_enc->hpd_source; 88606ddcee4SJake Wang panel_instance = link->panel_cntl->inst; 8878a0e210cSChris Park 8888a0e210cSChris Park if (ctx->dc->ctx->dmub_srv && 8898a0e210cSChris Park ctx->dc->debug.dmub_command_table) { 8908a0e210cSChris Park if (cntl.action == TRANSMITTER_CONTROL_POWER_ON) 8918a0e210cSChris Park bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 89206ddcee4SJake Wang LVTMA_CONTROL_POWER_ON, 89306ddcee4SJake Wang panel_instance); 8948a0e210cSChris Park else 8958a0e210cSChris Park bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 89606ddcee4SJake Wang LVTMA_CONTROL_POWER_OFF, 89706ddcee4SJake Wang panel_instance); 8988a0e210cSChris Park } 8998a0e210cSChris Park 90087401969SAndrew Jiang bp_result = link_transmitter_control(ctx->dc_bios, &cntl); 90187401969SAndrew Jiang 902172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 903172c9b77SAshley Thomas "%s: END: Panel Power action: %s bp_result=%u\n", 904172c9b77SAshley Thomas __func__, (power_up ? "On":"Off"), 905172c9b77SAshley Thomas bp_result); 906172c9b77SAshley Thomas 90778d5d04dSCharlene Liu if (!power_up) 90878d5d04dSCharlene Liu /*save driver power off time stamp*/ 90978d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx); 91078d5d04dSCharlene Liu else 91178d5d04dSCharlene Liu link->link_trace.time_stamp.edp_poweron = dm_get_timestamp(ctx); 91278d5d04dSCharlene Liu 913172c9b77SAshley Thomas DC_LOG_HW_RESUME_S3( 914172c9b77SAshley Thomas "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n", 915172c9b77SAshley Thomas __func__, 916172c9b77SAshley Thomas link->link_trace.time_stamp.edp_poweroff, 917172c9b77SAshley Thomas link->link_trace.time_stamp.edp_poweron); 918172c9b77SAshley Thomas 91987401969SAndrew Jiang if (bp_result != BP_RESULT_OK) 9201296423bSBhawanpreet Lakha DC_LOG_ERROR( 92187401969SAndrew Jiang "%s: Panel Power bp_result: %d\n", 92287401969SAndrew Jiang __func__, bp_result); 92387401969SAndrew Jiang } else { 9241296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 92587401969SAndrew Jiang "%s: Skipping Panel Power action: %s\n", 92687401969SAndrew Jiang __func__, (power_up ? "On":"Off")); 92787401969SAndrew Jiang } 92887401969SAndrew Jiang } 9295eefbc40SYue Hin Lau 930cf3a2627SJun Lei void dce110_edp_wait_for_T12( 931cf3a2627SJun Lei struct dc_link *link) 932cf3a2627SJun Lei { 933cf3a2627SJun Lei struct dc_context *ctx = link->ctx; 934cf3a2627SJun Lei 935cf3a2627SJun Lei if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 936cf3a2627SJun Lei != CONNECTOR_ID_EDP) { 937cf3a2627SJun Lei BREAK_TO_DEBUGGER(); 938cf3a2627SJun Lei return; 939cf3a2627SJun Lei } 940cf3a2627SJun Lei 941cf3a2627SJun Lei if (!link->panel_cntl) 942cf3a2627SJun Lei return; 943cf3a2627SJun Lei 944cf3a2627SJun Lei if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) && 945cf3a2627SJun Lei link->link_trace.time_stamp.edp_poweroff != 0) { 946cf3a2627SJun Lei unsigned int t12_duration = 500; // Default T12 as per spec 947cf3a2627SJun Lei unsigned long long current_ts = dm_get_timestamp(ctx); 948cf3a2627SJun Lei unsigned long long time_since_edp_poweroff_ms = 949cf3a2627SJun Lei div64_u64(dm_get_elapse_time_in_ns( 950cf3a2627SJun Lei ctx, 951cf3a2627SJun Lei current_ts, 952cf3a2627SJun Lei link->link_trace.time_stamp.edp_poweroff), 1000000); 953cf3a2627SJun Lei 954cf3a2627SJun Lei t12_duration += link->local_sink->edid_caps.panel_patch.extra_t12_ms; // Add extra T12 955cf3a2627SJun Lei 956cf3a2627SJun Lei if (time_since_edp_poweroff_ms < t12_duration) 957cf3a2627SJun Lei msleep(t12_duration - time_since_edp_poweroff_ms); 958cf3a2627SJun Lei } 959cf3a2627SJun Lei } 960cf3a2627SJun Lei 9615eefbc40SYue Hin Lau /*todo: cloned in stream enc, fix*/ 9625eefbc40SYue Hin Lau /* 9635eefbc40SYue Hin Lau * @brief 9645eefbc40SYue Hin Lau * eDP only. Control the backlight of the eDP panel 9655eefbc40SYue Hin Lau */ 9668a31820bSMartin Leung void dce110_edp_backlight_control( 9675eefbc40SYue Hin Lau struct dc_link *link, 9685eefbc40SYue Hin Lau bool enable) 9695eefbc40SYue Hin Lau { 970069d418fSAndrew Jiang struct dc_context *ctx = link->ctx; 9715eefbc40SYue Hin Lau struct bp_transmitter_control cntl = { 0 }; 97206ddcee4SJake Wang uint8_t panel_instance; 9735eefbc40SYue Hin Lau 974069d418fSAndrew Jiang if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 9755eefbc40SYue Hin Lau != CONNECTOR_ID_EDP) { 9765eefbc40SYue Hin Lau BREAK_TO_DEBUGGER(); 9775eefbc40SYue Hin Lau return; 9785eefbc40SYue Hin Lau } 9795eefbc40SYue Hin Lau 980014427adSSherry if (link->panel_cntl) { 981014427adSSherry bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); 982014427adSSherry 983014427adSSherry if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { 9841296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 985014427adSSherry "%s: panel already powered up/off. Do nothing.\n", 9865eefbc40SYue Hin Lau __func__); 9875eefbc40SYue Hin Lau return; 9885eefbc40SYue Hin Lau } 989014427adSSherry } 9905eefbc40SYue Hin Lau 9915eefbc40SYue Hin Lau /* Send VBIOS command to control eDP panel backlight */ 9925eefbc40SYue Hin Lau 9931296423bSBhawanpreet Lakha DC_LOG_HW_RESUME_S3( 9945eefbc40SYue Hin Lau "%s: backlight action: %s\n", 9955eefbc40SYue Hin Lau __func__, (enable ? "On":"Off")); 9965eefbc40SYue Hin Lau 9975eefbc40SYue Hin Lau cntl.action = enable ? 9985eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_ON : 9995eefbc40SYue Hin Lau TRANSMITTER_CONTROL_BACKLIGHT_OFF; 100087401969SAndrew Jiang 10015eefbc40SYue Hin Lau /*cntl.engine_id = ctx->engine;*/ 10025eefbc40SYue Hin Lau cntl.transmitter = link->link_enc->transmitter; 10035eefbc40SYue Hin Lau cntl.connector_obj_id = link->link_enc->connector; 10045eefbc40SYue Hin Lau /*todo: unhardcode*/ 10055eefbc40SYue Hin Lau cntl.lanes_number = LANE_COUNT_FOUR; 10065eefbc40SYue Hin Lau cntl.hpd_sel = link->link_enc->hpd_source; 1007cf1835f0SCharlene Liu cntl.signal = SIGNAL_TYPE_EDP; 10085eefbc40SYue Hin Lau 10095eefbc40SYue Hin Lau /* For eDP, the following delays might need to be considered 10105eefbc40SYue Hin Lau * after link training completed: 10115eefbc40SYue Hin Lau * idle period - min. accounts for required BS-Idle pattern, 10125eefbc40SYue Hin Lau * max. allows for source frame synchronization); 10135eefbc40SYue Hin Lau * 50 msec max. delay from valid video data from source 10145eefbc40SYue Hin Lau * to video on dislpay or backlight enable. 10155eefbc40SYue Hin Lau * 10165eefbc40SYue Hin Lau * Disable the delay for now. 10175eefbc40SYue Hin Lau * Enable it in the future if necessary. 10185eefbc40SYue Hin Lau */ 10195eefbc40SYue Hin Lau /* dc_service_sleep_in_milliseconds(50); */ 10205180d4a4SCharlene Liu /*edp 1.2*/ 102106ddcee4SJake Wang panel_instance = link->panel_cntl->inst; 10225180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 10235180d4a4SCharlene Liu edp_receiver_ready_T7(link); 10248a0e210cSChris Park 10258a0e210cSChris Park if (ctx->dc->ctx->dmub_srv && 10268a0e210cSChris Park ctx->dc->debug.dmub_command_table) { 10278a0e210cSChris Park if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 10288a0e210cSChris Park ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 102906ddcee4SJake Wang LVTMA_CONTROL_LCD_BLON, 103006ddcee4SJake Wang panel_instance); 10318a0e210cSChris Park else 10328a0e210cSChris Park ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 103306ddcee4SJake Wang LVTMA_CONTROL_LCD_BLOFF, 103406ddcee4SJake Wang panel_instance); 10358a0e210cSChris Park } 10368a0e210cSChris Park 1037069d418fSAndrew Jiang link_transmitter_control(ctx->dc_bios, &cntl); 103896577cf8SHersen Wu 103996577cf8SHersen Wu if (enable && link->dpcd_sink_ext_caps.bits.oled) 104096577cf8SHersen Wu msleep(OLED_POST_T7_DELAY); 104196577cf8SHersen Wu 104296577cf8SHersen Wu if (link->dpcd_sink_ext_caps.bits.oled || 104396577cf8SHersen Wu link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || 104496577cf8SHersen Wu link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1) 104596577cf8SHersen Wu dc_link_backlight_enable_aux(link, enable); 104696577cf8SHersen Wu 104769b9723aSCharlene Liu /*edp 1.2*/ 10485180d4a4SCharlene Liu if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) 10493a372bedSHugo Hu edp_add_delay_for_T9(link); 105096577cf8SHersen Wu 105196577cf8SHersen Wu if (!enable && link->dpcd_sink_ext_caps.bits.oled) 105296577cf8SHersen Wu msleep(OLED_PRE_T11_DELAY); 10535eefbc40SYue Hin Lau } 10545eefbc40SYue Hin Lau 10551a05873fSAnthony Koo void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) 10564562236bSHarry Wentland { 10571a05873fSAnthony Koo /* notify audio driver for audio modes of monitor */ 10582b77dcc5SAnthony Koo struct dc *dc; 10591d0610bcSAlvin Lee struct clk_mgr *clk_mgr; 10601a05873fSAnthony Koo unsigned int i, num_audio = 1; 10611a05873fSAnthony Koo 10621d0610bcSAlvin Lee if (!pipe_ctx->stream) 10631d0610bcSAlvin Lee return; 10641d0610bcSAlvin Lee 10652b77dcc5SAnthony Koo dc = pipe_ctx->stream->ctx->dc; 10662b77dcc5SAnthony Koo clk_mgr = dc->clk_mgr; 10671d0610bcSAlvin Lee 10680a32df9cSEryk Brol if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true) 10690a32df9cSEryk Brol return; 10700a32df9cSEryk Brol 10711a05873fSAnthony Koo if (pipe_ctx->stream_res.audio) { 10721a05873fSAnthony Koo for (i = 0; i < MAX_PIPES; i++) { 10731a05873fSAnthony Koo /*current_state not updated yet*/ 10742b77dcc5SAnthony Koo if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) 10751a05873fSAnthony Koo num_audio++; 10761a05873fSAnthony Koo } 10771a05873fSAnthony Koo 10781a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); 10791a05873fSAnthony Koo 1080170a2398SSu Sung Chung if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) 10811a05873fSAnthony Koo /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1082170a2398SSu Sung Chung clk_mgr->funcs->enable_pme_wa(clk_mgr); 10831a05873fSAnthony Koo /* un-mute audio */ 10841a05873fSAnthony Koo /* TODO: audio should be per stream rather than per link */ 10851a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 10861a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, false); 10870a32df9cSEryk Brol if (pipe_ctx->stream_res.audio) 10880a32df9cSEryk Brol pipe_ctx->stream_res.audio->enabled = true; 10891a05873fSAnthony Koo } 10901a05873fSAnthony Koo } 10911a05873fSAnthony Koo 109257430404SSu Sung Chung void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) 10931a05873fSAnthony Koo { 10941d0610bcSAlvin Lee struct dc *dc; 10951d0610bcSAlvin Lee struct clk_mgr *clk_mgr; 10961d0610bcSAlvin Lee 10971d0610bcSAlvin Lee if (!pipe_ctx || !pipe_ctx->stream) 10981d0610bcSAlvin Lee return; 10991d0610bcSAlvin Lee 11001d0610bcSAlvin Lee dc = pipe_ctx->stream->ctx->dc; 11011d0610bcSAlvin Lee clk_mgr = dc->clk_mgr; 11024562236bSHarry Wentland 11030a32df9cSEryk Brol if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false) 11040a32df9cSEryk Brol return; 11050a32df9cSEryk Brol 11062b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( 11072b7c97d6SCharlene Liu pipe_ctx->stream_res.stream_enc, true); 1108afaacef4SHarry Wentland if (pipe_ctx->stream_res.audio) { 11093f52aa9fSNicholas Kazlauskas pipe_ctx->stream_res.audio->enabled = false; 11103f52aa9fSNicholas Kazlauskas 11114562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal)) 11128e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( 11138e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 11144562236bSHarry Wentland else 11158e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( 11168e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc); 111757430404SSu Sung Chung 1118170a2398SSu Sung Chung if (clk_mgr->funcs->enable_pme_wa) 1119070fe724SCharlene Liu /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1120170a2398SSu Sung Chung clk_mgr->funcs->enable_pme_wa(clk_mgr); 11214562236bSHarry Wentland 11224562236bSHarry Wentland /* TODO: notify audio driver for if audio modes list changed 11234562236bSHarry Wentland * add audio mode list change flag */ 11244562236bSHarry Wentland /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 11254562236bSHarry Wentland * stream->stream_engine_id); 11264562236bSHarry Wentland */ 11274562236bSHarry Wentland } 11281a05873fSAnthony Koo } 11294562236bSHarry Wentland 113057430404SSu Sung Chung void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 11311a05873fSAnthony Koo { 11321a05873fSAnthony Koo struct dc_stream_state *stream = pipe_ctx->stream; 1133ceb3dbb4SJun Lei struct dc_link *link = stream->link; 11341a05873fSAnthony Koo struct dc *dc = pipe_ctx->stream->ctx->dc; 11351a05873fSAnthony Koo 1136ac42fd63SWenjing Liu if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { 11371a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 11381a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 1139ac42fd63SWenjing Liu pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute( 1140ac42fd63SWenjing Liu pipe_ctx->stream_res.stream_enc); 1141ac42fd63SWenjing Liu } 11421a05873fSAnthony Koo 11431a05873fSAnthony Koo if (dc_is_dp_signal(pipe_ctx->stream->signal)) 11441a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 11451a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc); 11461a05873fSAnthony Koo 114757430404SSu Sung Chung dc->hwss.disable_audio_stream(pipe_ctx); 1148904623eeSYongqiang Sun 11494562236bSHarry Wentland link->link_enc->funcs->connect_dig_be_to_fe( 11504562236bSHarry Wentland link->link_enc, 11518e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->id, 11524562236bSHarry Wentland false); 11534562236bSHarry Wentland 11544562236bSHarry Wentland } 11554562236bSHarry Wentland 11564562236bSHarry Wentland void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 11574562236bSHarry Wentland struct dc_link_settings *link_settings) 11584562236bSHarry Wentland { 11594562236bSHarry Wentland struct encoder_unblank_param params = { { 0 } }; 116041b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 1161ceb3dbb4SJun Lei struct dc_link *link = stream->link; 1162f42ea55bSAnthony Koo struct dce_hwseq *hws = link->dc->hwseq; 11634562236bSHarry Wentland 11644562236bSHarry Wentland /* only 3 items below are used by unblank */ 11657fe538a4SCharlene Liu params.timing = pipe_ctx->stream->timing; 11664562236bSHarry Wentland params.link_settings.link_rate = link_settings->link_rate; 116741b49742SCharlene Liu 116841b49742SCharlene Liu if (dc_is_dp_signal(pipe_ctx->stream->signal)) 11698e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); 117041b49742SCharlene Liu 117114d6f644SYongqiang Sun if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1172f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(link, true); 117314d6f644SYongqiang Sun } 117441b49742SCharlene Liu } 11752c850b7bSDmytro Laktyushkin 117641b49742SCharlene Liu void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 117741b49742SCharlene Liu { 117841b49742SCharlene Liu struct dc_stream_state *stream = pipe_ctx->stream; 1179ceb3dbb4SJun Lei struct dc_link *link = stream->link; 1180f42ea55bSAnthony Koo struct dce_hwseq *hws = link->dc->hwseq; 118141b49742SCharlene Liu 1182ab892598SRoman Li if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1183f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(link, false); 11843ba01817SYongqiang Sun link->dc->hwss.set_abm_immediate_disable(pipe_ctx); 1185ab892598SRoman Li } 118641b49742SCharlene Liu 1187eec3303dSAric Cyr if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 118841b49742SCharlene Liu pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); 1189eec3303dSAric Cyr 11903a372bedSHugo Hu if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) { 1191eec3303dSAric Cyr /* 1192eec3303dSAric Cyr * After output is idle pattern some sinks need time to recognize the stream 1193eec3303dSAric Cyr * has changed or they enter protection state and hang. 1194eec3303dSAric Cyr */ 1195eec3303dSAric Cyr msleep(60); 11963a372bedSHugo Hu } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) 11973a372bedSHugo Hu edp_receiver_ready_T9(link); 1198eec3303dSAric Cyr } 1199eec3303dSAric Cyr 12004562236bSHarry Wentland } 12014562236bSHarry Wentland 120215e17335SCharlene Liu 120315e17335SCharlene Liu void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 120415e17335SCharlene Liu { 12058e9c4c8cSHarry Wentland if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL) 12068e9c4c8cSHarry Wentland pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 120715e17335SCharlene Liu } 120815e17335SCharlene Liu 12094562236bSHarry Wentland static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 12104562236bSHarry Wentland { 12114562236bSHarry Wentland switch (crtc_id) { 12124562236bSHarry Wentland case CONTROLLER_ID_D0: 12134562236bSHarry Wentland return DTO_SOURCE_ID0; 12144562236bSHarry Wentland case CONTROLLER_ID_D1: 12154562236bSHarry Wentland return DTO_SOURCE_ID1; 12164562236bSHarry Wentland case CONTROLLER_ID_D2: 12174562236bSHarry Wentland return DTO_SOURCE_ID2; 12184562236bSHarry Wentland case CONTROLLER_ID_D3: 12194562236bSHarry Wentland return DTO_SOURCE_ID3; 12204562236bSHarry Wentland case CONTROLLER_ID_D4: 12214562236bSHarry Wentland return DTO_SOURCE_ID4; 12224562236bSHarry Wentland case CONTROLLER_ID_D5: 12234562236bSHarry Wentland return DTO_SOURCE_ID5; 12244562236bSHarry Wentland default: 12254562236bSHarry Wentland return DTO_SOURCE_UNKNOWN; 12264562236bSHarry Wentland } 12274562236bSHarry Wentland } 12284562236bSHarry Wentland 12294562236bSHarry Wentland static void build_audio_output( 1230ab8db3e1SAndrey Grodzovsky struct dc_state *state, 12314562236bSHarry Wentland const struct pipe_ctx *pipe_ctx, 12324562236bSHarry Wentland struct audio_output *audio_output) 12334562236bSHarry Wentland { 12340971c40eSHarry Wentland const struct dc_stream_state *stream = pipe_ctx->stream; 12358e9c4c8cSHarry Wentland audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id; 12364562236bSHarry Wentland 12374562236bSHarry Wentland audio_output->signal = pipe_ctx->stream->signal; 12384562236bSHarry Wentland 12394562236bSHarry Wentland /* audio_crtc_info */ 12404562236bSHarry Wentland 12414562236bSHarry Wentland audio_output->crtc_info.h_total = 12424fa086b9SLeo (Sunpeng) Li stream->timing.h_total; 12434562236bSHarry Wentland 12444562236bSHarry Wentland /* 12454562236bSHarry Wentland * Audio packets are sent during actual CRTC blank physical signal, we 12464562236bSHarry Wentland * need to specify actual active signal portion 12474562236bSHarry Wentland */ 12484562236bSHarry Wentland audio_output->crtc_info.h_active = 12494fa086b9SLeo (Sunpeng) Li stream->timing.h_addressable 12504fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_left 12514fa086b9SLeo (Sunpeng) Li + stream->timing.h_border_right; 12524562236bSHarry Wentland 12534562236bSHarry Wentland audio_output->crtc_info.v_active = 12544fa086b9SLeo (Sunpeng) Li stream->timing.v_addressable 12554fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_top 12564fa086b9SLeo (Sunpeng) Li + stream->timing.v_border_bottom; 12574562236bSHarry Wentland 12584562236bSHarry Wentland audio_output->crtc_info.pixel_repetition = 1; 12594562236bSHarry Wentland 12604562236bSHarry Wentland audio_output->crtc_info.interlaced = 12614fa086b9SLeo (Sunpeng) Li stream->timing.flags.INTERLACE; 12624562236bSHarry Wentland 12634562236bSHarry Wentland audio_output->crtc_info.refresh_rate = 126440fd9090SNevenko Stupar (stream->timing.pix_clk_100hz*100)/ 12654fa086b9SLeo (Sunpeng) Li (stream->timing.h_total*stream->timing.v_total); 12664562236bSHarry Wentland 12674562236bSHarry Wentland audio_output->crtc_info.color_depth = 12684fa086b9SLeo (Sunpeng) Li stream->timing.display_color_depth; 12694562236bSHarry Wentland 127040fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz = 127140fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 12724562236bSHarry Wentland 127340fd9090SNevenko Stupar audio_output->crtc_info.calculated_pixel_clock_100Hz = 127440fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 12754562236bSHarry Wentland 127687b58768SCharlene Liu /*for HDMI, audio ACR is with deep color ratio factor*/ 12772166d9fbSCharlene Liu if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) && 127840fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz == 127940fd9090SNevenko Stupar (stream->timing.pix_clk_100hz)) { 128010688217SHarry Wentland if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 128140fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz = 128240fd9090SNevenko Stupar audio_output->crtc_info.requested_pixel_clock_100Hz/2; 128340fd9090SNevenko Stupar audio_output->crtc_info.calculated_pixel_clock_100Hz = 128440fd9090SNevenko Stupar pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2; 128587b58768SCharlene Liu 128687b58768SCharlene Liu } 128787b58768SCharlene Liu } 128887b58768SCharlene Liu 1289ed476602SAhzo if (state->clk_mgr && 1290ed476602SAhzo (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 1291ed476602SAhzo pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { 12924562236bSHarry Wentland audio_output->pll_info.dp_dto_source_clock_in_khz = 12930de34efcSDmytro Laktyushkin state->clk_mgr->funcs->get_dp_ref_clk_frequency( 12940de34efcSDmytro Laktyushkin state->clk_mgr); 12954562236bSHarry Wentland } 12964562236bSHarry Wentland 12974562236bSHarry Wentland audio_output->pll_info.feed_back_divider = 12984562236bSHarry Wentland pipe_ctx->pll_settings.feedback_divider; 12994562236bSHarry Wentland 13004562236bSHarry Wentland audio_output->pll_info.dto_source = 13014562236bSHarry Wentland translate_to_dto_source( 1302e07f541fSYongqiang Sun pipe_ctx->stream_res.tg->inst + 1); 13034562236bSHarry Wentland 13044562236bSHarry Wentland /* TODO hard code to enable for now. Need get from stream */ 13054562236bSHarry Wentland audio_output->pll_info.ss_enabled = true; 13064562236bSHarry Wentland 13074562236bSHarry Wentland audio_output->pll_info.ss_percentage = 13084562236bSHarry Wentland pipe_ctx->pll_settings.ss_percentage; 13094562236bSHarry Wentland } 13104562236bSHarry Wentland 13114562236bSHarry Wentland static void get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 13124562236bSHarry Wentland struct tg_color *color) 13134562236bSHarry Wentland { 13142a54bd6eSJerry (Fangzhi) Zuo uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4; 13154562236bSHarry Wentland 13166702a9acSHarry Wentland switch (pipe_ctx->plane_res.scl_data.format) { 13174562236bSHarry Wentland case PIXEL_FORMAT_ARGB8888: 13184562236bSHarry Wentland /* set boarder color to red */ 13194562236bSHarry Wentland color->color_r_cr = color_value; 13204562236bSHarry Wentland break; 13214562236bSHarry Wentland 13224562236bSHarry Wentland case PIXEL_FORMAT_ARGB2101010: 13234562236bSHarry Wentland /* set boarder color to blue */ 13244562236bSHarry Wentland color->color_b_cb = color_value; 13254562236bSHarry Wentland break; 132687449a90SAnthony Koo case PIXEL_FORMAT_420BPP8: 13274562236bSHarry Wentland /* set boarder color to green */ 13284562236bSHarry Wentland color->color_g_y = color_value; 13294562236bSHarry Wentland break; 133087449a90SAnthony Koo case PIXEL_FORMAT_420BPP10: 133187449a90SAnthony Koo /* set boarder color to yellow */ 133287449a90SAnthony Koo color->color_g_y = color_value; 133387449a90SAnthony Koo color->color_r_cr = color_value; 133487449a90SAnthony Koo break; 13354562236bSHarry Wentland case PIXEL_FORMAT_FP16: 13364562236bSHarry Wentland /* set boarder color to white */ 13374562236bSHarry Wentland color->color_r_cr = color_value; 13384562236bSHarry Wentland color->color_b_cb = color_value; 13394562236bSHarry Wentland color->color_g_y = color_value; 13404562236bSHarry Wentland break; 13414562236bSHarry Wentland default: 13424562236bSHarry Wentland break; 13434562236bSHarry Wentland } 13444562236bSHarry Wentland } 13454562236bSHarry Wentland 1346fb3466a4SBhawanpreet Lakha static void program_scaler(const struct dc *dc, 13474562236bSHarry Wentland const struct pipe_ctx *pipe_ctx) 13484562236bSHarry Wentland { 13494562236bSHarry Wentland struct tg_color color = {0}; 13504562236bSHarry Wentland 1351b86a1aa3SBhawanpreet Lakha #if defined(CONFIG_DRM_AMD_DC_DCN) 1352ff5ef992SAlex Deucher /* TOFPGA */ 135386a66c4eSHarry Wentland if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) 1354ff5ef992SAlex Deucher return; 1355ff5ef992SAlex Deucher #endif 1356ff5ef992SAlex Deucher 1357bf53769dSGloria Li if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) 13584562236bSHarry Wentland get_surface_visual_confirm_color(pipe_ctx, &color); 13594562236bSHarry Wentland else 13604562236bSHarry Wentland color_space_to_black_color(dc, 13614fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space, 13624562236bSHarry Wentland &color); 13634562236bSHarry Wentland 136486a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 136586a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, 13666702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.depth, 13674562236bSHarry Wentland &pipe_ctx->stream->bit_depth_params); 13684562236bSHarry Wentland 136912750d16SEric Yang if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) { 137012750d16SEric Yang /* 137112750d16SEric Yang * The way 420 is packed, 2 channels carry Y component, 1 channel 137212750d16SEric Yang * alternate between Cb and Cr, so both channels need the pixel 137312750d16SEric Yang * value for Y 137412750d16SEric Yang */ 137512750d16SEric Yang if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) 137612750d16SEric Yang color.color_r_cr = color.color_g_y; 137712750d16SEric Yang 13786b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 13796b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 13804562236bSHarry Wentland &color); 138112750d16SEric Yang } 13824562236bSHarry Wentland 138386a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 13846702a9acSHarry Wentland &pipe_ctx->plane_res.scl_data); 13854562236bSHarry Wentland } 13864562236bSHarry Wentland 13873158223eSEric Bernstein static enum dc_status dce110_enable_stream_timing( 13884562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1389608ac7bbSJerry Zuo struct dc_state *context, 1390fb3466a4SBhawanpreet Lakha struct dc *dc) 13914562236bSHarry Wentland { 13920971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 1393608ac7bbSJerry Zuo struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 13944562236bSHarry Wentland pipe_ctx[pipe_ctx->pipe_idx]; 13954562236bSHarry Wentland struct tg_color black_color = {0}; 13964562236bSHarry Wentland 13974562236bSHarry Wentland if (!pipe_ctx_old->stream) { 13984562236bSHarry Wentland 13994562236bSHarry Wentland /* program blank color */ 14004562236bSHarry Wentland color_space_to_black_color(dc, 14014fa086b9SLeo (Sunpeng) Li stream->output_color_space, &black_color); 14026b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank_color( 14036b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 14044562236bSHarry Wentland &black_color); 14054b5e7d62SHersen Wu 14064562236bSHarry Wentland /* 14074562236bSHarry Wentland * Must blank CRTC after disabling power gating and before any 14084562236bSHarry Wentland * programming, otherwise CRTC will be hung in bad state 14094562236bSHarry Wentland */ 14106b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true); 14114562236bSHarry Wentland 14124562236bSHarry Wentland if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 14134562236bSHarry Wentland pipe_ctx->clock_source, 141410688217SHarry Wentland &pipe_ctx->stream_res.pix_clk_params, 14154562236bSHarry Wentland &pipe_ctx->pll_settings)) { 14164562236bSHarry Wentland BREAK_TO_DEBUGGER(); 14174562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 14184562236bSHarry Wentland } 14194562236bSHarry Wentland 14206b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->program_timing( 14216b670fa9SHarry Wentland pipe_ctx->stream_res.tg, 14224fa086b9SLeo (Sunpeng) Li &stream->timing, 1423e7e10c46SDmytro Laktyushkin 0, 1424e7e10c46SDmytro Laktyushkin 0, 1425e7e10c46SDmytro Laktyushkin 0, 1426e7e10c46SDmytro Laktyushkin 0, 1427e7e10c46SDmytro Laktyushkin pipe_ctx->stream->signal, 14284562236bSHarry Wentland true); 14294562236bSHarry Wentland } 14304562236bSHarry Wentland 14314562236bSHarry Wentland if (!pipe_ctx_old->stream) { 14326b670fa9SHarry Wentland if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc( 14336b670fa9SHarry Wentland pipe_ctx->stream_res.tg)) { 14344562236bSHarry Wentland BREAK_TO_DEBUGGER(); 14354562236bSHarry Wentland return DC_ERROR_UNEXPECTED; 14364562236bSHarry Wentland } 14374562236bSHarry Wentland } 14384562236bSHarry Wentland 14394562236bSHarry Wentland return DC_OK; 14404562236bSHarry Wentland } 14414562236bSHarry Wentland 14424562236bSHarry Wentland static enum dc_status apply_single_controller_ctx_to_hw( 14434562236bSHarry Wentland struct pipe_ctx *pipe_ctx, 1444608ac7bbSJerry Zuo struct dc_state *context, 1445fb3466a4SBhawanpreet Lakha struct dc *dc) 14464562236bSHarry Wentland { 14470971c40eSHarry Wentland struct dc_stream_state *stream = pipe_ctx->stream; 14489c0fb8d4SAnthony Koo struct drr_params params = {0}; 14499c0fb8d4SAnthony Koo unsigned int event_triggers = 0; 1450b1f6d01cSDmytro Laktyushkin struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; 1451f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 14524562236bSHarry Wentland 1453f42ea55bSAnthony Koo if (hws->funcs.disable_stream_gating) { 1454f42ea55bSAnthony Koo hws->funcs.disable_stream_gating(dc, pipe_ctx); 1455240d09d0SGary Kattan } 1456240d09d0SGary Kattan 14571a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 14581a05873fSAnthony Koo struct audio_output audio_output; 14591a05873fSAnthony Koo 14601a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 14611a05873fSAnthony Koo 14621a05873fSAnthony Koo if (dc_is_dp_signal(pipe_ctx->stream->signal)) 14631a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( 14641a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, 14651a05873fSAnthony Koo pipe_ctx->stream_res.audio->inst, 14661a05873fSAnthony Koo &pipe_ctx->stream->audio_info); 14671a05873fSAnthony Koo else 14681a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( 14691a05873fSAnthony Koo pipe_ctx->stream_res.stream_enc, 14701a05873fSAnthony Koo pipe_ctx->stream_res.audio->inst, 14711a05873fSAnthony Koo &pipe_ctx->stream->audio_info, 14721a05873fSAnthony Koo &audio_output.crtc_info); 14731a05873fSAnthony Koo 14741a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->az_configure( 14751a05873fSAnthony Koo pipe_ctx->stream_res.audio, 14761a05873fSAnthony Koo pipe_ctx->stream->signal, 14771a05873fSAnthony Koo &audio_output.crtc_info, 14781a05873fSAnthony Koo &pipe_ctx->stream->audio_info); 14791a05873fSAnthony Koo } 14801a05873fSAnthony Koo 14814562236bSHarry Wentland /* */ 1482d2d7885fSAnthony Koo /* Do not touch stream timing on seamless boot optimization. */ 1483d2d7885fSAnthony Koo if (!pipe_ctx->stream->apply_seamless_boot_optimization) 1484f42ea55bSAnthony Koo hws->funcs.enable_stream_timing(pipe_ctx, context, dc); 14854562236bSHarry Wentland 1486f42ea55bSAnthony Koo if (hws->funcs.setup_vupdate_interrupt) 1487f42ea55bSAnthony Koo hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx); 1488a122b62dSAnthony Koo 14899c0fb8d4SAnthony Koo params.vertical_total_min = stream->adjust.v_total_min; 14909c0fb8d4SAnthony Koo params.vertical_total_max = stream->adjust.v_total_max; 14919c0fb8d4SAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_drr) 14929c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg->funcs->set_drr( 14939c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg, ¶ms); 14949c0fb8d4SAnthony Koo 14959c0fb8d4SAnthony Koo // DRR should set trigger event to monitor surface update event 14969c0fb8d4SAnthony Koo if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0) 14979c0fb8d4SAnthony Koo event_triggers = 0x80; 14985b5abe95SAnthony Koo /* Event triggers and num frames initialized for DRR, but can be 14995b5abe95SAnthony Koo * later updated for PSR use. Note DRR trigger events are generated 15005b5abe95SAnthony Koo * regardless of whether num frames met. 15015b5abe95SAnthony Koo */ 15029c0fb8d4SAnthony Koo if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control) 15039c0fb8d4SAnthony Koo pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 15045b5abe95SAnthony Koo pipe_ctx->stream_res.tg, event_triggers, 2); 15059c0fb8d4SAnthony Koo 1506248cbed6SEric Bernstein if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) 1507d2c460e7Shersen wu pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( 1508d2c460e7Shersen wu pipe_ctx->stream_res.stream_enc, 1509d2c460e7Shersen wu pipe_ctx->stream_res.tg->inst); 1510aa9c4abeSNikola Cornij 1511f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1512f0c4d997SCorbin McElhanney pipe_ctx->stream_res.opp, 1513f0c4d997SCorbin McElhanney COLOR_SPACE_YCBCR601, 1514f0c4d997SCorbin McElhanney stream->timing.display_color_depth, 1515661a8cd9SDmytro Laktyushkin stream->signal); 15164562236bSHarry Wentland 1517a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1518a6a6cb34SHarry Wentland pipe_ctx->stream_res.opp, 1519181a888fSCharlene Liu &stream->bit_depth_params, 1520181a888fSCharlene Liu &stream->clamping); 1521b1f6d01cSDmytro Laktyushkin while (odm_pipe) { 15227ed4e635SHarry Wentland odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion( 15237ed4e635SHarry Wentland odm_pipe->stream_res.opp, 15247ed4e635SHarry Wentland COLOR_SPACE_YCBCR601, 15257ed4e635SHarry Wentland stream->timing.display_color_depth, 15267ed4e635SHarry Wentland stream->signal); 15277ed4e635SHarry Wentland 15287ed4e635SHarry Wentland odm_pipe->stream_res.opp->funcs->opp_program_fmt( 15297ed4e635SHarry Wentland odm_pipe->stream_res.opp, 15307ed4e635SHarry Wentland &stream->bit_depth_params, 15317ed4e635SHarry Wentland &stream->clamping); 1532b1f6d01cSDmytro Laktyushkin odm_pipe = odm_pipe->next_odm_pipe; 15337ed4e635SHarry Wentland } 1534603767f9STony Cheng 15351e7e86c4SSamson Tam if (!stream->dpms_off) 1536ab8db3e1SAndrey Grodzovsky core_link_enable_stream(context, pipe_ctx); 15374562236bSHarry Wentland 15386702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 15394562236bSHarry Wentland 1540d1ebfdd8SWyatt Wood pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; 154194267b3dSSylvia Tsai 15424562236bSHarry Wentland return DC_OK; 15434562236bSHarry Wentland } 15444562236bSHarry Wentland 15454562236bSHarry Wentland /******************************************************************************/ 15464562236bSHarry Wentland 1547fb3466a4SBhawanpreet Lakha static void power_down_encoders(struct dc *dc) 15484562236bSHarry Wentland { 15494562236bSHarry Wentland int i; 1550b9b171ffSHersen Wu 1551b9b171ffSHersen Wu /* do not know BIOS back-front mapping, simply blank all. It will not 1552b9b171ffSHersen Wu * hurt for non-DP 1553b9b171ffSHersen Wu */ 1554b9b171ffSHersen Wu for (i = 0; i < dc->res_pool->stream_enc_count; i++) { 1555b9b171ffSHersen Wu dc->res_pool->stream_enc[i]->funcs->dp_blank( 1556b9b171ffSHersen Wu dc->res_pool->stream_enc[i]); 1557b9b171ffSHersen Wu } 1558b9b171ffSHersen Wu 15594562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 1560d4c2a96fSLewis Huang enum signal_type signal = dc->links[i]->connector_signal; 1561a0c38ebaSCharlene Liu 1562d4c2a96fSLewis Huang if ((signal == SIGNAL_TYPE_EDP) || 1563d4c2a96fSLewis Huang (signal == SIGNAL_TYPE_DISPLAY_PORT)) 1564a0c38ebaSCharlene Liu if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) 1565a0c38ebaSCharlene Liu dp_receiver_power_ctrl(dc->links[i], false); 1566a0c38ebaSCharlene Liu 15674338ffa8SSung Lee if (signal != SIGNAL_TYPE_EDP) 15684338ffa8SSung Lee signal = SIGNAL_TYPE_NONE; 15694338ffa8SSung Lee 15704562236bSHarry Wentland dc->links[i]->link_enc->funcs->disable_output( 1571069d418fSAndrew Jiang dc->links[i]->link_enc, signal); 1572b56e90eaSPaul Hsieh 1573b56e90eaSPaul Hsieh dc->links[i]->link_status.link_active = false; 157407920450SJoshua Aberback memset(&dc->links[i]->cur_link_settings, 0, 157507920450SJoshua Aberback sizeof(dc->links[i]->cur_link_settings)); 15764562236bSHarry Wentland } 15774562236bSHarry Wentland } 15784562236bSHarry Wentland 1579fb3466a4SBhawanpreet Lakha static void power_down_controllers(struct dc *dc) 15804562236bSHarry Wentland { 15814562236bSHarry Wentland int i; 15824562236bSHarry Wentland 15837f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 15844562236bSHarry Wentland dc->res_pool->timing_generators[i]->funcs->disable_crtc( 15854562236bSHarry Wentland dc->res_pool->timing_generators[i]); 15864562236bSHarry Wentland } 15874562236bSHarry Wentland } 15884562236bSHarry Wentland 1589fb3466a4SBhawanpreet Lakha static void power_down_clock_sources(struct dc *dc) 15904562236bSHarry Wentland { 15914562236bSHarry Wentland int i; 15924562236bSHarry Wentland 15934562236bSHarry Wentland if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 15944562236bSHarry Wentland dc->res_pool->dp_clock_source) == false) 15954562236bSHarry Wentland dm_error("Failed to power down pll! (dp clk src)\n"); 15964562236bSHarry Wentland 15974562236bSHarry Wentland for (i = 0; i < dc->res_pool->clk_src_count; i++) { 15984562236bSHarry Wentland if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 15994562236bSHarry Wentland dc->res_pool->clock_sources[i]) == false) 16004562236bSHarry Wentland dm_error("Failed to power down pll! (clk src index=%d)\n", i); 16014562236bSHarry Wentland } 16024562236bSHarry Wentland } 16034562236bSHarry Wentland 1604fb3466a4SBhawanpreet Lakha static void power_down_all_hw_blocks(struct dc *dc) 16054562236bSHarry Wentland { 16064562236bSHarry Wentland power_down_encoders(dc); 16074562236bSHarry Wentland 16084562236bSHarry Wentland power_down_controllers(dc); 16094562236bSHarry Wentland 16104562236bSHarry Wentland power_down_clock_sources(dc); 16111663ae1cSBhawanpreet Lakha 16122f3bfb27SRoman Li if (dc->fbc_compressor) 16131663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 16144562236bSHarry Wentland } 16154562236bSHarry Wentland 16164562236bSHarry Wentland static void disable_vga_and_power_gate_all_controllers( 1617fb3466a4SBhawanpreet Lakha struct dc *dc) 16184562236bSHarry Wentland { 16194562236bSHarry Wentland int i; 16204562236bSHarry Wentland struct timing_generator *tg; 16214562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 16224562236bSHarry Wentland 16237f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 16244562236bSHarry Wentland tg = dc->res_pool->timing_generators[i]; 16254562236bSHarry Wentland 16260a87425aSTony Cheng if (tg->funcs->disable_vga) 16274562236bSHarry Wentland tg->funcs->disable_vga(tg); 16287f93c1deSCharlene Liu } 16297f93c1deSCharlene Liu for (i = 0; i < dc->res_pool->pipe_count; i++) { 16304562236bSHarry Wentland /* Enable CLOCK gating for each pipe BEFORE controller 16314562236bSHarry Wentland * powergating. */ 16324562236bSHarry Wentland enable_display_pipe_clock_gating(ctx, 16334562236bSHarry Wentland true); 16344562236bSHarry Wentland 1635e6c258cbSYongqiang Sun dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i; 16367f914a62SYongqiang Sun dc->hwss.disable_plane(dc, 1637e6c258cbSYongqiang Sun &dc->current_state->res_ctx.pipe_ctx[i]); 16384562236bSHarry Wentland } 16394562236bSHarry Wentland } 16404562236bSHarry Wentland 16413de5aa81SSivapiriyanKumarasamy 164245a1261bSJake Wang static void get_edp_streams(struct dc_state *context, 164345a1261bSJake Wang struct dc_stream_state **edp_streams, 164445a1261bSJake Wang int *edp_stream_num) 16453de5aa81SSivapiriyanKumarasamy { 16463de5aa81SSivapiriyanKumarasamy int i; 16473de5aa81SSivapiriyanKumarasamy 164845a1261bSJake Wang *edp_stream_num = 0; 16493de5aa81SSivapiriyanKumarasamy for (i = 0; i < context->stream_count; i++) { 165045a1261bSJake Wang if (context->streams[i]->signal == SIGNAL_TYPE_EDP) { 165145a1261bSJake Wang edp_streams[*edp_stream_num] = context->streams[i]; 165245a1261bSJake Wang if (++(*edp_stream_num) == MAX_NUM_EDP) 165345a1261bSJake Wang return; 16543de5aa81SSivapiriyanKumarasamy } 165545a1261bSJake Wang } 16563de5aa81SSivapiriyanKumarasamy } 16573de5aa81SSivapiriyanKumarasamy 165845a1261bSJake Wang static void get_edp_links_with_sink( 165925292028SYongqiang Sun struct dc *dc, 166045a1261bSJake Wang struct dc_link **edp_links_with_sink, 166145a1261bSJake Wang int *edp_with_sink_num) 166225292028SYongqiang Sun { 166325292028SYongqiang Sun int i; 166425292028SYongqiang Sun 166525292028SYongqiang Sun /* check if there is an eDP panel not in use */ 166645a1261bSJake Wang *edp_with_sink_num = 0; 166725292028SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 166825292028SYongqiang Sun if (dc->links[i]->local_sink && 166925292028SYongqiang Sun dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 167045a1261bSJake Wang edp_links_with_sink[*edp_with_sink_num] = dc->links[i]; 167145a1261bSJake Wang if (++(*edp_with_sink_num) == MAX_NUM_EDP) 167245a1261bSJake Wang return; 167325292028SYongqiang Sun } 167425292028SYongqiang Sun } 167525292028SYongqiang Sun } 167625292028SYongqiang Sun 16771c17952eSLee Jones /* 16784562236bSHarry Wentland * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 16794562236bSHarry Wentland * 1. Power down all DC HW blocks 16804562236bSHarry Wentland * 2. Disable VGA engine on all controllers 16814562236bSHarry Wentland * 3. Enable power gating for controller 16824562236bSHarry Wentland * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 16834562236bSHarry Wentland */ 168425292028SYongqiang Sun void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 16854562236bSHarry Wentland { 168645a1261bSJake Wang struct dc_link *edp_links_with_sink[MAX_NUM_EDP]; 168745a1261bSJake Wang struct dc_link *edp_links[MAX_NUM_EDP]; 168845a1261bSJake Wang struct dc_stream_state *edp_streams[MAX_NUM_EDP]; 168945a1261bSJake Wang struct dc_link *edp_link_with_sink = NULL; 169045a1261bSJake Wang struct dc_link *edp_link = NULL; 16913de5aa81SSivapiriyanKumarasamy struct dc_stream_state *edp_stream = NULL; 169245a1261bSJake Wang struct dce_hwseq *hws = dc->hwseq; 169345a1261bSJake Wang int edp_with_sink_num; 169445a1261bSJake Wang int edp_num; 169545a1261bSJake Wang int edp_stream_num; 169645a1261bSJake Wang int i; 1697be4b289fSSivapiriyanKumarasamy bool can_apply_edp_fast_boot = false; 1698ce72741bSAnthony Koo bool can_apply_seamless_boot = false; 16993de5aa81SSivapiriyanKumarasamy bool keep_edp_vdd_on = false; 17000eda55caSMichael Strauss DC_LOGGER_INIT(); 17010eda55caSMichael Strauss 170245a1261bSJake Wang 170345a1261bSJake Wang get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num); 170445a1261bSJake Wang get_edp_links(dc, edp_links, &edp_num); 1705ce72741bSAnthony Koo 1706f42ea55bSAnthony Koo if (hws->funcs.init_pipes) 1707f42ea55bSAnthony Koo hws->funcs.init_pipes(dc, context); 1708be4b289fSSivapiriyanKumarasamy 170945a1261bSJake Wang get_edp_streams(context, edp_streams, &edp_stream_num); 17103de5aa81SSivapiriyanKumarasamy 1711be4b289fSSivapiriyanKumarasamy // Check fastboot support, disable on DCE8 because of blank screens 171245a1261bSJake Wang if (edp_num && dc->ctx->dce_version != DCE_VERSION_8_0 && 1713be4b289fSSivapiriyanKumarasamy dc->ctx->dce_version != DCE_VERSION_8_1 && 1714be4b289fSSivapiriyanKumarasamy dc->ctx->dce_version != DCE_VERSION_8_3) { 171545a1261bSJake Wang for (i = 0; i < edp_num; i++) { 171645a1261bSJake Wang edp_link = edp_links[i]; 1717be4b289fSSivapiriyanKumarasamy // enable fastboot if backend is enabled on eDP 1718be4b289fSSivapiriyanKumarasamy if (edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc)) { 17193de5aa81SSivapiriyanKumarasamy /* Set optimization flag on eDP stream*/ 172045a1261bSJake Wang if (edp_stream_num && edp_link->link_status.link_active) { 172145a1261bSJake Wang edp_stream = edp_streams[0]; 1722f9fc6f39SMichael Strauss can_apply_edp_fast_boot = !is_edp_ilr_optimization_required(edp_stream->link, &edp_stream->timing); 1723f9fc6f39SMichael Strauss edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot; 17240eda55caSMichael Strauss if (can_apply_edp_fast_boot) 17250eda55caSMichael Strauss DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n"); 1726f9fc6f39SMichael Strauss 172745a1261bSJake Wang break; 1728be4b289fSSivapiriyanKumarasamy } 1729be4b289fSSivapiriyanKumarasamy } 173045a1261bSJake Wang } 17313de5aa81SSivapiriyanKumarasamy // We are trying to enable eDP, don't power down VDD 173245a1261bSJake Wang if (edp_stream_num) 17333de5aa81SSivapiriyanKumarasamy keep_edp_vdd_on = true; 1734be4b289fSSivapiriyanKumarasamy } 1735be4b289fSSivapiriyanKumarasamy 1736be4b289fSSivapiriyanKumarasamy // Check seamless boot support 1737ce72741bSAnthony Koo for (i = 0; i < context->stream_count; i++) { 1738ce72741bSAnthony Koo if (context->streams[i]->apply_seamless_boot_optimization) { 1739ce72741bSAnthony Koo can_apply_seamless_boot = true; 1740ce72741bSAnthony Koo break; 1741ce72741bSAnthony Koo } 1742ce72741bSAnthony Koo } 17434cac1e6dSYongqiang Sun 1744be4b289fSSivapiriyanKumarasamy /* eDP should not have stream in resume from S4 and so even with VBios post 1745be4b289fSSivapiriyanKumarasamy * it should get turned off 17462c37e49aSYongqiang Sun */ 174745a1261bSJake Wang if (edp_with_sink_num) 174845a1261bSJake Wang edp_link_with_sink = edp_links_with_sink[0]; 174945a1261bSJake Wang 1750be4b289fSSivapiriyanKumarasamy if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) { 17513de5aa81SSivapiriyanKumarasamy if (edp_link_with_sink && !keep_edp_vdd_on) { 17524cac1e6dSYongqiang Sun /*turn off backlight before DP_blank and encoder powered down*/ 1753f42ea55bSAnthony Koo hws->funcs.edp_backlight_control(edp_link_with_sink, false); 1754c5fc7f59SCharlene Liu } 1755c5fc7f59SCharlene Liu /*resume from S3, no vbios posting, no need to power down again*/ 175625292028SYongqiang Sun power_down_all_hw_blocks(dc); 17574562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 17583de5aa81SSivapiriyanKumarasamy if (edp_link_with_sink && !keep_edp_vdd_on) 1759be4b289fSSivapiriyanKumarasamy dc->hwss.edp_power_control(edp_link_with_sink, false); 1760c5fc7f59SCharlene Liu } 17611c5ea40cSYao Wang1 bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); 17624562236bSHarry Wentland } 17634562236bSHarry Wentland 17644562236bSHarry Wentland static uint32_t compute_pstate_blackout_duration( 17654562236bSHarry Wentland struct bw_fixed blackout_duration, 17660971c40eSHarry Wentland const struct dc_stream_state *stream) 17674562236bSHarry Wentland { 17684562236bSHarry Wentland uint32_t total_dest_line_time_ns; 17694562236bSHarry Wentland uint32_t pstate_blackout_duration_ns; 17704562236bSHarry Wentland 17714562236bSHarry Wentland pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 17724562236bSHarry Wentland 17734562236bSHarry Wentland total_dest_line_time_ns = 1000000UL * 1774380604e2SKen Chalmers (stream->timing.h_total * 10) / 1775380604e2SKen Chalmers stream->timing.pix_clk_100hz + 17764562236bSHarry Wentland pstate_blackout_duration_ns; 17774562236bSHarry Wentland 17784562236bSHarry Wentland return total_dest_line_time_ns; 17794562236bSHarry Wentland } 17804562236bSHarry Wentland 1781f774b339SEric Yang static void dce110_set_displaymarks( 1782fb3466a4SBhawanpreet Lakha const struct dc *dc, 1783608ac7bbSJerry Zuo struct dc_state *context) 17844562236bSHarry Wentland { 17854562236bSHarry Wentland uint8_t i, num_pipes; 17864562236bSHarry Wentland unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 17874562236bSHarry Wentland 17884562236bSHarry Wentland for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 17894562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 17904562236bSHarry Wentland uint32_t total_dest_line_time_ns; 17914562236bSHarry Wentland 17924562236bSHarry Wentland if (pipe_ctx->stream == NULL) 17934562236bSHarry Wentland continue; 17944562236bSHarry Wentland 17954562236bSHarry Wentland total_dest_line_time_ns = compute_pstate_blackout_duration( 179677a4ea53SBhawanpreet Lakha dc->bw_vbios->blackout_duration, pipe_ctx->stream); 179786a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( 179886a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 1799813d20dcSAidan Wood context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 1800813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 1801813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes], 1802813d20dcSAidan Wood context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 18034562236bSHarry Wentland total_dest_line_time_ns); 18044562236bSHarry Wentland if (i == underlay_idx) { 18054562236bSHarry Wentland num_pipes++; 180686a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( 180786a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 1808813d20dcSAidan Wood context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 1809813d20dcSAidan Wood context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 1810813d20dcSAidan Wood context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 18114562236bSHarry Wentland total_dest_line_time_ns); 18124562236bSHarry Wentland } 18134562236bSHarry Wentland num_pipes++; 18144562236bSHarry Wentland } 18154562236bSHarry Wentland } 18164562236bSHarry Wentland 1817fab55d61SDmytro Laktyushkin void dce110_set_safe_displaymarks( 1818a2b8659dSTony Cheng struct resource_context *res_ctx, 1819a2b8659dSTony Cheng const struct resource_pool *pool) 18204562236bSHarry Wentland { 18214562236bSHarry Wentland int i; 1822a2b8659dSTony Cheng int underlay_idx = pool->underlay_pipe_index; 18239037d802SDmytro Laktyushkin struct dce_watermarks max_marks = { 18244562236bSHarry Wentland MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 18259037d802SDmytro Laktyushkin struct dce_watermarks nbp_marks = { 18264562236bSHarry Wentland SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 18273722c794SMikita Lipski struct dce_watermarks min_marks = { 0, 0, 0, 0}; 18284562236bSHarry Wentland 18294562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 18308feabd03SYue Hin Lau if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) 18314562236bSHarry Wentland continue; 18324562236bSHarry Wentland 183386a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 183486a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 18354562236bSHarry Wentland nbp_marks, 18364562236bSHarry Wentland max_marks, 18373722c794SMikita Lipski min_marks, 18384562236bSHarry Wentland max_marks, 18394562236bSHarry Wentland MAX_WATERMARK); 18408feabd03SYue Hin Lau 18414562236bSHarry Wentland if (i == underlay_idx) 184286a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 184386a66c4eSHarry Wentland res_ctx->pipe_ctx[i].plane_res.mi, 18444562236bSHarry Wentland nbp_marks, 18454562236bSHarry Wentland max_marks, 18464562236bSHarry Wentland max_marks, 18474562236bSHarry Wentland MAX_WATERMARK); 18488feabd03SYue Hin Lau 18494562236bSHarry Wentland } 18504562236bSHarry Wentland } 18514562236bSHarry Wentland 18524562236bSHarry Wentland /******************************************************************************* 18534562236bSHarry Wentland * Public functions 18544562236bSHarry Wentland ******************************************************************************/ 18554562236bSHarry Wentland 18564562236bSHarry Wentland static void set_drr(struct pipe_ctx **pipe_ctx, 185749c70eceSAlvin Lee int num_pipes, struct dc_crtc_timing_adjust adjust) 18584562236bSHarry Wentland { 18594562236bSHarry Wentland int i = 0; 18604562236bSHarry Wentland struct drr_params params = {0}; 186198e6436dSAnthony Koo // DRR should set trigger event to monitor surface update event 186298e6436dSAnthony Koo unsigned int event_triggers = 0x80; 18635b5abe95SAnthony Koo // Note DRR trigger events are generated regardless of whether num frames met. 18645b5abe95SAnthony Koo unsigned int num_frames = 2; 18654562236bSHarry Wentland 186649c70eceSAlvin Lee params.vertical_total_max = adjust.v_total_max; 186749c70eceSAlvin Lee params.vertical_total_min = adjust.v_total_min; 18684562236bSHarry Wentland 18694562236bSHarry Wentland /* TODO: If multiple pipes are to be supported, you need 187098e6436dSAnthony Koo * some GSL stuff. Static screen triggers may be programmed differently 187198e6436dSAnthony Koo * as well. 18724562236bSHarry Wentland */ 18734562236bSHarry Wentland for (i = 0; i < num_pipes; i++) { 187498e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_drr( 187598e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, ¶ms); 187698e6436dSAnthony Koo 187749c70eceSAlvin Lee if (adjust.v_total_max != 0 && adjust.v_total_min != 0) 187898e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control( 187998e6436dSAnthony Koo pipe_ctx[i]->stream_res.tg, 18805b5abe95SAnthony Koo event_triggers, num_frames); 18814562236bSHarry Wentland } 18824562236bSHarry Wentland } 18834562236bSHarry Wentland 188472ada5f7SEric Cook static void get_position(struct pipe_ctx **pipe_ctx, 188572ada5f7SEric Cook int num_pipes, 188672ada5f7SEric Cook struct crtc_position *position) 188772ada5f7SEric Cook { 188872ada5f7SEric Cook int i = 0; 188972ada5f7SEric Cook 189072ada5f7SEric Cook /* TODO: handle pipes > 1 189172ada5f7SEric Cook */ 189272ada5f7SEric Cook for (i = 0; i < num_pipes; i++) 18936b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position); 189472ada5f7SEric Cook } 189572ada5f7SEric Cook 18964562236bSHarry Wentland static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 18975b5abe95SAnthony Koo int num_pipes, const struct dc_static_screen_params *params) 18984562236bSHarry Wentland { 18994562236bSHarry Wentland unsigned int i; 19005b5abe95SAnthony Koo unsigned int triggers = 0; 190194267b3dSSylvia Tsai 19025b5abe95SAnthony Koo if (params->triggers.overlay_update) 19035b5abe95SAnthony Koo triggers |= 0x100; 19045b5abe95SAnthony Koo if (params->triggers.surface_update) 19055b5abe95SAnthony Koo triggers |= 0x80; 19065b5abe95SAnthony Koo if (params->triggers.cursor_update) 19075b5abe95SAnthony Koo triggers |= 0x2; 19085b5abe95SAnthony Koo if (params->triggers.force_trigger) 19095b5abe95SAnthony Koo triggers |= 0x1; 19104562236bSHarry Wentland 1911593f79a2SAlex Deucher if (num_pipes) { 1912593f79a2SAlex Deucher struct dc *dc = pipe_ctx[0]->stream->ctx->dc; 1913593f79a2SAlex Deucher 1914593f79a2SAlex Deucher if (dc->fbc_compressor) 19155b5abe95SAnthony Koo triggers |= 0x84; 1916593f79a2SAlex Deucher } 1917c3aa1d67SBhawanpreet Lakha 19184562236bSHarry Wentland for (i = 0; i < num_pipes; i++) 19196b670fa9SHarry Wentland pipe_ctx[i]->stream_res.tg->funcs-> 19205b5abe95SAnthony Koo set_static_screen_control(pipe_ctx[i]->stream_res.tg, 19215b5abe95SAnthony Koo triggers, params->num_frames); 19224562236bSHarry Wentland } 19234562236bSHarry Wentland 1924f6baff4dSHarry Wentland /* 1925690b5e39SRoman Li * Check if FBC can be enabled 1926690b5e39SRoman Li */ 19279c6569deSHarry Wentland static bool should_enable_fbc(struct dc *dc, 19283bc4aaa9SRoman Li struct dc_state *context, 19293bc4aaa9SRoman Li uint32_t *pipe_idx) 1930690b5e39SRoman Li { 19313bc4aaa9SRoman Li uint32_t i; 19323bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = NULL; 19333bc4aaa9SRoman Li struct resource_context *res_ctx = &context->res_ctx; 193465d38262Shersen wu unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 19353bc4aaa9SRoman Li 1936690b5e39SRoman Li 1937690b5e39SRoman Li ASSERT(dc->fbc_compressor); 1938690b5e39SRoman Li 1939690b5e39SRoman Li /* FBC memory should be allocated */ 1940690b5e39SRoman Li if (!dc->ctx->fbc_gpu_addr) 19419c6569deSHarry Wentland return false; 1942690b5e39SRoman Li 1943690b5e39SRoman Li /* Only supports single display */ 1944690b5e39SRoman Li if (context->stream_count != 1) 19459c6569deSHarry Wentland return false; 1946690b5e39SRoman Li 19473bc4aaa9SRoman Li for (i = 0; i < dc->res_pool->pipe_count; i++) { 19483bc4aaa9SRoman Li if (res_ctx->pipe_ctx[i].stream) { 194965d38262Shersen wu 19503bc4aaa9SRoman Li pipe_ctx = &res_ctx->pipe_ctx[i]; 195165d38262Shersen wu 195265d38262Shersen wu if (!pipe_ctx) 195365d38262Shersen wu continue; 195465d38262Shersen wu 195565d38262Shersen wu /* fbc not applicable on underlay pipe */ 195665d38262Shersen wu if (pipe_ctx->pipe_idx != underlay_idx) { 19573bc4aaa9SRoman Li *pipe_idx = i; 19583bc4aaa9SRoman Li break; 19593bc4aaa9SRoman Li } 19603bc4aaa9SRoman Li } 196165d38262Shersen wu } 19623bc4aaa9SRoman Li 196365d38262Shersen wu if (i == dc->res_pool->pipe_count) 196465d38262Shersen wu return false; 196565d38262Shersen wu 1966ceb3dbb4SJun Lei if (!pipe_ctx->stream->link) 196765d38262Shersen wu return false; 19687a840773SRoman Li 1969690b5e39SRoman Li /* Only supports eDP */ 1970ceb3dbb4SJun Lei if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP) 19719c6569deSHarry Wentland return false; 1972690b5e39SRoman Li 1973690b5e39SRoman Li /* PSR should not be enabled */ 1974d1ebfdd8SWyatt Wood if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled) 19759c6569deSHarry Wentland return false; 1976690b5e39SRoman Li 197793984bbcSShirish S /* Nothing to compress */ 197893984bbcSShirish S if (!pipe_ctx->plane_state) 19799c6569deSHarry Wentland return false; 198093984bbcSShirish S 198105230fa9SRoman Li /* Only for non-linear tiling */ 198205230fa9SRoman Li if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 19839c6569deSHarry Wentland return false; 198405230fa9SRoman Li 19859c6569deSHarry Wentland return true; 1986690b5e39SRoman Li } 1987690b5e39SRoman Li 1988690b5e39SRoman Li /* 1989690b5e39SRoman Li * Enable FBC 1990690b5e39SRoman Li */ 199165d38262Shersen wu static void enable_fbc( 199265d38262Shersen wu struct dc *dc, 1993608ac7bbSJerry Zuo struct dc_state *context) 1994690b5e39SRoman Li { 19953bc4aaa9SRoman Li uint32_t pipe_idx = 0; 19963bc4aaa9SRoman Li 19973bc4aaa9SRoman Li if (should_enable_fbc(dc, context, &pipe_idx)) { 1998690b5e39SRoman Li /* Program GRPH COMPRESSED ADDRESS and PITCH */ 1999690b5e39SRoman Li struct compr_addr_and_pitch_params params = {0, 0, 0}; 2000690b5e39SRoman Li struct compressor *compr = dc->fbc_compressor; 20013bc4aaa9SRoman Li struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 20023bc4aaa9SRoman Li 20039c6569deSHarry Wentland params.source_view_width = pipe_ctx->stream->timing.h_addressable; 20049c6569deSHarry Wentland params.source_view_height = pipe_ctx->stream->timing.v_addressable; 200565d38262Shersen wu params.inst = pipe_ctx->stream_res.tg->inst; 2006690b5e39SRoman Li compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 2007690b5e39SRoman Li 2008690b5e39SRoman Li compr->funcs->surface_address_and_pitch(compr, ¶ms); 2009690b5e39SRoman Li compr->funcs->set_fbc_invalidation_triggers(compr, 1); 2010690b5e39SRoman Li 2011690b5e39SRoman Li compr->funcs->enable_fbc(compr, ¶ms); 2012690b5e39SRoman Li } 2013690b5e39SRoman Li } 2014690b5e39SRoman Li 201554e8695eSDmytro Laktyushkin static void dce110_reset_hw_ctx_wrap( 2016fb3466a4SBhawanpreet Lakha struct dc *dc, 2017608ac7bbSJerry Zuo struct dc_state *context) 20184562236bSHarry Wentland { 20194562236bSHarry Wentland int i; 20204562236bSHarry Wentland 20214562236bSHarry Wentland /* Reset old context */ 20224562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 2023a2b8659dSTony Cheng for (i = 0; i < MAX_PIPES; i++) { 20244562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 2025608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 20264562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 20274562236bSHarry Wentland 20284562236bSHarry Wentland /* Note: We need to disable output if clock sources change, 20294562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 20304562236bSHarry Wentland * PHY when not already disabled. 20314562236bSHarry Wentland */ 20324562236bSHarry Wentland 20334562236bSHarry Wentland /* Skip underlay pipe since it will be handled in commit surface*/ 20344562236bSHarry Wentland if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 20354562236bSHarry Wentland continue; 20364562236bSHarry Wentland 20374562236bSHarry Wentland if (!pipe_ctx->stream || 203854e8695eSDmytro Laktyushkin pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 203921e67d4dSHarry Wentland struct clock_source *old_clk = pipe_ctx_old->clock_source; 204021e67d4dSHarry Wentland 2041827f11e9SLeo (Sunpeng) Li /* Disable if new stream is null. O/w, if stream is 2042827f11e9SLeo (Sunpeng) Li * disabled already, no need to disable again. 2043827f11e9SLeo (Sunpeng) Li */ 204457430404SSu Sung Chung if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) { 204557430404SSu Sung Chung core_link_disable_stream(pipe_ctx_old); 204657430404SSu Sung Chung 204757430404SSu Sung Chung /* free acquired resources*/ 204857430404SSu Sung Chung if (pipe_ctx_old->stream_res.audio) { 204957430404SSu Sung Chung /*disable az_endpoint*/ 205057430404SSu Sung Chung pipe_ctx_old->stream_res.audio->funcs-> 205157430404SSu Sung Chung az_disable(pipe_ctx_old->stream_res.audio); 205257430404SSu Sung Chung 205357430404SSu Sung Chung /*free audio*/ 205457430404SSu Sung Chung if (dc->caps.dynamic_audio == true) { 205557430404SSu Sung Chung /*we have to dynamic arbitrate the audio endpoints*/ 205657430404SSu Sung Chung /*we free the resource, need reset is_audio_acquired*/ 205757430404SSu Sung Chung update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, 205857430404SSu Sung Chung pipe_ctx_old->stream_res.audio, false); 205957430404SSu Sung Chung pipe_ctx_old->stream_res.audio = NULL; 206057430404SSu Sung Chung } 206157430404SSu Sung Chung } 206257430404SSu Sung Chung } 2063d050f8edSHersen Wu 20646b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 20656b670fa9SHarry Wentland if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 206654e8695eSDmytro Laktyushkin dm_error("DC: failed to blank crtc!\n"); 206754e8695eSDmytro Laktyushkin BREAK_TO_DEBUGGER(); 206854e8695eSDmytro Laktyushkin } 20696b670fa9SHarry Wentland pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); 207086a66c4eSHarry Wentland pipe_ctx_old->plane_res.mi->funcs->free_mem_input( 2071608ac7bbSJerry Zuo pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); 207254e8695eSDmytro Laktyushkin 2073ad8960a6SMikita Lipski if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx, 2074ad8960a6SMikita Lipski dc->res_pool, 2075ad8960a6SMikita Lipski old_clk)) 207621e67d4dSHarry Wentland old_clk->funcs->cs_power_down(old_clk); 207721e67d4dSHarry Wentland 20787f914a62SYongqiang Sun dc->hwss.disable_plane(dc, pipe_ctx_old); 207954e8695eSDmytro Laktyushkin 208054e8695eSDmytro Laktyushkin pipe_ctx_old->stream = NULL; 208154e8695eSDmytro Laktyushkin } 20824562236bSHarry Wentland } 20834562236bSHarry Wentland } 20844562236bSHarry Wentland 20851a05873fSAnthony Koo static void dce110_setup_audio_dto( 20861a05873fSAnthony Koo struct dc *dc, 20871a05873fSAnthony Koo struct dc_state *context) 20881a05873fSAnthony Koo { 20891a05873fSAnthony Koo int i; 20901a05873fSAnthony Koo 20911a05873fSAnthony Koo /* program audio wall clock. use HDMI as clock source if HDMI 20921a05873fSAnthony Koo * audio active. Otherwise, use DP as clock source 20931a05873fSAnthony Koo * first, loop to find any HDMI audio, if not, loop find DP audio 20941a05873fSAnthony Koo */ 20951a05873fSAnthony Koo /* Setup audio rate clock source */ 20961a05873fSAnthony Koo /* Issue: 20971a05873fSAnthony Koo * Audio lag happened on DP monitor when unplug a HDMI monitor 20981a05873fSAnthony Koo * 20991a05873fSAnthony Koo * Cause: 21001a05873fSAnthony Koo * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 21011a05873fSAnthony Koo * is set to either dto0 or dto1, audio should work fine. 21021a05873fSAnthony Koo * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 21031a05873fSAnthony Koo * set to dto0 will cause audio lag. 21041a05873fSAnthony Koo * 21051a05873fSAnthony Koo * Solution: 21061a05873fSAnthony Koo * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 21071a05873fSAnthony Koo * find first available pipe with audio, setup audio wall DTO per topology 21081a05873fSAnthony Koo * instead of per pipe. 21091a05873fSAnthony Koo */ 21101a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 21111a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 21121a05873fSAnthony Koo 21131a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 21141a05873fSAnthony Koo continue; 21151a05873fSAnthony Koo 21161a05873fSAnthony Koo if (pipe_ctx->top_pipe) 21171a05873fSAnthony Koo continue; 21181a05873fSAnthony Koo if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 21191a05873fSAnthony Koo continue; 21201a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 21211a05873fSAnthony Koo struct audio_output audio_output; 21221a05873fSAnthony Koo 21231a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 21241a05873fSAnthony Koo 21251a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 21261a05873fSAnthony Koo pipe_ctx->stream_res.audio, 21271a05873fSAnthony Koo pipe_ctx->stream->signal, 21281a05873fSAnthony Koo &audio_output.crtc_info, 21291a05873fSAnthony Koo &audio_output.pll_info); 21301a05873fSAnthony Koo break; 21311a05873fSAnthony Koo } 21321a05873fSAnthony Koo } 21331a05873fSAnthony Koo 21341a05873fSAnthony Koo /* no HDMI audio is found, try DP audio */ 21351a05873fSAnthony Koo if (i == dc->res_pool->pipe_count) { 21361a05873fSAnthony Koo for (i = 0; i < dc->res_pool->pipe_count; i++) { 21371a05873fSAnthony Koo struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 21381a05873fSAnthony Koo 21391a05873fSAnthony Koo if (pipe_ctx->stream == NULL) 21401a05873fSAnthony Koo continue; 21411a05873fSAnthony Koo 21421a05873fSAnthony Koo if (pipe_ctx->top_pipe) 21431a05873fSAnthony Koo continue; 21441a05873fSAnthony Koo 21451a05873fSAnthony Koo if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 21461a05873fSAnthony Koo continue; 21471a05873fSAnthony Koo 21481a05873fSAnthony Koo if (pipe_ctx->stream_res.audio != NULL) { 21491a05873fSAnthony Koo struct audio_output audio_output; 21501a05873fSAnthony Koo 21511a05873fSAnthony Koo build_audio_output(context, pipe_ctx, &audio_output); 21521a05873fSAnthony Koo 21531a05873fSAnthony Koo pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 21541a05873fSAnthony Koo pipe_ctx->stream_res.audio, 21551a05873fSAnthony Koo pipe_ctx->stream->signal, 21561a05873fSAnthony Koo &audio_output.crtc_info, 21571a05873fSAnthony Koo &audio_output.pll_info); 21581a05873fSAnthony Koo break; 21591a05873fSAnthony Koo } 21601a05873fSAnthony Koo } 21611a05873fSAnthony Koo } 21621a05873fSAnthony Koo } 2163cf437593SDmytro Laktyushkin 21644562236bSHarry Wentland enum dc_status dce110_apply_ctx_to_hw( 2165fb3466a4SBhawanpreet Lakha struct dc *dc, 2166608ac7bbSJerry Zuo struct dc_state *context) 21674562236bSHarry Wentland { 2168f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 21694562236bSHarry Wentland struct dc_bios *dcb = dc->ctx->dc_bios; 21704562236bSHarry Wentland enum dc_status status; 21714562236bSHarry Wentland int i; 21724562236bSHarry Wentland 21734562236bSHarry Wentland /* Reset old context */ 21744562236bSHarry Wentland /* look up the targets that have been removed since last commit */ 2175f42ea55bSAnthony Koo hws->funcs.reset_hw_ctx_wrap(dc, context); 21764562236bSHarry Wentland 21774562236bSHarry Wentland /* Skip applying if no targets */ 2178ab2541b6SAric Cyr if (context->stream_count <= 0) 21794562236bSHarry Wentland return DC_OK; 21804562236bSHarry Wentland 21814562236bSHarry Wentland /* Apply new context */ 21824562236bSHarry Wentland dcb->funcs->set_scratch_critical_state(dcb, true); 21834562236bSHarry Wentland 21844562236bSHarry Wentland /* below is for real asic only */ 2185a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 21864562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old = 2187608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 21884562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 21894562236bSHarry Wentland 21904562236bSHarry Wentland if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 21914562236bSHarry Wentland continue; 21924562236bSHarry Wentland 21934562236bSHarry Wentland if (pipe_ctx->stream == pipe_ctx_old->stream) { 21944562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 21954562236bSHarry Wentland dce_crtc_switch_to_clk_src(dc->hwseq, 21964562236bSHarry Wentland pipe_ctx->clock_source, i); 21974562236bSHarry Wentland continue; 21984562236bSHarry Wentland } 21994562236bSHarry Wentland 2200f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 22014562236bSHarry Wentland dc, i, dc->ctx->dc_bios, 22024562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 22034562236bSHarry Wentland } 22044562236bSHarry Wentland 22052f3bfb27SRoman Li if (dc->fbc_compressor) 22061663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 22075099114bSAlex Deucher 22081a05873fSAnthony Koo dce110_setup_audio_dto(dc, context); 2209ab8812a3SHersen Wu 2210a2b8659dSTony Cheng for (i = 0; i < dc->res_pool->pipe_count; i++) { 2211ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx_old = 2212608ac7bbSJerry Zuo &dc->current_state->res_ctx.pipe_ctx[i]; 2213ab8812a3SHersen Wu struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2214ab8812a3SHersen Wu 2215ab8812a3SHersen Wu if (pipe_ctx->stream == NULL) 2216ab8812a3SHersen Wu continue; 2217ab8812a3SHersen Wu 2218eed928dcSCharlene Liu if (pipe_ctx->stream == pipe_ctx_old->stream && 2219eed928dcSCharlene Liu pipe_ctx->stream->link->link_state_valid) { 2220ab8812a3SHersen Wu continue; 2221eed928dcSCharlene Liu } 2222ab8812a3SHersen Wu 22235b92d9d4SHarry Wentland if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 2224313bf4ffSYongqiang Sun continue; 2225313bf4ffSYongqiang Sun 2226b1f6d01cSDmytro Laktyushkin if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) 2227ab8812a3SHersen Wu continue; 2228ab8812a3SHersen Wu 22294562236bSHarry Wentland status = apply_single_controller_ctx_to_hw( 22304562236bSHarry Wentland pipe_ctx, 22314562236bSHarry Wentland context, 22324562236bSHarry Wentland dc); 22334562236bSHarry Wentland 22344562236bSHarry Wentland if (DC_OK != status) 22354562236bSHarry Wentland return status; 22364562236bSHarry Wentland } 22374562236bSHarry Wentland 2238690b5e39SRoman Li if (dc->fbc_compressor) 223965d38262Shersen wu enable_fbc(dc, dc->current_state); 224065d38262Shersen wu 224165d38262Shersen wu dcb->funcs->set_scratch_critical_state(dcb, false); 2242690b5e39SRoman Li 22434562236bSHarry Wentland return DC_OK; 22444562236bSHarry Wentland } 22454562236bSHarry Wentland 22464562236bSHarry Wentland /******************************************************************************* 22474562236bSHarry Wentland * Front End programming 22484562236bSHarry Wentland ******************************************************************************/ 22494562236bSHarry Wentland static void set_default_colors(struct pipe_ctx *pipe_ctx) 22504562236bSHarry Wentland { 22514562236bSHarry Wentland struct default_adjustment default_adjust = { 0 }; 22524562236bSHarry Wentland 22534562236bSHarry Wentland default_adjust.force_hw_default = false; 225434996173SHarry Wentland default_adjust.in_color_space = pipe_ctx->plane_state->color_space; 225534996173SHarry Wentland default_adjust.out_color_space = pipe_ctx->stream->output_color_space; 22564562236bSHarry Wentland default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 22576702a9acSHarry Wentland default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 22584562236bSHarry Wentland 22594562236bSHarry Wentland /* display color depth */ 22604562236bSHarry Wentland default_adjust.color_depth = 22614fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->timing.display_color_depth; 22624562236bSHarry Wentland 22634562236bSHarry Wentland /* Lb color depth */ 22646702a9acSHarry Wentland default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 22654562236bSHarry Wentland 226686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 226786a66c4eSHarry Wentland pipe_ctx->plane_res.xfm, &default_adjust); 22684562236bSHarry Wentland } 22694562236bSHarry Wentland 2270b06b7680SLeon Elazar 2271b06b7680SLeon Elazar /******************************************************************************* 2272b06b7680SLeon Elazar * In order to turn on/off specific surface we will program 2273b06b7680SLeon Elazar * Blender + CRTC 2274b06b7680SLeon Elazar * 2275b06b7680SLeon Elazar * In case that we have two surfaces and they have a different visibility 2276b06b7680SLeon Elazar * we can't turn off the CRTC since it will turn off the entire display 2277b06b7680SLeon Elazar * 2278b06b7680SLeon Elazar * |----------------------------------------------- | 2279b06b7680SLeon Elazar * |bottom pipe|curr pipe | | | 2280b06b7680SLeon Elazar * |Surface |Surface | Blender | CRCT | 2281b06b7680SLeon Elazar * |visibility |visibility | Configuration| | 2282b06b7680SLeon Elazar * |------------------------------------------------| 2283b06b7680SLeon Elazar * | off | off | CURRENT_PIPE | blank | 2284b06b7680SLeon Elazar * | off | on | CURRENT_PIPE | unblank | 2285b06b7680SLeon Elazar * | on | off | OTHER_PIPE | unblank | 2286b06b7680SLeon Elazar * | on | on | BLENDING | unblank | 2287b06b7680SLeon Elazar * -------------------------------------------------| 2288b06b7680SLeon Elazar * 2289b06b7680SLeon Elazar ******************************************************************************/ 2290fb3466a4SBhawanpreet Lakha static void program_surface_visibility(const struct dc *dc, 22914562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 22924562236bSHarry Wentland { 22934562236bSHarry Wentland enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 2294b06b7680SLeon Elazar bool blank_target = false; 22954562236bSHarry Wentland 22964562236bSHarry Wentland if (pipe_ctx->bottom_pipe) { 2297b06b7680SLeon Elazar 2298b06b7680SLeon Elazar /* For now we are supporting only two pipes */ 2299b06b7680SLeon Elazar ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 2300b06b7680SLeon Elazar 23013be5262eSHarry Wentland if (pipe_ctx->bottom_pipe->plane_state->visible) { 23023be5262eSHarry Wentland if (pipe_ctx->plane_state->visible) 23034562236bSHarry Wentland blender_mode = BLND_MODE_BLENDING; 23044562236bSHarry Wentland else 23054562236bSHarry Wentland blender_mode = BLND_MODE_OTHER_PIPE; 2306b06b7680SLeon Elazar 23073be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2308b06b7680SLeon Elazar blank_target = true; 2309b06b7680SLeon Elazar 23103be5262eSHarry Wentland } else if (!pipe_ctx->plane_state->visible) 2311b06b7680SLeon Elazar blank_target = true; 2312b06b7680SLeon Elazar 2313e07f541fSYongqiang Sun dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode); 23146b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 2315b06b7680SLeon Elazar 23164562236bSHarry Wentland } 23174562236bSHarry Wentland 23181bf56e62SZeyu Fan static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 23191bf56e62SZeyu Fan { 2320146a9f63SKrunoslav Kovac int i = 0; 23211bf56e62SZeyu Fan struct xfm_grph_csc_adjustment adjust; 23221bf56e62SZeyu Fan memset(&adjust, 0, sizeof(adjust)); 23231bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 23241bf56e62SZeyu Fan 23251bf56e62SZeyu Fan 23264fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 23271bf56e62SZeyu Fan adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2328146a9f63SKrunoslav Kovac 2329146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2330146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2331146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 23321bf56e62SZeyu Fan } 23331bf56e62SZeyu Fan 233486a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 23351bf56e62SZeyu Fan } 2336fb3466a4SBhawanpreet Lakha static void update_plane_addr(const struct dc *dc, 23374562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 23384562236bSHarry Wentland { 23393be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 23404562236bSHarry Wentland 23413be5262eSHarry Wentland if (plane_state == NULL) 23424562236bSHarry Wentland return; 23434562236bSHarry Wentland 234486a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 234586a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 23463be5262eSHarry Wentland &plane_state->address, 23473be5262eSHarry Wentland plane_state->flip_immediate); 23484562236bSHarry Wentland 23493be5262eSHarry Wentland plane_state->status.requested_address = plane_state->address; 23504562236bSHarry Wentland } 23514562236bSHarry Wentland 2352f774b339SEric Yang static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 23534562236bSHarry Wentland { 23543be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 23554562236bSHarry Wentland 23563be5262eSHarry Wentland if (plane_state == NULL) 23574562236bSHarry Wentland return; 23584562236bSHarry Wentland 23593be5262eSHarry Wentland plane_state->status.is_flip_pending = 236086a66c4eSHarry Wentland pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 236186a66c4eSHarry Wentland pipe_ctx->plane_res.mi); 23624562236bSHarry Wentland 23633be5262eSHarry Wentland if (plane_state->status.is_flip_pending && !plane_state->visible) 236486a66c4eSHarry Wentland pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address; 23654562236bSHarry Wentland 236686a66c4eSHarry Wentland plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 236786a66c4eSHarry Wentland if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 23686b670fa9SHarry Wentland pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) { 23693be5262eSHarry Wentland plane_state->status.is_right_eye =\ 23706b670fa9SHarry Wentland !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 23717f5c22d1SVitaly Prosyak } 23724562236bSHarry Wentland } 23734562236bSHarry Wentland 2374fb3466a4SBhawanpreet Lakha void dce110_power_down(struct dc *dc) 23754562236bSHarry Wentland { 23764562236bSHarry Wentland power_down_all_hw_blocks(dc); 23774562236bSHarry Wentland disable_vga_and_power_gate_all_controllers(dc); 23784562236bSHarry Wentland } 23794562236bSHarry Wentland 23804562236bSHarry Wentland static bool wait_for_reset_trigger_to_occur( 23814562236bSHarry Wentland struct dc_context *dc_ctx, 23824562236bSHarry Wentland struct timing_generator *tg) 23834562236bSHarry Wentland { 23844562236bSHarry Wentland bool rc = false; 23854562236bSHarry Wentland 23864562236bSHarry Wentland /* To avoid endless loop we wait at most 23874562236bSHarry Wentland * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 23884562236bSHarry Wentland const uint32_t frames_to_wait_on_triggered_reset = 10; 23894562236bSHarry Wentland uint32_t i; 23904562236bSHarry Wentland 23914562236bSHarry Wentland for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 23924562236bSHarry Wentland 23934562236bSHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 23944562236bSHarry Wentland DC_ERROR("TG counter is not moving!\n"); 23954562236bSHarry Wentland break; 23964562236bSHarry Wentland } 23974562236bSHarry Wentland 23984562236bSHarry Wentland if (tg->funcs->did_triggered_reset_occur(tg)) { 23994562236bSHarry Wentland rc = true; 24004562236bSHarry Wentland /* usually occurs at i=1 */ 24014562236bSHarry Wentland DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 24024562236bSHarry Wentland i); 24034562236bSHarry Wentland break; 24044562236bSHarry Wentland } 24054562236bSHarry Wentland 24064562236bSHarry Wentland /* Wait for one frame. */ 24074562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 24084562236bSHarry Wentland tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 24094562236bSHarry Wentland } 24104562236bSHarry Wentland 24114562236bSHarry Wentland if (false == rc) 24124562236bSHarry Wentland DC_ERROR("GSL: Timeout on reset trigger!\n"); 24134562236bSHarry Wentland 24144562236bSHarry Wentland return rc; 24154562236bSHarry Wentland } 24164562236bSHarry Wentland 24174562236bSHarry Wentland /* Enable timing synchronization for a group of Timing Generators. */ 24184562236bSHarry Wentland static void dce110_enable_timing_synchronization( 2419fb3466a4SBhawanpreet Lakha struct dc *dc, 24204562236bSHarry Wentland int group_index, 24214562236bSHarry Wentland int group_size, 24224562236bSHarry Wentland struct pipe_ctx *grouped_pipes[]) 24234562236bSHarry Wentland { 24244562236bSHarry Wentland struct dc_context *dc_ctx = dc->ctx; 24254562236bSHarry Wentland struct dcp_gsl_params gsl_params = { 0 }; 24264562236bSHarry Wentland int i; 24274562236bSHarry Wentland 24284562236bSHarry Wentland DC_SYNC_INFO("GSL: Setting-up...\n"); 24294562236bSHarry Wentland 24304562236bSHarry Wentland /* Designate a single TG in the group as a master. 24314562236bSHarry Wentland * Since HW doesn't care which one, we always assign 24324562236bSHarry Wentland * the 1st one in the group. */ 24334562236bSHarry Wentland gsl_params.gsl_group = 0; 24346b670fa9SHarry Wentland gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst; 24354562236bSHarry Wentland 24364562236bSHarry Wentland for (i = 0; i < group_size; i++) 24376b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 24386b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg, &gsl_params); 24394562236bSHarry Wentland 24404562236bSHarry Wentland /* Reset slave controllers on master VSync */ 24414562236bSHarry Wentland DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 24424562236bSHarry Wentland 24434562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) 24446b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( 2445fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2446fa2123dbSMikita Lipski gsl_params.gsl_group); 24474562236bSHarry Wentland 24484562236bSHarry Wentland for (i = 1 /* skip the master */; i < group_size; i++) { 24494562236bSHarry Wentland DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 24506b670fa9SHarry Wentland wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2451fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( 2452fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg); 24534562236bSHarry Wentland } 24544562236bSHarry Wentland 24554562236bSHarry Wentland /* GSL Vblank synchronization is a one time sync mechanism, assumption 24564562236bSHarry Wentland * is that the sync'ed displays will not drift out of sync over time*/ 24574562236bSHarry Wentland DC_SYNC_INFO("GSL: Restoring register states.\n"); 24584562236bSHarry Wentland for (i = 0; i < group_size; i++) 24596b670fa9SHarry Wentland grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 24604562236bSHarry Wentland 24614562236bSHarry Wentland DC_SYNC_INFO("GSL: Set-up complete.\n"); 24624562236bSHarry Wentland } 24634562236bSHarry Wentland 2464fa2123dbSMikita Lipski static void dce110_enable_per_frame_crtc_position_reset( 2465fa2123dbSMikita Lipski struct dc *dc, 2466fa2123dbSMikita Lipski int group_size, 2467fa2123dbSMikita Lipski struct pipe_ctx *grouped_pipes[]) 2468fa2123dbSMikita Lipski { 2469fa2123dbSMikita Lipski struct dc_context *dc_ctx = dc->ctx; 2470fa2123dbSMikita Lipski struct dcp_gsl_params gsl_params = { 0 }; 2471fa2123dbSMikita Lipski int i; 2472fa2123dbSMikita Lipski 2473fa2123dbSMikita Lipski gsl_params.gsl_group = 0; 247437cd85ceSDavid Francis gsl_params.gsl_master = 0; 2475fa2123dbSMikita Lipski 2476fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2477fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 2478fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, &gsl_params); 2479fa2123dbSMikita Lipski 2480fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 2481fa2123dbSMikita Lipski 2482fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2483fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( 2484fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg, 2485fa2123dbSMikita Lipski gsl_params.gsl_master, 2486fa2123dbSMikita Lipski &grouped_pipes[i]->stream->triggered_crtc_reset); 2487fa2123dbSMikita Lipski 2488fa2123dbSMikita Lipski DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 2489fa2123dbSMikita Lipski for (i = 1; i < group_size; i++) 2490fa2123dbSMikita Lipski wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2491fa2123dbSMikita Lipski 2492fa2123dbSMikita Lipski for (i = 0; i < group_size; i++) 2493fa2123dbSMikita Lipski grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 2494fa2123dbSMikita Lipski 2495fa2123dbSMikita Lipski } 2496fa2123dbSMikita Lipski 2497fb55546eSAnthony Koo static void init_pipes(struct dc *dc, struct dc_state *context) 2498fb55546eSAnthony Koo { 2499fb55546eSAnthony Koo // Do nothing 2500fb55546eSAnthony Koo } 2501fb55546eSAnthony Koo 2502fb3466a4SBhawanpreet Lakha static void init_hw(struct dc *dc) 25034562236bSHarry Wentland { 25044562236bSHarry Wentland int i; 25054562236bSHarry Wentland struct dc_bios *bp; 25064562236bSHarry Wentland struct transform *xfm; 25075e7773a2SAnthony Koo struct abm *abm; 250870d9e8cbSPaul Hsieh struct dmcu *dmcu; 2509f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 25103ba01817SYongqiang Sun uint32_t backlight = MAX_BACKLIGHT_LEVEL; 25114562236bSHarry Wentland 25124562236bSHarry Wentland bp = dc->ctx->dc_bios; 25134562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 25144562236bSHarry Wentland xfm = dc->res_pool->transforms[i]; 25154562236bSHarry Wentland xfm->funcs->transform_reset(xfm); 25164562236bSHarry Wentland 2517f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 25184562236bSHarry Wentland dc, i, bp, 25194562236bSHarry Wentland PIPE_GATING_CONTROL_INIT); 2520f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 25214562236bSHarry Wentland dc, i, bp, 25224562236bSHarry Wentland PIPE_GATING_CONTROL_DISABLE); 2523f42ea55bSAnthony Koo hws->funcs.enable_display_pipe_clock_gating( 25244562236bSHarry Wentland dc->ctx, 25254562236bSHarry Wentland true); 25264562236bSHarry Wentland } 25274562236bSHarry Wentland 2528e166ad43SJulia Lawall dce_clock_gating_power_up(dc->hwseq, false); 25294562236bSHarry Wentland /***************************************/ 25304562236bSHarry Wentland 25314562236bSHarry Wentland for (i = 0; i < dc->link_count; i++) { 25324562236bSHarry Wentland /****************************************/ 25334562236bSHarry Wentland /* Power up AND update implementation according to the 25344562236bSHarry Wentland * required signal (which may be different from the 25354562236bSHarry Wentland * default signal on connector). */ 2536d0778ebfSHarry Wentland struct dc_link *link = dc->links[i]; 2537069d418fSAndrew Jiang 25384562236bSHarry Wentland link->link_enc->funcs->hw_init(link->link_enc); 25394562236bSHarry Wentland } 25404562236bSHarry Wentland 25414562236bSHarry Wentland for (i = 0; i < dc->res_pool->pipe_count; i++) { 25424562236bSHarry Wentland struct timing_generator *tg = dc->res_pool->timing_generators[i]; 25434562236bSHarry Wentland 25444562236bSHarry Wentland tg->funcs->disable_vga(tg); 25454562236bSHarry Wentland 25464562236bSHarry Wentland /* Blank controller using driver code instead of 25474562236bSHarry Wentland * command table. */ 25484562236bSHarry Wentland tg->funcs->set_blank(tg, true); 25494b5e7d62SHersen Wu hwss_wait_for_blank_complete(tg); 25504562236bSHarry Wentland } 25514562236bSHarry Wentland 25524562236bSHarry Wentland for (i = 0; i < dc->res_pool->audio_count; i++) { 25534562236bSHarry Wentland struct audio *audio = dc->res_pool->audios[i]; 25544562236bSHarry Wentland audio->funcs->hw_init(audio); 25554562236bSHarry Wentland } 25565e7773a2SAnthony Koo 25573ba01817SYongqiang Sun for (i = 0; i < dc->link_count; i++) { 25583ba01817SYongqiang Sun struct dc_link *link = dc->links[i]; 25593ba01817SYongqiang Sun 25603ba01817SYongqiang Sun if (link->panel_cntl) 25613ba01817SYongqiang Sun backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); 25624562236bSHarry Wentland } 25635099114bSAlex Deucher 25643ba01817SYongqiang Sun abm = dc->res_pool->abm; 25653ba01817SYongqiang Sun if (abm != NULL) 25663ba01817SYongqiang Sun abm->funcs->abm_init(abm, backlight); 25673ba01817SYongqiang Sun 256870d9e8cbSPaul Hsieh dmcu = dc->res_pool->dmcu; 256970d9e8cbSPaul Hsieh if (dmcu != NULL && abm != NULL) 257070d9e8cbSPaul Hsieh abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu); 257170d9e8cbSPaul Hsieh 25722f3bfb27SRoman Li if (dc->fbc_compressor) 25731663ae1cSBhawanpreet Lakha dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 2574690b5e39SRoman Li 25756728b30cSAnthony Koo } 25764562236bSHarry Wentland 25779566b675SDmytro Laktyushkin 25789566b675SDmytro Laktyushkin void dce110_prepare_bandwidth( 2579fb3466a4SBhawanpreet Lakha struct dc *dc, 25809566b675SDmytro Laktyushkin struct dc_state *context) 2581cf437593SDmytro Laktyushkin { 2582dc88b4a6SEric Yang struct clk_mgr *dccg = dc->clk_mgr; 2583fab55d61SDmytro Laktyushkin 2584fab55d61SDmytro Laktyushkin dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); 2585cf437593SDmytro Laktyushkin 25865a83c932SNicholas Kazlauskas dccg->funcs->update_clocks( 25875a83c932SNicholas Kazlauskas dccg, 258824f7dd7eSDmytro Laktyushkin context, 25899566b675SDmytro Laktyushkin false); 25909566b675SDmytro Laktyushkin } 25919566b675SDmytro Laktyushkin 25929566b675SDmytro Laktyushkin void dce110_optimize_bandwidth( 25939566b675SDmytro Laktyushkin struct dc *dc, 25949566b675SDmytro Laktyushkin struct dc_state *context) 25959566b675SDmytro Laktyushkin { 2596dc88b4a6SEric Yang struct clk_mgr *dccg = dc->clk_mgr; 25979566b675SDmytro Laktyushkin 25989566b675SDmytro Laktyushkin dce110_set_displaymarks(dc, context); 25999566b675SDmytro Laktyushkin 26009566b675SDmytro Laktyushkin dccg->funcs->update_clocks( 26019566b675SDmytro Laktyushkin dccg, 26029566b675SDmytro Laktyushkin context, 26039566b675SDmytro Laktyushkin true); 26044562236bSHarry Wentland } 26054562236bSHarry Wentland 26064562236bSHarry Wentland static void dce110_program_front_end_for_pipe( 2607fb3466a4SBhawanpreet Lakha struct dc *dc, struct pipe_ctx *pipe_ctx) 26084562236bSHarry Wentland { 260986a66c4eSHarry Wentland struct mem_input *mi = pipe_ctx->plane_res.mi; 26103be5262eSHarry Wentland struct dc_plane_state *plane_state = pipe_ctx->plane_state; 26114562236bSHarry Wentland struct xfm_grph_csc_adjustment adjust; 26124562236bSHarry Wentland struct out_csc_color_matrix tbl_entry; 26134562236bSHarry Wentland unsigned int i; 2614f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 2615f42ea55bSAnthony Koo 26165d4b05ddSBhawanpreet Lakha DC_LOGGER_INIT(); 26174562236bSHarry Wentland memset(&tbl_entry, 0, sizeof(tbl_entry)); 26184562236bSHarry Wentland 26194562236bSHarry Wentland memset(&adjust, 0, sizeof(adjust)); 26204562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 26214562236bSHarry Wentland 2622e07f541fSYongqiang Sun dce_enable_fe_clock(dc->hwseq, mi->inst, true); 26234562236bSHarry Wentland 26244562236bSHarry Wentland set_default_colors(pipe_ctx); 26254fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 26264562236bSHarry Wentland == true) { 26274562236bSHarry Wentland tbl_entry.color_space = 26284fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->output_color_space; 26294562236bSHarry Wentland 26304562236bSHarry Wentland for (i = 0; i < 12; i++) 26314562236bSHarry Wentland tbl_entry.regval[i] = 26324fa086b9SLeo (Sunpeng) Li pipe_ctx->stream->csc_color_matrix.matrix[i]; 26334562236bSHarry Wentland 263486a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 263586a66c4eSHarry Wentland (pipe_ctx->plane_res.xfm, &tbl_entry); 26364562236bSHarry Wentland } 26374562236bSHarry Wentland 26384fa086b9SLeo (Sunpeng) Li if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 26394562236bSHarry Wentland adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2640146a9f63SKrunoslav Kovac 2641146a9f63SKrunoslav Kovac for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2642146a9f63SKrunoslav Kovac adjust.temperature_matrix[i] = 2643146a9f63SKrunoslav Kovac pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 26444562236bSHarry Wentland } 26454562236bSHarry Wentland 264686a66c4eSHarry Wentland pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 26474562236bSHarry Wentland 26486702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 2649c1473558SAndrey Grodzovsky 26504562236bSHarry Wentland program_scaler(dc, pipe_ctx); 26514562236bSHarry Wentland 26524562236bSHarry Wentland mi->funcs->mem_input_program_surface_config( 26534562236bSHarry Wentland mi, 26543be5262eSHarry Wentland plane_state->format, 26553be5262eSHarry Wentland &plane_state->tiling_info, 26563be5262eSHarry Wentland &plane_state->plane_size, 26573be5262eSHarry Wentland plane_state->rotation, 2658624d7c47SYongqiang Sun NULL, 26594b28b76bSDmytro Laktyushkin false); 26604b28b76bSDmytro Laktyushkin if (mi->funcs->set_blank) 26613be5262eSHarry Wentland mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 26624562236bSHarry Wentland 2663fb3466a4SBhawanpreet Lakha if (dc->config.gpu_vm_support) 26644562236bSHarry Wentland mi->funcs->mem_input_program_pte_vm( 266586a66c4eSHarry Wentland pipe_ctx->plane_res.mi, 26663be5262eSHarry Wentland plane_state->format, 26673be5262eSHarry Wentland &plane_state->tiling_info, 26683be5262eSHarry Wentland plane_state->rotation); 26694562236bSHarry Wentland 2670067c878aSYongqiang Sun /* Moved programming gamma from dc to hwss */ 2671405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update || 2672405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 2673405c50a0SAndrew Jiang pipe_ctx->plane_state->update_flags.bits.gamma_change) 2674f42ea55bSAnthony Koo hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); 2675405c50a0SAndrew Jiang 2676405c50a0SAndrew Jiang if (pipe_ctx->plane_state->update_flags.bits.full_update) 2677f42ea55bSAnthony Koo hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream); 2678067c878aSYongqiang Sun 26791296423bSBhawanpreet Lakha DC_LOG_SURFACE( 26803032deb5SBhawanpreet Lakha "Pipe:%d %p: addr hi:0x%x, " 26814562236bSHarry Wentland "addr low:0x%x, " 26824562236bSHarry Wentland "src: %d, %d, %d," 26834562236bSHarry Wentland " %d; dst: %d, %d, %d, %d;" 26844562236bSHarry Wentland "clip: %d, %d, %d, %d\n", 26854562236bSHarry Wentland pipe_ctx->pipe_idx, 26863032deb5SBhawanpreet Lakha (void *) pipe_ctx->plane_state, 26873be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.high_part, 26883be5262eSHarry Wentland pipe_ctx->plane_state->address.grph.addr.low_part, 26893be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.x, 26903be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.y, 26913be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.width, 26923be5262eSHarry Wentland pipe_ctx->plane_state->src_rect.height, 26933be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.x, 26943be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.y, 26953be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.width, 26963be5262eSHarry Wentland pipe_ctx->plane_state->dst_rect.height, 26973be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.x, 26983be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.y, 26993be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.width, 27003be5262eSHarry Wentland pipe_ctx->plane_state->clip_rect.height); 27014562236bSHarry Wentland 27021296423bSBhawanpreet Lakha DC_LOG_SURFACE( 27034562236bSHarry Wentland "Pipe %d: width, height, x, y\n" 27044562236bSHarry Wentland "viewport:%d, %d, %d, %d\n" 27054562236bSHarry Wentland "recout: %d, %d, %d, %d\n", 27064562236bSHarry Wentland pipe_ctx->pipe_idx, 27076702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.width, 27086702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.height, 27096702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.x, 27106702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.viewport.y, 27116702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.width, 27126702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.height, 27136702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.x, 27146702a9acSHarry Wentland pipe_ctx->plane_res.scl_data.recout.y); 27154562236bSHarry Wentland } 27164562236bSHarry Wentland 27174562236bSHarry Wentland static void dce110_apply_ctx_for_surface( 2718fb3466a4SBhawanpreet Lakha struct dc *dc, 27193e9ad616SEric Yang const struct dc_stream_state *stream, 27203e9ad616SEric Yang int num_planes, 2721608ac7bbSJerry Zuo struct dc_state *context) 27224562236bSHarry Wentland { 27232194e3aeSRoman Li int i; 27244562236bSHarry Wentland 27253e9ad616SEric Yang if (num_planes == 0) 27264562236bSHarry Wentland return; 27274562236bSHarry Wentland 272865d38262Shersen wu if (dc->fbc_compressor) 272965d38262Shersen wu dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 273065d38262Shersen wu 27313e9ad616SEric Yang for (i = 0; i < dc->res_pool->pipe_count; i++) { 27323dc780ecSYongqiang Sun struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 27334562236bSHarry Wentland 2734a2607aefSHarry Wentland if (pipe_ctx->stream != stream) 27354562236bSHarry Wentland continue; 27364562236bSHarry Wentland 27373b21b6d2SJerry Zuo /* Need to allocate mem before program front end for Fiji */ 27383b21b6d2SJerry Zuo pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 27393b21b6d2SJerry Zuo pipe_ctx->plane_res.mi, 27403b21b6d2SJerry Zuo pipe_ctx->stream->timing.h_total, 27413b21b6d2SJerry Zuo pipe_ctx->stream->timing.v_total, 2742380604e2SKen Chalmers pipe_ctx->stream->timing.pix_clk_100hz / 10, 27433b21b6d2SJerry Zuo context->stream_count); 27443b21b6d2SJerry Zuo 27454562236bSHarry Wentland dce110_program_front_end_for_pipe(dc, pipe_ctx); 27464f804817SYongqiang Sun 27474f804817SYongqiang Sun dc->hwss.update_plane_addr(dc, pipe_ctx); 27484f804817SYongqiang Sun 2749b06b7680SLeon Elazar program_surface_visibility(dc, pipe_ctx); 27504562236bSHarry Wentland 27514562236bSHarry Wentland } 27523dc780ecSYongqiang Sun 275365d38262Shersen wu if (dc->fbc_compressor) 275412a8bd88SShirish S enable_fbc(dc, context); 27554562236bSHarry Wentland } 27564562236bSHarry Wentland 2757bbf5f6c3SAnthony Koo static void dce110_post_unlock_program_front_end( 2758bbf5f6c3SAnthony Koo struct dc *dc, 2759bbf5f6c3SAnthony Koo struct dc_state *context) 2760bbf5f6c3SAnthony Koo { 2761bbf5f6c3SAnthony Koo } 2762009114f6SAnthony Koo 2763e6c258cbSYongqiang Sun static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) 27644562236bSHarry Wentland { 2765f42ea55bSAnthony Koo struct dce_hwseq *hws = dc->hwseq; 2766bc373a89SRoman Li int fe_idx = pipe_ctx->plane_res.mi ? 2767bc373a89SRoman Li pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx; 2768e6c258cbSYongqiang Sun 27697950f0f9SDmytro Laktyushkin /* Do not power down fe when stream is active on dce*/ 2770608ac7bbSJerry Zuo if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) 27714562236bSHarry Wentland return; 27724562236bSHarry Wentland 2773f42ea55bSAnthony Koo hws->funcs.enable_display_power_gating( 2774cfe4645eSDmytro Laktyushkin dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 2775cfe4645eSDmytro Laktyushkin 2776cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 2777cfe4645eSDmytro Laktyushkin dc->res_pool->transforms[fe_idx]); 27784562236bSHarry Wentland } 27794562236bSHarry Wentland 27806be425f3SEric Yang static void dce110_wait_for_mpcc_disconnect( 2781fb3466a4SBhawanpreet Lakha struct dc *dc, 27826be425f3SEric Yang struct resource_pool *res_pool, 27836be425f3SEric Yang struct pipe_ctx *pipe_ctx) 2784b6762f0cSEric Yang { 2785b6762f0cSEric Yang /* do nothing*/ 2786b6762f0cSEric Yang } 2787b6762f0cSEric Yang 27884bd0dc68SJoshua Aberback static void program_output_csc(struct dc *dc, 27894bd0dc68SJoshua Aberback struct pipe_ctx *pipe_ctx, 27904bd0dc68SJoshua Aberback enum dc_color_space colorspace, 27914bd0dc68SJoshua Aberback uint16_t *matrix, 27924bd0dc68SJoshua Aberback int opp_id) 27934bd0dc68SJoshua Aberback { 27944bd0dc68SJoshua Aberback int i; 27954bd0dc68SJoshua Aberback struct out_csc_color_matrix tbl_entry; 27964bd0dc68SJoshua Aberback 27974bd0dc68SJoshua Aberback if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { 27984bd0dc68SJoshua Aberback enum dc_color_space color_space = pipe_ctx->stream->output_color_space; 27994bd0dc68SJoshua Aberback 28004bd0dc68SJoshua Aberback for (i = 0; i < 12; i++) 28014bd0dc68SJoshua Aberback tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; 28024bd0dc68SJoshua Aberback 28034bd0dc68SJoshua Aberback tbl_entry.color_space = color_space; 28044bd0dc68SJoshua Aberback 28054bd0dc68SJoshua Aberback pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment( 28064bd0dc68SJoshua Aberback pipe_ctx->plane_res.xfm, &tbl_entry); 28074bd0dc68SJoshua Aberback } 28084bd0dc68SJoshua Aberback } 28094bd0dc68SJoshua Aberback 2810faf0389fSJason Yan static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) 281133fd17d9SEric Yang { 281233fd17d9SEric Yang struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; 281333fd17d9SEric Yang struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 281433fd17d9SEric Yang struct mem_input *mi = pipe_ctx->plane_res.mi; 281533fd17d9SEric Yang struct dc_cursor_mi_param param = { 2816380604e2SKen Chalmers .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10, 281733d7598dSJun Lei .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz, 281839a9f4d8SDmytro Laktyushkin .viewport = pipe_ctx->plane_res.scl_data.viewport, 281939a9f4d8SDmytro Laktyushkin .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, 282039a9f4d8SDmytro Laktyushkin .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, 282108ed681cSDmytro Laktyushkin .rotation = pipe_ctx->plane_state->rotation, 282208ed681cSDmytro Laktyushkin .mirror = pipe_ctx->plane_state->horizontal_mirror 282333fd17d9SEric Yang }; 282433fd17d9SEric Yang 282503a4059bSNicholas Kazlauskas /** 282603a4059bSNicholas Kazlauskas * If the cursor's source viewport is clipped then we need to 282703a4059bSNicholas Kazlauskas * translate the cursor to appear in the correct position on 282803a4059bSNicholas Kazlauskas * the screen. 282903a4059bSNicholas Kazlauskas * 283003a4059bSNicholas Kazlauskas * This translation isn't affected by scaling so it needs to be 283103a4059bSNicholas Kazlauskas * done *after* we adjust the position for the scale factor. 2832033baeeeSNicholas Kazlauskas * 2833033baeeeSNicholas Kazlauskas * This is only done by opt-in for now since there are still 2834033baeeeSNicholas Kazlauskas * some usecases like tiled display that might enable the 2835033baeeeSNicholas Kazlauskas * cursor on both streams while expecting dc to clip it. 283603a4059bSNicholas Kazlauskas */ 2837033baeeeSNicholas Kazlauskas if (pos_cpy.translate_by_source) { 283803a4059bSNicholas Kazlauskas pos_cpy.x += pipe_ctx->plane_state->src_rect.x; 283903a4059bSNicholas Kazlauskas pos_cpy.y += pipe_ctx->plane_state->src_rect.y; 2840033baeeeSNicholas Kazlauskas } 284103a4059bSNicholas Kazlauskas 284233fd17d9SEric Yang if (pipe_ctx->plane_state->address.type 284333fd17d9SEric Yang == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) 284433fd17d9SEric Yang pos_cpy.enable = false; 284533fd17d9SEric Yang 284633fd17d9SEric Yang if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 284733fd17d9SEric Yang pos_cpy.enable = false; 284833fd17d9SEric Yang 2849dc75dd70SRoman Li if (ipp->funcs->ipp_cursor_set_position) 285033fd17d9SEric Yang ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); 2851dc75dd70SRoman Li if (mi->funcs->set_cursor_position) 285233fd17d9SEric Yang mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); 285333fd17d9SEric Yang } 285433fd17d9SEric Yang 2855faf0389fSJason Yan static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) 285633fd17d9SEric Yang { 285733fd17d9SEric Yang struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; 285833fd17d9SEric Yang 2859d1aaad05SHarry Wentland if (pipe_ctx->plane_res.ipp && 2860d1aaad05SHarry Wentland pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) 286133fd17d9SEric Yang pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( 286233fd17d9SEric Yang pipe_ctx->plane_res.ipp, attributes); 286333fd17d9SEric Yang 2864d1aaad05SHarry Wentland if (pipe_ctx->plane_res.mi && 2865d1aaad05SHarry Wentland pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) 286633fd17d9SEric Yang pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( 286733fd17d9SEric Yang pipe_ctx->plane_res.mi, attributes); 286833fd17d9SEric Yang 2869d1aaad05SHarry Wentland if (pipe_ctx->plane_res.xfm && 2870d1aaad05SHarry Wentland pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) 287133fd17d9SEric Yang pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( 287233fd17d9SEric Yang pipe_ctx->plane_res.xfm, attributes); 287333fd17d9SEric Yang } 287433fd17d9SEric Yang 28754b0e95d1SYongqiang Sun bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, 28764b0e95d1SYongqiang Sun uint32_t backlight_pwm_u16_16, 28774b0e95d1SYongqiang Sun uint32_t frame_ramp) 28784b0e95d1SYongqiang Sun { 28794b0e95d1SYongqiang Sun struct dc_link *link = pipe_ctx->stream->link; 28804b0e95d1SYongqiang Sun struct dc *dc = link->ctx->dc; 28814b0e95d1SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 28823ba01817SYongqiang Sun struct panel_cntl *panel_cntl = link->panel_cntl; 28834b0e95d1SYongqiang Sun struct dmcu *dmcu = dc->res_pool->dmcu; 28844b0e95d1SYongqiang Sun bool fw_set_brightness = true; 28854b0e95d1SYongqiang Sun /* DMCU -1 for all controller id values, 28864b0e95d1SYongqiang Sun * therefore +1 here 28874b0e95d1SYongqiang Sun */ 28884b0e95d1SYongqiang Sun uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1; 28894b0e95d1SYongqiang Sun 28903ba01817SYongqiang Sun if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL)) 28914b0e95d1SYongqiang Sun return false; 28924b0e95d1SYongqiang Sun 28934b0e95d1SYongqiang Sun if (dmcu) 28944b0e95d1SYongqiang Sun fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); 28954b0e95d1SYongqiang Sun 28963ba01817SYongqiang Sun if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight) 28973ba01817SYongqiang Sun panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16); 28983ba01817SYongqiang Sun else 28994b0e95d1SYongqiang Sun abm->funcs->set_backlight_level_pwm( 29004b0e95d1SYongqiang Sun abm, 29014b0e95d1SYongqiang Sun backlight_pwm_u16_16, 29024b0e95d1SYongqiang Sun frame_ramp, 29034b0e95d1SYongqiang Sun controller_id, 29043ba01817SYongqiang Sun link->panel_cntl->inst); 29054b0e95d1SYongqiang Sun 29064b0e95d1SYongqiang Sun return true; 29074b0e95d1SYongqiang Sun } 29084b0e95d1SYongqiang Sun 29093ba01817SYongqiang Sun void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx) 29103ba01817SYongqiang Sun { 29113ba01817SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 29123ba01817SYongqiang Sun struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 29133ba01817SYongqiang Sun 29143ba01817SYongqiang Sun if (abm) 29153ba01817SYongqiang Sun abm->funcs->set_abm_immediate_disable(abm, 29163ba01817SYongqiang Sun pipe_ctx->stream->link->panel_cntl->inst); 29173ba01817SYongqiang Sun 29183ba01817SYongqiang Sun if (panel_cntl) 29193ba01817SYongqiang Sun panel_cntl->funcs->store_backlight_level(panel_cntl); 29203ba01817SYongqiang Sun } 29213ba01817SYongqiang Sun 2922474ac4a8SYongqiang Sun void dce110_set_pipe(struct pipe_ctx *pipe_ctx) 2923474ac4a8SYongqiang Sun { 2924474ac4a8SYongqiang Sun struct abm *abm = pipe_ctx->stream_res.abm; 2925474ac4a8SYongqiang Sun struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 2926474ac4a8SYongqiang Sun uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1; 2927474ac4a8SYongqiang Sun 2928474ac4a8SYongqiang Sun if (abm && panel_cntl) 2929474ac4a8SYongqiang Sun abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst); 2930474ac4a8SYongqiang Sun } 2931474ac4a8SYongqiang Sun 29324562236bSHarry Wentland static const struct hw_sequencer_funcs dce110_funcs = { 29331bf56e62SZeyu Fan .program_gamut_remap = program_gamut_remap, 29344bd0dc68SJoshua Aberback .program_output_csc = program_output_csc, 29354562236bSHarry Wentland .init_hw = init_hw, 29364562236bSHarry Wentland .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 29374562236bSHarry Wentland .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 2938bbf5f6c3SAnthony Koo .post_unlock_program_front_end = dce110_post_unlock_program_front_end, 29394562236bSHarry Wentland .update_plane_addr = update_plane_addr, 29404562236bSHarry Wentland .update_pending_status = dce110_update_pending_status, 29414562236bSHarry Wentland .enable_accelerated_mode = dce110_enable_accelerated_mode, 29424562236bSHarry Wentland .enable_timing_synchronization = dce110_enable_timing_synchronization, 2943fa2123dbSMikita Lipski .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, 29444562236bSHarry Wentland .update_info_frame = dce110_update_info_frame, 29454562236bSHarry Wentland .enable_stream = dce110_enable_stream, 29464562236bSHarry Wentland .disable_stream = dce110_disable_stream, 29474562236bSHarry Wentland .unblank_stream = dce110_unblank_stream, 294841b49742SCharlene Liu .blank_stream = dce110_blank_stream, 29491a05873fSAnthony Koo .enable_audio_stream = dce110_enable_audio_stream, 29501a05873fSAnthony Koo .disable_audio_stream = dce110_disable_audio_stream, 29517f914a62SYongqiang Sun .disable_plane = dce110_power_down_fe, 29524562236bSHarry Wentland .pipe_control_lock = dce_pipe_control_lock, 2953009114f6SAnthony Koo .interdependent_update_lock = NULL, 29541e461c37SAric Cyr .cursor_lock = dce_pipe_control_lock, 29559566b675SDmytro Laktyushkin .prepare_bandwidth = dce110_prepare_bandwidth, 29569566b675SDmytro Laktyushkin .optimize_bandwidth = dce110_optimize_bandwidth, 29574562236bSHarry Wentland .set_drr = set_drr, 295872ada5f7SEric Cook .get_position = get_position, 29594562236bSHarry Wentland .set_static_screen_control = set_static_screen_control, 296015e17335SCharlene Liu .setup_stereo = NULL, 296115e17335SCharlene Liu .set_avmute = dce110_set_avmute, 296241f97c07SHersen Wu .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 2963099303e9SPeikang Zhang .edp_backlight_control = dce110_edp_backlight_control, 29648a31820bSMartin Leung .edp_power_control = dce110_edp_power_control, 29658a31820bSMartin Leung .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, 296633fd17d9SEric Yang .set_cursor_position = dce110_set_cursor_position, 29674b0e95d1SYongqiang Sun .set_cursor_attribute = dce110_set_cursor_attribute, 29684b0e95d1SYongqiang Sun .set_backlight_level = dce110_set_backlight_level, 29693ba01817SYongqiang Sun .set_abm_immediate_disable = dce110_set_abm_immediate_disable, 2970474ac4a8SYongqiang Sun .set_pipe = dce110_set_pipe, 29714562236bSHarry Wentland }; 29724562236bSHarry Wentland 2973f42ea55bSAnthony Koo static const struct hwseq_private_funcs dce110_private_funcs = { 2974f42ea55bSAnthony Koo .init_pipes = init_pipes, 2975f42ea55bSAnthony Koo .update_plane_addr = update_plane_addr, 2976f42ea55bSAnthony Koo .set_input_transfer_func = dce110_set_input_transfer_func, 2977f42ea55bSAnthony Koo .set_output_transfer_func = dce110_set_output_transfer_func, 2978f42ea55bSAnthony Koo .power_down = dce110_power_down, 2979f42ea55bSAnthony Koo .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 2980f42ea55bSAnthony Koo .enable_display_power_gating = dce110_enable_display_power_gating, 2981f42ea55bSAnthony Koo .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 2982f42ea55bSAnthony Koo .enable_stream_timing = dce110_enable_stream_timing, 2983f42ea55bSAnthony Koo .disable_stream_gating = NULL, 2984f42ea55bSAnthony Koo .enable_stream_gating = NULL, 2985f42ea55bSAnthony Koo .edp_backlight_control = dce110_edp_backlight_control, 2986f42ea55bSAnthony Koo }; 2987f42ea55bSAnthony Koo 2988c13b408bSDave Airlie void dce110_hw_sequencer_construct(struct dc *dc) 29894562236bSHarry Wentland { 29904562236bSHarry Wentland dc->hwss = dce110_funcs; 2991f42ea55bSAnthony Koo dc->hwseq->funcs = dce110_private_funcs; 29924562236bSHarry Wentland } 29934562236bSHarry Wentland 2994