10c41891cSEric Bernstein /* 20c41891cSEric Bernstein * Copyright 2012-15 Advanced Micro Devices, Inc. 30c41891cSEric Bernstein * 40c41891cSEric Bernstein * Permission is hereby granted, free of charge, to any person obtaining a 50c41891cSEric Bernstein * copy of this software and associated documentation files (the "Software"), 60c41891cSEric Bernstein * to deal in the Software without restriction, including without limitation 70c41891cSEric Bernstein * the rights to use, copy, modify, merge, publish, distribute, sublicense, 80c41891cSEric Bernstein * and/or sell copies of the Software, and to permit persons to whom the 90c41891cSEric Bernstein * Software is furnished to do so, subject to the following conditions: 100c41891cSEric Bernstein * 110c41891cSEric Bernstein * The above copyright notice and this permission notice shall be included in 120c41891cSEric Bernstein * all copies or substantial portions of the Software. 130c41891cSEric Bernstein * 140c41891cSEric Bernstein * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 150c41891cSEric Bernstein * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 160c41891cSEric Bernstein * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 170c41891cSEric Bernstein * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 180c41891cSEric Bernstein * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 190c41891cSEric Bernstein * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 200c41891cSEric Bernstein * OTHER DEALINGS IN THE SOFTWARE. 210c41891cSEric Bernstein * 220c41891cSEric Bernstein * Authors: AMD 230c41891cSEric Bernstein * 240c41891cSEric Bernstein */ 250c41891cSEric Bernstein 26c366be54SSam Ravnborg #include <linux/delay.h> 270c41891cSEric Bernstein 280c41891cSEric Bernstein #include "dc_bios_types.h" 290c41891cSEric Bernstein #include "dcn10_stream_encoder.h" 300c41891cSEric Bernstein #include "reg_helper.h" 31c5011872SEric Bernstein #include "hw_shared.h" 323550d622SLeo (Hanghong) Ma #include "inc/link_dpcd.h" 333550d622SLeo (Hanghong) Ma #include "dpcd_defs.h" 34*18b4f1a0SMichael Strauss #include "dcn30/dcn30_afmt.h" 35c5011872SEric Bernstein 360c41891cSEric Bernstein #define DC_LOGGER \ 370c41891cSEric Bernstein enc1->base.ctx->logger 380c41891cSEric Bernstein 390c41891cSEric Bernstein 400c41891cSEric Bernstein #define REG(reg)\ 410c41891cSEric Bernstein (enc1->regs->reg) 420c41891cSEric Bernstein 430c41891cSEric Bernstein #undef FN 440c41891cSEric Bernstein #define FN(reg_name, field_name) \ 450c41891cSEric Bernstein enc1->se_shift->field_name, enc1->se_mask->field_name 460c41891cSEric Bernstein 470c41891cSEric Bernstein #define VBI_LINE_0 0 480c41891cSEric Bernstein #define DP_BLANK_MAX_RETRY 20 490c41891cSEric Bernstein #define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000 500c41891cSEric Bernstein 510c41891cSEric Bernstein 520c41891cSEric Bernstein enum { 530c41891cSEric Bernstein DP_MST_UPDATE_MAX_RETRY = 50 540c41891cSEric Bernstein }; 550c41891cSEric Bernstein 560c41891cSEric Bernstein #define CTX \ 570c41891cSEric Bernstein enc1->base.ctx 580c41891cSEric Bernstein 59c5011872SEric Bernstein void enc1_update_generic_info_packet( 600c41891cSEric Bernstein struct dcn10_stream_encoder *enc1, 610c41891cSEric Bernstein uint32_t packet_index, 620c41891cSEric Bernstein const struct dc_info_packet *info_packet) 630c41891cSEric Bernstein { 640c41891cSEric Bernstein uint32_t regval; 650c41891cSEric Bernstein /* TODOFPGA Figure out a proper number for max_retries polling for lock 660c41891cSEric Bernstein * use 50 for now. 670c41891cSEric Bernstein */ 680c41891cSEric Bernstein uint32_t max_retries = 50; 690c41891cSEric Bernstein 700c41891cSEric Bernstein /*we need turn on clock before programming AFMT block*/ 710c41891cSEric Bernstein REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); 720c41891cSEric Bernstein 730c41891cSEric Bernstein if (packet_index >= 8) 740c41891cSEric Bernstein ASSERT(0); 750c41891cSEric Bernstein 760c41891cSEric Bernstein /* poll dig_update_lock is not locked -> asic internal signal 770c41891cSEric Bernstein * assume otg master lock will unlock it 780c41891cSEric Bernstein */ 790c41891cSEric Bernstein /* REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, 800c41891cSEric Bernstein 0, 10, max_retries);*/ 810c41891cSEric Bernstein 820c41891cSEric Bernstein /* check if HW reading GSP memory */ 830c41891cSEric Bernstein REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT, 840c41891cSEric Bernstein 0, 10, max_retries); 850c41891cSEric Bernstein 860c41891cSEric Bernstein /* HW does is not reading GSP memory not reading too long -> 870c41891cSEric Bernstein * something wrong. clear GPS memory access and notify? 880c41891cSEric Bernstein * hw SW is writing to GSP memory 890c41891cSEric Bernstein */ 900c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1); 910c41891cSEric Bernstein 920c41891cSEric Bernstein /* choose which generic packet to use */ 930c41891cSEric Bernstein regval = REG_READ(AFMT_VBI_PACKET_CONTROL); 940c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL, 950c41891cSEric Bernstein AFMT_GENERIC_INDEX, packet_index); 960c41891cSEric Bernstein 970c41891cSEric Bernstein /* write generic packet header 980c41891cSEric Bernstein * (4th byte is for GENERIC0 only) 990c41891cSEric Bernstein */ 1000c41891cSEric Bernstein REG_SET_4(AFMT_GENERIC_HDR, 0, 1010c41891cSEric Bernstein AFMT_GENERIC_HB0, info_packet->hb0, 1020c41891cSEric Bernstein AFMT_GENERIC_HB1, info_packet->hb1, 1030c41891cSEric Bernstein AFMT_GENERIC_HB2, info_packet->hb2, 1040c41891cSEric Bernstein AFMT_GENERIC_HB3, info_packet->hb3); 1050c41891cSEric Bernstein 1060c41891cSEric Bernstein /* write generic packet contents 1070c41891cSEric Bernstein * (we never use last 4 bytes) 1080c41891cSEric Bernstein * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers 1090c41891cSEric Bernstein */ 1100c41891cSEric Bernstein { 1110c41891cSEric Bernstein const uint32_t *content = 1120c41891cSEric Bernstein (const uint32_t *) &info_packet->sb[0]; 1130c41891cSEric Bernstein 1140c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_0, *content++); 1150c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_1, *content++); 1160c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_2, *content++); 1170c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_3, *content++); 1180c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_4, *content++); 1190c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_5, *content++); 1200c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_6, *content++); 1210c41891cSEric Bernstein REG_WRITE(AFMT_GENERIC_7, *content); 1220c41891cSEric Bernstein } 1230c41891cSEric Bernstein 1240c41891cSEric Bernstein switch (packet_index) { 1250c41891cSEric Bernstein case 0: 1260c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 127abba907cSAnthony Koo AFMT_GENERIC0_IMMEDIATE_UPDATE, 1); 1280c41891cSEric Bernstein break; 1290c41891cSEric Bernstein case 1: 1300c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 131abba907cSAnthony Koo AFMT_GENERIC1_IMMEDIATE_UPDATE, 1); 1320c41891cSEric Bernstein break; 1330c41891cSEric Bernstein case 2: 1340c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 135abba907cSAnthony Koo AFMT_GENERIC2_IMMEDIATE_UPDATE, 1); 1360c41891cSEric Bernstein break; 1370c41891cSEric Bernstein case 3: 1380c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 139abba907cSAnthony Koo AFMT_GENERIC3_IMMEDIATE_UPDATE, 1); 1400c41891cSEric Bernstein break; 1410c41891cSEric Bernstein case 4: 1420c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 143abba907cSAnthony Koo AFMT_GENERIC4_IMMEDIATE_UPDATE, 1); 1440c41891cSEric Bernstein break; 1450c41891cSEric Bernstein case 5: 1460c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 147abba907cSAnthony Koo AFMT_GENERIC5_IMMEDIATE_UPDATE, 1); 1480c41891cSEric Bernstein break; 1490c41891cSEric Bernstein case 6: 1500c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 151abba907cSAnthony Koo AFMT_GENERIC6_IMMEDIATE_UPDATE, 1); 1520c41891cSEric Bernstein break; 1530c41891cSEric Bernstein case 7: 1540c41891cSEric Bernstein REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 155abba907cSAnthony Koo AFMT_GENERIC7_IMMEDIATE_UPDATE, 1); 1560c41891cSEric Bernstein break; 1570c41891cSEric Bernstein default: 1580c41891cSEric Bernstein break; 1590c41891cSEric Bernstein } 1600c41891cSEric Bernstein } 1610c41891cSEric Bernstein 1620c41891cSEric Bernstein static void enc1_update_hdmi_info_packet( 1630c41891cSEric Bernstein struct dcn10_stream_encoder *enc1, 1640c41891cSEric Bernstein uint32_t packet_index, 1650c41891cSEric Bernstein const struct dc_info_packet *info_packet) 1660c41891cSEric Bernstein { 1670c41891cSEric Bernstein uint32_t cont, send, line; 1680c41891cSEric Bernstein 1690c41891cSEric Bernstein if (info_packet->valid) { 1700c41891cSEric Bernstein enc1_update_generic_info_packet( 1710c41891cSEric Bernstein enc1, 1720c41891cSEric Bernstein packet_index, 1730c41891cSEric Bernstein info_packet); 1740c41891cSEric Bernstein 1750c41891cSEric Bernstein /* enable transmission of packet(s) - 1760c41891cSEric Bernstein * packet transmission begins on the next frame 1770c41891cSEric Bernstein */ 1780c41891cSEric Bernstein cont = 1; 1790c41891cSEric Bernstein /* send packet(s) every frame */ 1800c41891cSEric Bernstein send = 1; 1810c41891cSEric Bernstein /* select line number to send packets on */ 1820c41891cSEric Bernstein line = 2; 1830c41891cSEric Bernstein } else { 1840c41891cSEric Bernstein cont = 0; 1850c41891cSEric Bernstein send = 0; 1860c41891cSEric Bernstein line = 0; 1870c41891cSEric Bernstein } 1880c41891cSEric Bernstein 1890c41891cSEric Bernstein /* choose which generic packet control to use */ 1900c41891cSEric Bernstein switch (packet_index) { 1910c41891cSEric Bernstein case 0: 1920c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0, 1930c41891cSEric Bernstein HDMI_GENERIC0_CONT, cont, 1940c41891cSEric Bernstein HDMI_GENERIC0_SEND, send, 1950c41891cSEric Bernstein HDMI_GENERIC0_LINE, line); 1960c41891cSEric Bernstein break; 1970c41891cSEric Bernstein case 1: 1980c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0, 1990c41891cSEric Bernstein HDMI_GENERIC1_CONT, cont, 2000c41891cSEric Bernstein HDMI_GENERIC1_SEND, send, 2010c41891cSEric Bernstein HDMI_GENERIC1_LINE, line); 2020c41891cSEric Bernstein break; 2030c41891cSEric Bernstein case 2: 2040c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1, 2050c41891cSEric Bernstein HDMI_GENERIC0_CONT, cont, 2060c41891cSEric Bernstein HDMI_GENERIC0_SEND, send, 2070c41891cSEric Bernstein HDMI_GENERIC0_LINE, line); 2080c41891cSEric Bernstein break; 2090c41891cSEric Bernstein case 3: 2100c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1, 2110c41891cSEric Bernstein HDMI_GENERIC1_CONT, cont, 2120c41891cSEric Bernstein HDMI_GENERIC1_SEND, send, 2130c41891cSEric Bernstein HDMI_GENERIC1_LINE, line); 2140c41891cSEric Bernstein break; 2150c41891cSEric Bernstein case 4: 2160c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, 2170c41891cSEric Bernstein HDMI_GENERIC0_CONT, cont, 2180c41891cSEric Bernstein HDMI_GENERIC0_SEND, send, 2190c41891cSEric Bernstein HDMI_GENERIC0_LINE, line); 2200c41891cSEric Bernstein break; 2210c41891cSEric Bernstein case 5: 2220c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, 2230c41891cSEric Bernstein HDMI_GENERIC1_CONT, cont, 2240c41891cSEric Bernstein HDMI_GENERIC1_SEND, send, 2250c41891cSEric Bernstein HDMI_GENERIC1_LINE, line); 2260c41891cSEric Bernstein break; 2270c41891cSEric Bernstein case 6: 2280c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3, 2290c41891cSEric Bernstein HDMI_GENERIC0_CONT, cont, 2300c41891cSEric Bernstein HDMI_GENERIC0_SEND, send, 2310c41891cSEric Bernstein HDMI_GENERIC0_LINE, line); 2320c41891cSEric Bernstein break; 2330c41891cSEric Bernstein case 7: 2340c41891cSEric Bernstein REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3, 2350c41891cSEric Bernstein HDMI_GENERIC1_CONT, cont, 2360c41891cSEric Bernstein HDMI_GENERIC1_SEND, send, 2370c41891cSEric Bernstein HDMI_GENERIC1_LINE, line); 2380c41891cSEric Bernstein break; 2390c41891cSEric Bernstein default: 2400c41891cSEric Bernstein /* invalid HW packet index */ 2410c41891cSEric Bernstein DC_LOG_WARNING( 2420c41891cSEric Bernstein "Invalid HW packet index: %s()\n", 2430c41891cSEric Bernstein __func__); 2440c41891cSEric Bernstein return; 2450c41891cSEric Bernstein } 2460c41891cSEric Bernstein } 2470c41891cSEric Bernstein 2480c41891cSEric Bernstein /* setup stream encoder in dp mode */ 249c5011872SEric Bernstein void enc1_stream_encoder_dp_set_stream_attribute( 2500c41891cSEric Bernstein struct stream_encoder *enc, 2510c41891cSEric Bernstein struct dc_crtc_timing *crtc_timing, 252bb1cb98eSNikola Cornij enum dc_color_space output_color_space, 2535ed78cd6SAnthony Koo bool use_vsc_sdp_for_colorimetry, 254bb1cb98eSNikola Cornij uint32_t enable_sdp_splitting) 2550c41891cSEric Bernstein { 2560c41891cSEric Bernstein uint32_t h_active_start; 2570c41891cSEric Bernstein uint32_t v_active_start; 2580c41891cSEric Bernstein uint32_t misc0 = 0; 2590c41891cSEric Bernstein uint32_t misc1 = 0; 2600c41891cSEric Bernstein uint32_t h_blank; 2610c41891cSEric Bernstein uint32_t h_back_porch; 2620c41891cSEric Bernstein uint8_t synchronous_clock = 0; /* asynchronous mode */ 2630c41891cSEric Bernstein uint8_t colorimetry_bpc; 2640c41891cSEric Bernstein uint8_t dynamic_range_rgb = 0; /*full range*/ 2650c41891cSEric Bernstein uint8_t dynamic_range_ycbcr = 1; /*bt709*/ 26612036586SEric Bernstein uint8_t dp_pixel_encoding = 0; 26712036586SEric Bernstein uint8_t dp_component_depth = 0; 2680c41891cSEric Bernstein 2690c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 2709983b800SCharlene Liu struct dc_crtc_timing hw_crtc_timing = *crtc_timing; 2719983b800SCharlene Liu 2729983b800SCharlene Liu if (hw_crtc_timing.flags.INTERLACE) { 2739983b800SCharlene Liu /*the input timing is in VESA spec format with Interlace flag =1*/ 2749983b800SCharlene Liu hw_crtc_timing.v_total /= 2; 2759983b800SCharlene Liu hw_crtc_timing.v_border_top /= 2; 2769983b800SCharlene Liu hw_crtc_timing.v_addressable /= 2; 2779983b800SCharlene Liu hw_crtc_timing.v_border_bottom /= 2; 2789983b800SCharlene Liu hw_crtc_timing.v_front_porch /= 2; 2799983b800SCharlene Liu hw_crtc_timing.v_sync_width /= 2; 2809983b800SCharlene Liu } 2819983b800SCharlene Liu 2820c41891cSEric Bernstein 2830c41891cSEric Bernstein /* set pixel encoding */ 2849983b800SCharlene Liu switch (hw_crtc_timing.pixel_encoding) { 2850c41891cSEric Bernstein case PIXEL_ENCODING_YCBCR422: 28612036586SEric Bernstein dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_YCBCR422; 2870c41891cSEric Bernstein break; 2880c41891cSEric Bernstein case PIXEL_ENCODING_YCBCR444: 28912036586SEric Bernstein dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_YCBCR444; 2900c41891cSEric Bernstein 2919983b800SCharlene Liu if (hw_crtc_timing.flags.Y_ONLY) 2929983b800SCharlene Liu if (hw_crtc_timing.display_color_depth != COLOR_DEPTH_666) 2930c41891cSEric Bernstein /* HW testing only, no use case yet. 2940c41891cSEric Bernstein * Color depth of Y-only could be 2950c41891cSEric Bernstein * 8, 10, 12, 16 bits 2960c41891cSEric Bernstein */ 29712036586SEric Bernstein dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_Y_ONLY; 29812036586SEric Bernstein 2990c41891cSEric Bernstein /* Note: DP_MSA_MISC1 bit 7 is the indicator 3000c41891cSEric Bernstein * of Y-only mode. 3010c41891cSEric Bernstein * This bit is set in HW if register 3020c41891cSEric Bernstein * DP_PIXEL_ENCODING is programmed to 0x4 3030c41891cSEric Bernstein */ 3040c41891cSEric Bernstein break; 3050c41891cSEric Bernstein case PIXEL_ENCODING_YCBCR420: 30612036586SEric Bernstein dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_YCBCR420; 3070c41891cSEric Bernstein break; 3080c41891cSEric Bernstein default: 30912036586SEric Bernstein dp_pixel_encoding = DP_PIXEL_ENCODING_TYPE_RGB444; 3100c41891cSEric Bernstein break; 3110c41891cSEric Bernstein } 3120c41891cSEric Bernstein 3130c41891cSEric Bernstein misc1 = REG_READ(DP_MSA_MISC); 3140b126112SEric Bernstein /* For YCbCr420 and BT2020 Colorimetry Formats, VSC SDP shall be used. 3150b126112SEric Bernstein * When MISC1, bit 6, is Set to 1, a Source device uses a VSC SDP to indicate the 3160b126112SEric Bernstein * Pixel Encoding/Colorimetry Format and that a Sink device shall ignore MISC1, bit 7, 317b7355232SKrunoslav Kovac * and MISC0, bits 7:1 (MISC1, bit 7, and MISC0, bits 7:1, become "don't care"). 3180b126112SEric Bernstein */ 3195ed78cd6SAnthony Koo if (use_vsc_sdp_for_colorimetry) 3200b126112SEric Bernstein misc1 = misc1 | 0x40; 3210b126112SEric Bernstein else 3220b126112SEric Bernstein misc1 = misc1 & ~0x40; 3230c41891cSEric Bernstein 3240c41891cSEric Bernstein /* set color depth */ 3259983b800SCharlene Liu switch (hw_crtc_timing.display_color_depth) { 3260c41891cSEric Bernstein case COLOR_DEPTH_666: 32712036586SEric Bernstein dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_6BPC; 3280c41891cSEric Bernstein break; 3290c41891cSEric Bernstein case COLOR_DEPTH_888: 33012036586SEric Bernstein dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_8BPC; 3310c41891cSEric Bernstein break; 3320c41891cSEric Bernstein case COLOR_DEPTH_101010: 33312036586SEric Bernstein dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_10BPC; 3340c41891cSEric Bernstein break; 3350c41891cSEric Bernstein case COLOR_DEPTH_121212: 33612036586SEric Bernstein dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_12BPC; 3370c41891cSEric Bernstein break; 33801884c02SEric Bernstein case COLOR_DEPTH_161616: 33912036586SEric Bernstein dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_16BPC; 34001884c02SEric Bernstein break; 3410c41891cSEric Bernstein default: 34212036586SEric Bernstein dp_component_depth = DP_COMPONENT_PIXEL_DEPTH_6BPC; 3430c41891cSEric Bernstein break; 3440c41891cSEric Bernstein } 3450c41891cSEric Bernstein 34612036586SEric Bernstein /* Set DP pixel encoding and component depth */ 34712036586SEric Bernstein REG_UPDATE_2(DP_PIXEL_FORMAT, 34812036586SEric Bernstein DP_PIXEL_ENCODING, dp_pixel_encoding, 34912036586SEric Bernstein DP_COMPONENT_DEPTH, dp_component_depth); 35012036586SEric Bernstein 3510c41891cSEric Bernstein /* set dynamic range and YCbCr range */ 3520c41891cSEric Bernstein 3539983b800SCharlene Liu switch (hw_crtc_timing.display_color_depth) { 3540c41891cSEric Bernstein case COLOR_DEPTH_666: 3550c41891cSEric Bernstein colorimetry_bpc = 0; 3560c41891cSEric Bernstein break; 3570c41891cSEric Bernstein case COLOR_DEPTH_888: 3580c41891cSEric Bernstein colorimetry_bpc = 1; 3590c41891cSEric Bernstein break; 3600c41891cSEric Bernstein case COLOR_DEPTH_101010: 3610c41891cSEric Bernstein colorimetry_bpc = 2; 3620c41891cSEric Bernstein break; 3630c41891cSEric Bernstein case COLOR_DEPTH_121212: 3640c41891cSEric Bernstein colorimetry_bpc = 3; 3650c41891cSEric Bernstein break; 3660c41891cSEric Bernstein default: 3670c41891cSEric Bernstein colorimetry_bpc = 0; 3680c41891cSEric Bernstein break; 3690c41891cSEric Bernstein } 3700c41891cSEric Bernstein 3710c41891cSEric Bernstein misc0 = misc0 | synchronous_clock; 3720c41891cSEric Bernstein misc0 = colorimetry_bpc << 5; 3730c41891cSEric Bernstein 3740c41891cSEric Bernstein switch (output_color_space) { 3750c41891cSEric Bernstein case COLOR_SPACE_SRGB: 3760c41891cSEric Bernstein misc1 = misc1 & ~0x80; /* bit7 = 0*/ 3770c41891cSEric Bernstein dynamic_range_rgb = 0; /*full range*/ 3780c41891cSEric Bernstein break; 3790c41891cSEric Bernstein case COLOR_SPACE_SRGB_LIMITED: 3800c41891cSEric Bernstein misc0 = misc0 | 0x8; /* bit3=1 */ 3810c41891cSEric Bernstein misc1 = misc1 & ~0x80; /* bit7 = 0*/ 3820c41891cSEric Bernstein dynamic_range_rgb = 1; /*limited range*/ 3830c41891cSEric Bernstein break; 3840c41891cSEric Bernstein case COLOR_SPACE_YCBCR601: 3850c41891cSEric Bernstein case COLOR_SPACE_YCBCR601_LIMITED: 3860c41891cSEric Bernstein misc0 = misc0 | 0x8; /* bit3=1, bit4=0 */ 3870c41891cSEric Bernstein misc1 = misc1 & ~0x80; /* bit7 = 0*/ 3880c41891cSEric Bernstein dynamic_range_ycbcr = 0; /*bt601*/ 3899983b800SCharlene Liu if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) 3900c41891cSEric Bernstein misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */ 3919983b800SCharlene Liu else if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR444) 3920c41891cSEric Bernstein misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */ 3930c41891cSEric Bernstein break; 3940c41891cSEric Bernstein case COLOR_SPACE_YCBCR709: 3950c41891cSEric Bernstein case COLOR_SPACE_YCBCR709_LIMITED: 3960c41891cSEric Bernstein misc0 = misc0 | 0x18; /* bit3=1, bit4=1 */ 3970c41891cSEric Bernstein misc1 = misc1 & ~0x80; /* bit7 = 0*/ 3980c41891cSEric Bernstein dynamic_range_ycbcr = 1; /*bt709*/ 3999983b800SCharlene Liu if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) 4000c41891cSEric Bernstein misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */ 4019983b800SCharlene Liu else if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR444) 4020c41891cSEric Bernstein misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */ 4030c41891cSEric Bernstein break; 4040c41891cSEric Bernstein case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 4050c41891cSEric Bernstein dynamic_range_rgb = 1; /*limited range*/ 4060c41891cSEric Bernstein break; 4070c41891cSEric Bernstein case COLOR_SPACE_2020_RGB_FULLRANGE: 4080c41891cSEric Bernstein case COLOR_SPACE_2020_YCBCR: 4090c41891cSEric Bernstein case COLOR_SPACE_XR_RGB: 4100c41891cSEric Bernstein case COLOR_SPACE_MSREF_SCRGB: 4110c41891cSEric Bernstein case COLOR_SPACE_ADOBERGB: 4120c41891cSEric Bernstein case COLOR_SPACE_DCIP3: 4130c41891cSEric Bernstein case COLOR_SPACE_XV_YCC_709: 4140c41891cSEric Bernstein case COLOR_SPACE_XV_YCC_601: 4150c41891cSEric Bernstein case COLOR_SPACE_DISPLAYNATIVE: 4160c41891cSEric Bernstein case COLOR_SPACE_DOLBYVISION: 4170c41891cSEric Bernstein case COLOR_SPACE_APPCTRL: 4180c41891cSEric Bernstein case COLOR_SPACE_CUSTOMPOINTS: 4190c41891cSEric Bernstein case COLOR_SPACE_UNKNOWN: 42040df2f80SCharlene Liu case COLOR_SPACE_YCBCR709_BLACK: 4210c41891cSEric Bernstein /* do nothing */ 4220c41891cSEric Bernstein break; 4230c41891cSEric Bernstein } 4240c41891cSEric Bernstein 4250c41891cSEric Bernstein REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0); 4260c41891cSEric Bernstein REG_WRITE(DP_MSA_MISC, misc1); /* MSA_MISC1 */ 4270c41891cSEric Bernstein 4280c41891cSEric Bernstein /* dcn new register 4290c41891cSEric Bernstein * dc_crtc_timing is vesa dmt struct. data from edid 4300c41891cSEric Bernstein */ 4310c41891cSEric Bernstein REG_SET_2(DP_MSA_TIMING_PARAM1, 0, 4329983b800SCharlene Liu DP_MSA_HTOTAL, hw_crtc_timing.h_total, 4339983b800SCharlene Liu DP_MSA_VTOTAL, hw_crtc_timing.v_total); 4340c41891cSEric Bernstein 4350c41891cSEric Bernstein /* calculate from vesa timing parameters 4360c41891cSEric Bernstein * h_active_start related to leading edge of sync 4370c41891cSEric Bernstein */ 4380c41891cSEric Bernstein 4399983b800SCharlene Liu h_blank = hw_crtc_timing.h_total - hw_crtc_timing.h_border_left - 4409983b800SCharlene Liu hw_crtc_timing.h_addressable - hw_crtc_timing.h_border_right; 4410c41891cSEric Bernstein 4429983b800SCharlene Liu h_back_porch = h_blank - hw_crtc_timing.h_front_porch - 4439983b800SCharlene Liu hw_crtc_timing.h_sync_width; 4440c41891cSEric Bernstein 4450c41891cSEric Bernstein /* start at beginning of left border */ 4469983b800SCharlene Liu h_active_start = hw_crtc_timing.h_sync_width + h_back_porch; 4470c41891cSEric Bernstein 4480c41891cSEric Bernstein 4499983b800SCharlene Liu v_active_start = hw_crtc_timing.v_total - hw_crtc_timing.v_border_top - 4509983b800SCharlene Liu hw_crtc_timing.v_addressable - hw_crtc_timing.v_border_bottom - 4519983b800SCharlene Liu hw_crtc_timing.v_front_porch; 4520c41891cSEric Bernstein 4530c41891cSEric Bernstein 4540c41891cSEric Bernstein /* start at beginning of left border */ 4550c41891cSEric Bernstein REG_SET_2(DP_MSA_TIMING_PARAM2, 0, 4560c41891cSEric Bernstein DP_MSA_HSTART, h_active_start, 4570c41891cSEric Bernstein DP_MSA_VSTART, v_active_start); 4580c41891cSEric Bernstein 4590c41891cSEric Bernstein REG_SET_4(DP_MSA_TIMING_PARAM3, 0, 4600c41891cSEric Bernstein DP_MSA_HSYNCWIDTH, 4619983b800SCharlene Liu hw_crtc_timing.h_sync_width, 4620c41891cSEric Bernstein DP_MSA_HSYNCPOLARITY, 4639983b800SCharlene Liu !hw_crtc_timing.flags.HSYNC_POSITIVE_POLARITY, 4640c41891cSEric Bernstein DP_MSA_VSYNCWIDTH, 4659983b800SCharlene Liu hw_crtc_timing.v_sync_width, 4660c41891cSEric Bernstein DP_MSA_VSYNCPOLARITY, 4679983b800SCharlene Liu !hw_crtc_timing.flags.VSYNC_POSITIVE_POLARITY); 4680c41891cSEric Bernstein 4690c41891cSEric Bernstein /* HWDITH include border or overscan */ 4700c41891cSEric Bernstein REG_SET_2(DP_MSA_TIMING_PARAM4, 0, 4719983b800SCharlene Liu DP_MSA_HWIDTH, hw_crtc_timing.h_border_left + 4729983b800SCharlene Liu hw_crtc_timing.h_addressable + hw_crtc_timing.h_border_right, 4739983b800SCharlene Liu DP_MSA_VHEIGHT, hw_crtc_timing.v_border_top + 4749983b800SCharlene Liu hw_crtc_timing.v_addressable + hw_crtc_timing.v_border_bottom); 4750c41891cSEric Bernstein } 4760c41891cSEric Bernstein 477c5c07cb5SEric Bernstein void enc1_stream_encoder_set_stream_attribute_helper( 4780c41891cSEric Bernstein struct dcn10_stream_encoder *enc1, 4790c41891cSEric Bernstein struct dc_crtc_timing *crtc_timing) 4800c41891cSEric Bernstein { 4810c41891cSEric Bernstein switch (crtc_timing->pixel_encoding) { 4820c41891cSEric Bernstein case PIXEL_ENCODING_YCBCR422: 4830c41891cSEric Bernstein REG_UPDATE(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, 1); 4840c41891cSEric Bernstein break; 4850c41891cSEric Bernstein default: 4860c41891cSEric Bernstein REG_UPDATE(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, 0); 4870c41891cSEric Bernstein break; 4880c41891cSEric Bernstein } 4890c41891cSEric Bernstein REG_UPDATE(DIG_FE_CNTL, TMDS_COLOR_FORMAT, 0); 4900c41891cSEric Bernstein } 4910c41891cSEric Bernstein 4920c41891cSEric Bernstein /* setup stream encoder in hdmi mode */ 493c5011872SEric Bernstein void enc1_stream_encoder_hdmi_set_stream_attribute( 4940c41891cSEric Bernstein struct stream_encoder *enc, 4950c41891cSEric Bernstein struct dc_crtc_timing *crtc_timing, 4960c41891cSEric Bernstein int actual_pix_clk_khz, 4970c41891cSEric Bernstein bool enable_audio) 4980c41891cSEric Bernstein { 4990c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 5000c41891cSEric Bernstein struct bp_encoder_control cntl = {0}; 5010c41891cSEric Bernstein 5020c41891cSEric Bernstein cntl.action = ENCODER_CONTROL_SETUP; 5030c41891cSEric Bernstein cntl.engine_id = enc1->base.id; 5040c41891cSEric Bernstein cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A; 5050c41891cSEric Bernstein cntl.enable_dp_audio = enable_audio; 5060c41891cSEric Bernstein cntl.pixel_clock = actual_pix_clk_khz; 5070c41891cSEric Bernstein cntl.lanes_number = LANE_COUNT_FOUR; 5080c41891cSEric Bernstein 5090c41891cSEric Bernstein if (enc1->base.bp->funcs->encoder_control( 5100c41891cSEric Bernstein enc1->base.bp, &cntl) != BP_RESULT_OK) 5110c41891cSEric Bernstein return; 5120c41891cSEric Bernstein 5130c41891cSEric Bernstein enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing); 5140c41891cSEric Bernstein 5150c41891cSEric Bernstein /* setup HDMI engine */ 51603f3e40cSCharlene Liu REG_UPDATE_6(HDMI_CONTROL, 5170c41891cSEric Bernstein HDMI_PACKET_GEN_VERSION, 1, 5180c41891cSEric Bernstein HDMI_KEEPOUT_MODE, 1, 5190c41891cSEric Bernstein HDMI_DEEP_COLOR_ENABLE, 0, 5200c41891cSEric Bernstein HDMI_DATA_SCRAMBLE_EN, 0, 52103f3e40cSCharlene Liu HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1, 5220c41891cSEric Bernstein HDMI_CLOCK_CHANNEL_RATE, 0); 5230c41891cSEric Bernstein 5240c41891cSEric Bernstein 5250c41891cSEric Bernstein switch (crtc_timing->display_color_depth) { 5260c41891cSEric Bernstein case COLOR_DEPTH_888: 5270c41891cSEric Bernstein REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0); 5283341d30dSPraful Swarnakar DC_LOG_DEBUG("HDMI source set to 24BPP deep color depth\n"); 5290c41891cSEric Bernstein break; 5300c41891cSEric Bernstein case COLOR_DEPTH_101010: 5310c41891cSEric Bernstein if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) { 5320c41891cSEric Bernstein REG_UPDATE_2(HDMI_CONTROL, 5330c41891cSEric Bernstein HDMI_DEEP_COLOR_DEPTH, 1, 5340c41891cSEric Bernstein HDMI_DEEP_COLOR_ENABLE, 0); 5353341d30dSPraful Swarnakar DC_LOG_DEBUG("HDMI source 30BPP deep color depth" \ 5363341d30dSPraful Swarnakar "disabled for YCBCR422 pixel encoding\n"); 5370c41891cSEric Bernstein } else { 5380c41891cSEric Bernstein REG_UPDATE_2(HDMI_CONTROL, 5390c41891cSEric Bernstein HDMI_DEEP_COLOR_DEPTH, 1, 5400c41891cSEric Bernstein HDMI_DEEP_COLOR_ENABLE, 1); 5413341d30dSPraful Swarnakar DC_LOG_DEBUG("HDMI source 30BPP deep color depth" \ 5423341d30dSPraful Swarnakar "enabled for YCBCR422 non-pixel encoding\n"); 5430c41891cSEric Bernstein } 5440c41891cSEric Bernstein break; 5450c41891cSEric Bernstein case COLOR_DEPTH_121212: 5460c41891cSEric Bernstein if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) { 5470c41891cSEric Bernstein REG_UPDATE_2(HDMI_CONTROL, 5480c41891cSEric Bernstein HDMI_DEEP_COLOR_DEPTH, 2, 5490c41891cSEric Bernstein HDMI_DEEP_COLOR_ENABLE, 0); 5503341d30dSPraful Swarnakar DC_LOG_DEBUG("HDMI source 36BPP deep color depth" \ 5513341d30dSPraful Swarnakar "disabled for YCBCR422 pixel encoding\n"); 5520c41891cSEric Bernstein } else { 5530c41891cSEric Bernstein REG_UPDATE_2(HDMI_CONTROL, 5540c41891cSEric Bernstein HDMI_DEEP_COLOR_DEPTH, 2, 5550c41891cSEric Bernstein HDMI_DEEP_COLOR_ENABLE, 1); 5563341d30dSPraful Swarnakar DC_LOG_DEBUG("HDMI source 36BPP deep color depth" \ 5573341d30dSPraful Swarnakar "enabled for non-pixel YCBCR422 encoding\n"); 5580c41891cSEric Bernstein } 5590c41891cSEric Bernstein break; 5600c41891cSEric Bernstein case COLOR_DEPTH_161616: 5610c41891cSEric Bernstein REG_UPDATE_2(HDMI_CONTROL, 5620c41891cSEric Bernstein HDMI_DEEP_COLOR_DEPTH, 3, 5630c41891cSEric Bernstein HDMI_DEEP_COLOR_ENABLE, 1); 5643341d30dSPraful Swarnakar DC_LOG_DEBUG("HDMI source deep color depth enabled in" \ 5653341d30dSPraful Swarnakar "reserved mode\n"); 5660c41891cSEric Bernstein break; 5670c41891cSEric Bernstein default: 5680c41891cSEric Bernstein break; 5690c41891cSEric Bernstein } 5700c41891cSEric Bernstein 5710c41891cSEric Bernstein if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) { 5720c41891cSEric Bernstein /* enable HDMI data scrambler 5730c41891cSEric Bernstein * HDMI_CLOCK_CHANNEL_RATE_MORE_340M 5740c41891cSEric Bernstein * Clock channel frequency is 1/4 of character rate. 5750c41891cSEric Bernstein */ 5760c41891cSEric Bernstein REG_UPDATE_2(HDMI_CONTROL, 5770c41891cSEric Bernstein HDMI_DATA_SCRAMBLE_EN, 1, 5780c41891cSEric Bernstein HDMI_CLOCK_CHANNEL_RATE, 1); 5790c41891cSEric Bernstein } else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) { 5800c41891cSEric Bernstein 5810c41891cSEric Bernstein /* TODO: New feature for DCE11, still need to implement */ 5820c41891cSEric Bernstein 5830c41891cSEric Bernstein /* enable HDMI data scrambler 5840c41891cSEric Bernstein * HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE 5850c41891cSEric Bernstein * Clock channel frequency is the same 5860c41891cSEric Bernstein * as character rate 5870c41891cSEric Bernstein */ 5880c41891cSEric Bernstein REG_UPDATE_2(HDMI_CONTROL, 5890c41891cSEric Bernstein HDMI_DATA_SCRAMBLE_EN, 1, 5900c41891cSEric Bernstein HDMI_CLOCK_CHANNEL_RATE, 0); 5910c41891cSEric Bernstein } 5920c41891cSEric Bernstein 5930c41891cSEric Bernstein 5940c41891cSEric Bernstein REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL, 5950c41891cSEric Bernstein HDMI_GC_CONT, 1, 5960c41891cSEric Bernstein HDMI_GC_SEND, 1, 5970c41891cSEric Bernstein HDMI_NULL_SEND, 1); 5980c41891cSEric Bernstein 5990c41891cSEric Bernstein /* following belongs to audio */ 6000c41891cSEric Bernstein REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1); 6010c41891cSEric Bernstein 6020c41891cSEric Bernstein REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1); 6030c41891cSEric Bernstein 6040c41891cSEric Bernstein REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE, 6050c41891cSEric Bernstein VBI_LINE_0 + 2); 6060c41891cSEric Bernstein 6070c41891cSEric Bernstein REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0); 6080c41891cSEric Bernstein } 6090c41891cSEric Bernstein 6100c41891cSEric Bernstein /* setup stream encoder in dvi mode */ 611c5011872SEric Bernstein void enc1_stream_encoder_dvi_set_stream_attribute( 6120c41891cSEric Bernstein struct stream_encoder *enc, 6130c41891cSEric Bernstein struct dc_crtc_timing *crtc_timing, 6140c41891cSEric Bernstein bool is_dual_link) 6150c41891cSEric Bernstein { 6160c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 6170c41891cSEric Bernstein struct bp_encoder_control cntl = {0}; 6180c41891cSEric Bernstein 6190c41891cSEric Bernstein cntl.action = ENCODER_CONTROL_SETUP; 6200c41891cSEric Bernstein cntl.engine_id = enc1->base.id; 6210c41891cSEric Bernstein cntl.signal = is_dual_link ? 6220c41891cSEric Bernstein SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK; 6230c41891cSEric Bernstein cntl.enable_dp_audio = false; 624380604e2SKen Chalmers cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10; 6250c41891cSEric Bernstein cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR; 6260c41891cSEric Bernstein 6270c41891cSEric Bernstein if (enc1->base.bp->funcs->encoder_control( 6280c41891cSEric Bernstein enc1->base.bp, &cntl) != BP_RESULT_OK) 6290c41891cSEric Bernstein return; 6300c41891cSEric Bernstein 6310c41891cSEric Bernstein ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB); 6320c41891cSEric Bernstein ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888); 6330c41891cSEric Bernstein enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing); 6340c41891cSEric Bernstein } 6350c41891cSEric Bernstein 6366c95320dSGeorge Shen void enc1_stream_encoder_set_throttled_vcp_size( 6370c41891cSEric Bernstein struct stream_encoder *enc, 6380c41891cSEric Bernstein struct fixed31_32 avg_time_slots_per_mtp) 6390c41891cSEric Bernstein { 6400c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 641eb0e5154SDmytro Laktyushkin uint32_t x = dc_fixpt_floor( 6420c41891cSEric Bernstein avg_time_slots_per_mtp); 643eb0e5154SDmytro Laktyushkin uint32_t y = dc_fixpt_ceil( 644eb0e5154SDmytro Laktyushkin dc_fixpt_shl( 645eb0e5154SDmytro Laktyushkin dc_fixpt_sub_int( 6460c41891cSEric Bernstein avg_time_slots_per_mtp, 6470c41891cSEric Bernstein x), 6480c41891cSEric Bernstein 26)); 6490c41891cSEric Bernstein 6500c41891cSEric Bernstein REG_SET_2(DP_MSE_RATE_CNTL, 0, 6510c41891cSEric Bernstein DP_MSE_RATE_X, x, 6520c41891cSEric Bernstein DP_MSE_RATE_Y, y); 6530c41891cSEric Bernstein 6540c41891cSEric Bernstein /* wait for update to be completed on the link */ 6550c41891cSEric Bernstein /* i.e. DP_MSE_RATE_UPDATE_PENDING field (read only) */ 6560c41891cSEric Bernstein /* is reset to 0 (not pending) */ 6570c41891cSEric Bernstein REG_WAIT(DP_MSE_RATE_UPDATE, DP_MSE_RATE_UPDATE_PENDING, 6580c41891cSEric Bernstein 0, 6590c41891cSEric Bernstein 10, DP_MST_UPDATE_MAX_RETRY); 6600c41891cSEric Bernstein } 6610c41891cSEric Bernstein 6620c41891cSEric Bernstein static void enc1_stream_encoder_update_hdmi_info_packets( 6630c41891cSEric Bernstein struct stream_encoder *enc, 6640c41891cSEric Bernstein const struct encoder_info_frame *info_frame) 6650c41891cSEric Bernstein { 6660c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 6670c41891cSEric Bernstein 6680c41891cSEric Bernstein /* for bring up, disable dp double TODO */ 6690c41891cSEric Bernstein REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1); 6700c41891cSEric Bernstein 6710c41891cSEric Bernstein enc1_update_hdmi_info_packet(enc1, 0, &info_frame->avi); 6720c41891cSEric Bernstein enc1_update_hdmi_info_packet(enc1, 1, &info_frame->vendor); 6730c41891cSEric Bernstein enc1_update_hdmi_info_packet(enc1, 2, &info_frame->gamut); 6740c41891cSEric Bernstein enc1_update_hdmi_info_packet(enc1, 3, &info_frame->spd); 6750c41891cSEric Bernstein enc1_update_hdmi_info_packet(enc1, 4, &info_frame->hdrsmd); 6760c41891cSEric Bernstein } 6770c41891cSEric Bernstein 6780c41891cSEric Bernstein static void enc1_stream_encoder_stop_hdmi_info_packets( 6790c41891cSEric Bernstein struct stream_encoder *enc) 6800c41891cSEric Bernstein { 6810c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 6820c41891cSEric Bernstein 6830c41891cSEric Bernstein /* stop generic packets 0 & 1 on HDMI */ 6840c41891cSEric Bernstein REG_SET_6(HDMI_GENERIC_PACKET_CONTROL0, 0, 6850c41891cSEric Bernstein HDMI_GENERIC1_CONT, 0, 6860c41891cSEric Bernstein HDMI_GENERIC1_LINE, 0, 6870c41891cSEric Bernstein HDMI_GENERIC1_SEND, 0, 6880c41891cSEric Bernstein HDMI_GENERIC0_CONT, 0, 6890c41891cSEric Bernstein HDMI_GENERIC0_LINE, 0, 6900c41891cSEric Bernstein HDMI_GENERIC0_SEND, 0); 6910c41891cSEric Bernstein 6920c41891cSEric Bernstein /* stop generic packets 2 & 3 on HDMI */ 6930c41891cSEric Bernstein REG_SET_6(HDMI_GENERIC_PACKET_CONTROL1, 0, 6940c41891cSEric Bernstein HDMI_GENERIC0_CONT, 0, 6950c41891cSEric Bernstein HDMI_GENERIC0_LINE, 0, 6960c41891cSEric Bernstein HDMI_GENERIC0_SEND, 0, 6970c41891cSEric Bernstein HDMI_GENERIC1_CONT, 0, 6980c41891cSEric Bernstein HDMI_GENERIC1_LINE, 0, 6990c41891cSEric Bernstein HDMI_GENERIC1_SEND, 0); 7000c41891cSEric Bernstein 7010c41891cSEric Bernstein /* stop generic packets 2 & 3 on HDMI */ 7020c41891cSEric Bernstein REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0, 7030c41891cSEric Bernstein HDMI_GENERIC0_CONT, 0, 7040c41891cSEric Bernstein HDMI_GENERIC0_LINE, 0, 7050c41891cSEric Bernstein HDMI_GENERIC0_SEND, 0, 7060c41891cSEric Bernstein HDMI_GENERIC1_CONT, 0, 7070c41891cSEric Bernstein HDMI_GENERIC1_LINE, 0, 7080c41891cSEric Bernstein HDMI_GENERIC1_SEND, 0); 7090c41891cSEric Bernstein 7100c41891cSEric Bernstein REG_SET_6(HDMI_GENERIC_PACKET_CONTROL3, 0, 7110c41891cSEric Bernstein HDMI_GENERIC0_CONT, 0, 7120c41891cSEric Bernstein HDMI_GENERIC0_LINE, 0, 7130c41891cSEric Bernstein HDMI_GENERIC0_SEND, 0, 7140c41891cSEric Bernstein HDMI_GENERIC1_CONT, 0, 7150c41891cSEric Bernstein HDMI_GENERIC1_LINE, 0, 7160c41891cSEric Bernstein HDMI_GENERIC1_SEND, 0); 7170c41891cSEric Bernstein } 7180c41891cSEric Bernstein 719c5011872SEric Bernstein void enc1_stream_encoder_update_dp_info_packets( 7200c41891cSEric Bernstein struct stream_encoder *enc, 7210c41891cSEric Bernstein const struct encoder_info_frame *info_frame) 7220c41891cSEric Bernstein { 7230c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 724388277b1SAnthony Koo uint32_t value = 0; 7250c41891cSEric Bernstein 7260c41891cSEric Bernstein if (info_frame->vsc.valid) 7270c41891cSEric Bernstein enc1_update_generic_info_packet( 7280c41891cSEric Bernstein enc1, 7290c41891cSEric Bernstein 0, /* packetIndex */ 7300c41891cSEric Bernstein &info_frame->vsc); 7310c41891cSEric Bernstein 73294b1c9c7SWyatt Wood /* VSC SDP at packetIndex 1 is used by PSR in DMCUB FW. 73394b1c9c7SWyatt Wood * Note that the enablement of GSP1 is not done below, 73494b1c9c7SWyatt Wood * it's done in FW. 73594b1c9c7SWyatt Wood */ 73694b1c9c7SWyatt Wood if (info_frame->vsc.valid) 73794b1c9c7SWyatt Wood enc1_update_generic_info_packet( 73894b1c9c7SWyatt Wood enc1, 73994b1c9c7SWyatt Wood 1, /* packetIndex */ 74094b1c9c7SWyatt Wood &info_frame->vsc); 74194b1c9c7SWyatt Wood 7420c41891cSEric Bernstein if (info_frame->spd.valid) 7430c41891cSEric Bernstein enc1_update_generic_info_packet( 7440c41891cSEric Bernstein enc1, 7450c41891cSEric Bernstein 2, /* packetIndex */ 7460c41891cSEric Bernstein &info_frame->spd); 7470c41891cSEric Bernstein 7480c41891cSEric Bernstein if (info_frame->hdrsmd.valid) 7490c41891cSEric Bernstein enc1_update_generic_info_packet( 7500c41891cSEric Bernstein enc1, 7510c41891cSEric Bernstein 3, /* packetIndex */ 7520c41891cSEric Bernstein &info_frame->hdrsmd); 7530c41891cSEric Bernstein 75488ccdf1dSLeo (Hanghong) Ma /* packetIndex 4 is used for send immediate sdp message, and please 75588ccdf1dSLeo (Hanghong) Ma * use other packetIndex (such as 5,6) for other info packet 75688ccdf1dSLeo (Hanghong) Ma */ 757d5f90f3aSLeo (Hanghong) Ma 7580c41891cSEric Bernstein /* enable/disable transmission of packet(s). 7590c41891cSEric Bernstein * If enabled, packet transmission begins on the next frame 7600c41891cSEric Bernstein */ 7610c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, info_frame->vsc.valid); 7620c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, info_frame->spd.valid); 7630c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, info_frame->hdrsmd.valid); 76488ccdf1dSLeo (Hanghong) Ma 76588ccdf1dSLeo (Hanghong) Ma /* This bit is the master enable bit. 76688ccdf1dSLeo (Hanghong) Ma * When enabling secondary stream engine, 76788ccdf1dSLeo (Hanghong) Ma * this master bit must also be set. 76888ccdf1dSLeo (Hanghong) Ma * This register shared with audio info frame. 76988ccdf1dSLeo (Hanghong) Ma * Therefore we need to enable master bit 77088ccdf1dSLeo (Hanghong) Ma * if at least on of the fields is not 0 77188ccdf1dSLeo (Hanghong) Ma */ 77288ccdf1dSLeo (Hanghong) Ma value = REG_READ(DP_SEC_CNTL); 77388ccdf1dSLeo (Hanghong) Ma if (value) 77488ccdf1dSLeo (Hanghong) Ma REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 77588ccdf1dSLeo (Hanghong) Ma } 77688ccdf1dSLeo (Hanghong) Ma 77788ccdf1dSLeo (Hanghong) Ma void enc1_stream_encoder_send_immediate_sdp_message( 77888ccdf1dSLeo (Hanghong) Ma struct stream_encoder *enc, 77988ccdf1dSLeo (Hanghong) Ma const uint8_t *custom_sdp_message, 78088ccdf1dSLeo (Hanghong) Ma unsigned int sdp_message_size) 78188ccdf1dSLeo (Hanghong) Ma { 78288ccdf1dSLeo (Hanghong) Ma struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 78388ccdf1dSLeo (Hanghong) Ma uint32_t value = 0; 78488ccdf1dSLeo (Hanghong) Ma 78588ccdf1dSLeo (Hanghong) Ma /* TODOFPGA Figure out a proper number for max_retries polling for lock 78688ccdf1dSLeo (Hanghong) Ma * use 50 for now. 78788ccdf1dSLeo (Hanghong) Ma */ 78888ccdf1dSLeo (Hanghong) Ma uint32_t max_retries = 50; 78988ccdf1dSLeo (Hanghong) Ma 79088ccdf1dSLeo (Hanghong) Ma /* check if GSP4 is transmitted */ 79188ccdf1dSLeo (Hanghong) Ma REG_WAIT(DP_SEC_CNTL2, DP_SEC_GSP4_SEND_PENDING, 79288ccdf1dSLeo (Hanghong) Ma 0, 10, max_retries); 79388ccdf1dSLeo (Hanghong) Ma 79488ccdf1dSLeo (Hanghong) Ma /* disable GSP4 transmitting */ 79588ccdf1dSLeo (Hanghong) Ma REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP4_SEND, 0); 79688ccdf1dSLeo (Hanghong) Ma 79788ccdf1dSLeo (Hanghong) Ma /* transmit GSP4 at the earliest time in a frame */ 79888ccdf1dSLeo (Hanghong) Ma REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP4_SEND_ANY_LINE, 1); 79988ccdf1dSLeo (Hanghong) Ma 80088ccdf1dSLeo (Hanghong) Ma /*we need turn on clock before programming AFMT block*/ 80188ccdf1dSLeo (Hanghong) Ma REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); 80288ccdf1dSLeo (Hanghong) Ma 80388ccdf1dSLeo (Hanghong) Ma /* check if HW reading GSP memory */ 80488ccdf1dSLeo (Hanghong) Ma REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT, 80588ccdf1dSLeo (Hanghong) Ma 0, 10, max_retries); 80688ccdf1dSLeo (Hanghong) Ma 80788ccdf1dSLeo (Hanghong) Ma /* HW does is not reading GSP memory not reading too long -> 80888ccdf1dSLeo (Hanghong) Ma * something wrong. clear GPS memory access and notify? 80988ccdf1dSLeo (Hanghong) Ma * hw SW is writing to GSP memory 81088ccdf1dSLeo (Hanghong) Ma */ 81188ccdf1dSLeo (Hanghong) Ma REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1); 81288ccdf1dSLeo (Hanghong) Ma 81388ccdf1dSLeo (Hanghong) Ma /* use generic packet 4 for immediate sdp message */ 81488ccdf1dSLeo (Hanghong) Ma REG_UPDATE(AFMT_VBI_PACKET_CONTROL, 81588ccdf1dSLeo (Hanghong) Ma AFMT_GENERIC_INDEX, 4); 81688ccdf1dSLeo (Hanghong) Ma 81788ccdf1dSLeo (Hanghong) Ma /* write generic packet header 81888ccdf1dSLeo (Hanghong) Ma * (4th byte is for GENERIC0 only) 81988ccdf1dSLeo (Hanghong) Ma */ 82088ccdf1dSLeo (Hanghong) Ma REG_SET_4(AFMT_GENERIC_HDR, 0, 82188ccdf1dSLeo (Hanghong) Ma AFMT_GENERIC_HB0, custom_sdp_message[0], 82288ccdf1dSLeo (Hanghong) Ma AFMT_GENERIC_HB1, custom_sdp_message[1], 82388ccdf1dSLeo (Hanghong) Ma AFMT_GENERIC_HB2, custom_sdp_message[2], 82488ccdf1dSLeo (Hanghong) Ma AFMT_GENERIC_HB3, custom_sdp_message[3]); 82588ccdf1dSLeo (Hanghong) Ma 82688ccdf1dSLeo (Hanghong) Ma /* write generic packet contents 82788ccdf1dSLeo (Hanghong) Ma * (we never use last 4 bytes) 82888ccdf1dSLeo (Hanghong) Ma * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers 82988ccdf1dSLeo (Hanghong) Ma */ 83088ccdf1dSLeo (Hanghong) Ma { 83188ccdf1dSLeo (Hanghong) Ma const uint32_t *content = 83288ccdf1dSLeo (Hanghong) Ma (const uint32_t *) &custom_sdp_message[4]; 83388ccdf1dSLeo (Hanghong) Ma 83488ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_0, *content++); 83588ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_1, *content++); 83688ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_2, *content++); 83788ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_3, *content++); 83888ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_4, *content++); 83988ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_5, *content++); 84088ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_6, *content++); 84188ccdf1dSLeo (Hanghong) Ma REG_WRITE(AFMT_GENERIC_7, *content); 84288ccdf1dSLeo (Hanghong) Ma } 84388ccdf1dSLeo (Hanghong) Ma 84488ccdf1dSLeo (Hanghong) Ma /* check whether GENERIC4 registers double buffer update in immediate mode 84588ccdf1dSLeo (Hanghong) Ma * is pending 84688ccdf1dSLeo (Hanghong) Ma */ 84788ccdf1dSLeo (Hanghong) Ma REG_WAIT(AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_IMMEDIATE_UPDATE_PENDING, 84888ccdf1dSLeo (Hanghong) Ma 0, 10, max_retries); 84988ccdf1dSLeo (Hanghong) Ma 85088ccdf1dSLeo (Hanghong) Ma /* atomically update double-buffered GENERIC4 registers in immediate mode 85188ccdf1dSLeo (Hanghong) Ma * (update immediately) 85288ccdf1dSLeo (Hanghong) Ma */ 85388ccdf1dSLeo (Hanghong) Ma REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, 85488ccdf1dSLeo (Hanghong) Ma AFMT_GENERIC4_IMMEDIATE_UPDATE, 1); 85588ccdf1dSLeo (Hanghong) Ma 85688ccdf1dSLeo (Hanghong) Ma /* enable GSP4 transmitting */ 85788ccdf1dSLeo (Hanghong) Ma REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP4_SEND, 1); 858388277b1SAnthony Koo 8590c41891cSEric Bernstein /* This bit is the master enable bit. 8600c41891cSEric Bernstein * When enabling secondary stream engine, 8610c41891cSEric Bernstein * this master bit must also be set. 8620c41891cSEric Bernstein * This register shared with audio info frame. 8630c41891cSEric Bernstein * Therefore we need to enable master bit 8640c41891cSEric Bernstein * if at least on of the fields is not 0 8650c41891cSEric Bernstein */ 866388277b1SAnthony Koo value = REG_READ(DP_SEC_CNTL); 8670c41891cSEric Bernstein if (value) 8680c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 8690c41891cSEric Bernstein } 8700c41891cSEric Bernstein 871c5011872SEric Bernstein void enc1_stream_encoder_stop_dp_info_packets( 8720c41891cSEric Bernstein struct stream_encoder *enc) 8730c41891cSEric Bernstein { 8740c41891cSEric Bernstein /* stop generic packets on DP */ 8750c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 876388277b1SAnthony Koo uint32_t value = 0; 8770c41891cSEric Bernstein 8780c41891cSEric Bernstein REG_SET_10(DP_SEC_CNTL, 0, 8790c41891cSEric Bernstein DP_SEC_GSP0_ENABLE, 0, 8800c41891cSEric Bernstein DP_SEC_GSP1_ENABLE, 0, 8810c41891cSEric Bernstein DP_SEC_GSP2_ENABLE, 0, 8820c41891cSEric Bernstein DP_SEC_GSP3_ENABLE, 0, 8830c41891cSEric Bernstein DP_SEC_GSP4_ENABLE, 0, 8840c41891cSEric Bernstein DP_SEC_GSP5_ENABLE, 0, 8850c41891cSEric Bernstein DP_SEC_GSP6_ENABLE, 0, 8860c41891cSEric Bernstein DP_SEC_GSP7_ENABLE, 0, 8870c41891cSEric Bernstein DP_SEC_MPG_ENABLE, 0, 8880c41891cSEric Bernstein DP_SEC_STREAM_ENABLE, 0); 8890c41891cSEric Bernstein 8900c41891cSEric Bernstein /* this register shared with audio info frame. 8910c41891cSEric Bernstein * therefore we need to keep master enabled 8920c41891cSEric Bernstein * if at least one of the fields is not 0 */ 893388277b1SAnthony Koo value = REG_READ(DP_SEC_CNTL); 8940c41891cSEric Bernstein if (value) 8950c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 8960c41891cSEric Bernstein 8970c41891cSEric Bernstein } 8980c41891cSEric Bernstein 899c5011872SEric Bernstein void enc1_stream_encoder_dp_blank( 9003550d622SLeo (Hanghong) Ma struct dc_link *link, 9010c41891cSEric Bernstein struct stream_encoder *enc) 9020c41891cSEric Bernstein { 9030c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 9040c41891cSEric Bernstein uint32_t reg1 = 0; 9050c41891cSEric Bernstein uint32_t max_retries = DP_BLANK_MAX_RETRY * 10; 9060c41891cSEric Bernstein 9070c41891cSEric Bernstein /* Note: For CZ, we are changing driver default to disable 9080c41891cSEric Bernstein * stream deferred to next VBLANK. If results are positive, we 9090c41891cSEric Bernstein * will make the same change to all DCE versions. There are a 9100c41891cSEric Bernstein * handful of panels that cannot handle disable stream at 9110c41891cSEric Bernstein * HBLANK and will result in a white line flash across the 9120c41891cSEric Bernstein * screen on stream disable. 9130c41891cSEric Bernstein */ 9140c41891cSEric Bernstein REG_GET(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, ®1); 9150c41891cSEric Bernstein if ((reg1 & 0x1) == 0) 9160c41891cSEric Bernstein /*stream not enabled*/ 9170c41891cSEric Bernstein return; 9180c41891cSEric Bernstein /* Specify the video stream disable point 9190c41891cSEric Bernstein * (2 = start of the next vertical blank) 9200c41891cSEric Bernstein */ 9210c41891cSEric Bernstein REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, 2); 9220c41891cSEric Bernstein /* Larger delay to wait until VBLANK - use max retry of 92337b7cb10SWesley Chalmers * 10us*10200=102ms. This covers 100.0ms of minimum 10 Hz mode + 9240c41891cSEric Bernstein * a little more because we may not trust delay accuracy. 9250c41891cSEric Bernstein */ 92637b7cb10SWesley Chalmers max_retries = DP_BLANK_MAX_RETRY * 501; 9270c41891cSEric Bernstein 9280c41891cSEric Bernstein /* disable DP stream */ 9290c41891cSEric Bernstein REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0); 9300c41891cSEric Bernstein 9313550d622SLeo (Hanghong) Ma dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM); 9323550d622SLeo (Hanghong) Ma 9330c41891cSEric Bernstein /* the encoder stops sending the video stream 9340c41891cSEric Bernstein * at the start of the vertical blanking. 9350c41891cSEric Bernstein * Poll for DP_VID_STREAM_STATUS == 0 9360c41891cSEric Bernstein */ 9370c41891cSEric Bernstein 9380c41891cSEric Bernstein REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 9390c41891cSEric Bernstein 0, 9400c41891cSEric Bernstein 10, max_retries); 9410c41891cSEric Bernstein 9420c41891cSEric Bernstein /* Tell the DP encoder to ignore timing from CRTC, must be done after 9430c41891cSEric Bernstein * the polling. If we set DP_STEER_FIFO_RESET before DP stream blank is 9440c41891cSEric Bernstein * complete, stream status will be stuck in video stream enabled state, 9450c41891cSEric Bernstein * i.e. DP_VID_STREAM_STATUS stuck at 1. 9460c41891cSEric Bernstein */ 9470c41891cSEric Bernstein 9480c41891cSEric Bernstein REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, true); 9493550d622SLeo (Hanghong) Ma 9503550d622SLeo (Hanghong) Ma dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET); 9510c41891cSEric Bernstein } 9520c41891cSEric Bernstein 9530c41891cSEric Bernstein /* output video stream to link encoder */ 954c5011872SEric Bernstein void enc1_stream_encoder_dp_unblank( 9553550d622SLeo (Hanghong) Ma struct dc_link *link, 9560c41891cSEric Bernstein struct stream_encoder *enc, 9570c41891cSEric Bernstein const struct encoder_unblank_param *param) 9580c41891cSEric Bernstein { 9590c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 9600c41891cSEric Bernstein 9610c41891cSEric Bernstein if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) { 9620c41891cSEric Bernstein uint32_t n_vid = 0x8000; 9630c41891cSEric Bernstein uint32_t m_vid; 964ae5041f3SEric Bernstein uint32_t n_multiply = 0; 965ae5041f3SEric Bernstein uint64_t m_vid_l = n_vid; 966ae5041f3SEric Bernstein 967ae5041f3SEric Bernstein /* YCbCr 4:2:0 : Computed VID_M will be 2X the input rate */ 9687fe538a4SCharlene Liu if (param->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 9697fe538a4SCharlene Liu /*this param->pixel_clk_khz is half of 444 rate for 420 already*/ 970ae5041f3SEric Bernstein n_multiply = 1; 9717fe538a4SCharlene Liu } 9720c41891cSEric Bernstein /* M / N = Fstream / Flink 9730c41891cSEric Bernstein * m_vid / n_vid = pixel rate / link rate 9740c41891cSEric Bernstein */ 9750c41891cSEric Bernstein 9767fe538a4SCharlene Liu m_vid_l *= param->timing.pix_clk_100hz / 10; 9770c41891cSEric Bernstein m_vid_l = div_u64(m_vid_l, 9780c41891cSEric Bernstein param->link_settings.link_rate 9790c41891cSEric Bernstein * LINK_RATE_REF_FREQ_IN_KHZ); 9800c41891cSEric Bernstein 9810c41891cSEric Bernstein m_vid = (uint32_t) m_vid_l; 9820c41891cSEric Bernstein 9830c41891cSEric Bernstein /* enable auto measurement */ 9840c41891cSEric Bernstein 9850c41891cSEric Bernstein REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0); 9860c41891cSEric Bernstein 9870c41891cSEric Bernstein /* auto measurement need 1 full 0x8000 symbol cycle to kick in, 9880c41891cSEric Bernstein * therefore program initial value for Mvid and Nvid 9890c41891cSEric Bernstein */ 9900c41891cSEric Bernstein 9910c41891cSEric Bernstein REG_UPDATE(DP_VID_N, DP_VID_N, n_vid); 9920c41891cSEric Bernstein 9930c41891cSEric Bernstein REG_UPDATE(DP_VID_M, DP_VID_M, m_vid); 9940c41891cSEric Bernstein 995ae5041f3SEric Bernstein REG_UPDATE_2(DP_VID_TIMING, 996ae5041f3SEric Bernstein DP_VID_M_N_GEN_EN, 1, 997ae5041f3SEric Bernstein DP_VID_N_MUL, n_multiply); 9980c41891cSEric Bernstein } 9990c41891cSEric Bernstein 10000c41891cSEric Bernstein /* set DIG_START to 0x1 to resync FIFO */ 10010c41891cSEric Bernstein 10020c41891cSEric Bernstein REG_UPDATE(DIG_FE_CNTL, DIG_START, 1); 10030c41891cSEric Bernstein 10040c41891cSEric Bernstein /* switch DP encoder to CRTC data */ 10050c41891cSEric Bernstein 10060c41891cSEric Bernstein REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0); 10070c41891cSEric Bernstein 10080c41891cSEric Bernstein /* wait 100us for DIG/DP logic to prime 10090c41891cSEric Bernstein * (i.e. a few video lines) 10100c41891cSEric Bernstein */ 10110c41891cSEric Bernstein udelay(100); 10120c41891cSEric Bernstein 10130c41891cSEric Bernstein /* the hardware would start sending video at the start of the next DP 10140c41891cSEric Bernstein * frame (i.e. rising edge of the vblank). 10150c41891cSEric Bernstein * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this 10160c41891cSEric Bernstein * register has no effect on enable transition! HW always guarantees 10170c41891cSEric Bernstein * VID_STREAM enable at start of next frame, and this is not 10180c41891cSEric Bernstein * programmable 10190c41891cSEric Bernstein */ 10200c41891cSEric Bernstein 10210c41891cSEric Bernstein REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); 10223550d622SLeo (Hanghong) Ma 10233550d622SLeo (Hanghong) Ma dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); 10240c41891cSEric Bernstein } 10250c41891cSEric Bernstein 1026c5011872SEric Bernstein void enc1_stream_encoder_set_avmute( 10270c41891cSEric Bernstein struct stream_encoder *enc, 10280c41891cSEric Bernstein bool enable) 10290c41891cSEric Bernstein { 10300c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 10310c41891cSEric Bernstein unsigned int value = enable ? 1 : 0; 10320c41891cSEric Bernstein 10330c41891cSEric Bernstein REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, value); 10340c41891cSEric Bernstein } 10350c41891cSEric Bernstein 1036ac42fd63SWenjing Liu void enc1_reset_hdmi_stream_attribute( 1037ac42fd63SWenjing Liu struct stream_encoder *enc) 1038ac42fd63SWenjing Liu { 1039ac42fd63SWenjing Liu struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 1040ac42fd63SWenjing Liu 1041ac42fd63SWenjing Liu REG_UPDATE_5(HDMI_CONTROL, 1042ac42fd63SWenjing Liu HDMI_PACKET_GEN_VERSION, 1, 1043ac42fd63SWenjing Liu HDMI_KEEPOUT_MODE, 1, 1044ac42fd63SWenjing Liu HDMI_DEEP_COLOR_ENABLE, 0, 1045ac42fd63SWenjing Liu HDMI_DATA_SCRAMBLE_EN, 0, 1046ac42fd63SWenjing Liu HDMI_CLOCK_CHANNEL_RATE, 0); 1047ac42fd63SWenjing Liu } 1048ac42fd63SWenjing Liu 10490c41891cSEric Bernstein 10500c41891cSEric Bernstein #define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x8000 10510c41891cSEric Bernstein #define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 1 10520c41891cSEric Bernstein 10530c41891cSEric Bernstein #include "include/audio_types.h" 10540c41891cSEric Bernstein 10550c41891cSEric Bernstein 10560c41891cSEric Bernstein /* 25.2MHz/1.001*/ 10570c41891cSEric Bernstein /* 25.2MHz/1.001*/ 10580c41891cSEric Bernstein /* 25.2MHz*/ 10590c41891cSEric Bernstein /* 27MHz */ 10600c41891cSEric Bernstein /* 27MHz*1.001*/ 10610c41891cSEric Bernstein /* 27MHz*1.001*/ 10620c41891cSEric Bernstein /* 54MHz*/ 10630c41891cSEric Bernstein /* 54MHz*1.001*/ 10640c41891cSEric Bernstein /* 74.25MHz/1.001*/ 10650c41891cSEric Bernstein /* 74.25MHz*/ 10660c41891cSEric Bernstein /* 148.5MHz/1.001*/ 10670c41891cSEric Bernstein /* 148.5MHz*/ 10680c41891cSEric Bernstein 10690c41891cSEric Bernstein static const struct audio_clock_info audio_clock_info_table[16] = { 10700c41891cSEric Bernstein {2517, 4576, 28125, 7007, 31250, 6864, 28125}, 10710c41891cSEric Bernstein {2518, 4576, 28125, 7007, 31250, 6864, 28125}, 10720c41891cSEric Bernstein {2520, 4096, 25200, 6272, 28000, 6144, 25200}, 10730c41891cSEric Bernstein {2700, 4096, 27000, 6272, 30000, 6144, 27000}, 10740c41891cSEric Bernstein {2702, 4096, 27027, 6272, 30030, 6144, 27027}, 10750c41891cSEric Bernstein {2703, 4096, 27027, 6272, 30030, 6144, 27027}, 10760c41891cSEric Bernstein {5400, 4096, 54000, 6272, 60000, 6144, 54000}, 10770c41891cSEric Bernstein {5405, 4096, 54054, 6272, 60060, 6144, 54054}, 10780c41891cSEric Bernstein {7417, 11648, 210937, 17836, 234375, 11648, 140625}, 10790c41891cSEric Bernstein {7425, 4096, 74250, 6272, 82500, 6144, 74250}, 10800c41891cSEric Bernstein {14835, 11648, 421875, 8918, 234375, 5824, 140625}, 10810c41891cSEric Bernstein {14850, 4096, 148500, 6272, 165000, 6144, 148500}, 10820c41891cSEric Bernstein {29670, 5824, 421875, 4459, 234375, 5824, 281250}, 10830c41891cSEric Bernstein {29700, 3072, 222750, 4704, 247500, 5120, 247500}, 10840c41891cSEric Bernstein {59340, 5824, 843750, 8918, 937500, 5824, 562500}, 10850c41891cSEric Bernstein {59400, 3072, 445500, 9408, 990000, 6144, 594000} 10860c41891cSEric Bernstein }; 10870c41891cSEric Bernstein 10880c41891cSEric Bernstein static const struct audio_clock_info audio_clock_info_table_36bpc[14] = { 10890c41891cSEric Bernstein {2517, 9152, 84375, 7007, 48875, 9152, 56250}, 10900c41891cSEric Bernstein {2518, 9152, 84375, 7007, 48875, 9152, 56250}, 10910c41891cSEric Bernstein {2520, 4096, 37800, 6272, 42000, 6144, 37800}, 10920c41891cSEric Bernstein {2700, 4096, 40500, 6272, 45000, 6144, 40500}, 10930c41891cSEric Bernstein {2702, 8192, 81081, 6272, 45045, 8192, 54054}, 10940c41891cSEric Bernstein {2703, 8192, 81081, 6272, 45045, 8192, 54054}, 10950c41891cSEric Bernstein {5400, 4096, 81000, 6272, 90000, 6144, 81000}, 10960c41891cSEric Bernstein {5405, 4096, 81081, 6272, 90090, 6144, 81081}, 10970c41891cSEric Bernstein {7417, 11648, 316406, 17836, 351562, 11648, 210937}, 10980c41891cSEric Bernstein {7425, 4096, 111375, 6272, 123750, 6144, 111375}, 10990c41891cSEric Bernstein {14835, 11648, 632812, 17836, 703125, 11648, 421875}, 11000c41891cSEric Bernstein {14850, 4096, 222750, 6272, 247500, 6144, 222750}, 11010c41891cSEric Bernstein {29670, 5824, 632812, 8918, 703125, 5824, 421875}, 11020c41891cSEric Bernstein {29700, 4096, 445500, 4704, 371250, 5120, 371250} 11030c41891cSEric Bernstein }; 11040c41891cSEric Bernstein 11050c41891cSEric Bernstein static const struct audio_clock_info audio_clock_info_table_48bpc[14] = { 11060c41891cSEric Bernstein {2517, 4576, 56250, 7007, 62500, 6864, 56250}, 11070c41891cSEric Bernstein {2518, 4576, 56250, 7007, 62500, 6864, 56250}, 11080c41891cSEric Bernstein {2520, 4096, 50400, 6272, 56000, 6144, 50400}, 11090c41891cSEric Bernstein {2700, 4096, 54000, 6272, 60000, 6144, 54000}, 11100c41891cSEric Bernstein {2702, 4096, 54054, 6267, 60060, 8192, 54054}, 11110c41891cSEric Bernstein {2703, 4096, 54054, 6272, 60060, 8192, 54054}, 11120c41891cSEric Bernstein {5400, 4096, 108000, 6272, 120000, 6144, 108000}, 11130c41891cSEric Bernstein {5405, 4096, 108108, 6272, 120120, 6144, 108108}, 11140c41891cSEric Bernstein {7417, 11648, 421875, 17836, 468750, 11648, 281250}, 11150c41891cSEric Bernstein {7425, 4096, 148500, 6272, 165000, 6144, 148500}, 11160c41891cSEric Bernstein {14835, 11648, 843750, 8918, 468750, 11648, 281250}, 11170c41891cSEric Bernstein {14850, 4096, 297000, 6272, 330000, 6144, 297000}, 11180c41891cSEric Bernstein {29670, 5824, 843750, 4459, 468750, 5824, 562500}, 11190c41891cSEric Bernstein {29700, 3072, 445500, 4704, 495000, 5120, 495000} 11200c41891cSEric Bernstein 11210c41891cSEric Bernstein 11220c41891cSEric Bernstein }; 11230c41891cSEric Bernstein 11240c41891cSEric Bernstein static union audio_cea_channels speakers_to_channels( 11250c41891cSEric Bernstein struct audio_speaker_flags speaker_flags) 11260c41891cSEric Bernstein { 11270c41891cSEric Bernstein union audio_cea_channels cea_channels = {0}; 11280c41891cSEric Bernstein 11290c41891cSEric Bernstein /* these are one to one */ 11300c41891cSEric Bernstein cea_channels.channels.FL = speaker_flags.FL_FR; 11310c41891cSEric Bernstein cea_channels.channels.FR = speaker_flags.FL_FR; 11320c41891cSEric Bernstein cea_channels.channels.LFE = speaker_flags.LFE; 11330c41891cSEric Bernstein cea_channels.channels.FC = speaker_flags.FC; 11340c41891cSEric Bernstein 11350c41891cSEric Bernstein /* if Rear Left and Right exist move RC speaker to channel 7 11360c41891cSEric Bernstein * otherwise to channel 5 11370c41891cSEric Bernstein */ 11380c41891cSEric Bernstein if (speaker_flags.RL_RR) { 11390c41891cSEric Bernstein cea_channels.channels.RL_RC = speaker_flags.RL_RR; 11400c41891cSEric Bernstein cea_channels.channels.RR = speaker_flags.RL_RR; 11410c41891cSEric Bernstein cea_channels.channels.RC_RLC_FLC = speaker_flags.RC; 11420c41891cSEric Bernstein } else { 11430c41891cSEric Bernstein cea_channels.channels.RL_RC = speaker_flags.RC; 11440c41891cSEric Bernstein } 11450c41891cSEric Bernstein 11460c41891cSEric Bernstein /* FRONT Left Right Center and REAR Left Right Center are exclusive */ 11470c41891cSEric Bernstein if (speaker_flags.FLC_FRC) { 11480c41891cSEric Bernstein cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC; 11490c41891cSEric Bernstein cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC; 11500c41891cSEric Bernstein } else { 11510c41891cSEric Bernstein cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC; 11520c41891cSEric Bernstein cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC; 11530c41891cSEric Bernstein } 11540c41891cSEric Bernstein 11550c41891cSEric Bernstein return cea_channels; 11560c41891cSEric Bernstein } 11570c41891cSEric Bernstein 1158c5c07cb5SEric Bernstein void get_audio_clock_info( 11590c41891cSEric Bernstein enum dc_color_depth color_depth, 116040fd9090SNevenko Stupar uint32_t crtc_pixel_clock_100Hz, 116140fd9090SNevenko Stupar uint32_t actual_pixel_clock_100Hz, 11620c41891cSEric Bernstein struct audio_clock_info *audio_clock_info) 11630c41891cSEric Bernstein { 11640c41891cSEric Bernstein const struct audio_clock_info *clock_info; 11650c41891cSEric Bernstein uint32_t index; 116640fd9090SNevenko Stupar uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_100Hz / 100; 11670c41891cSEric Bernstein uint32_t audio_array_size; 11680c41891cSEric Bernstein 11690c41891cSEric Bernstein switch (color_depth) { 11700c41891cSEric Bernstein case COLOR_DEPTH_161616: 11710c41891cSEric Bernstein clock_info = audio_clock_info_table_48bpc; 11720c41891cSEric Bernstein audio_array_size = ARRAY_SIZE( 11730c41891cSEric Bernstein audio_clock_info_table_48bpc); 11740c41891cSEric Bernstein break; 11750c41891cSEric Bernstein case COLOR_DEPTH_121212: 11760c41891cSEric Bernstein clock_info = audio_clock_info_table_36bpc; 11770c41891cSEric Bernstein audio_array_size = ARRAY_SIZE( 11780c41891cSEric Bernstein audio_clock_info_table_36bpc); 11790c41891cSEric Bernstein break; 11800c41891cSEric Bernstein default: 11810c41891cSEric Bernstein clock_info = audio_clock_info_table; 11820c41891cSEric Bernstein audio_array_size = ARRAY_SIZE( 11830c41891cSEric Bernstein audio_clock_info_table); 11840c41891cSEric Bernstein break; 11850c41891cSEric Bernstein } 11860c41891cSEric Bernstein 11870c41891cSEric Bernstein if (clock_info != NULL) { 11880c41891cSEric Bernstein /* search for exact pixel clock in table */ 11890c41891cSEric Bernstein for (index = 0; index < audio_array_size; index++) { 11900c41891cSEric Bernstein if (clock_info[index].pixel_clock_in_10khz > 11910c41891cSEric Bernstein crtc_pixel_clock_in_10khz) 11920c41891cSEric Bernstein break; /* not match */ 11930c41891cSEric Bernstein else if (clock_info[index].pixel_clock_in_10khz == 11940c41891cSEric Bernstein crtc_pixel_clock_in_10khz) { 11950c41891cSEric Bernstein /* match found */ 11960c41891cSEric Bernstein *audio_clock_info = clock_info[index]; 11970c41891cSEric Bernstein return; 11980c41891cSEric Bernstein } 11990c41891cSEric Bernstein } 12000c41891cSEric Bernstein } 12010c41891cSEric Bernstein 12020c41891cSEric Bernstein /* not found */ 120340fd9090SNevenko Stupar if (actual_pixel_clock_100Hz == 0) 120440fd9090SNevenko Stupar actual_pixel_clock_100Hz = crtc_pixel_clock_100Hz; 12050c41891cSEric Bernstein 12060c41891cSEric Bernstein /* See HDMI spec the table entry under 12070c41891cSEric Bernstein * pixel clock of "Other". */ 12080c41891cSEric Bernstein audio_clock_info->pixel_clock_in_10khz = 120940fd9090SNevenko Stupar actual_pixel_clock_100Hz / 100; 121040fd9090SNevenko Stupar audio_clock_info->cts_32khz = actual_pixel_clock_100Hz / 10; 121140fd9090SNevenko Stupar audio_clock_info->cts_44khz = actual_pixel_clock_100Hz / 10; 121240fd9090SNevenko Stupar audio_clock_info->cts_48khz = actual_pixel_clock_100Hz / 10; 12130c41891cSEric Bernstein 12140c41891cSEric Bernstein audio_clock_info->n_32khz = 4096; 12150c41891cSEric Bernstein audio_clock_info->n_44khz = 6272; 12160c41891cSEric Bernstein audio_clock_info->n_48khz = 6144; 12170c41891cSEric Bernstein } 12180c41891cSEric Bernstein 12190c41891cSEric Bernstein static void enc1_se_audio_setup( 12200c41891cSEric Bernstein struct stream_encoder *enc, 12210c41891cSEric Bernstein unsigned int az_inst, 12220c41891cSEric Bernstein struct audio_info *audio_info) 12230c41891cSEric Bernstein { 12240c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 12250c41891cSEric Bernstein 12260c41891cSEric Bernstein uint32_t channels = 0; 12270c41891cSEric Bernstein 12280c41891cSEric Bernstein ASSERT(audio_info); 12290c41891cSEric Bernstein if (audio_info == NULL) 12300c41891cSEric Bernstein /* This should not happen.it does so we don't get BSOD*/ 12310c41891cSEric Bernstein return; 12320c41891cSEric Bernstein 12330c41891cSEric Bernstein channels = speakers_to_channels(audio_info->flags.speaker_flags).all; 12340c41891cSEric Bernstein 12350c41891cSEric Bernstein /* setup the audio stream source select (audio -> dig mapping) */ 12360c41891cSEric Bernstein REG_SET(AFMT_AUDIO_SRC_CONTROL, 0, AFMT_AUDIO_SRC_SELECT, az_inst); 12370c41891cSEric Bernstein 12380c41891cSEric Bernstein /* Channel allocation */ 12390c41891cSEric Bernstein REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels); 12400c41891cSEric Bernstein } 12410c41891cSEric Bernstein 12420c41891cSEric Bernstein static void enc1_se_setup_hdmi_audio( 12430c41891cSEric Bernstein struct stream_encoder *enc, 12440c41891cSEric Bernstein const struct audio_crtc_info *crtc_info) 12450c41891cSEric Bernstein { 12460c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 12470c41891cSEric Bernstein 12480c41891cSEric Bernstein struct audio_clock_info audio_clock_info = {0}; 12490c41891cSEric Bernstein 12500c41891cSEric Bernstein /* HDMI_AUDIO_PACKET_CONTROL */ 1251b4f84bdfSEric Bernstein REG_UPDATE(HDMI_AUDIO_PACKET_CONTROL, 12520c41891cSEric Bernstein HDMI_AUDIO_DELAY_EN, 1); 12530c41891cSEric Bernstein 12540c41891cSEric Bernstein /* AFMT_AUDIO_PACKET_CONTROL */ 12550c41891cSEric Bernstein REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1); 12560c41891cSEric Bernstein 12570c41891cSEric Bernstein /* AFMT_AUDIO_PACKET_CONTROL2 */ 12580c41891cSEric Bernstein REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2, 12590c41891cSEric Bernstein AFMT_AUDIO_LAYOUT_OVRD, 0, 12600c41891cSEric Bernstein AFMT_60958_OSF_OVRD, 0); 12610c41891cSEric Bernstein 12620c41891cSEric Bernstein /* HDMI_ACR_PACKET_CONTROL */ 12630c41891cSEric Bernstein REG_UPDATE_3(HDMI_ACR_PACKET_CONTROL, 12640c41891cSEric Bernstein HDMI_ACR_AUTO_SEND, 1, 12650c41891cSEric Bernstein HDMI_ACR_SOURCE, 0, 12660c41891cSEric Bernstein HDMI_ACR_AUDIO_PRIORITY, 0); 12670c41891cSEric Bernstein 12680c41891cSEric Bernstein /* Program audio clock sample/regeneration parameters */ 12690c41891cSEric Bernstein get_audio_clock_info(crtc_info->color_depth, 127040fd9090SNevenko Stupar crtc_info->requested_pixel_clock_100Hz, 127140fd9090SNevenko Stupar crtc_info->calculated_pixel_clock_100Hz, 12720c41891cSEric Bernstein &audio_clock_info); 12730c41891cSEric Bernstein DC_LOG_HW_AUDIO( 127440fd9090SNevenko Stupar "\n%s:Input::requested_pixel_clock_100Hz = %d" \ 127540fd9090SNevenko Stupar "calculated_pixel_clock_100Hz = %d \n", __func__, \ 127640fd9090SNevenko Stupar crtc_info->requested_pixel_clock_100Hz, \ 127740fd9090SNevenko Stupar crtc_info->calculated_pixel_clock_100Hz); 12780c41891cSEric Bernstein 12790c41891cSEric Bernstein /* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */ 12800c41891cSEric Bernstein REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz); 12810c41891cSEric Bernstein 12820c41891cSEric Bernstein /* HDMI_ACR_32_1__HDMI_ACR_N_32_MASK */ 12830c41891cSEric Bernstein REG_UPDATE(HDMI_ACR_32_1, HDMI_ACR_N_32, audio_clock_info.n_32khz); 12840c41891cSEric Bernstein 12850c41891cSEric Bernstein /* HDMI_ACR_44_0__HDMI_ACR_CTS_44_MASK */ 12860c41891cSEric Bernstein REG_UPDATE(HDMI_ACR_44_0, HDMI_ACR_CTS_44, audio_clock_info.cts_44khz); 12870c41891cSEric Bernstein 12880c41891cSEric Bernstein /* HDMI_ACR_44_1__HDMI_ACR_N_44_MASK */ 12890c41891cSEric Bernstein REG_UPDATE(HDMI_ACR_44_1, HDMI_ACR_N_44, audio_clock_info.n_44khz); 12900c41891cSEric Bernstein 12910c41891cSEric Bernstein /* HDMI_ACR_48_0__HDMI_ACR_CTS_48_MASK */ 12920c41891cSEric Bernstein REG_UPDATE(HDMI_ACR_48_0, HDMI_ACR_CTS_48, audio_clock_info.cts_48khz); 12930c41891cSEric Bernstein 12940c41891cSEric Bernstein /* HDMI_ACR_48_1__HDMI_ACR_N_48_MASK */ 12950c41891cSEric Bernstein REG_UPDATE(HDMI_ACR_48_1, HDMI_ACR_N_48, audio_clock_info.n_48khz); 12960c41891cSEric Bernstein 12970c41891cSEric Bernstein /* Video driver cannot know in advance which sample rate will 12980c41891cSEric Bernstein * be used by HD Audio driver 12990c41891cSEric Bernstein * HDMI_ACR_PACKET_CONTROL__HDMI_ACR_N_MULTIPLE field is 13000c41891cSEric Bernstein * programmed below in interruppt callback 13010c41891cSEric Bernstein */ 13020c41891cSEric Bernstein 13030c41891cSEric Bernstein /* AFMT_60958_0__AFMT_60958_CS_CHANNEL_NUMBER_L_MASK & 13040c41891cSEric Bernstein * AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK 13050c41891cSEric Bernstein */ 13060c41891cSEric Bernstein REG_UPDATE_2(AFMT_60958_0, 13070c41891cSEric Bernstein AFMT_60958_CS_CHANNEL_NUMBER_L, 1, 13080c41891cSEric Bernstein AFMT_60958_CS_CLOCK_ACCURACY, 0); 13090c41891cSEric Bernstein 13100c41891cSEric Bernstein /* AFMT_60958_1 AFMT_60958_CS_CHALNNEL_NUMBER_R */ 13110c41891cSEric Bernstein REG_UPDATE(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, 2); 13120c41891cSEric Bernstein 13130c41891cSEric Bernstein /* AFMT_60958_2 now keep this settings until 13140c41891cSEric Bernstein * Programming guide comes out 13150c41891cSEric Bernstein */ 13160c41891cSEric Bernstein REG_UPDATE_6(AFMT_60958_2, 13170c41891cSEric Bernstein AFMT_60958_CS_CHANNEL_NUMBER_2, 3, 13180c41891cSEric Bernstein AFMT_60958_CS_CHANNEL_NUMBER_3, 4, 13190c41891cSEric Bernstein AFMT_60958_CS_CHANNEL_NUMBER_4, 5, 13200c41891cSEric Bernstein AFMT_60958_CS_CHANNEL_NUMBER_5, 6, 13210c41891cSEric Bernstein AFMT_60958_CS_CHANNEL_NUMBER_6, 7, 13220c41891cSEric Bernstein AFMT_60958_CS_CHANNEL_NUMBER_7, 8); 13230c41891cSEric Bernstein } 13240c41891cSEric Bernstein 13250c41891cSEric Bernstein static void enc1_se_setup_dp_audio( 13260c41891cSEric Bernstein struct stream_encoder *enc) 13270c41891cSEric Bernstein { 13280c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 13290c41891cSEric Bernstein 13300c41891cSEric Bernstein /* --- DP Audio packet configurations --- */ 13310c41891cSEric Bernstein 13320c41891cSEric Bernstein /* ATP Configuration */ 13330c41891cSEric Bernstein REG_SET(DP_SEC_AUD_N, 0, 13340c41891cSEric Bernstein DP_SEC_AUD_N, DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT); 13350c41891cSEric Bernstein 13360c41891cSEric Bernstein /* Async/auto-calc timestamp mode */ 13370c41891cSEric Bernstein REG_SET(DP_SEC_TIMESTAMP, 0, DP_SEC_TIMESTAMP_MODE, 13380c41891cSEric Bernstein DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC); 13390c41891cSEric Bernstein 13400c41891cSEric Bernstein /* --- The following are the registers 13410c41891cSEric Bernstein * copied from the SetupHDMI --- 13420c41891cSEric Bernstein */ 13430c41891cSEric Bernstein 13440c41891cSEric Bernstein /* AFMT_AUDIO_PACKET_CONTROL */ 13450c41891cSEric Bernstein REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1); 13460c41891cSEric Bernstein 13470c41891cSEric Bernstein /* AFMT_AUDIO_PACKET_CONTROL2 */ 13480c41891cSEric Bernstein /* Program the ATP and AIP next */ 13490c41891cSEric Bernstein REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2, 13500c41891cSEric Bernstein AFMT_AUDIO_LAYOUT_OVRD, 0, 13510c41891cSEric Bernstein AFMT_60958_OSF_OVRD, 0); 13520c41891cSEric Bernstein 13530c41891cSEric Bernstein /* AFMT_INFOFRAME_CONTROL0 */ 13540c41891cSEric Bernstein REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1); 13550c41891cSEric Bernstein 13560c41891cSEric Bernstein /* AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */ 13570c41891cSEric Bernstein REG_UPDATE(AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, 0); 13580c41891cSEric Bernstein } 13590c41891cSEric Bernstein 1360c5c07cb5SEric Bernstein void enc1_se_enable_audio_clock( 13610c41891cSEric Bernstein struct stream_encoder *enc, 13620c41891cSEric Bernstein bool enable) 13630c41891cSEric Bernstein { 13640c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 13650c41891cSEric Bernstein 13660c41891cSEric Bernstein if (REG(AFMT_CNTL) == 0) 13670c41891cSEric Bernstein return; /* DCE8/10 does not have this register */ 13680c41891cSEric Bernstein 13690c41891cSEric Bernstein REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, !!enable); 13700c41891cSEric Bernstein 13710c41891cSEric Bernstein /* wait for AFMT clock to turn on, 13720c41891cSEric Bernstein * expectation: this should complete in 1-2 reads 13730c41891cSEric Bernstein * 13740c41891cSEric Bernstein * REG_WAIT(AFMT_CNTL, AFMT_AUDIO_CLOCK_ON, !!enable, 1, 10); 13750c41891cSEric Bernstein * 13760c41891cSEric Bernstein * TODO: wait for clock_on does not work well. May need HW 13770c41891cSEric Bernstein * program sequence. But audio seems work normally even without wait 13780c41891cSEric Bernstein * for clock_on status change 13790c41891cSEric Bernstein */ 13800c41891cSEric Bernstein } 13810c41891cSEric Bernstein 1382c5c07cb5SEric Bernstein void enc1_se_enable_dp_audio( 13830c41891cSEric Bernstein struct stream_encoder *enc) 13840c41891cSEric Bernstein { 13850c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 13860c41891cSEric Bernstein 13870c41891cSEric Bernstein /* Enable Audio packets */ 13880c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_ASP_ENABLE, 1); 13890c41891cSEric Bernstein 13900c41891cSEric Bernstein /* Program the ATP and AIP next */ 13910c41891cSEric Bernstein REG_UPDATE_2(DP_SEC_CNTL, 13920c41891cSEric Bernstein DP_SEC_ATP_ENABLE, 1, 13930c41891cSEric Bernstein DP_SEC_AIP_ENABLE, 1); 13940c41891cSEric Bernstein 13950c41891cSEric Bernstein /* Program STREAM_ENABLE after all the other enables. */ 13960c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 13970c41891cSEric Bernstein } 13980c41891cSEric Bernstein 13990c41891cSEric Bernstein static void enc1_se_disable_dp_audio( 14000c41891cSEric Bernstein struct stream_encoder *enc) 14010c41891cSEric Bernstein { 14020c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 1403388277b1SAnthony Koo uint32_t value = 0; 14040c41891cSEric Bernstein 1405*18b4f1a0SMichael Strauss #if defined(CONFIG_DRM_AMD_DC_DCN) 1406*18b4f1a0SMichael Strauss if (enc->afmt && enc->afmt->funcs->afmt_powerdown) 1407*18b4f1a0SMichael Strauss enc->afmt->funcs->afmt_powerdown(enc->afmt); 1408*18b4f1a0SMichael Strauss #endif 1409*18b4f1a0SMichael Strauss 14100c41891cSEric Bernstein /* Disable Audio packets */ 14110c41891cSEric Bernstein REG_UPDATE_5(DP_SEC_CNTL, 14120c41891cSEric Bernstein DP_SEC_ASP_ENABLE, 0, 14130c41891cSEric Bernstein DP_SEC_ATP_ENABLE, 0, 14140c41891cSEric Bernstein DP_SEC_AIP_ENABLE, 0, 14150c41891cSEric Bernstein DP_SEC_ACM_ENABLE, 0, 14160c41891cSEric Bernstein DP_SEC_STREAM_ENABLE, 0); 14170c41891cSEric Bernstein 14180c41891cSEric Bernstein /* This register shared with encoder info frame. Therefore we need to 14190c41891cSEric Bernstein * keep master enabled if at least on of the fields is not 0 14200c41891cSEric Bernstein */ 1421388277b1SAnthony Koo value = REG_READ(DP_SEC_CNTL); 14220c41891cSEric Bernstein if (value != 0) 14230c41891cSEric Bernstein REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1); 14240c41891cSEric Bernstein 14250c41891cSEric Bernstein } 14260c41891cSEric Bernstein 14270c41891cSEric Bernstein void enc1_se_audio_mute_control( 14280c41891cSEric Bernstein struct stream_encoder *enc, 14290c41891cSEric Bernstein bool mute) 14300c41891cSEric Bernstein { 14310c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 14320c41891cSEric Bernstein 14330c41891cSEric Bernstein REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute); 14340c41891cSEric Bernstein } 14350c41891cSEric Bernstein 14360c41891cSEric Bernstein void enc1_se_dp_audio_setup( 14370c41891cSEric Bernstein struct stream_encoder *enc, 14380c41891cSEric Bernstein unsigned int az_inst, 14390c41891cSEric Bernstein struct audio_info *info) 14400c41891cSEric Bernstein { 14410c41891cSEric Bernstein enc1_se_audio_setup(enc, az_inst, info); 14420c41891cSEric Bernstein } 14430c41891cSEric Bernstein 14440c41891cSEric Bernstein void enc1_se_dp_audio_enable( 14450c41891cSEric Bernstein struct stream_encoder *enc) 14460c41891cSEric Bernstein { 14470c41891cSEric Bernstein enc1_se_enable_audio_clock(enc, true); 14480c41891cSEric Bernstein enc1_se_setup_dp_audio(enc); 14490c41891cSEric Bernstein enc1_se_enable_dp_audio(enc); 14500c41891cSEric Bernstein } 14510c41891cSEric Bernstein 14520c41891cSEric Bernstein void enc1_se_dp_audio_disable( 14530c41891cSEric Bernstein struct stream_encoder *enc) 14540c41891cSEric Bernstein { 14550c41891cSEric Bernstein enc1_se_disable_dp_audio(enc); 14560c41891cSEric Bernstein enc1_se_enable_audio_clock(enc, false); 14570c41891cSEric Bernstein } 14580c41891cSEric Bernstein 14590c41891cSEric Bernstein void enc1_se_hdmi_audio_setup( 14600c41891cSEric Bernstein struct stream_encoder *enc, 14610c41891cSEric Bernstein unsigned int az_inst, 14620c41891cSEric Bernstein struct audio_info *info, 14630c41891cSEric Bernstein struct audio_crtc_info *audio_crtc_info) 14640c41891cSEric Bernstein { 14650c41891cSEric Bernstein enc1_se_enable_audio_clock(enc, true); 14660c41891cSEric Bernstein enc1_se_setup_hdmi_audio(enc, audio_crtc_info); 14670c41891cSEric Bernstein enc1_se_audio_setup(enc, az_inst, info); 14680c41891cSEric Bernstein } 14690c41891cSEric Bernstein 14700c41891cSEric Bernstein void enc1_se_hdmi_audio_disable( 14710c41891cSEric Bernstein struct stream_encoder *enc) 14720c41891cSEric Bernstein { 1473*18b4f1a0SMichael Strauss #if defined(CONFIG_DRM_AMD_DC_DCN) 1474*18b4f1a0SMichael Strauss if (enc->afmt && enc->afmt->funcs->afmt_powerdown) 1475*18b4f1a0SMichael Strauss enc->afmt->funcs->afmt_powerdown(enc->afmt); 1476*18b4f1a0SMichael Strauss #endif 14770c41891cSEric Bernstein enc1_se_enable_audio_clock(enc, false); 14780c41891cSEric Bernstein } 14790c41891cSEric Bernstein 14800c41891cSEric Bernstein 1481c5011872SEric Bernstein void enc1_setup_stereo_sync( 14820c41891cSEric Bernstein struct stream_encoder *enc, 14830c41891cSEric Bernstein int tg_inst, bool enable) 14840c41891cSEric Bernstein { 14850c41891cSEric Bernstein struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 14860c41891cSEric Bernstein REG_UPDATE(DIG_FE_CNTL, DIG_STEREOSYNC_SELECT, tg_inst); 14870c41891cSEric Bernstein REG_UPDATE(DIG_FE_CNTL, DIG_STEREOSYNC_GATE_EN, !enable); 14880c41891cSEric Bernstein } 14890c41891cSEric Bernstein 1490d2c460e7Shersen wu void enc1_dig_connect_to_otg( 1491d2c460e7Shersen wu struct stream_encoder *enc, 1492d2c460e7Shersen wu int tg_inst) 1493d2c460e7Shersen wu { 1494d2c460e7Shersen wu struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 1495d2c460e7Shersen wu 1496d2c460e7Shersen wu REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst); 1497d2c460e7Shersen wu } 14980c41891cSEric Bernstein 14995ec43edaSMartin Leung unsigned int enc1_dig_source_otg( 15005ec43edaSMartin Leung struct stream_encoder *enc) 15015ec43edaSMartin Leung { 15025ec43edaSMartin Leung uint32_t tg_inst = 0; 15035ec43edaSMartin Leung struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 15045ec43edaSMartin Leung 15055ec43edaSMartin Leung REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst); 15065ec43edaSMartin Leung 15075ec43edaSMartin Leung return tg_inst; 15085ec43edaSMartin Leung } 15095ec43edaSMartin Leung 151093c2340bSMartin Leung bool enc1_stream_encoder_dp_get_pixel_format( 151193c2340bSMartin Leung struct stream_encoder *enc, 151293c2340bSMartin Leung enum dc_pixel_encoding *encoding, 151393c2340bSMartin Leung enum dc_color_depth *depth) 151493c2340bSMartin Leung { 151593c2340bSMartin Leung uint32_t hw_encoding = 0; 151693c2340bSMartin Leung uint32_t hw_depth = 0; 151793c2340bSMartin Leung struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); 151893c2340bSMartin Leung 151993c2340bSMartin Leung if (enc == NULL || 152093c2340bSMartin Leung encoding == NULL || 152193c2340bSMartin Leung depth == NULL) 152293c2340bSMartin Leung return false; 152393c2340bSMartin Leung 152493c2340bSMartin Leung REG_GET_2(DP_PIXEL_FORMAT, 152593c2340bSMartin Leung DP_PIXEL_ENCODING, &hw_encoding, 152693c2340bSMartin Leung DP_COMPONENT_DEPTH, &hw_depth); 152793c2340bSMartin Leung 152893c2340bSMartin Leung switch (hw_depth) { 152993c2340bSMartin Leung case DP_COMPONENT_PIXEL_DEPTH_6BPC: 153093c2340bSMartin Leung *depth = COLOR_DEPTH_666; 153193c2340bSMartin Leung break; 153293c2340bSMartin Leung case DP_COMPONENT_PIXEL_DEPTH_8BPC: 153393c2340bSMartin Leung *depth = COLOR_DEPTH_888; 153493c2340bSMartin Leung break; 153593c2340bSMartin Leung case DP_COMPONENT_PIXEL_DEPTH_10BPC: 153693c2340bSMartin Leung *depth = COLOR_DEPTH_101010; 153793c2340bSMartin Leung break; 153893c2340bSMartin Leung case DP_COMPONENT_PIXEL_DEPTH_12BPC: 153993c2340bSMartin Leung *depth = COLOR_DEPTH_121212; 154093c2340bSMartin Leung break; 154193c2340bSMartin Leung case DP_COMPONENT_PIXEL_DEPTH_16BPC: 154293c2340bSMartin Leung *depth = COLOR_DEPTH_161616; 154393c2340bSMartin Leung break; 154493c2340bSMartin Leung default: 154593c2340bSMartin Leung *depth = COLOR_DEPTH_UNDEFINED; 154693c2340bSMartin Leung break; 154793c2340bSMartin Leung } 154893c2340bSMartin Leung 154993c2340bSMartin Leung switch (hw_encoding) { 155093c2340bSMartin Leung case DP_PIXEL_ENCODING_TYPE_RGB444: 155193c2340bSMartin Leung *encoding = PIXEL_ENCODING_RGB; 155293c2340bSMartin Leung break; 155393c2340bSMartin Leung case DP_PIXEL_ENCODING_TYPE_YCBCR422: 155493c2340bSMartin Leung *encoding = PIXEL_ENCODING_YCBCR422; 155593c2340bSMartin Leung break; 155693c2340bSMartin Leung case DP_PIXEL_ENCODING_TYPE_YCBCR444: 155793c2340bSMartin Leung case DP_PIXEL_ENCODING_TYPE_Y_ONLY: 155893c2340bSMartin Leung *encoding = PIXEL_ENCODING_YCBCR444; 155993c2340bSMartin Leung break; 156093c2340bSMartin Leung case DP_PIXEL_ENCODING_TYPE_YCBCR420: 156193c2340bSMartin Leung *encoding = PIXEL_ENCODING_YCBCR420; 156293c2340bSMartin Leung break; 156393c2340bSMartin Leung default: 156493c2340bSMartin Leung *encoding = PIXEL_ENCODING_UNDEFINED; 156593c2340bSMartin Leung break; 156693c2340bSMartin Leung } 156793c2340bSMartin Leung return true; 156893c2340bSMartin Leung } 156993c2340bSMartin Leung 15700c41891cSEric Bernstein static const struct stream_encoder_funcs dcn10_str_enc_funcs = { 15710c41891cSEric Bernstein .dp_set_stream_attribute = 15720c41891cSEric Bernstein enc1_stream_encoder_dp_set_stream_attribute, 15730c41891cSEric Bernstein .hdmi_set_stream_attribute = 15740c41891cSEric Bernstein enc1_stream_encoder_hdmi_set_stream_attribute, 15750c41891cSEric Bernstein .dvi_set_stream_attribute = 15760c41891cSEric Bernstein enc1_stream_encoder_dvi_set_stream_attribute, 15776c95320dSGeorge Shen .set_throttled_vcp_size = 15786c95320dSGeorge Shen enc1_stream_encoder_set_throttled_vcp_size, 15790c41891cSEric Bernstein .update_hdmi_info_packets = 15800c41891cSEric Bernstein enc1_stream_encoder_update_hdmi_info_packets, 15810c41891cSEric Bernstein .stop_hdmi_info_packets = 15820c41891cSEric Bernstein enc1_stream_encoder_stop_hdmi_info_packets, 15830c41891cSEric Bernstein .update_dp_info_packets = 15840c41891cSEric Bernstein enc1_stream_encoder_update_dp_info_packets, 158588ccdf1dSLeo (Hanghong) Ma .send_immediate_sdp_message = 158688ccdf1dSLeo (Hanghong) Ma enc1_stream_encoder_send_immediate_sdp_message, 15870c41891cSEric Bernstein .stop_dp_info_packets = 15880c41891cSEric Bernstein enc1_stream_encoder_stop_dp_info_packets, 15890c41891cSEric Bernstein .dp_blank = 15900c41891cSEric Bernstein enc1_stream_encoder_dp_blank, 15910c41891cSEric Bernstein .dp_unblank = 15920c41891cSEric Bernstein enc1_stream_encoder_dp_unblank, 15930c41891cSEric Bernstein .audio_mute_control = enc1_se_audio_mute_control, 15940c41891cSEric Bernstein 15950c41891cSEric Bernstein .dp_audio_setup = enc1_se_dp_audio_setup, 15960c41891cSEric Bernstein .dp_audio_enable = enc1_se_dp_audio_enable, 15970c41891cSEric Bernstein .dp_audio_disable = enc1_se_dp_audio_disable, 15980c41891cSEric Bernstein 15990c41891cSEric Bernstein .hdmi_audio_setup = enc1_se_hdmi_audio_setup, 16000c41891cSEric Bernstein .hdmi_audio_disable = enc1_se_hdmi_audio_disable, 16010c41891cSEric Bernstein .setup_stereo_sync = enc1_setup_stereo_sync, 16020c41891cSEric Bernstein .set_avmute = enc1_stream_encoder_set_avmute, 1603d2c460e7Shersen wu .dig_connect_to_otg = enc1_dig_connect_to_otg, 1604ac42fd63SWenjing Liu .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute, 16055ec43edaSMartin Leung .dig_source_otg = enc1_dig_source_otg, 160693c2340bSMartin Leung 160793c2340bSMartin Leung .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format, 16080c41891cSEric Bernstein }; 16090c41891cSEric Bernstein 16100c41891cSEric Bernstein void dcn10_stream_encoder_construct( 16110c41891cSEric Bernstein struct dcn10_stream_encoder *enc1, 16120c41891cSEric Bernstein struct dc_context *ctx, 16130c41891cSEric Bernstein struct dc_bios *bp, 16140c41891cSEric Bernstein enum engine_id eng_id, 16150c41891cSEric Bernstein const struct dcn10_stream_enc_registers *regs, 16160c41891cSEric Bernstein const struct dcn10_stream_encoder_shift *se_shift, 16170c41891cSEric Bernstein const struct dcn10_stream_encoder_mask *se_mask) 16180c41891cSEric Bernstein { 16190c41891cSEric Bernstein enc1->base.funcs = &dcn10_str_enc_funcs; 16200c41891cSEric Bernstein enc1->base.ctx = ctx; 16210c41891cSEric Bernstein enc1->base.id = eng_id; 16220c41891cSEric Bernstein enc1->base.bp = bp; 16230c41891cSEric Bernstein enc1->regs = regs; 16240c41891cSEric Bernstein enc1->se_shift = se_shift; 16250c41891cSEric Bernstein enc1->se_mask = se_mask; 16263f0940f8SCharlene Liu enc1->base.stream_enc_inst = eng_id - ENGINE_ID_DIGA; 16270c41891cSEric Bernstein } 16280c41891cSEric Bernstein 1629