14562236bSHarry Wentland /* 24562236bSHarry Wentland * Copyright 2012-15 Advanced Micro Devices, Inc. 34562236bSHarry Wentland * 44562236bSHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a 54562236bSHarry Wentland * copy of this software and associated documentation files (the "Software"), 64562236bSHarry Wentland * to deal in the Software without restriction, including without limitation 74562236bSHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 84562236bSHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the 94562236bSHarry Wentland * Software is furnished to do so, subject to the following conditions: 104562236bSHarry Wentland * 114562236bSHarry Wentland * The above copyright notice and this permission notice shall be included in 124562236bSHarry Wentland * all copies or substantial portions of the Software. 134562236bSHarry Wentland * 144562236bSHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 154562236bSHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 164562236bSHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 174562236bSHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 184562236bSHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 194562236bSHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 204562236bSHarry Wentland * OTHER DEALINGS IN THE SOFTWARE. 214562236bSHarry Wentland * 224562236bSHarry Wentland * Authors: AMD 234562236bSHarry Wentland * 244562236bSHarry Wentland */ 254562236bSHarry Wentland #include "dm_services.h" 264562236bSHarry Wentland 274562236bSHarry Wentland #include "resource.h" 284562236bSHarry Wentland #include "include/irq_service_interface.h" 294562236bSHarry Wentland #include "link_encoder.h" 304562236bSHarry Wentland #include "stream_encoder.h" 314562236bSHarry Wentland #include "opp.h" 324562236bSHarry Wentland #include "timing_generator.h" 334562236bSHarry Wentland #include "transform.h" 344562236bSHarry Wentland #include "set_mode_types.h" 354562236bSHarry Wentland #include "virtual/virtual_stream_encoder.h" 364562236bSHarry Wentland 374562236bSHarry Wentland #include "dce80/dce80_resource.h" 384562236bSHarry Wentland #include "dce100/dce100_resource.h" 394562236bSHarry Wentland #include "dce110/dce110_resource.h" 404562236bSHarry Wentland #include "dce112/dce112_resource.h" 414562236bSHarry Wentland 424562236bSHarry Wentland enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) 434562236bSHarry Wentland { 444562236bSHarry Wentland enum dce_version dc_version = DCE_VERSION_UNKNOWN; 454562236bSHarry Wentland switch (asic_id.chip_family) { 464562236bSHarry Wentland 474562236bSHarry Wentland case FAMILY_CI: 484562236bSHarry Wentland case FAMILY_KV: 494562236bSHarry Wentland dc_version = DCE_VERSION_8_0; 504562236bSHarry Wentland break; 514562236bSHarry Wentland case FAMILY_CZ: 524562236bSHarry Wentland dc_version = DCE_VERSION_11_0; 534562236bSHarry Wentland break; 544562236bSHarry Wentland 554562236bSHarry Wentland case FAMILY_VI: 564562236bSHarry Wentland if (ASIC_REV_IS_TONGA_P(asic_id.hw_internal_rev) || 574562236bSHarry Wentland ASIC_REV_IS_FIJI_P(asic_id.hw_internal_rev)) { 584562236bSHarry Wentland dc_version = DCE_VERSION_10_0; 594562236bSHarry Wentland break; 604562236bSHarry Wentland } 614562236bSHarry Wentland if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev) || 62b264d345SJordan Lazare ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev) || 63b264d345SJordan Lazare ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev)) { 644562236bSHarry Wentland dc_version = DCE_VERSION_11_2; 654562236bSHarry Wentland } 664562236bSHarry Wentland break; 674562236bSHarry Wentland default: 684562236bSHarry Wentland dc_version = DCE_VERSION_UNKNOWN; 694562236bSHarry Wentland break; 704562236bSHarry Wentland } 714562236bSHarry Wentland return dc_version; 724562236bSHarry Wentland } 734562236bSHarry Wentland 744562236bSHarry Wentland struct resource_pool *dc_create_resource_pool( 754562236bSHarry Wentland struct core_dc *dc, 764562236bSHarry Wentland int num_virtual_links, 774562236bSHarry Wentland enum dce_version dc_version, 784562236bSHarry Wentland struct hw_asic_id asic_id) 794562236bSHarry Wentland { 804562236bSHarry Wentland 814562236bSHarry Wentland switch (dc_version) { 824562236bSHarry Wentland case DCE_VERSION_8_0: 834562236bSHarry Wentland return dce80_create_resource_pool( 844562236bSHarry Wentland num_virtual_links, dc); 854562236bSHarry Wentland case DCE_VERSION_10_0: 864562236bSHarry Wentland return dce100_create_resource_pool( 874562236bSHarry Wentland num_virtual_links, dc); 884562236bSHarry Wentland case DCE_VERSION_11_0: 894562236bSHarry Wentland return dce110_create_resource_pool( 904562236bSHarry Wentland num_virtual_links, dc, asic_id); 914562236bSHarry Wentland case DCE_VERSION_11_2: 924562236bSHarry Wentland return dce112_create_resource_pool( 934562236bSHarry Wentland num_virtual_links, dc); 944562236bSHarry Wentland default: 954562236bSHarry Wentland break; 964562236bSHarry Wentland } 974562236bSHarry Wentland 984562236bSHarry Wentland return false; 994562236bSHarry Wentland } 1004562236bSHarry Wentland 1014562236bSHarry Wentland void dc_destroy_resource_pool(struct core_dc *dc) 1024562236bSHarry Wentland { 1034562236bSHarry Wentland if (dc) { 1044562236bSHarry Wentland if (dc->res_pool) 1054562236bSHarry Wentland dc->res_pool->funcs->destroy(&dc->res_pool); 1064562236bSHarry Wentland 1074562236bSHarry Wentland if (dc->hwseq) 1084562236bSHarry Wentland dm_free(dc->hwseq); 1094562236bSHarry Wentland } 1104562236bSHarry Wentland } 1114562236bSHarry Wentland 1124562236bSHarry Wentland static void update_num_audio( 1134562236bSHarry Wentland const struct resource_straps *straps, 1144562236bSHarry Wentland unsigned int *num_audio, 1154562236bSHarry Wentland struct audio_support *aud_support) 1164562236bSHarry Wentland { 1174562236bSHarry Wentland if (straps->hdmi_disable == 0) { 1184562236bSHarry Wentland aud_support->hdmi_audio_native = true; 1194562236bSHarry Wentland aud_support->hdmi_audio_on_dongle = true; 1204562236bSHarry Wentland aud_support->dp_audio = true; 1214562236bSHarry Wentland } else { 1224562236bSHarry Wentland if (straps->dc_pinstraps_audio & 0x2) { 1234562236bSHarry Wentland aud_support->hdmi_audio_on_dongle = true; 1244562236bSHarry Wentland aud_support->dp_audio = true; 1254562236bSHarry Wentland } else { 1264562236bSHarry Wentland aud_support->dp_audio = true; 1274562236bSHarry Wentland } 1284562236bSHarry Wentland } 1294562236bSHarry Wentland 1304562236bSHarry Wentland switch (straps->audio_stream_number) { 1314562236bSHarry Wentland case 0: /* multi streams supported */ 1324562236bSHarry Wentland break; 1334562236bSHarry Wentland case 1: /* multi streams not supported */ 1344562236bSHarry Wentland *num_audio = 1; 1354562236bSHarry Wentland break; 1364562236bSHarry Wentland default: 1374562236bSHarry Wentland DC_ERR("DC: unexpected audio fuse!\n"); 1384562236bSHarry Wentland }; 1394562236bSHarry Wentland } 1404562236bSHarry Wentland 1414562236bSHarry Wentland bool resource_construct( 1424562236bSHarry Wentland unsigned int num_virtual_links, 1434562236bSHarry Wentland struct core_dc *dc, 1444562236bSHarry Wentland struct resource_pool *pool, 1454562236bSHarry Wentland const struct resource_create_funcs *create_funcs) 1464562236bSHarry Wentland { 1474562236bSHarry Wentland struct dc_context *ctx = dc->ctx; 1484562236bSHarry Wentland const struct resource_caps *caps = pool->res_cap; 1494562236bSHarry Wentland int i; 1504562236bSHarry Wentland unsigned int num_audio = caps->num_audio; 1514562236bSHarry Wentland struct resource_straps straps = {0}; 1524562236bSHarry Wentland 1534562236bSHarry Wentland if (create_funcs->read_dce_straps) 1544562236bSHarry Wentland create_funcs->read_dce_straps(dc->ctx, &straps); 1554562236bSHarry Wentland 1564562236bSHarry Wentland pool->audio_count = 0; 1574562236bSHarry Wentland if (create_funcs->create_audio) { 1584562236bSHarry Wentland /* find the total number of streams available via the 1594562236bSHarry Wentland * AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 1604562236bSHarry Wentland * registers (one for each pin) starting from pin 1 1614562236bSHarry Wentland * up to the max number of audio pins. 1624562236bSHarry Wentland * We stop on the first pin where 1634562236bSHarry Wentland * PORT_CONNECTIVITY == 1 (as instructed by HW team). 1644562236bSHarry Wentland */ 1654562236bSHarry Wentland update_num_audio(&straps, &num_audio, &pool->audio_support); 1664562236bSHarry Wentland for (i = 0; i < pool->pipe_count && i < num_audio; i++) { 1674562236bSHarry Wentland struct audio *aud = create_funcs->create_audio(ctx, i); 1684562236bSHarry Wentland 1694562236bSHarry Wentland if (aud == NULL) { 1704562236bSHarry Wentland DC_ERR("DC: failed to create audio!\n"); 1714562236bSHarry Wentland return false; 1724562236bSHarry Wentland } 1734562236bSHarry Wentland 1744562236bSHarry Wentland if (!aud->funcs->endpoint_valid(aud)) { 1754562236bSHarry Wentland aud->funcs->destroy(&aud); 1764562236bSHarry Wentland break; 1774562236bSHarry Wentland } 1784562236bSHarry Wentland 1794562236bSHarry Wentland pool->audios[i] = aud; 1804562236bSHarry Wentland pool->audio_count++; 1814562236bSHarry Wentland } 1824562236bSHarry Wentland } 1834562236bSHarry Wentland 1844562236bSHarry Wentland pool->stream_enc_count = 0; 1854562236bSHarry Wentland if (create_funcs->create_stream_encoder) { 1864562236bSHarry Wentland for (i = 0; i < caps->num_stream_encoder; i++) { 1874562236bSHarry Wentland pool->stream_enc[i] = create_funcs->create_stream_encoder(i, ctx); 1884562236bSHarry Wentland if (pool->stream_enc[i] == NULL) 1894562236bSHarry Wentland DC_ERR("DC: failed to create stream_encoder!\n"); 1904562236bSHarry Wentland pool->stream_enc_count++; 1914562236bSHarry Wentland } 1924562236bSHarry Wentland } 1934562236bSHarry Wentland 1944562236bSHarry Wentland for (i = 0; i < num_virtual_links; i++) { 1954562236bSHarry Wentland pool->stream_enc[pool->stream_enc_count] = 1964562236bSHarry Wentland virtual_stream_encoder_create( 1974562236bSHarry Wentland ctx, ctx->dc_bios); 1984562236bSHarry Wentland if (pool->stream_enc[pool->stream_enc_count] == NULL) { 1994562236bSHarry Wentland DC_ERR("DC: failed to create stream_encoder!\n"); 2004562236bSHarry Wentland return false; 2014562236bSHarry Wentland } 2024562236bSHarry Wentland pool->stream_enc_count++; 2034562236bSHarry Wentland } 2044562236bSHarry Wentland 2054562236bSHarry Wentland dc->hwseq = create_funcs->create_hwseq(ctx); 2064562236bSHarry Wentland 2074562236bSHarry Wentland return true; 2084562236bSHarry Wentland } 2094562236bSHarry Wentland 2104562236bSHarry Wentland 2114562236bSHarry Wentland void resource_unreference_clock_source( 2124562236bSHarry Wentland struct resource_context *res_ctx, 2138c737fccSYongqiang Sun struct clock_source **clock_source) 2144562236bSHarry Wentland { 2154562236bSHarry Wentland int i; 2164562236bSHarry Wentland for (i = 0; i < res_ctx->pool->clk_src_count; i++) { 2178c737fccSYongqiang Sun if (res_ctx->pool->clock_sources[i] != *clock_source) 2184562236bSHarry Wentland continue; 2194562236bSHarry Wentland 2204562236bSHarry Wentland res_ctx->clock_source_ref_count[i]--; 2214562236bSHarry Wentland 2224562236bSHarry Wentland if (res_ctx->clock_source_ref_count[i] == 0) 2238c737fccSYongqiang Sun (*clock_source)->funcs->cs_power_down(*clock_source); 2244562236bSHarry Wentland 2254562236bSHarry Wentland break; 2264562236bSHarry Wentland } 2274562236bSHarry Wentland 2288c737fccSYongqiang Sun if (res_ctx->pool->dp_clock_source == *clock_source) { 2294562236bSHarry Wentland res_ctx->dp_clock_source_ref_count--; 2304562236bSHarry Wentland 2314562236bSHarry Wentland if (res_ctx->dp_clock_source_ref_count == 0) 2328c737fccSYongqiang Sun (*clock_source)->funcs->cs_power_down(*clock_source); 2334562236bSHarry Wentland } 2348c737fccSYongqiang Sun *clock_source = NULL; 2354562236bSHarry Wentland } 2364562236bSHarry Wentland 2374562236bSHarry Wentland void resource_reference_clock_source( 2384562236bSHarry Wentland struct resource_context *res_ctx, 2394562236bSHarry Wentland struct clock_source *clock_source) 2404562236bSHarry Wentland { 2414562236bSHarry Wentland int i; 2424562236bSHarry Wentland for (i = 0; i < res_ctx->pool->clk_src_count; i++) { 2434562236bSHarry Wentland if (res_ctx->pool->clock_sources[i] != clock_source) 2444562236bSHarry Wentland continue; 2454562236bSHarry Wentland 2464562236bSHarry Wentland res_ctx->clock_source_ref_count[i]++; 2474562236bSHarry Wentland break; 2484562236bSHarry Wentland } 2494562236bSHarry Wentland 2504562236bSHarry Wentland if (res_ctx->pool->dp_clock_source == clock_source) 2514562236bSHarry Wentland res_ctx->dp_clock_source_ref_count++; 2524562236bSHarry Wentland } 2534562236bSHarry Wentland 2544562236bSHarry Wentland bool resource_are_streams_timing_synchronizable( 2554562236bSHarry Wentland const struct core_stream *stream1, 2564562236bSHarry Wentland const struct core_stream *stream2) 2574562236bSHarry Wentland { 2584562236bSHarry Wentland if (stream1->public.timing.h_total != stream2->public.timing.h_total) 2594562236bSHarry Wentland return false; 2604562236bSHarry Wentland 2614562236bSHarry Wentland if (stream1->public.timing.v_total != stream2->public.timing.v_total) 2624562236bSHarry Wentland return false; 2634562236bSHarry Wentland 2644562236bSHarry Wentland if (stream1->public.timing.h_addressable 2654562236bSHarry Wentland != stream2->public.timing.h_addressable) 2664562236bSHarry Wentland return false; 2674562236bSHarry Wentland 2684562236bSHarry Wentland if (stream1->public.timing.v_addressable 2694562236bSHarry Wentland != stream2->public.timing.v_addressable) 2704562236bSHarry Wentland return false; 2714562236bSHarry Wentland 2724562236bSHarry Wentland if (stream1->public.timing.pix_clk_khz 2734562236bSHarry Wentland != stream2->public.timing.pix_clk_khz) 2744562236bSHarry Wentland return false; 2754562236bSHarry Wentland 2764562236bSHarry Wentland if (stream1->phy_pix_clk != stream2->phy_pix_clk 2774562236bSHarry Wentland && !dc_is_dp_signal(stream1->signal) 2784562236bSHarry Wentland && !dc_is_dp_signal(stream2->signal)) 2794562236bSHarry Wentland return false; 2804562236bSHarry Wentland 2814562236bSHarry Wentland return true; 2824562236bSHarry Wentland } 2834562236bSHarry Wentland 2844562236bSHarry Wentland static bool is_sharable_clk_src( 2854562236bSHarry Wentland const struct pipe_ctx *pipe_with_clk_src, 2864562236bSHarry Wentland const struct pipe_ctx *pipe) 2874562236bSHarry Wentland { 2884562236bSHarry Wentland if (pipe_with_clk_src->clock_source == NULL) 2894562236bSHarry Wentland return false; 2904562236bSHarry Wentland 2914562236bSHarry Wentland if (pipe_with_clk_src->stream->signal == SIGNAL_TYPE_VIRTUAL) 2924562236bSHarry Wentland return false; 2934562236bSHarry Wentland 2944562236bSHarry Wentland if (dc_is_dp_signal(pipe_with_clk_src->stream->signal)) 2954562236bSHarry Wentland return false; 2964562236bSHarry Wentland 2974562236bSHarry Wentland if (dc_is_hdmi_signal(pipe_with_clk_src->stream->signal) 2984562236bSHarry Wentland && dc_is_dvi_signal(pipe->stream->signal)) 2994562236bSHarry Wentland return false; 3004562236bSHarry Wentland 3014562236bSHarry Wentland if (dc_is_hdmi_signal(pipe->stream->signal) 3024562236bSHarry Wentland && dc_is_dvi_signal(pipe_with_clk_src->stream->signal)) 3034562236bSHarry Wentland return false; 3044562236bSHarry Wentland 3054562236bSHarry Wentland if (!resource_are_streams_timing_synchronizable( 3064562236bSHarry Wentland pipe_with_clk_src->stream, pipe->stream)) 3074562236bSHarry Wentland return false; 3084562236bSHarry Wentland 3094562236bSHarry Wentland return true; 3104562236bSHarry Wentland } 3114562236bSHarry Wentland 3124562236bSHarry Wentland struct clock_source *resource_find_used_clk_src_for_sharing( 3134562236bSHarry Wentland struct resource_context *res_ctx, 3144562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 3154562236bSHarry Wentland { 3164562236bSHarry Wentland int i; 3174562236bSHarry Wentland 3184562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 3194562236bSHarry Wentland if (is_sharable_clk_src(&res_ctx->pipe_ctx[i], pipe_ctx)) 3204562236bSHarry Wentland return res_ctx->pipe_ctx[i].clock_source; 3214562236bSHarry Wentland } 3224562236bSHarry Wentland 3234562236bSHarry Wentland return NULL; 3244562236bSHarry Wentland } 3254562236bSHarry Wentland 3264562236bSHarry Wentland static enum pixel_format convert_pixel_format_to_dalsurface( 3274562236bSHarry Wentland enum surface_pixel_format surface_pixel_format) 3284562236bSHarry Wentland { 3294562236bSHarry Wentland enum pixel_format dal_pixel_format = PIXEL_FORMAT_UNKNOWN; 3304562236bSHarry Wentland 3314562236bSHarry Wentland switch (surface_pixel_format) { 3324562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: 3334562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_INDEX8; 3344562236bSHarry Wentland break; 3354562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 3364562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_RGB565; 3374562236bSHarry Wentland break; 3384562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 3394562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_RGB565; 3404562236bSHarry Wentland break; 3414562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 3424562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_ARGB8888; 3434562236bSHarry Wentland break; 3444562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_BGRA8888: 3454562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_ARGB8888; 3464562236bSHarry Wentland break; 3474562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 3484562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_ARGB2101010; 3494562236bSHarry Wentland break; 3504562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 3514562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_ARGB2101010; 3524562236bSHarry Wentland break; 3534562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: 3544562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_ARGB2101010_XRBIAS; 3554562236bSHarry Wentland break; 3564562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 3574562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 3584562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_FP16; 3594562236bSHarry Wentland break; 3604562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: 3614562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_420BPP12; 3624562236bSHarry Wentland break; 3634562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: 3644562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_420BPP12; 3654562236bSHarry Wentland break; 3664562236bSHarry Wentland case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 3674562236bSHarry Wentland default: 3684562236bSHarry Wentland dal_pixel_format = PIXEL_FORMAT_UNKNOWN; 3694562236bSHarry Wentland break; 3704562236bSHarry Wentland } 3714562236bSHarry Wentland return dal_pixel_format; 3724562236bSHarry Wentland } 3734562236bSHarry Wentland 3744562236bSHarry Wentland static void rect_swap_helper(struct rect *rect) 3754562236bSHarry Wentland { 3764562236bSHarry Wentland uint32_t temp = 0; 3774562236bSHarry Wentland 3784562236bSHarry Wentland temp = rect->height; 3794562236bSHarry Wentland rect->height = rect->width; 3804562236bSHarry Wentland rect->width = temp; 3814562236bSHarry Wentland 3824562236bSHarry Wentland temp = rect->x; 3834562236bSHarry Wentland rect->x = rect->y; 3844562236bSHarry Wentland rect->y = temp; 3854562236bSHarry Wentland } 3864562236bSHarry Wentland 3874562236bSHarry Wentland static void calculate_viewport( 3884562236bSHarry Wentland const struct dc_surface *surface, 3894562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 3904562236bSHarry Wentland { 3914562236bSHarry Wentland struct rect stream_src = pipe_ctx->stream->public.src; 3924562236bSHarry Wentland struct rect src = surface->src_rect; 3934562236bSHarry Wentland struct rect dst = surface->dst_rect; 3944562236bSHarry Wentland struct rect surface_clip = surface->clip_rect; 3954562236bSHarry Wentland struct rect clip = {0}; 3964562236bSHarry Wentland 3974562236bSHarry Wentland 3984562236bSHarry Wentland if (surface->rotation == ROTATION_ANGLE_90 || 3994562236bSHarry Wentland surface->rotation == ROTATION_ANGLE_270) { 4004562236bSHarry Wentland rect_swap_helper(&src); 4014562236bSHarry Wentland rect_swap_helper(&dst); 4024562236bSHarry Wentland rect_swap_helper(&surface_clip); 4034562236bSHarry Wentland rect_swap_helper(&stream_src); 4044562236bSHarry Wentland } 4054562236bSHarry Wentland 4064562236bSHarry Wentland /* The actual clip is an intersection between stream 4074562236bSHarry Wentland * source and surface clip 4084562236bSHarry Wentland */ 4094562236bSHarry Wentland clip.x = stream_src.x > surface_clip.x ? 4104562236bSHarry Wentland stream_src.x : surface_clip.x; 4114562236bSHarry Wentland 4124562236bSHarry Wentland clip.width = stream_src.x + stream_src.width < 4134562236bSHarry Wentland surface_clip.x + surface_clip.width ? 4144562236bSHarry Wentland stream_src.x + stream_src.width - clip.x : 4154562236bSHarry Wentland surface_clip.x + surface_clip.width - clip.x ; 4164562236bSHarry Wentland 4174562236bSHarry Wentland clip.y = stream_src.y > surface_clip.y ? 4184562236bSHarry Wentland stream_src.y : surface_clip.y; 4194562236bSHarry Wentland 4204562236bSHarry Wentland clip.height = stream_src.y + stream_src.height < 4214562236bSHarry Wentland surface_clip.y + surface_clip.height ? 4224562236bSHarry Wentland stream_src.y + stream_src.height - clip.y : 4234562236bSHarry Wentland surface_clip.y + surface_clip.height - clip.y ; 4244562236bSHarry Wentland 4254562236bSHarry Wentland /* offset = src.ofs + (clip.ofs - dst.ofs) * scl_ratio 4264562236bSHarry Wentland * num_pixels = clip.num_pix * scl_ratio 4274562236bSHarry Wentland */ 4284562236bSHarry Wentland pipe_ctx->scl_data.viewport.x = src.x + (clip.x - dst.x) * 4294562236bSHarry Wentland src.width / dst.width; 4304562236bSHarry Wentland pipe_ctx->scl_data.viewport.width = clip.width * 4314562236bSHarry Wentland src.width / dst.width; 4324562236bSHarry Wentland 4334562236bSHarry Wentland pipe_ctx->scl_data.viewport.y = src.y + (clip.y - dst.y) * 4344562236bSHarry Wentland src.height / dst.height; 4354562236bSHarry Wentland pipe_ctx->scl_data.viewport.height = clip.height * 4364562236bSHarry Wentland src.height / dst.height; 4374562236bSHarry Wentland 4384562236bSHarry Wentland /* Minimum viewport such that 420/422 chroma vp is non 0 */ 4394562236bSHarry Wentland if (pipe_ctx->scl_data.viewport.width < 2) 4404562236bSHarry Wentland pipe_ctx->scl_data.viewport.width = 2; 4414562236bSHarry Wentland if (pipe_ctx->scl_data.viewport.height < 2) 4424562236bSHarry Wentland pipe_ctx->scl_data.viewport.height = 2; 4434562236bSHarry Wentland } 4444562236bSHarry Wentland 4454562236bSHarry Wentland static void calculate_recout( 4464562236bSHarry Wentland const struct dc_surface *surface, 4474562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 4484562236bSHarry Wentland { 4494562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 4504562236bSHarry Wentland struct rect clip = surface->clip_rect; 4514562236bSHarry Wentland 4524562236bSHarry Wentland pipe_ctx->scl_data.recout.x = stream->public.dst.x; 4534562236bSHarry Wentland if (stream->public.src.x < clip.x) 4544562236bSHarry Wentland pipe_ctx->scl_data.recout.x += (clip.x 4554562236bSHarry Wentland - stream->public.src.x) * stream->public.dst.width 4564562236bSHarry Wentland / stream->public.src.width; 4574562236bSHarry Wentland 4584562236bSHarry Wentland pipe_ctx->scl_data.recout.width = clip.width * 4594562236bSHarry Wentland stream->public.dst.width / stream->public.src.width; 4604562236bSHarry Wentland if (pipe_ctx->scl_data.recout.width + pipe_ctx->scl_data.recout.x > 4614562236bSHarry Wentland stream->public.dst.x + stream->public.dst.width) 4624562236bSHarry Wentland pipe_ctx->scl_data.recout.width = 4634562236bSHarry Wentland stream->public.dst.x + stream->public.dst.width 4644562236bSHarry Wentland - pipe_ctx->scl_data.recout.x; 4654562236bSHarry Wentland 4664562236bSHarry Wentland pipe_ctx->scl_data.recout.y = stream->public.dst.y; 4674562236bSHarry Wentland if (stream->public.src.y < clip.y) 4684562236bSHarry Wentland pipe_ctx->scl_data.recout.y += (clip.y 4694562236bSHarry Wentland - stream->public.src.y) * stream->public.dst.height 4704562236bSHarry Wentland / stream->public.src.height; 4714562236bSHarry Wentland 4724562236bSHarry Wentland pipe_ctx->scl_data.recout.height = clip.height * 4734562236bSHarry Wentland stream->public.dst.height / stream->public.src.height; 4744562236bSHarry Wentland if (pipe_ctx->scl_data.recout.height + pipe_ctx->scl_data.recout.y > 4754562236bSHarry Wentland stream->public.dst.y + stream->public.dst.height) 4764562236bSHarry Wentland pipe_ctx->scl_data.recout.height = 4774562236bSHarry Wentland stream->public.dst.y + stream->public.dst.height 4784562236bSHarry Wentland - pipe_ctx->scl_data.recout.y; 4794562236bSHarry Wentland } 4804562236bSHarry Wentland 4814562236bSHarry Wentland static void calculate_scaling_ratios( 4824562236bSHarry Wentland const struct dc_surface *surface, 4834562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 4844562236bSHarry Wentland { 4854562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 4864562236bSHarry Wentland const uint32_t in_w = stream->public.src.width; 4874562236bSHarry Wentland const uint32_t in_h = stream->public.src.height; 4884562236bSHarry Wentland const uint32_t out_w = stream->public.dst.width; 4894562236bSHarry Wentland const uint32_t out_h = stream->public.dst.height; 4904562236bSHarry Wentland 4914562236bSHarry Wentland pipe_ctx->scl_data.ratios.horz = dal_fixed31_32_from_fraction( 4924562236bSHarry Wentland surface->src_rect.width, 4934562236bSHarry Wentland surface->dst_rect.width); 4944562236bSHarry Wentland pipe_ctx->scl_data.ratios.vert = dal_fixed31_32_from_fraction( 4954562236bSHarry Wentland surface->src_rect.height, 4964562236bSHarry Wentland surface->dst_rect.height); 4974562236bSHarry Wentland 4984562236bSHarry Wentland if (surface->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE) 4994562236bSHarry Wentland pipe_ctx->scl_data.ratios.horz.value *= 2; 5004562236bSHarry Wentland else if (surface->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) 5014562236bSHarry Wentland pipe_ctx->scl_data.ratios.vert.value *= 2; 5024562236bSHarry Wentland 5034562236bSHarry Wentland pipe_ctx->scl_data.ratios.vert.value = div64_s64( 5044562236bSHarry Wentland pipe_ctx->scl_data.ratios.vert.value * in_h, out_h); 5054562236bSHarry Wentland pipe_ctx->scl_data.ratios.horz.value = div64_s64( 5064562236bSHarry Wentland pipe_ctx->scl_data.ratios.horz.value * in_w, out_w); 5074562236bSHarry Wentland 5084562236bSHarry Wentland pipe_ctx->scl_data.ratios.horz_c = pipe_ctx->scl_data.ratios.horz; 5094562236bSHarry Wentland pipe_ctx->scl_data.ratios.vert_c = pipe_ctx->scl_data.ratios.vert; 5104562236bSHarry Wentland 5114562236bSHarry Wentland if (pipe_ctx->scl_data.format == PIXEL_FORMAT_420BPP12) { 5124562236bSHarry Wentland pipe_ctx->scl_data.ratios.horz_c.value /= 2; 5134562236bSHarry Wentland pipe_ctx->scl_data.ratios.vert_c.value /= 2; 5144562236bSHarry Wentland } 5154562236bSHarry Wentland } 5164562236bSHarry Wentland 5174562236bSHarry Wentland bool resource_build_scaling_params( 5184562236bSHarry Wentland const struct dc_surface *surface, 5194562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 5204562236bSHarry Wentland { 5214562236bSHarry Wentland bool res; 5224562236bSHarry Wentland struct dc_crtc_timing *timing = &pipe_ctx->stream->public.timing; 5234562236bSHarry Wentland /* Important: scaling ratio calculation requires pixel format, 5244562236bSHarry Wentland * lb depth calculation requires recout and taps require scaling ratios. 5254562236bSHarry Wentland */ 5264562236bSHarry Wentland pipe_ctx->scl_data.format = convert_pixel_format_to_dalsurface(surface->format); 5274562236bSHarry Wentland 5284562236bSHarry Wentland calculate_viewport(surface, pipe_ctx); 5294562236bSHarry Wentland 5304562236bSHarry Wentland if (pipe_ctx->scl_data.viewport.height < 16 || pipe_ctx->scl_data.viewport.width < 16) 5314562236bSHarry Wentland return false; 5324562236bSHarry Wentland 5334562236bSHarry Wentland calculate_scaling_ratios(surface, pipe_ctx); 5344562236bSHarry Wentland 5354562236bSHarry Wentland calculate_recout(surface, pipe_ctx); 5364562236bSHarry Wentland 5374562236bSHarry Wentland /** 5384562236bSHarry Wentland * Setting line buffer pixel depth to 24bpp yields banding 5394562236bSHarry Wentland * on certain displays, such as the Sharp 4k 5404562236bSHarry Wentland */ 5414562236bSHarry Wentland pipe_ctx->scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; 5424562236bSHarry Wentland 5434562236bSHarry Wentland pipe_ctx->scl_data.h_active = timing->h_addressable; 5444562236bSHarry Wentland pipe_ctx->scl_data.v_active = timing->v_addressable; 5454562236bSHarry Wentland 5464562236bSHarry Wentland /* Taps calculations */ 5474562236bSHarry Wentland res = pipe_ctx->xfm->funcs->transform_get_optimal_number_of_taps( 5484562236bSHarry Wentland pipe_ctx->xfm, &pipe_ctx->scl_data, &surface->scaling_quality); 5494562236bSHarry Wentland 5504562236bSHarry Wentland if (!res) { 5514562236bSHarry Wentland /* Try 24 bpp linebuffer */ 5524562236bSHarry Wentland pipe_ctx->scl_data.lb_params.depth = LB_PIXEL_DEPTH_24BPP; 5534562236bSHarry Wentland 5544562236bSHarry Wentland res = pipe_ctx->xfm->funcs->transform_get_optimal_number_of_taps( 5554562236bSHarry Wentland pipe_ctx->xfm, &pipe_ctx->scl_data, &surface->scaling_quality); 5564562236bSHarry Wentland } 5574562236bSHarry Wentland 5584562236bSHarry Wentland dm_logger_write(pipe_ctx->stream->ctx->logger, LOG_SCALER, 5594562236bSHarry Wentland "%s: Viewport:\nheight:%d width:%d x:%d " 5604562236bSHarry Wentland "y:%d\n dst_rect:\nheight:%d width:%d x:%d " 5614562236bSHarry Wentland "y:%d\n", 5624562236bSHarry Wentland __func__, 5634562236bSHarry Wentland pipe_ctx->scl_data.viewport.height, 5644562236bSHarry Wentland pipe_ctx->scl_data.viewport.width, 5654562236bSHarry Wentland pipe_ctx->scl_data.viewport.x, 5664562236bSHarry Wentland pipe_ctx->scl_data.viewport.y, 5674562236bSHarry Wentland surface->dst_rect.height, 5684562236bSHarry Wentland surface->dst_rect.width, 5694562236bSHarry Wentland surface->dst_rect.x, 5704562236bSHarry Wentland surface->dst_rect.y); 5714562236bSHarry Wentland 5724562236bSHarry Wentland return res; 5734562236bSHarry Wentland } 5744562236bSHarry Wentland 5754562236bSHarry Wentland 5764562236bSHarry Wentland enum dc_status resource_build_scaling_params_for_context( 5774562236bSHarry Wentland const struct core_dc *dc, 5784562236bSHarry Wentland struct validate_context *context) 5794562236bSHarry Wentland { 5804562236bSHarry Wentland int i; 5814562236bSHarry Wentland 5824562236bSHarry Wentland for (i = 0; i < MAX_PIPES; i++) { 5834562236bSHarry Wentland if (context->res_ctx.pipe_ctx[i].surface != NULL && 5844562236bSHarry Wentland context->res_ctx.pipe_ctx[i].stream != NULL) 5854562236bSHarry Wentland if (!resource_build_scaling_params( 5864562236bSHarry Wentland &context->res_ctx.pipe_ctx[i].surface->public, 5874562236bSHarry Wentland &context->res_ctx.pipe_ctx[i])) 5884562236bSHarry Wentland return DC_FAIL_BANDWIDTH_VALIDATE; 5894562236bSHarry Wentland } 5904562236bSHarry Wentland 5914562236bSHarry Wentland return DC_OK; 5924562236bSHarry Wentland } 5934562236bSHarry Wentland 5944562236bSHarry Wentland static void detach_surfaces_for_target( 5954562236bSHarry Wentland struct validate_context *context, 5964562236bSHarry Wentland const struct dc_target *dc_target) 5974562236bSHarry Wentland { 5984562236bSHarry Wentland int i; 5994562236bSHarry Wentland struct core_stream *stream = DC_STREAM_TO_CORE(dc_target->streams[0]); 6004562236bSHarry Wentland 6014562236bSHarry Wentland for (i = 0; i < context->res_ctx.pool->pipe_count; i++) { 6024562236bSHarry Wentland struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i]; 6034562236bSHarry Wentland if (cur_pipe->stream == stream) { 6044562236bSHarry Wentland cur_pipe->surface = NULL; 6054562236bSHarry Wentland cur_pipe->top_pipe = NULL; 6064562236bSHarry Wentland cur_pipe->bottom_pipe = NULL; 6074562236bSHarry Wentland } 6084562236bSHarry Wentland } 6094562236bSHarry Wentland } 6104562236bSHarry Wentland 6114562236bSHarry Wentland struct pipe_ctx *find_idle_secondary_pipe(struct resource_context *res_ctx) 6124562236bSHarry Wentland { 6134562236bSHarry Wentland int i; 6144562236bSHarry Wentland struct pipe_ctx *secondary_pipe = NULL; 6154562236bSHarry Wentland 6164562236bSHarry Wentland /* 6174562236bSHarry Wentland * search backwards for the second pipe to keep pipe 6184562236bSHarry Wentland * assignment more consistent 6194562236bSHarry Wentland */ 6204562236bSHarry Wentland 6214562236bSHarry Wentland for (i = res_ctx->pool->pipe_count - 1; i >= 0; i--) { 6224562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream == NULL) { 6234562236bSHarry Wentland secondary_pipe = &res_ctx->pipe_ctx[i]; 6244562236bSHarry Wentland secondary_pipe->pipe_idx = i; 6254562236bSHarry Wentland break; 6264562236bSHarry Wentland } 6274562236bSHarry Wentland } 6284562236bSHarry Wentland 6294562236bSHarry Wentland 6304562236bSHarry Wentland return secondary_pipe; 6314562236bSHarry Wentland } 6324562236bSHarry Wentland 6334562236bSHarry Wentland struct pipe_ctx *resource_get_head_pipe_for_stream( 6344562236bSHarry Wentland struct resource_context *res_ctx, 6354562236bSHarry Wentland const struct core_stream *stream) 6364562236bSHarry Wentland { 6374562236bSHarry Wentland int i; 6384562236bSHarry Wentland for (i = 0; i < res_ctx->pool->pipe_count; i++) { 6394562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream == stream && 6404562236bSHarry Wentland !res_ctx->pipe_ctx[i].top_pipe) { 6414562236bSHarry Wentland return &res_ctx->pipe_ctx[i]; 6424562236bSHarry Wentland break; 6434562236bSHarry Wentland } 6444562236bSHarry Wentland } 6454562236bSHarry Wentland return NULL; 6464562236bSHarry Wentland } 6474562236bSHarry Wentland 6484562236bSHarry Wentland /* 6494562236bSHarry Wentland * A free_pipe for a target is defined here as a pipe with a stream that belongs 6504562236bSHarry Wentland * to the target but has no surface attached yet 6514562236bSHarry Wentland */ 6524562236bSHarry Wentland static struct pipe_ctx *acquire_free_pipe_for_target( 6534562236bSHarry Wentland struct resource_context *res_ctx, 6544562236bSHarry Wentland const struct dc_target *dc_target) 6554562236bSHarry Wentland { 6564562236bSHarry Wentland int i; 6574562236bSHarry Wentland struct core_stream *stream = DC_STREAM_TO_CORE(dc_target->streams[0]); 6584562236bSHarry Wentland 6594562236bSHarry Wentland struct pipe_ctx *head_pipe = NULL; 6604562236bSHarry Wentland 6614562236bSHarry Wentland /* Find head pipe, which has the back end set up*/ 6624562236bSHarry Wentland 6634562236bSHarry Wentland head_pipe = resource_get_head_pipe_for_stream(res_ctx, stream); 6644562236bSHarry Wentland 6654562236bSHarry Wentland if (!head_pipe) 6664562236bSHarry Wentland ASSERT(0); 6674562236bSHarry Wentland 6684562236bSHarry Wentland if (!head_pipe->surface) 6694562236bSHarry Wentland return head_pipe; 6704562236bSHarry Wentland 6714562236bSHarry Wentland /* Re-use pipe already acquired for this stream if available*/ 6724562236bSHarry Wentland for (i = res_ctx->pool->pipe_count - 1; i >= 0; i--) { 6734562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream == stream && 6744562236bSHarry Wentland !res_ctx->pipe_ctx[i].surface) { 6754562236bSHarry Wentland return &res_ctx->pipe_ctx[i]; 6764562236bSHarry Wentland } 6774562236bSHarry Wentland } 6784562236bSHarry Wentland 6794562236bSHarry Wentland /* 6804562236bSHarry Wentland * At this point we have no re-useable pipe for this stream and we need 6814562236bSHarry Wentland * to acquire an idle one to satisfy the request 6824562236bSHarry Wentland */ 6834562236bSHarry Wentland 6844562236bSHarry Wentland if(!res_ctx->pool->funcs->acquire_idle_pipe_for_layer) 6854562236bSHarry Wentland return NULL; 6864562236bSHarry Wentland 6874562236bSHarry Wentland return res_ctx->pool->funcs->acquire_idle_pipe_for_layer(res_ctx, stream); 6884562236bSHarry Wentland 6894562236bSHarry Wentland } 6904562236bSHarry Wentland 6914562236bSHarry Wentland static void release_free_pipes_for_target( 6924562236bSHarry Wentland struct resource_context *res_ctx, 6934562236bSHarry Wentland const struct dc_target *dc_target) 6944562236bSHarry Wentland { 6954562236bSHarry Wentland int i; 6964562236bSHarry Wentland struct core_stream *stream = DC_STREAM_TO_CORE(dc_target->streams[0]); 6974562236bSHarry Wentland 6984562236bSHarry Wentland for (i = res_ctx->pool->pipe_count - 1; i >= 0; i--) { 6994562236bSHarry Wentland if (res_ctx->pipe_ctx[i].stream == stream && 7004562236bSHarry Wentland !res_ctx->pipe_ctx[i].surface) { 7014562236bSHarry Wentland res_ctx->pipe_ctx[i].stream = NULL; 7024562236bSHarry Wentland } 7034562236bSHarry Wentland } 7044562236bSHarry Wentland } 7054562236bSHarry Wentland 7064562236bSHarry Wentland bool resource_attach_surfaces_to_context( 7074562236bSHarry Wentland const struct dc_surface * const *surfaces, 7084562236bSHarry Wentland int surface_count, 7094562236bSHarry Wentland const struct dc_target *dc_target, 7104562236bSHarry Wentland struct validate_context *context) 7114562236bSHarry Wentland { 7124562236bSHarry Wentland int i; 7134562236bSHarry Wentland struct pipe_ctx *tail_pipe; 7144562236bSHarry Wentland struct dc_target_status *target_status = NULL; 7154562236bSHarry Wentland 7164562236bSHarry Wentland 7174562236bSHarry Wentland if (surface_count > MAX_SURFACE_NUM) { 7184562236bSHarry Wentland dm_error("Surface: can not attach %d surfaces! Maximum is: %d\n", 7194562236bSHarry Wentland surface_count, MAX_SURFACE_NUM); 7204562236bSHarry Wentland return false; 7214562236bSHarry Wentland } 7224562236bSHarry Wentland 7234562236bSHarry Wentland for (i = 0; i < context->target_count; i++) 7244562236bSHarry Wentland if (&context->targets[i]->public == dc_target) { 7254562236bSHarry Wentland target_status = &context->target_status[i]; 7264562236bSHarry Wentland break; 7274562236bSHarry Wentland } 7284562236bSHarry Wentland if (target_status == NULL) { 7294562236bSHarry Wentland dm_error("Existing target not found; failed to attach surfaces\n"); 7304562236bSHarry Wentland return false; 7314562236bSHarry Wentland } 7324562236bSHarry Wentland 7334562236bSHarry Wentland /* retain new surfaces */ 7344562236bSHarry Wentland for (i = 0; i < surface_count; i++) 7354562236bSHarry Wentland dc_surface_retain(surfaces[i]); 7364562236bSHarry Wentland 7374562236bSHarry Wentland detach_surfaces_for_target(context, dc_target); 7384562236bSHarry Wentland 7394562236bSHarry Wentland /* release existing surfaces*/ 7404562236bSHarry Wentland for (i = 0; i < target_status->surface_count; i++) 7414562236bSHarry Wentland dc_surface_release(target_status->surfaces[i]); 7424562236bSHarry Wentland 7434562236bSHarry Wentland for (i = surface_count; i < target_status->surface_count; i++) 7444562236bSHarry Wentland target_status->surfaces[i] = NULL; 7454562236bSHarry Wentland 7464562236bSHarry Wentland target_status->surface_count = 0; 7474562236bSHarry Wentland 7484562236bSHarry Wentland if (surface_count == 0) 7494562236bSHarry Wentland return true; 7504562236bSHarry Wentland 7514562236bSHarry Wentland tail_pipe = NULL; 7524562236bSHarry Wentland for (i = 0; i < surface_count; i++) { 7534562236bSHarry Wentland struct core_surface *surface = DC_SURFACE_TO_CORE(surfaces[i]); 7544562236bSHarry Wentland struct pipe_ctx *free_pipe = acquire_free_pipe_for_target( 7554562236bSHarry Wentland &context->res_ctx, dc_target); 7564562236bSHarry Wentland 7574562236bSHarry Wentland if (!free_pipe) { 7584562236bSHarry Wentland target_status->surfaces[i] = NULL; 7594562236bSHarry Wentland return false; 7604562236bSHarry Wentland } 7614562236bSHarry Wentland 7624562236bSHarry Wentland free_pipe->surface = surface; 7634562236bSHarry Wentland 7644562236bSHarry Wentland if (tail_pipe) { 7654562236bSHarry Wentland free_pipe->top_pipe = tail_pipe; 7664562236bSHarry Wentland tail_pipe->bottom_pipe = free_pipe; 7674562236bSHarry Wentland } 7684562236bSHarry Wentland 7694562236bSHarry Wentland tail_pipe = free_pipe; 7704562236bSHarry Wentland } 7714562236bSHarry Wentland 7724562236bSHarry Wentland release_free_pipes_for_target(&context->res_ctx, dc_target); 7734562236bSHarry Wentland 7744562236bSHarry Wentland /* assign new surfaces*/ 7754562236bSHarry Wentland for (i = 0; i < surface_count; i++) 7764562236bSHarry Wentland target_status->surfaces[i] = surfaces[i]; 7774562236bSHarry Wentland 7784562236bSHarry Wentland target_status->surface_count = surface_count; 7794562236bSHarry Wentland 7804562236bSHarry Wentland return true; 7814562236bSHarry Wentland } 7824562236bSHarry Wentland 7834562236bSHarry Wentland 7844562236bSHarry Wentland static bool is_timing_changed(const struct core_stream *cur_stream, 7854562236bSHarry Wentland const struct core_stream *new_stream) 7864562236bSHarry Wentland { 7874562236bSHarry Wentland if (cur_stream == NULL) 7884562236bSHarry Wentland return true; 7894562236bSHarry Wentland 7904562236bSHarry Wentland /* If sink pointer changed, it means this is a hotplug, we should do 7914562236bSHarry Wentland * full hw setting. 7924562236bSHarry Wentland */ 7934562236bSHarry Wentland if (cur_stream->sink != new_stream->sink) 7944562236bSHarry Wentland return true; 7954562236bSHarry Wentland 7964562236bSHarry Wentland /* If output color space is changed, need to reprogram info frames */ 7974562236bSHarry Wentland if (cur_stream->public.output_color_space != 7984562236bSHarry Wentland new_stream->public.output_color_space) 7994562236bSHarry Wentland return true; 8004562236bSHarry Wentland 8014562236bSHarry Wentland return memcmp( 8024562236bSHarry Wentland &cur_stream->public.timing, 8034562236bSHarry Wentland &new_stream->public.timing, 8044562236bSHarry Wentland sizeof(struct dc_crtc_timing)) != 0; 8054562236bSHarry Wentland } 8064562236bSHarry Wentland 8074562236bSHarry Wentland static bool are_stream_backends_same( 8084562236bSHarry Wentland const struct core_stream *stream_a, const struct core_stream *stream_b) 8094562236bSHarry Wentland { 8104562236bSHarry Wentland if (stream_a == stream_b) 8114562236bSHarry Wentland return true; 8124562236bSHarry Wentland 8134562236bSHarry Wentland if (stream_a == NULL || stream_b == NULL) 8144562236bSHarry Wentland return false; 8154562236bSHarry Wentland 8164562236bSHarry Wentland if (is_timing_changed(stream_a, stream_b)) 8174562236bSHarry Wentland return false; 8184562236bSHarry Wentland 8194562236bSHarry Wentland return true; 8204562236bSHarry Wentland } 8214562236bSHarry Wentland 8224562236bSHarry Wentland bool is_target_unchanged( 8234562236bSHarry Wentland const struct core_target *old_target, const struct core_target *target) 8244562236bSHarry Wentland { 8254562236bSHarry Wentland int i; 8264562236bSHarry Wentland 8274562236bSHarry Wentland if (old_target == target) 8284562236bSHarry Wentland return true; 8294562236bSHarry Wentland if (old_target->public.stream_count != target->public.stream_count) 8304562236bSHarry Wentland return false; 8314562236bSHarry Wentland 8324562236bSHarry Wentland for (i = 0; i < old_target->public.stream_count; i++) { 8334562236bSHarry Wentland const struct core_stream *old_stream = DC_STREAM_TO_CORE( 8344562236bSHarry Wentland old_target->public.streams[i]); 8354562236bSHarry Wentland const struct core_stream *stream = DC_STREAM_TO_CORE( 8364562236bSHarry Wentland target->public.streams[i]); 8374562236bSHarry Wentland 8384562236bSHarry Wentland if (!are_stream_backends_same(old_stream, stream)) 8394562236bSHarry Wentland return false; 8404562236bSHarry Wentland } 8414562236bSHarry Wentland 8424562236bSHarry Wentland return true; 8434562236bSHarry Wentland } 8444562236bSHarry Wentland 8454562236bSHarry Wentland bool resource_validate_attach_surfaces( 8464562236bSHarry Wentland const struct dc_validation_set set[], 8474562236bSHarry Wentland int set_count, 8484562236bSHarry Wentland const struct validate_context *old_context, 8494562236bSHarry Wentland struct validate_context *context) 8504562236bSHarry Wentland { 8514562236bSHarry Wentland int i, j; 8524562236bSHarry Wentland 8534562236bSHarry Wentland for (i = 0; i < set_count; i++) { 8544562236bSHarry Wentland for (j = 0; j < old_context->target_count; j++) 8554562236bSHarry Wentland if (is_target_unchanged( 8564562236bSHarry Wentland old_context->targets[j], 8574562236bSHarry Wentland context->targets[i])) { 8584562236bSHarry Wentland if (!resource_attach_surfaces_to_context( 8594562236bSHarry Wentland old_context->target_status[j].surfaces, 8604562236bSHarry Wentland old_context->target_status[j].surface_count, 8614562236bSHarry Wentland &context->targets[i]->public, 8624562236bSHarry Wentland context)) 8634562236bSHarry Wentland return false; 8644562236bSHarry Wentland context->target_status[i] = old_context->target_status[j]; 8654562236bSHarry Wentland } 8664562236bSHarry Wentland if (set[i].surface_count != 0) 8674562236bSHarry Wentland if (!resource_attach_surfaces_to_context( 8684562236bSHarry Wentland set[i].surfaces, 8694562236bSHarry Wentland set[i].surface_count, 8704562236bSHarry Wentland &context->targets[i]->public, 8714562236bSHarry Wentland context)) 8724562236bSHarry Wentland return false; 8734562236bSHarry Wentland 8744562236bSHarry Wentland } 8754562236bSHarry Wentland 8764562236bSHarry Wentland return true; 8774562236bSHarry Wentland } 8784562236bSHarry Wentland 8794562236bSHarry Wentland /* Maximum TMDS single link pixel clock 165MHz */ 8804562236bSHarry Wentland #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 8814562236bSHarry Wentland 8824562236bSHarry Wentland static void set_stream_engine_in_use( 8834562236bSHarry Wentland struct resource_context *res_ctx, 8844562236bSHarry Wentland struct stream_encoder *stream_enc) 8854562236bSHarry Wentland { 8864562236bSHarry Wentland int i; 8874562236bSHarry Wentland 8884562236bSHarry Wentland for (i = 0; i < res_ctx->pool->stream_enc_count; i++) { 8894562236bSHarry Wentland if (res_ctx->pool->stream_enc[i] == stream_enc) 8904562236bSHarry Wentland res_ctx->is_stream_enc_acquired[i] = true; 8914562236bSHarry Wentland } 8924562236bSHarry Wentland } 8934562236bSHarry Wentland 8944562236bSHarry Wentland /* TODO: release audio object */ 8954562236bSHarry Wentland static void set_audio_in_use( 8964562236bSHarry Wentland struct resource_context *res_ctx, 8974562236bSHarry Wentland struct audio *audio) 8984562236bSHarry Wentland { 8994562236bSHarry Wentland int i; 9004562236bSHarry Wentland for (i = 0; i < res_ctx->pool->audio_count; i++) { 9014562236bSHarry Wentland if (res_ctx->pool->audios[i] == audio) { 9024562236bSHarry Wentland res_ctx->is_audio_acquired[i] = true; 9034562236bSHarry Wentland } 9044562236bSHarry Wentland } 9054562236bSHarry Wentland } 9064562236bSHarry Wentland 9074562236bSHarry Wentland static int acquire_first_free_pipe( 9084562236bSHarry Wentland struct resource_context *res_ctx, 9094562236bSHarry Wentland struct core_stream *stream) 9104562236bSHarry Wentland { 9114562236bSHarry Wentland int i; 9124562236bSHarry Wentland 9134562236bSHarry Wentland for (i = 0; i < res_ctx->pool->pipe_count; i++) { 9144562236bSHarry Wentland if (!res_ctx->pipe_ctx[i].stream) { 9154562236bSHarry Wentland struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; 9164562236bSHarry Wentland 9174562236bSHarry Wentland pipe_ctx->tg = res_ctx->pool->timing_generators[i]; 9184562236bSHarry Wentland pipe_ctx->mi = res_ctx->pool->mis[i]; 9194562236bSHarry Wentland pipe_ctx->ipp = res_ctx->pool->ipps[i]; 9204562236bSHarry Wentland pipe_ctx->xfm = res_ctx->pool->transforms[i]; 9214562236bSHarry Wentland pipe_ctx->opp = res_ctx->pool->opps[i]; 9224562236bSHarry Wentland pipe_ctx->dis_clk = res_ctx->pool->display_clock; 9234562236bSHarry Wentland pipe_ctx->pipe_idx = i; 9244562236bSHarry Wentland 9254562236bSHarry Wentland pipe_ctx->stream = stream; 9264562236bSHarry Wentland return i; 9274562236bSHarry Wentland } 9284562236bSHarry Wentland } 9294562236bSHarry Wentland return -1; 9304562236bSHarry Wentland } 9314562236bSHarry Wentland 9324562236bSHarry Wentland static struct stream_encoder *find_first_free_match_stream_enc_for_link( 9334562236bSHarry Wentland struct resource_context *res_ctx, 9344562236bSHarry Wentland struct core_stream *stream) 9354562236bSHarry Wentland { 9364562236bSHarry Wentland int i; 9374562236bSHarry Wentland int j = -1; 9384562236bSHarry Wentland struct core_link *link = stream->sink->link; 9394562236bSHarry Wentland 9404562236bSHarry Wentland for (i = 0; i < res_ctx->pool->stream_enc_count; i++) { 9414562236bSHarry Wentland if (!res_ctx->is_stream_enc_acquired[i] && 9424562236bSHarry Wentland res_ctx->pool->stream_enc[i]) { 9434562236bSHarry Wentland /* Store first available for MST second display 9444562236bSHarry Wentland * in daisy chain use case */ 9454562236bSHarry Wentland j = i; 9464562236bSHarry Wentland if (res_ctx->pool->stream_enc[i]->id == 9474562236bSHarry Wentland link->link_enc->preferred_engine) 9484562236bSHarry Wentland return res_ctx->pool->stream_enc[i]; 9494562236bSHarry Wentland } 9504562236bSHarry Wentland } 9514562236bSHarry Wentland 9524562236bSHarry Wentland /* 9534562236bSHarry Wentland * below can happen in cases when stream encoder is acquired: 9544562236bSHarry Wentland * 1) for second MST display in chain, so preferred engine already 9554562236bSHarry Wentland * acquired; 9564562236bSHarry Wentland * 2) for another link, which preferred engine already acquired by any 9574562236bSHarry Wentland * MST configuration. 9584562236bSHarry Wentland * 9594562236bSHarry Wentland * If signal is of DP type and preferred engine not found, return last available 9604562236bSHarry Wentland * 9614562236bSHarry Wentland * TODO - This is just a patch up and a generic solution is 9624562236bSHarry Wentland * required for non DP connectors. 9634562236bSHarry Wentland */ 9644562236bSHarry Wentland 9654562236bSHarry Wentland if (j >= 0 && dc_is_dp_signal(stream->signal)) 9664562236bSHarry Wentland return res_ctx->pool->stream_enc[j]; 9674562236bSHarry Wentland 9684562236bSHarry Wentland return NULL; 9694562236bSHarry Wentland } 9704562236bSHarry Wentland 9714562236bSHarry Wentland static struct audio *find_first_free_audio(struct resource_context *res_ctx) 9724562236bSHarry Wentland { 9734562236bSHarry Wentland int i; 9744562236bSHarry Wentland for (i = 0; i < res_ctx->pool->audio_count; i++) { 9754562236bSHarry Wentland if (res_ctx->is_audio_acquired[i] == false) { 9764562236bSHarry Wentland return res_ctx->pool->audios[i]; 9774562236bSHarry Wentland } 9784562236bSHarry Wentland } 9794562236bSHarry Wentland 9804562236bSHarry Wentland return 0; 9814562236bSHarry Wentland } 9824562236bSHarry Wentland 9834562236bSHarry Wentland static void update_stream_signal(struct core_stream *stream) 9844562236bSHarry Wentland { 9854562236bSHarry Wentland const struct dc_sink *dc_sink = stream->public.sink; 9864562236bSHarry Wentland 9872796eaeeSJoshua Aberback if (dc_sink->sink_signal == SIGNAL_TYPE_NONE) 9882796eaeeSJoshua Aberback stream->signal = stream->sink->link->public.connector_signal; 9892796eaeeSJoshua Aberback else if (dc_sink->sink_signal == SIGNAL_TYPE_DVI_SINGLE_LINK || 9902796eaeeSJoshua Aberback dc_sink->sink_signal == SIGNAL_TYPE_DVI_DUAL_LINK) 9914562236bSHarry Wentland /* For asic supports dual link DVI, we should adjust signal type 9924562236bSHarry Wentland * based on timing pixel clock. If pixel clock more than 165Mhz, 9934562236bSHarry Wentland * signal is dual link, otherwise, single link. 9944562236bSHarry Wentland */ 9952796eaeeSJoshua Aberback if (stream->public.timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK_IN_KHZ) 9964562236bSHarry Wentland stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK; 9974562236bSHarry Wentland else 9984562236bSHarry Wentland stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK; 9992796eaeeSJoshua Aberback else 10002796eaeeSJoshua Aberback stream->signal = dc_sink->sink_signal; 10014562236bSHarry Wentland } 10024562236bSHarry Wentland 10034562236bSHarry Wentland bool resource_is_stream_unchanged( 10044562236bSHarry Wentland const struct validate_context *old_context, struct core_stream *stream) 10054562236bSHarry Wentland { 10064562236bSHarry Wentland int i, j; 10074562236bSHarry Wentland 10084562236bSHarry Wentland for (i = 0; i < old_context->target_count; i++) { 10094562236bSHarry Wentland struct core_target *old_target = old_context->targets[i]; 10104562236bSHarry Wentland 10114562236bSHarry Wentland for (j = 0; j < old_target->public.stream_count; j++) { 10124562236bSHarry Wentland struct core_stream *old_stream = 10134562236bSHarry Wentland DC_STREAM_TO_CORE(old_target->public.streams[j]); 10144562236bSHarry Wentland 10154562236bSHarry Wentland if (are_stream_backends_same(old_stream, stream)) 10164562236bSHarry Wentland return true; 10174562236bSHarry Wentland } 10184562236bSHarry Wentland } 10194562236bSHarry Wentland 10204562236bSHarry Wentland return false; 10214562236bSHarry Wentland } 10224562236bSHarry Wentland 10234562236bSHarry Wentland static void copy_pipe_ctx( 10244562236bSHarry Wentland const struct pipe_ctx *from_pipe_ctx, struct pipe_ctx *to_pipe_ctx) 10254562236bSHarry Wentland { 10264562236bSHarry Wentland struct core_surface *surface = to_pipe_ctx->surface; 10274562236bSHarry Wentland struct core_stream *stream = to_pipe_ctx->stream; 10284562236bSHarry Wentland 10294562236bSHarry Wentland *to_pipe_ctx = *from_pipe_ctx; 10304562236bSHarry Wentland to_pipe_ctx->stream = stream; 10314562236bSHarry Wentland if (surface != NULL) 10324562236bSHarry Wentland to_pipe_ctx->surface = surface; 10334562236bSHarry Wentland } 10344562236bSHarry Wentland 10354562236bSHarry Wentland static struct core_stream *find_pll_sharable_stream( 10364562236bSHarry Wentland const struct core_stream *stream_needs_pll, 10374562236bSHarry Wentland struct validate_context *context) 10384562236bSHarry Wentland { 10394562236bSHarry Wentland int i, j; 10404562236bSHarry Wentland 10414562236bSHarry Wentland for (i = 0; i < context->target_count; i++) { 10424562236bSHarry Wentland struct core_target *target = context->targets[i]; 10434562236bSHarry Wentland 10444562236bSHarry Wentland for (j = 0; j < target->public.stream_count; j++) { 10454562236bSHarry Wentland struct core_stream *stream_has_pll = 10464562236bSHarry Wentland DC_STREAM_TO_CORE(target->public.streams[j]); 10474562236bSHarry Wentland 10484562236bSHarry Wentland /* We are looking for non dp, non virtual stream */ 10494562236bSHarry Wentland if (resource_are_streams_timing_synchronizable( 10504562236bSHarry Wentland stream_needs_pll, stream_has_pll) 10514562236bSHarry Wentland && !dc_is_dp_signal(stream_has_pll->signal) 10524562236bSHarry Wentland && stream_has_pll->sink->link->public.connector_signal 10534562236bSHarry Wentland != SIGNAL_TYPE_VIRTUAL) 10544562236bSHarry Wentland return stream_has_pll; 10554562236bSHarry Wentland } 10564562236bSHarry Wentland } 10574562236bSHarry Wentland 10584562236bSHarry Wentland return NULL; 10594562236bSHarry Wentland } 10604562236bSHarry Wentland 10614562236bSHarry Wentland static int get_norm_pix_clk(const struct dc_crtc_timing *timing) 10624562236bSHarry Wentland { 10634562236bSHarry Wentland uint32_t pix_clk = timing->pix_clk_khz; 10644562236bSHarry Wentland uint32_t normalized_pix_clk = pix_clk; 10654562236bSHarry Wentland 10664562236bSHarry Wentland if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) 10674562236bSHarry Wentland pix_clk /= 2; 10684562236bSHarry Wentland 10694562236bSHarry Wentland switch (timing->display_color_depth) { 10704562236bSHarry Wentland case COLOR_DEPTH_888: 10714562236bSHarry Wentland normalized_pix_clk = pix_clk; 10724562236bSHarry Wentland break; 10734562236bSHarry Wentland case COLOR_DEPTH_101010: 10744562236bSHarry Wentland normalized_pix_clk = (pix_clk * 30) / 24; 10754562236bSHarry Wentland break; 10764562236bSHarry Wentland case COLOR_DEPTH_121212: 10774562236bSHarry Wentland normalized_pix_clk = (pix_clk * 36) / 24; 10784562236bSHarry Wentland break; 10794562236bSHarry Wentland case COLOR_DEPTH_161616: 10804562236bSHarry Wentland normalized_pix_clk = (pix_clk * 48) / 24; 10814562236bSHarry Wentland break; 10824562236bSHarry Wentland default: 10834562236bSHarry Wentland ASSERT(0); 10844562236bSHarry Wentland break; 10854562236bSHarry Wentland } 10864562236bSHarry Wentland 10874562236bSHarry Wentland return normalized_pix_clk; 10884562236bSHarry Wentland } 10894562236bSHarry Wentland 10904562236bSHarry Wentland static void calculate_phy_pix_clks( 10914562236bSHarry Wentland const struct core_dc *dc, 10924562236bSHarry Wentland struct validate_context *context) 10934562236bSHarry Wentland { 10944562236bSHarry Wentland int i, j; 10954562236bSHarry Wentland 10964562236bSHarry Wentland for (i = 0; i < context->target_count; i++) { 10974562236bSHarry Wentland struct core_target *target = context->targets[i]; 10984562236bSHarry Wentland 10994562236bSHarry Wentland for (j = 0; j < target->public.stream_count; j++) { 11004562236bSHarry Wentland struct core_stream *stream = 11014562236bSHarry Wentland DC_STREAM_TO_CORE(target->public.streams[j]); 11024562236bSHarry Wentland 11034562236bSHarry Wentland update_stream_signal(stream); 11044562236bSHarry Wentland 11054562236bSHarry Wentland /* update actual pixel clock on all streams */ 11064562236bSHarry Wentland if (dc_is_hdmi_signal(stream->signal)) 11074562236bSHarry Wentland stream->phy_pix_clk = get_norm_pix_clk( 11084562236bSHarry Wentland &stream->public.timing); 11094562236bSHarry Wentland else 11104562236bSHarry Wentland stream->phy_pix_clk = 11114562236bSHarry Wentland stream->public.timing.pix_clk_khz; 11124562236bSHarry Wentland } 11134562236bSHarry Wentland } 11144562236bSHarry Wentland } 11154562236bSHarry Wentland 11164562236bSHarry Wentland enum dc_status resource_map_pool_resources( 11174562236bSHarry Wentland const struct core_dc *dc, 11184562236bSHarry Wentland struct validate_context *context) 11194562236bSHarry Wentland { 11204562236bSHarry Wentland int i, j, k; 11214562236bSHarry Wentland 11224562236bSHarry Wentland calculate_phy_pix_clks(dc, context); 11234562236bSHarry Wentland 11244562236bSHarry Wentland for (i = 0; i < context->target_count; i++) { 11254562236bSHarry Wentland struct core_target *target = context->targets[i]; 11264562236bSHarry Wentland 11274562236bSHarry Wentland for (j = 0; j < target->public.stream_count; j++) { 11284562236bSHarry Wentland struct core_stream *stream = 11294562236bSHarry Wentland DC_STREAM_TO_CORE(target->public.streams[j]); 11304562236bSHarry Wentland 11314562236bSHarry Wentland if (!resource_is_stream_unchanged(dc->current_context, stream)) 11324562236bSHarry Wentland continue; 11334562236bSHarry Wentland 11344562236bSHarry Wentland /* mark resources used for stream that is already active */ 11354562236bSHarry Wentland for (k = 0; k < MAX_PIPES; k++) { 11364562236bSHarry Wentland struct pipe_ctx *pipe_ctx = 11374562236bSHarry Wentland &context->res_ctx.pipe_ctx[k]; 11384562236bSHarry Wentland const struct pipe_ctx *old_pipe_ctx = 11394562236bSHarry Wentland &dc->current_context->res_ctx.pipe_ctx[k]; 11404562236bSHarry Wentland 11414562236bSHarry Wentland if (!are_stream_backends_same(old_pipe_ctx->stream, stream)) 11424562236bSHarry Wentland continue; 11434562236bSHarry Wentland 11444562236bSHarry Wentland pipe_ctx->stream = stream; 11454562236bSHarry Wentland copy_pipe_ctx(old_pipe_ctx, pipe_ctx); 11464562236bSHarry Wentland 11478c737fccSYongqiang Sun /* Split pipe resource, do not acquire back end */ 11488c737fccSYongqiang Sun if (!pipe_ctx->stream_enc) 11498c737fccSYongqiang Sun continue; 11508c737fccSYongqiang Sun 11514562236bSHarry Wentland set_stream_engine_in_use( 11524562236bSHarry Wentland &context->res_ctx, 11534562236bSHarry Wentland pipe_ctx->stream_enc); 11544562236bSHarry Wentland 11554562236bSHarry Wentland /* Switch to dp clock source only if there is 11564562236bSHarry Wentland * no non dp stream that shares the same timing 11574562236bSHarry Wentland * with the dp stream. 11584562236bSHarry Wentland */ 11594562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal) && 11604562236bSHarry Wentland !find_pll_sharable_stream(stream, context)) 11614562236bSHarry Wentland pipe_ctx->clock_source = 11624562236bSHarry Wentland context->res_ctx.pool->dp_clock_source; 11634562236bSHarry Wentland 11644562236bSHarry Wentland resource_reference_clock_source( 11654562236bSHarry Wentland &context->res_ctx, 11664562236bSHarry Wentland pipe_ctx->clock_source); 11674562236bSHarry Wentland 11684562236bSHarry Wentland set_audio_in_use(&context->res_ctx, 11694562236bSHarry Wentland pipe_ctx->audio); 11704562236bSHarry Wentland } 11714562236bSHarry Wentland } 11724562236bSHarry Wentland } 11734562236bSHarry Wentland 11744562236bSHarry Wentland for (i = 0; i < context->target_count; i++) { 11754562236bSHarry Wentland struct core_target *target = context->targets[i]; 11764562236bSHarry Wentland 11774562236bSHarry Wentland for (j = 0; j < target->public.stream_count; j++) { 11784562236bSHarry Wentland struct core_stream *stream = 11794562236bSHarry Wentland DC_STREAM_TO_CORE(target->public.streams[j]); 11804562236bSHarry Wentland struct pipe_ctx *pipe_ctx = NULL; 11814562236bSHarry Wentland int pipe_idx = -1; 11824562236bSHarry Wentland 11834562236bSHarry Wentland if (resource_is_stream_unchanged(dc->current_context, stream)) 11844562236bSHarry Wentland continue; 11854562236bSHarry Wentland /* acquire new resources */ 11864562236bSHarry Wentland pipe_idx = acquire_first_free_pipe( 11874562236bSHarry Wentland &context->res_ctx, stream); 11884562236bSHarry Wentland if (pipe_idx < 0) 11894562236bSHarry Wentland return DC_NO_CONTROLLER_RESOURCE; 11904562236bSHarry Wentland 11914562236bSHarry Wentland 11924562236bSHarry Wentland pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 11934562236bSHarry Wentland 11944562236bSHarry Wentland pipe_ctx->stream_enc = 11954562236bSHarry Wentland find_first_free_match_stream_enc_for_link( 11964562236bSHarry Wentland &context->res_ctx, stream); 11974562236bSHarry Wentland 11984562236bSHarry Wentland if (!pipe_ctx->stream_enc) 11994562236bSHarry Wentland return DC_NO_STREAM_ENG_RESOURCE; 12004562236bSHarry Wentland 12014562236bSHarry Wentland set_stream_engine_in_use( 12024562236bSHarry Wentland &context->res_ctx, 12034562236bSHarry Wentland pipe_ctx->stream_enc); 12044562236bSHarry Wentland 12054562236bSHarry Wentland /* TODO: Add check if ASIC support and EDID audio */ 12064562236bSHarry Wentland if (!stream->sink->converter_disable_audio && 12074562236bSHarry Wentland dc_is_audio_capable_signal(pipe_ctx->stream->signal) && 12084562236bSHarry Wentland stream->public.audio_info.mode_count) { 12094562236bSHarry Wentland pipe_ctx->audio = find_first_free_audio( 12104562236bSHarry Wentland &context->res_ctx); 12114562236bSHarry Wentland 12124562236bSHarry Wentland /* 12134562236bSHarry Wentland * Audio assigned in order first come first get. 12144562236bSHarry Wentland * There are asics which has number of audio 12154562236bSHarry Wentland * resources less then number of pipes 12164562236bSHarry Wentland */ 12174562236bSHarry Wentland if (pipe_ctx->audio) 12184562236bSHarry Wentland set_audio_in_use( 12194562236bSHarry Wentland &context->res_ctx, 12204562236bSHarry Wentland pipe_ctx->audio); 12214562236bSHarry Wentland } 12224562236bSHarry Wentland 12234562236bSHarry Wentland if (j == 0) { 12244562236bSHarry Wentland context->target_status[i].primary_otg_inst = 12254562236bSHarry Wentland pipe_ctx->tg->inst; 12264562236bSHarry Wentland } 12274562236bSHarry Wentland } 12284562236bSHarry Wentland } 12294562236bSHarry Wentland 12304562236bSHarry Wentland return DC_OK; 12314562236bSHarry Wentland } 12324562236bSHarry Wentland 12334562236bSHarry Wentland /* first target in the context is used to populate the rest */ 12344562236bSHarry Wentland void validate_guaranteed_copy_target( 12354562236bSHarry Wentland struct validate_context *context, 12364562236bSHarry Wentland int max_targets) 12374562236bSHarry Wentland { 12384562236bSHarry Wentland int i; 12394562236bSHarry Wentland 12404562236bSHarry Wentland for (i = 1; i < max_targets; i++) { 12414562236bSHarry Wentland context->targets[i] = context->targets[0]; 12424562236bSHarry Wentland 12434562236bSHarry Wentland copy_pipe_ctx(&context->res_ctx.pipe_ctx[0], 12444562236bSHarry Wentland &context->res_ctx.pipe_ctx[i]); 12454562236bSHarry Wentland context->res_ctx.pipe_ctx[i].stream = 12464562236bSHarry Wentland context->res_ctx.pipe_ctx[0].stream; 12474562236bSHarry Wentland 12484562236bSHarry Wentland dc_target_retain(&context->targets[i]->public); 12494562236bSHarry Wentland context->target_count++; 12504562236bSHarry Wentland } 12514562236bSHarry Wentland } 12524562236bSHarry Wentland 12534562236bSHarry Wentland static void translate_info_frame(const struct hw_info_frame *hw_info_frame, 12544562236bSHarry Wentland struct encoder_info_frame *encoder_info_frame) 12554562236bSHarry Wentland { 12564562236bSHarry Wentland memset( 12574562236bSHarry Wentland encoder_info_frame, 0, sizeof(struct encoder_info_frame)); 12584562236bSHarry Wentland 12594562236bSHarry Wentland /* For gamut we recalc checksum */ 12604562236bSHarry Wentland if (hw_info_frame->gamut_packet.valid) { 12614562236bSHarry Wentland uint8_t chk_sum = 0; 12624562236bSHarry Wentland uint8_t *ptr; 12634562236bSHarry Wentland uint8_t i; 12644562236bSHarry Wentland 12654562236bSHarry Wentland memmove( 12664562236bSHarry Wentland &encoder_info_frame->gamut, 12674562236bSHarry Wentland &hw_info_frame->gamut_packet, 12684562236bSHarry Wentland sizeof(struct hw_info_packet)); 12694562236bSHarry Wentland 12704562236bSHarry Wentland /*start of the Gamut data. */ 12714562236bSHarry Wentland ptr = &encoder_info_frame->gamut.sb[3]; 12724562236bSHarry Wentland 12734562236bSHarry Wentland for (i = 0; i <= encoder_info_frame->gamut.sb[1]; i++) 12744562236bSHarry Wentland chk_sum += ptr[i]; 12754562236bSHarry Wentland 12764562236bSHarry Wentland encoder_info_frame->gamut.sb[2] = (uint8_t) (0x100 - chk_sum); 12774562236bSHarry Wentland } 12784562236bSHarry Wentland 12794562236bSHarry Wentland if (hw_info_frame->avi_info_packet.valid) { 12804562236bSHarry Wentland memmove( 12814562236bSHarry Wentland &encoder_info_frame->avi, 12824562236bSHarry Wentland &hw_info_frame->avi_info_packet, 12834562236bSHarry Wentland sizeof(struct hw_info_packet)); 12844562236bSHarry Wentland } 12854562236bSHarry Wentland 12864562236bSHarry Wentland if (hw_info_frame->vendor_info_packet.valid) { 12874562236bSHarry Wentland memmove( 12884562236bSHarry Wentland &encoder_info_frame->vendor, 12894562236bSHarry Wentland &hw_info_frame->vendor_info_packet, 12904562236bSHarry Wentland sizeof(struct hw_info_packet)); 12914562236bSHarry Wentland } 12924562236bSHarry Wentland 12934562236bSHarry Wentland if (hw_info_frame->spd_packet.valid) { 12944562236bSHarry Wentland memmove( 12954562236bSHarry Wentland &encoder_info_frame->spd, 12964562236bSHarry Wentland &hw_info_frame->spd_packet, 12974562236bSHarry Wentland sizeof(struct hw_info_packet)); 12984562236bSHarry Wentland } 12994562236bSHarry Wentland 13004562236bSHarry Wentland if (hw_info_frame->vsc_packet.valid) { 13014562236bSHarry Wentland memmove( 13024562236bSHarry Wentland &encoder_info_frame->vsc, 13034562236bSHarry Wentland &hw_info_frame->vsc_packet, 13044562236bSHarry Wentland sizeof(struct hw_info_packet)); 13054562236bSHarry Wentland } 13061646a6feSAndrew Wong 13071646a6feSAndrew Wong if (hw_info_frame->hdrsmd_packet.valid) { 13081646a6feSAndrew Wong memmove( 13091646a6feSAndrew Wong &encoder_info_frame->hdrsmd, 13101646a6feSAndrew Wong &hw_info_frame->hdrsmd_packet, 13111646a6feSAndrew Wong sizeof(struct hw_info_packet)); 13121646a6feSAndrew Wong } 13134562236bSHarry Wentland } 13144562236bSHarry Wentland 13154562236bSHarry Wentland static void set_avi_info_frame( 13164562236bSHarry Wentland struct hw_info_packet *info_packet, 13174562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 13184562236bSHarry Wentland { 13194562236bSHarry Wentland struct core_stream *stream = pipe_ctx->stream; 13204562236bSHarry Wentland enum dc_color_space color_space = COLOR_SPACE_UNKNOWN; 13214562236bSHarry Wentland struct info_frame info_frame = { {0} }; 13224562236bSHarry Wentland uint32_t pixel_encoding = 0; 13234562236bSHarry Wentland enum scanning_type scan_type = SCANNING_TYPE_NODATA; 13244562236bSHarry Wentland enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA; 13254562236bSHarry Wentland bool itc = false; 13264562236bSHarry Wentland uint8_t cn0_cn1 = 0; 13274562236bSHarry Wentland uint8_t *check_sum = NULL; 13284562236bSHarry Wentland uint8_t byte_index = 0; 13294562236bSHarry Wentland 13304562236bSHarry Wentland if (info_packet == NULL) 13314562236bSHarry Wentland return; 13324562236bSHarry Wentland 13334562236bSHarry Wentland color_space = pipe_ctx->stream->public.output_color_space; 13344562236bSHarry Wentland 13354562236bSHarry Wentland /* Initialize header */ 13364562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.header. 13374562236bSHarry Wentland info_frame_type = INFO_FRAME_AVI; 13384562236bSHarry Wentland /* InfoFrameVersion_3 is defined by CEA861F (Section 6.4), but shall 13394562236bSHarry Wentland * not be used in HDMI 2.0 (Section 10.1) */ 13404562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.header.version = 13414562236bSHarry Wentland INFO_FRAME_VERSION_2; 13424562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.header.length = 13434562236bSHarry Wentland INFO_FRAME_SIZE_AVI; 13444562236bSHarry Wentland 13454562236bSHarry Wentland /* 13464562236bSHarry Wentland * IDO-defined (Y2,Y1,Y0 = 1,1,1) shall not be used by devices built 13474562236bSHarry Wentland * according to HDMI 2.0 spec (Section 10.1) 13484562236bSHarry Wentland */ 13494562236bSHarry Wentland 13504562236bSHarry Wentland switch (stream->public.timing.pixel_encoding) { 13514562236bSHarry Wentland case PIXEL_ENCODING_YCBCR422: 13524562236bSHarry Wentland pixel_encoding = 1; 13534562236bSHarry Wentland break; 13544562236bSHarry Wentland 13554562236bSHarry Wentland case PIXEL_ENCODING_YCBCR444: 13564562236bSHarry Wentland pixel_encoding = 2; 13574562236bSHarry Wentland break; 13584562236bSHarry Wentland case PIXEL_ENCODING_YCBCR420: 13594562236bSHarry Wentland pixel_encoding = 3; 13604562236bSHarry Wentland break; 13614562236bSHarry Wentland 13624562236bSHarry Wentland case PIXEL_ENCODING_RGB: 13634562236bSHarry Wentland default: 13644562236bSHarry Wentland pixel_encoding = 0; 13654562236bSHarry Wentland } 13664562236bSHarry Wentland 13674562236bSHarry Wentland /* Y0_Y1_Y2 : The pixel encoding */ 13684562236bSHarry Wentland /* H14b AVI InfoFrame has extension on Y-field from 2 bits to 3 bits */ 13694562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.Y0_Y1_Y2 = 13704562236bSHarry Wentland pixel_encoding; 13714562236bSHarry Wentland 13724562236bSHarry Wentland /* A0 = 1 Active Format Information valid */ 13734562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.A0 = 13744562236bSHarry Wentland ACTIVE_FORMAT_VALID; 13754562236bSHarry Wentland 13764562236bSHarry Wentland /* B0, B1 = 3; Bar info data is valid */ 13774562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.B0_B1 = 13784562236bSHarry Wentland BAR_INFO_BOTH_VALID; 13794562236bSHarry Wentland 13804562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.SC0_SC1 = 13814562236bSHarry Wentland PICTURE_SCALING_UNIFORM; 13824562236bSHarry Wentland 13834562236bSHarry Wentland /* S0, S1 : Underscan / Overscan */ 13844562236bSHarry Wentland /* TODO: un-hardcode scan type */ 13854562236bSHarry Wentland scan_type = SCANNING_TYPE_UNDERSCAN; 13864562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.S0_S1 = scan_type; 13874562236bSHarry Wentland 13884562236bSHarry Wentland /* C0, C1 : Colorimetry */ 13894562236bSHarry Wentland if (color_space == COLOR_SPACE_YCBCR709) 13904562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 = 13914562236bSHarry Wentland COLORIMETRY_ITU709; 13924562236bSHarry Wentland else if (color_space == COLOR_SPACE_YCBCR601) 13934562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 = 13944562236bSHarry Wentland COLORIMETRY_ITU601; 13954562236bSHarry Wentland else 13964562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 = 13974562236bSHarry Wentland COLORIMETRY_NO_DATA; 13984562236bSHarry Wentland 13994562236bSHarry Wentland /* TODO: un-hardcode aspect ratio */ 14004562236bSHarry Wentland aspect = stream->public.timing.aspect_ratio; 14014562236bSHarry Wentland 14024562236bSHarry Wentland switch (aspect) { 14034562236bSHarry Wentland case ASPECT_RATIO_4_3: 14044562236bSHarry Wentland case ASPECT_RATIO_16_9: 14054562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.M0_M1 = aspect; 14064562236bSHarry Wentland break; 14074562236bSHarry Wentland 14084562236bSHarry Wentland case ASPECT_RATIO_NO_DATA: 14094562236bSHarry Wentland case ASPECT_RATIO_64_27: 14104562236bSHarry Wentland case ASPECT_RATIO_256_135: 14114562236bSHarry Wentland default: 14124562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.M0_M1 = 0; 14134562236bSHarry Wentland } 14144562236bSHarry Wentland 14154562236bSHarry Wentland /* Active Format Aspect ratio - same as Picture Aspect Ratio. */ 14164562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.R0_R3 = 14174562236bSHarry Wentland ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE; 14184562236bSHarry Wentland 14194562236bSHarry Wentland /* TODO: un-hardcode cn0_cn1 and itc */ 14204562236bSHarry Wentland cn0_cn1 = 0; 14214562236bSHarry Wentland itc = false; 14224562236bSHarry Wentland 14234562236bSHarry Wentland if (itc) { 14244562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.ITC = 1; 14254562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.CN0_CN1 = 14264562236bSHarry Wentland cn0_cn1; 14274562236bSHarry Wentland } 14284562236bSHarry Wentland 14294562236bSHarry Wentland /* TODO : We should handle YCC quantization */ 14304562236bSHarry Wentland /* but we do not have matrix calculation */ 14314562236bSHarry Wentland if (color_space == COLOR_SPACE_SRGB) { 14324562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.Q0_Q1 = 14334562236bSHarry Wentland RGB_QUANTIZATION_FULL_RANGE; 14344562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.YQ0_YQ1 = 14354562236bSHarry Wentland YYC_QUANTIZATION_FULL_RANGE; 14364562236bSHarry Wentland } else if (color_space == COLOR_SPACE_SRGB_LIMITED) { 14374562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.Q0_Q1 = 14384562236bSHarry Wentland RGB_QUANTIZATION_LIMITED_RANGE; 14394562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.YQ0_YQ1 = 14404562236bSHarry Wentland YYC_QUANTIZATION_LIMITED_RANGE; 14414562236bSHarry Wentland } else { 14424562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.Q0_Q1 = 14434562236bSHarry Wentland RGB_QUANTIZATION_DEFAULT_RANGE; 14444562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.YQ0_YQ1 = 14454562236bSHarry Wentland YYC_QUANTIZATION_LIMITED_RANGE; 14464562236bSHarry Wentland } 14474562236bSHarry Wentland 14484562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.VIC0_VIC7 = 14494562236bSHarry Wentland stream->public.timing.vic; 14504562236bSHarry Wentland 14514562236bSHarry Wentland /* pixel repetition 14524562236bSHarry Wentland * PR0 - PR3 start from 0 whereas pHwPathMode->mode.timing.flags.pixel 14534562236bSHarry Wentland * repetition start from 1 */ 14544562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.PR0_PR3 = 0; 14554562236bSHarry Wentland 14564562236bSHarry Wentland /* Bar Info 14574562236bSHarry Wentland * barTop: Line Number of End of Top Bar. 14584562236bSHarry Wentland * barBottom: Line Number of Start of Bottom Bar. 14594562236bSHarry Wentland * barLeft: Pixel Number of End of Left Bar. 14604562236bSHarry Wentland * barRight: Pixel Number of Start of Right Bar. */ 14614562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.bar_top = 14624562236bSHarry Wentland stream->public.timing.v_border_top; 14634562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.bar_bottom = 14644562236bSHarry Wentland (stream->public.timing.v_border_top 14654562236bSHarry Wentland - stream->public.timing.v_border_bottom + 1); 14664562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.bar_left = 14674562236bSHarry Wentland stream->public.timing.h_border_left; 14684562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.bits.bar_right = 14694562236bSHarry Wentland (stream->public.timing.h_total 14704562236bSHarry Wentland - stream->public.timing.h_border_right + 1); 14714562236bSHarry Wentland 14724562236bSHarry Wentland /* check_sum - Calculate AFMT_AVI_INFO0 ~ AFMT_AVI_INFO3 */ 14734562236bSHarry Wentland check_sum = 14744562236bSHarry Wentland &info_frame. 14754562236bSHarry Wentland avi_info_packet.info_packet_hdmi.packet_raw_data.sb[0]; 14764562236bSHarry Wentland *check_sum = INFO_FRAME_AVI + INFO_FRAME_SIZE_AVI 14774562236bSHarry Wentland + INFO_FRAME_VERSION_2; 14784562236bSHarry Wentland 14794562236bSHarry Wentland for (byte_index = 1; byte_index <= INFO_FRAME_SIZE_AVI; byte_index++) 14804562236bSHarry Wentland *check_sum += info_frame.avi_info_packet.info_packet_hdmi. 14814562236bSHarry Wentland packet_raw_data.sb[byte_index]; 14824562236bSHarry Wentland 14834562236bSHarry Wentland /* one byte complement */ 14844562236bSHarry Wentland *check_sum = (uint8_t) (0x100 - *check_sum); 14854562236bSHarry Wentland 14864562236bSHarry Wentland /* Store in hw_path_mode */ 14874562236bSHarry Wentland info_packet->hb0 = 14884562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.packet_raw_data.hb0; 14894562236bSHarry Wentland info_packet->hb1 = 14904562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.packet_raw_data.hb1; 14914562236bSHarry Wentland info_packet->hb2 = 14924562236bSHarry Wentland info_frame.avi_info_packet.info_packet_hdmi.packet_raw_data.hb2; 14934562236bSHarry Wentland 1494e66e4d64SHarry Wentland for (byte_index = 0; byte_index < sizeof(info_frame.avi_info_packet. 1495e66e4d64SHarry Wentland info_packet_hdmi.packet_raw_data.sb); byte_index++) 14964562236bSHarry Wentland info_packet->sb[byte_index] = info_frame.avi_info_packet. 14974562236bSHarry Wentland info_packet_hdmi.packet_raw_data.sb[byte_index]; 14984562236bSHarry Wentland 14994562236bSHarry Wentland info_packet->valid = true; 15004562236bSHarry Wentland } 15014562236bSHarry Wentland 15024562236bSHarry Wentland static void set_vendor_info_packet(struct core_stream *stream, 15034562236bSHarry Wentland struct hw_info_packet *info_packet) 15044562236bSHarry Wentland { 15054562236bSHarry Wentland uint32_t length = 0; 15064562236bSHarry Wentland bool hdmi_vic_mode = false; 15074562236bSHarry Wentland uint8_t checksum = 0; 15084562236bSHarry Wentland uint32_t i = 0; 15094562236bSHarry Wentland enum dc_timing_3d_format format; 15104562236bSHarry Wentland 15114562236bSHarry Wentland ASSERT_CRITICAL(stream != NULL); 15124562236bSHarry Wentland ASSERT_CRITICAL(info_packet != NULL); 15134562236bSHarry Wentland 15144562236bSHarry Wentland format = stream->public.timing.timing_3d_format; 15154562236bSHarry Wentland 15164562236bSHarry Wentland /* Can be different depending on packet content */ 15174562236bSHarry Wentland length = 5; 15184562236bSHarry Wentland 15194562236bSHarry Wentland if (stream->public.timing.hdmi_vic != 0 15204562236bSHarry Wentland && stream->public.timing.h_total >= 3840 15214562236bSHarry Wentland && stream->public.timing.v_total >= 2160) 15224562236bSHarry Wentland hdmi_vic_mode = true; 15234562236bSHarry Wentland 15244562236bSHarry Wentland /* According to HDMI 1.4a CTS, VSIF should be sent 15254562236bSHarry Wentland * for both 3D stereo and HDMI VIC modes. 15264562236bSHarry Wentland * For all other modes, there is no VSIF sent. */ 15274562236bSHarry Wentland 15284562236bSHarry Wentland if (format == TIMING_3D_FORMAT_NONE && !hdmi_vic_mode) 15294562236bSHarry Wentland return; 15304562236bSHarry Wentland 15314562236bSHarry Wentland /* 24bit IEEE Registration identifier (0x000c03). LSB first. */ 15324562236bSHarry Wentland info_packet->sb[1] = 0x03; 15334562236bSHarry Wentland info_packet->sb[2] = 0x0C; 15344562236bSHarry Wentland info_packet->sb[3] = 0x00; 15354562236bSHarry Wentland 15364562236bSHarry Wentland /*PB4: 5 lower bytes = 0 (reserved). 3 higher bits = HDMI_Video_Format. 15374562236bSHarry Wentland * The value for HDMI_Video_Format are: 15384562236bSHarry Wentland * 0x0 (0b000) - No additional HDMI video format is presented in this 15394562236bSHarry Wentland * packet 15404562236bSHarry Wentland * 0x1 (0b001) - Extended resolution format present. 1 byte of HDMI_VIC 15414562236bSHarry Wentland * parameter follows 15424562236bSHarry Wentland * 0x2 (0b010) - 3D format indication present. 3D_Structure and 15434562236bSHarry Wentland * potentially 3D_Ext_Data follows 15444562236bSHarry Wentland * 0x3..0x7 (0b011..0b111) - reserved for future use */ 15454562236bSHarry Wentland if (format != TIMING_3D_FORMAT_NONE) 15464562236bSHarry Wentland info_packet->sb[4] = (2 << 5); 15474562236bSHarry Wentland else if (hdmi_vic_mode) 15484562236bSHarry Wentland info_packet->sb[4] = (1 << 5); 15494562236bSHarry Wentland 15504562236bSHarry Wentland /* PB5: If PB4 claims 3D timing (HDMI_Video_Format = 0x2): 15514562236bSHarry Wentland * 4 lower bites = 0 (reserved). 4 higher bits = 3D_Structure. 15524562236bSHarry Wentland * The value for 3D_Structure are: 15534562236bSHarry Wentland * 0x0 - Frame Packing 15544562236bSHarry Wentland * 0x1 - Field Alternative 15554562236bSHarry Wentland * 0x2 - Line Alternative 15564562236bSHarry Wentland * 0x3 - Side-by-Side (full) 15574562236bSHarry Wentland * 0x4 - L + depth 15584562236bSHarry Wentland * 0x5 - L + depth + graphics + graphics-depth 15594562236bSHarry Wentland * 0x6 - Top-and-Bottom 15604562236bSHarry Wentland * 0x7 - Reserved for future use 15614562236bSHarry Wentland * 0x8 - Side-by-Side (Half) 15624562236bSHarry Wentland * 0x9..0xE - Reserved for future use 15634562236bSHarry Wentland * 0xF - Not used */ 15644562236bSHarry Wentland switch (format) { 15654562236bSHarry Wentland case TIMING_3D_FORMAT_HW_FRAME_PACKING: 15664562236bSHarry Wentland case TIMING_3D_FORMAT_SW_FRAME_PACKING: 15674562236bSHarry Wentland info_packet->sb[5] = (0x0 << 4); 15684562236bSHarry Wentland break; 15694562236bSHarry Wentland 15704562236bSHarry Wentland case TIMING_3D_FORMAT_SIDE_BY_SIDE: 15714562236bSHarry Wentland case TIMING_3D_FORMAT_SBS_SW_PACKED: 15724562236bSHarry Wentland info_packet->sb[5] = (0x8 << 4); 15734562236bSHarry Wentland length = 6; 15744562236bSHarry Wentland break; 15754562236bSHarry Wentland 15764562236bSHarry Wentland case TIMING_3D_FORMAT_TOP_AND_BOTTOM: 15774562236bSHarry Wentland case TIMING_3D_FORMAT_TB_SW_PACKED: 15784562236bSHarry Wentland info_packet->sb[5] = (0x6 << 4); 15794562236bSHarry Wentland break; 15804562236bSHarry Wentland 15814562236bSHarry Wentland default: 15824562236bSHarry Wentland break; 15834562236bSHarry Wentland } 15844562236bSHarry Wentland 15854562236bSHarry Wentland /*PB5: If PB4 is set to 0x1 (extended resolution format) 15864562236bSHarry Wentland * fill PB5 with the correct HDMI VIC code */ 15874562236bSHarry Wentland if (hdmi_vic_mode) 15884562236bSHarry Wentland info_packet->sb[5] = stream->public.timing.hdmi_vic; 15894562236bSHarry Wentland 15904562236bSHarry Wentland /* Header */ 15914562236bSHarry Wentland info_packet->hb0 = 0x81; /* VSIF packet type. */ 15924562236bSHarry Wentland info_packet->hb1 = 0x01; /* Version */ 15934562236bSHarry Wentland 15944562236bSHarry Wentland /* 4 lower bits = Length, 4 higher bits = 0 (reserved) */ 15954562236bSHarry Wentland info_packet->hb2 = (uint8_t) (length); 15964562236bSHarry Wentland 15974562236bSHarry Wentland /* Calculate checksum */ 15984562236bSHarry Wentland checksum = 0; 15994562236bSHarry Wentland checksum += info_packet->hb0; 16004562236bSHarry Wentland checksum += info_packet->hb1; 16014562236bSHarry Wentland checksum += info_packet->hb2; 16024562236bSHarry Wentland 16034562236bSHarry Wentland for (i = 1; i <= length; i++) 16044562236bSHarry Wentland checksum += info_packet->sb[i]; 16054562236bSHarry Wentland 16064562236bSHarry Wentland info_packet->sb[0] = (uint8_t) (0x100 - checksum); 16074562236bSHarry Wentland 16084562236bSHarry Wentland info_packet->valid = true; 16094562236bSHarry Wentland } 16104562236bSHarry Wentland 16114562236bSHarry Wentland static void set_spd_info_packet(struct core_stream *stream, 16124562236bSHarry Wentland struct hw_info_packet *info_packet) 16134562236bSHarry Wentland { 16144562236bSHarry Wentland /* SPD info packet for FreeSync */ 16154562236bSHarry Wentland 16164562236bSHarry Wentland unsigned char checksum = 0; 16174562236bSHarry Wentland unsigned int idx, payload_size = 0; 16184562236bSHarry Wentland 16194562236bSHarry Wentland /* Check if Freesync is supported. Return if false. If true, 16204562236bSHarry Wentland * set the corresponding bit in the info packet 16214562236bSHarry Wentland */ 16224562236bSHarry Wentland if (stream->public.freesync_ctx.supported == false) 16234562236bSHarry Wentland return; 16244562236bSHarry Wentland 16254562236bSHarry Wentland if (dc_is_hdmi_signal(stream->signal)) { 16264562236bSHarry Wentland 16274562236bSHarry Wentland /* HEADER */ 16284562236bSHarry Wentland 16294562236bSHarry Wentland /* HB0 = Packet Type = 0x83 (Source Product 16304562236bSHarry Wentland * Descriptor InfoFrame) 16314562236bSHarry Wentland */ 16324562236bSHarry Wentland info_packet->hb0 = 0x83; 16334562236bSHarry Wentland 16344562236bSHarry Wentland /* HB1 = Version = 0x01 */ 16354562236bSHarry Wentland info_packet->hb1 = 0x01; 16364562236bSHarry Wentland 16374562236bSHarry Wentland /* HB2 = [Bits 7:5 = 0] [Bits 4:0 = Length = 0x08] */ 16384562236bSHarry Wentland info_packet->hb2 = 0x08; 16394562236bSHarry Wentland 16404562236bSHarry Wentland payload_size = 0x08; 16414562236bSHarry Wentland 16424562236bSHarry Wentland } else if (dc_is_dp_signal(stream->signal)) { 16434562236bSHarry Wentland 16444562236bSHarry Wentland /* HEADER */ 16454562236bSHarry Wentland 16464562236bSHarry Wentland /* HB0 = Secondary-data Packet ID = 0 - Only non-zero 16474562236bSHarry Wentland * when used to associate audio related info packets 16484562236bSHarry Wentland */ 16494562236bSHarry Wentland info_packet->hb0 = 0x00; 16504562236bSHarry Wentland 16514562236bSHarry Wentland /* HB1 = Packet Type = 0x83 (Source Product 16524562236bSHarry Wentland * Descriptor InfoFrame) 16534562236bSHarry Wentland */ 16544562236bSHarry Wentland info_packet->hb1 = 0x83; 16554562236bSHarry Wentland 16564562236bSHarry Wentland /* HB2 = [Bits 7:0 = Least significant eight bits - 16574562236bSHarry Wentland * For INFOFRAME, the value must be 1Bh] 16584562236bSHarry Wentland */ 16594562236bSHarry Wentland info_packet->hb2 = 0x1B; 16604562236bSHarry Wentland 16614562236bSHarry Wentland /* HB3 = [Bits 7:2 = INFOFRAME SDP Version Number = 0x1] 16624562236bSHarry Wentland * [Bits 1:0 = Most significant two bits = 0x00] 16634562236bSHarry Wentland */ 16644562236bSHarry Wentland info_packet->hb3 = 0x04; 16654562236bSHarry Wentland 16664562236bSHarry Wentland payload_size = 0x1B; 16674562236bSHarry Wentland } 16684562236bSHarry Wentland 16694562236bSHarry Wentland /* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */ 16704562236bSHarry Wentland info_packet->sb[1] = 0x1A; 16714562236bSHarry Wentland 16724562236bSHarry Wentland /* PB2 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 1) */ 16734562236bSHarry Wentland info_packet->sb[2] = 0x00; 16744562236bSHarry Wentland 16754562236bSHarry Wentland /* PB3 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 2) */ 16764562236bSHarry Wentland info_packet->sb[3] = 0x00; 16774562236bSHarry Wentland 16784562236bSHarry Wentland /* PB4 = Reserved */ 16794562236bSHarry Wentland info_packet->sb[4] = 0x00; 16804562236bSHarry Wentland 16814562236bSHarry Wentland /* PB5 = Reserved */ 16824562236bSHarry Wentland info_packet->sb[5] = 0x00; 16834562236bSHarry Wentland 16844562236bSHarry Wentland /* PB6 = [Bits 7:3 = Reserved] */ 16854562236bSHarry Wentland info_packet->sb[6] = 0x00; 16864562236bSHarry Wentland 16874562236bSHarry Wentland if (stream->public.freesync_ctx.supported == true) 16884562236bSHarry Wentland /* PB6 = [Bit 0 = FreeSync Supported] */ 16894562236bSHarry Wentland info_packet->sb[6] |= 0x01; 16904562236bSHarry Wentland 16914562236bSHarry Wentland if (stream->public.freesync_ctx.enabled == true) 16924562236bSHarry Wentland /* PB6 = [Bit 1 = FreeSync Enabled] */ 16934562236bSHarry Wentland info_packet->sb[6] |= 0x02; 16944562236bSHarry Wentland 16954562236bSHarry Wentland if (stream->public.freesync_ctx.active == true) 16964562236bSHarry Wentland /* PB6 = [Bit 2 = FreeSync Active] */ 16974562236bSHarry Wentland info_packet->sb[6] |= 0x04; 16984562236bSHarry Wentland 16994562236bSHarry Wentland /* PB7 = FreeSync Minimum refresh rate (Hz) */ 17004562236bSHarry Wentland info_packet->sb[7] = (unsigned char) (stream->public.freesync_ctx. 17014562236bSHarry Wentland min_refresh_in_micro_hz / 1000000); 17024562236bSHarry Wentland 17034562236bSHarry Wentland /* PB8 = FreeSync Maximum refresh rate (Hz) 17044562236bSHarry Wentland * 17054562236bSHarry Wentland * Note: We do not use the maximum capable refresh rate 17064562236bSHarry Wentland * of the panel, because we should never go above the field 17074562236bSHarry Wentland * rate of the mode timing set. 17084562236bSHarry Wentland */ 17094562236bSHarry Wentland info_packet->sb[8] = (unsigned char) (stream->public.freesync_ctx. 17104562236bSHarry Wentland nominal_refresh_in_micro_hz / 1000000); 17114562236bSHarry Wentland 17124562236bSHarry Wentland /* PB9 - PB27 = Reserved */ 17134562236bSHarry Wentland for (idx = 9; idx <= 27; idx++) 17144562236bSHarry Wentland info_packet->sb[idx] = 0x00; 17154562236bSHarry Wentland 17164562236bSHarry Wentland /* Calculate checksum */ 17174562236bSHarry Wentland checksum += info_packet->hb0; 17184562236bSHarry Wentland checksum += info_packet->hb1; 17194562236bSHarry Wentland checksum += info_packet->hb2; 17204562236bSHarry Wentland checksum += info_packet->hb3; 17214562236bSHarry Wentland 17224562236bSHarry Wentland for (idx = 1; idx <= payload_size; idx++) 17234562236bSHarry Wentland checksum += info_packet->sb[idx]; 17244562236bSHarry Wentland 17254562236bSHarry Wentland /* PB0 = Checksum (one byte complement) */ 17264562236bSHarry Wentland info_packet->sb[0] = (unsigned char) (0x100 - checksum); 17274562236bSHarry Wentland 17284562236bSHarry Wentland info_packet->valid = true; 17294562236bSHarry Wentland } 17304562236bSHarry Wentland 17311646a6feSAndrew Wong static void set_hdr_static_info_packet( 17321646a6feSAndrew Wong struct core_surface *surface, 17331646a6feSAndrew Wong struct core_stream *stream, 17341646a6feSAndrew Wong struct hw_info_packet *info_packet) 17351646a6feSAndrew Wong { 1736e5cf325bSHarry Wentland uint16_t i = 0; 17371646a6feSAndrew Wong enum signal_type signal = stream->signal; 1738e5cf325bSHarry Wentland struct dc_hdr_static_metadata hdr_metadata; 1739e5cf325bSHarry Wentland uint32_t data; 17401646a6feSAndrew Wong 17411646a6feSAndrew Wong if (!surface) 17421646a6feSAndrew Wong return; 17431646a6feSAndrew Wong 1744e5cf325bSHarry Wentland hdr_metadata = surface->public.hdr_static_ctx; 17451646a6feSAndrew Wong 174610bff005SYongqiang Sun if (!hdr_metadata.is_hdr) 174710bff005SYongqiang Sun return; 174810bff005SYongqiang Sun 17491646a6feSAndrew Wong if (dc_is_hdmi_signal(signal)) { 17501646a6feSAndrew Wong info_packet->valid = true; 17511646a6feSAndrew Wong 17521646a6feSAndrew Wong info_packet->hb0 = 0x87; 17531646a6feSAndrew Wong info_packet->hb1 = 0x01; 17541646a6feSAndrew Wong info_packet->hb2 = 0x1A; 17551646a6feSAndrew Wong i = 1; 17561646a6feSAndrew Wong } else if (dc_is_dp_signal(signal)) { 17571646a6feSAndrew Wong info_packet->valid = true; 17581646a6feSAndrew Wong 17591646a6feSAndrew Wong info_packet->hb0 = 0x00; 17601646a6feSAndrew Wong info_packet->hb1 = 0x87; 17611646a6feSAndrew Wong info_packet->hb2 = 0x1D; 17621646a6feSAndrew Wong info_packet->hb3 = (0x13 << 2); 17631646a6feSAndrew Wong i = 2; 17641646a6feSAndrew Wong } 17651646a6feSAndrew Wong 17661646a6feSAndrew Wong data = hdr_metadata.is_hdr; 17671646a6feSAndrew Wong info_packet->sb[i++] = data ? 0x02 : 0x00; 17681646a6feSAndrew Wong info_packet->sb[i++] = 0x00; 17691646a6feSAndrew Wong 17701646a6feSAndrew Wong data = hdr_metadata.chromaticity_green_x / 2; 17711646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 17721646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 17731646a6feSAndrew Wong 17741646a6feSAndrew Wong data = hdr_metadata.chromaticity_green_y / 2; 17751646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 17761646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 17771646a6feSAndrew Wong 17781646a6feSAndrew Wong data = hdr_metadata.chromaticity_blue_x / 2; 17791646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 17801646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 17811646a6feSAndrew Wong 17821646a6feSAndrew Wong data = hdr_metadata.chromaticity_blue_y / 2; 17831646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 17841646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 17851646a6feSAndrew Wong 17861646a6feSAndrew Wong data = hdr_metadata.chromaticity_red_x / 2; 17871646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 17881646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 17891646a6feSAndrew Wong 17901646a6feSAndrew Wong data = hdr_metadata.chromaticity_red_y / 2; 17911646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 17921646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 17931646a6feSAndrew Wong 17941646a6feSAndrew Wong data = hdr_metadata.chromaticity_white_point_x / 2; 17951646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 17961646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 17971646a6feSAndrew Wong 17981646a6feSAndrew Wong data = hdr_metadata.chromaticity_white_point_y / 2; 17991646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 18001646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 18011646a6feSAndrew Wong 18021646a6feSAndrew Wong data = hdr_metadata.max_luminance; 18031646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 18041646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 18051646a6feSAndrew Wong 18061646a6feSAndrew Wong data = hdr_metadata.min_luminance; 18071646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 18081646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 18091646a6feSAndrew Wong 18101646a6feSAndrew Wong data = hdr_metadata.maximum_content_light_level; 18111646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 18121646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 18131646a6feSAndrew Wong 18141646a6feSAndrew Wong data = hdr_metadata.maximum_frame_average_light_level; 18151646a6feSAndrew Wong info_packet->sb[i++] = data & 0xFF; 18161646a6feSAndrew Wong info_packet->sb[i++] = (data & 0xFF00) >> 8; 18171646a6feSAndrew Wong 18181646a6feSAndrew Wong if (dc_is_hdmi_signal(signal)) { 18191646a6feSAndrew Wong uint32_t checksum = 0; 18201646a6feSAndrew Wong 18211646a6feSAndrew Wong checksum += info_packet->hb0; 18221646a6feSAndrew Wong checksum += info_packet->hb1; 18231646a6feSAndrew Wong checksum += info_packet->hb2; 18241646a6feSAndrew Wong 18251646a6feSAndrew Wong for (i = 1; i <= info_packet->hb2; i++) 18261646a6feSAndrew Wong checksum += info_packet->sb[i]; 18271646a6feSAndrew Wong 18281646a6feSAndrew Wong info_packet->sb[0] = 0x100 - checksum; 18291646a6feSAndrew Wong } else if (dc_is_dp_signal(signal)) { 18301646a6feSAndrew Wong info_packet->sb[0] = 0x01; 18311646a6feSAndrew Wong info_packet->sb[1] = 0x1A; 18321646a6feSAndrew Wong } 18331646a6feSAndrew Wong } 18341646a6feSAndrew Wong 18354562236bSHarry Wentland static void set_vsc_info_packet(struct core_stream *stream, 18364562236bSHarry Wentland struct hw_info_packet *info_packet) 18374562236bSHarry Wentland { 18384562236bSHarry Wentland unsigned int vscPacketRevision = 0; 18394562236bSHarry Wentland unsigned int i; 18404562236bSHarry Wentland 18414562236bSHarry Wentland if (stream->sink->link->public.psr_caps.psr_version != 0) { 18424562236bSHarry Wentland vscPacketRevision = 2; 18434562236bSHarry Wentland } 18444562236bSHarry Wentland 18454562236bSHarry Wentland /* VSC packet not needed based on the features 18464562236bSHarry Wentland * supported by this DP display 18474562236bSHarry Wentland */ 18484562236bSHarry Wentland if (vscPacketRevision == 0) 18494562236bSHarry Wentland return; 18504562236bSHarry Wentland 18514562236bSHarry Wentland if (vscPacketRevision == 0x2) { 18524562236bSHarry Wentland /* Secondary-data Packet ID = 0*/ 18534562236bSHarry Wentland info_packet->hb0 = 0x00; 18544562236bSHarry Wentland /* 07h - Packet Type Value indicating Video 18554562236bSHarry Wentland * Stream Configuration packet 18564562236bSHarry Wentland */ 18574562236bSHarry Wentland info_packet->hb1 = 0x07; 18584562236bSHarry Wentland /* 02h = VSC SDP supporting 3D stereo and PSR 18594562236bSHarry Wentland * (applies to eDP v1.3 or higher). 18604562236bSHarry Wentland */ 18614562236bSHarry Wentland info_packet->hb2 = 0x02; 18624562236bSHarry Wentland /* 08h = VSC packet supporting 3D stereo + PSR 18634562236bSHarry Wentland * (HB2 = 02h). 18644562236bSHarry Wentland */ 18654562236bSHarry Wentland info_packet->hb3 = 0x08; 18664562236bSHarry Wentland 18674562236bSHarry Wentland for (i = 0; i < 28; i++) 18684562236bSHarry Wentland info_packet->sb[i] = 0; 18694562236bSHarry Wentland 18704562236bSHarry Wentland info_packet->valid = true; 18714562236bSHarry Wentland } 18724562236bSHarry Wentland 18734562236bSHarry Wentland /*TODO: stereo 3D support and extend pixel encoding colorimetry*/ 18744562236bSHarry Wentland } 18754562236bSHarry Wentland 18764562236bSHarry Wentland void resource_validate_ctx_destruct(struct validate_context *context) 18774562236bSHarry Wentland { 18784562236bSHarry Wentland int i, j; 18794562236bSHarry Wentland 18804562236bSHarry Wentland for (i = 0; i < context->target_count; i++) { 18814562236bSHarry Wentland for (j = 0; j < context->target_status[i].surface_count; j++) 18824562236bSHarry Wentland dc_surface_release( 18834562236bSHarry Wentland context->target_status[i].surfaces[j]); 18844562236bSHarry Wentland 18854562236bSHarry Wentland context->target_status[i].surface_count = 0; 18864562236bSHarry Wentland dc_target_release(&context->targets[i]->public); 18874562236bSHarry Wentland } 18884562236bSHarry Wentland } 18894562236bSHarry Wentland 18904562236bSHarry Wentland /* 18914562236bSHarry Wentland * Copy src_ctx into dst_ctx and retain all surfaces and targets referenced 18924562236bSHarry Wentland * by the src_ctx 18934562236bSHarry Wentland */ 18944562236bSHarry Wentland void resource_validate_ctx_copy_construct( 18954562236bSHarry Wentland const struct validate_context *src_ctx, 18964562236bSHarry Wentland struct validate_context *dst_ctx) 18974562236bSHarry Wentland { 18984562236bSHarry Wentland int i, j; 18994562236bSHarry Wentland 19004562236bSHarry Wentland *dst_ctx = *src_ctx; 19014562236bSHarry Wentland 19024562236bSHarry Wentland for (i = 0; i < dst_ctx->res_ctx.pool->pipe_count; i++) { 19034562236bSHarry Wentland struct pipe_ctx *cur_pipe = &dst_ctx->res_ctx.pipe_ctx[i]; 19044562236bSHarry Wentland 19054562236bSHarry Wentland if (cur_pipe->top_pipe) 19064562236bSHarry Wentland cur_pipe->top_pipe = &dst_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx]; 19074562236bSHarry Wentland 19084562236bSHarry Wentland if (cur_pipe->bottom_pipe) 19094562236bSHarry Wentland cur_pipe->bottom_pipe = &dst_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx]; 19104562236bSHarry Wentland 19114562236bSHarry Wentland } 19124562236bSHarry Wentland 19134562236bSHarry Wentland for (i = 0; i < dst_ctx->target_count; i++) { 19144562236bSHarry Wentland dc_target_retain(&dst_ctx->targets[i]->public); 19154562236bSHarry Wentland for (j = 0; j < dst_ctx->target_status[i].surface_count; j++) 19164562236bSHarry Wentland dc_surface_retain( 19174562236bSHarry Wentland dst_ctx->target_status[i].surfaces[j]); 19184562236bSHarry Wentland } 19194562236bSHarry Wentland } 19204562236bSHarry Wentland 19214562236bSHarry Wentland struct clock_source *dc_resource_find_first_free_pll( 19224562236bSHarry Wentland struct resource_context *res_ctx) 19234562236bSHarry Wentland { 19244562236bSHarry Wentland int i; 19254562236bSHarry Wentland 19264562236bSHarry Wentland for (i = 0; i < res_ctx->pool->clk_src_count; ++i) { 19274562236bSHarry Wentland if (res_ctx->clock_source_ref_count[i] == 0) 19284562236bSHarry Wentland return res_ctx->pool->clock_sources[i]; 19294562236bSHarry Wentland } 19304562236bSHarry Wentland 19314562236bSHarry Wentland return NULL; 19324562236bSHarry Wentland } 19334562236bSHarry Wentland 19344562236bSHarry Wentland void resource_build_info_frame(struct pipe_ctx *pipe_ctx) 19354562236bSHarry Wentland { 19364562236bSHarry Wentland enum signal_type signal = SIGNAL_TYPE_NONE; 19374562236bSHarry Wentland struct hw_info_frame info_frame = { { 0 } }; 19384562236bSHarry Wentland 19394562236bSHarry Wentland /* default all packets to invalid */ 19404562236bSHarry Wentland info_frame.avi_info_packet.valid = false; 19414562236bSHarry Wentland info_frame.gamut_packet.valid = false; 19424562236bSHarry Wentland info_frame.vendor_info_packet.valid = false; 19434562236bSHarry Wentland info_frame.spd_packet.valid = false; 19444562236bSHarry Wentland info_frame.vsc_packet.valid = false; 19451646a6feSAndrew Wong info_frame.hdrsmd_packet.valid = false; 19464562236bSHarry Wentland 19474562236bSHarry Wentland signal = pipe_ctx->stream->signal; 19484562236bSHarry Wentland 19494562236bSHarry Wentland /* HDMi and DP have different info packets*/ 19504562236bSHarry Wentland if (dc_is_hdmi_signal(signal)) { 19514562236bSHarry Wentland set_avi_info_frame( 19524562236bSHarry Wentland &info_frame.avi_info_packet, pipe_ctx); 19534562236bSHarry Wentland set_vendor_info_packet( 19544562236bSHarry Wentland pipe_ctx->stream, &info_frame.vendor_info_packet); 19554562236bSHarry Wentland set_spd_info_packet(pipe_ctx->stream, &info_frame.spd_packet); 19561646a6feSAndrew Wong set_hdr_static_info_packet(pipe_ctx->surface, 19571646a6feSAndrew Wong pipe_ctx->stream, &info_frame.hdrsmd_packet); 1958a33fa99dSHarry Wentland } else if (dc_is_dp_signal(signal)) { 19594562236bSHarry Wentland set_vsc_info_packet(pipe_ctx->stream, &info_frame.vsc_packet); 19604562236bSHarry Wentland set_spd_info_packet(pipe_ctx->stream, &info_frame.spd_packet); 19611646a6feSAndrew Wong set_hdr_static_info_packet(pipe_ctx->surface, 19621646a6feSAndrew Wong pipe_ctx->stream, &info_frame.hdrsmd_packet); 1963a33fa99dSHarry Wentland } 19644562236bSHarry Wentland 19654562236bSHarry Wentland translate_info_frame(&info_frame, 19664562236bSHarry Wentland &pipe_ctx->encoder_info_frame); 19674562236bSHarry Wentland } 19684562236bSHarry Wentland 19694562236bSHarry Wentland enum dc_status resource_map_clock_resources( 19704562236bSHarry Wentland const struct core_dc *dc, 19714562236bSHarry Wentland struct validate_context *context) 19724562236bSHarry Wentland { 19734562236bSHarry Wentland int i, j, k; 19744562236bSHarry Wentland 19754562236bSHarry Wentland /* acquire new resources */ 19764562236bSHarry Wentland for (i = 0; i < context->target_count; i++) { 19774562236bSHarry Wentland struct core_target *target = context->targets[i]; 19784562236bSHarry Wentland 19794562236bSHarry Wentland for (j = 0; j < target->public.stream_count; j++) { 19804562236bSHarry Wentland struct core_stream *stream = 19814562236bSHarry Wentland DC_STREAM_TO_CORE(target->public.streams[j]); 19824562236bSHarry Wentland 19834562236bSHarry Wentland if (resource_is_stream_unchanged(dc->current_context, stream)) 19844562236bSHarry Wentland continue; 19854562236bSHarry Wentland 19864562236bSHarry Wentland for (k = 0; k < MAX_PIPES; k++) { 19874562236bSHarry Wentland struct pipe_ctx *pipe_ctx = 19884562236bSHarry Wentland &context->res_ctx.pipe_ctx[k]; 19894562236bSHarry Wentland 19904562236bSHarry Wentland if (context->res_ctx.pipe_ctx[k].stream != stream) 19914562236bSHarry Wentland continue; 19924562236bSHarry Wentland 19934562236bSHarry Wentland if (dc_is_dp_signal(pipe_ctx->stream->signal) 19944562236bSHarry Wentland || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) 19954562236bSHarry Wentland pipe_ctx->clock_source = 19964562236bSHarry Wentland context->res_ctx.pool->dp_clock_source; 19974562236bSHarry Wentland else { 19984562236bSHarry Wentland pipe_ctx->clock_source = NULL; 19994562236bSHarry Wentland 20004562236bSHarry Wentland if (!dc->public.config.disable_disp_pll_sharing) 20014562236bSHarry Wentland resource_find_used_clk_src_for_sharing( 20024562236bSHarry Wentland &context->res_ctx, 20034562236bSHarry Wentland pipe_ctx); 20044562236bSHarry Wentland 20054562236bSHarry Wentland if (pipe_ctx->clock_source == NULL) 20064562236bSHarry Wentland pipe_ctx->clock_source = 20074562236bSHarry Wentland dc_resource_find_first_free_pll(&context->res_ctx); 20084562236bSHarry Wentland } 20094562236bSHarry Wentland 20104562236bSHarry Wentland if (pipe_ctx->clock_source == NULL) 20114562236bSHarry Wentland return DC_NO_CLOCK_SOURCE_RESOURCE; 20124562236bSHarry Wentland 20134562236bSHarry Wentland resource_reference_clock_source( 20144562236bSHarry Wentland &context->res_ctx, 20154562236bSHarry Wentland pipe_ctx->clock_source); 20164562236bSHarry Wentland 20174562236bSHarry Wentland /* only one cs per stream regardless of mpo */ 20184562236bSHarry Wentland break; 20194562236bSHarry Wentland } 20204562236bSHarry Wentland } 20214562236bSHarry Wentland } 20224562236bSHarry Wentland 20234562236bSHarry Wentland return DC_OK; 20244562236bSHarry Wentland } 20254562236bSHarry Wentland 20264562236bSHarry Wentland /* 20274562236bSHarry Wentland * Note: We need to disable output if clock sources change, 20284562236bSHarry Wentland * since bios does optimization and doesn't apply if changing 20294562236bSHarry Wentland * PHY when not already disabled. 20304562236bSHarry Wentland */ 20314562236bSHarry Wentland bool pipe_need_reprogram( 20324562236bSHarry Wentland struct pipe_ctx *pipe_ctx_old, 20334562236bSHarry Wentland struct pipe_ctx *pipe_ctx) 20344562236bSHarry Wentland { 20354562236bSHarry Wentland if (pipe_ctx_old->stream->sink != pipe_ctx->stream->sink) 20364562236bSHarry Wentland return true; 20374562236bSHarry Wentland 20384562236bSHarry Wentland if (pipe_ctx_old->stream->signal != pipe_ctx->stream->signal) 20394562236bSHarry Wentland return true; 20404562236bSHarry Wentland 20414562236bSHarry Wentland if (pipe_ctx_old->audio != pipe_ctx->audio) 20424562236bSHarry Wentland return true; 20434562236bSHarry Wentland 20444562236bSHarry Wentland if (pipe_ctx_old->clock_source != pipe_ctx->clock_source 20454562236bSHarry Wentland && pipe_ctx_old->stream != pipe_ctx->stream) 20464562236bSHarry Wentland return true; 20474562236bSHarry Wentland 20484562236bSHarry Wentland if (pipe_ctx_old->stream_enc != pipe_ctx->stream_enc) 20494562236bSHarry Wentland return true; 20504562236bSHarry Wentland 20514562236bSHarry Wentland if (is_timing_changed(pipe_ctx_old->stream, pipe_ctx->stream)) 20524562236bSHarry Wentland return true; 20534562236bSHarry Wentland 20544562236bSHarry Wentland 20554562236bSHarry Wentland return false; 20564562236bSHarry Wentland } 2057