1b8fdfcc6SHarry Wentland /* 2b8fdfcc6SHarry Wentland * Copyright 2012-15 Advanced Micro Devices, Inc. 3b8fdfcc6SHarry Wentland * 4b8fdfcc6SHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a 5b8fdfcc6SHarry Wentland * copy of this software and associated documentation files (the "Software"), 6b8fdfcc6SHarry Wentland * to deal in the Software without restriction, including without limitation 7b8fdfcc6SHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8fdfcc6SHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the 9b8fdfcc6SHarry Wentland * Software is furnished to do so, subject to the following conditions: 10b8fdfcc6SHarry Wentland * 11b8fdfcc6SHarry Wentland * The above copyright notice and this permission notice shall be included in 12b8fdfcc6SHarry Wentland * all copies or substantial portions of the Software. 13b8fdfcc6SHarry Wentland * 14b8fdfcc6SHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15b8fdfcc6SHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16b8fdfcc6SHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17b8fdfcc6SHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18b8fdfcc6SHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19b8fdfcc6SHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20b8fdfcc6SHarry Wentland * OTHER DEALINGS IN THE SOFTWARE. 21b8fdfcc6SHarry Wentland * 22b8fdfcc6SHarry Wentland * Authors: AMD 23b8fdfcc6SHarry Wentland * 24b8fdfcc6SHarry Wentland */ 25b8fdfcc6SHarry Wentland 26b8fdfcc6SHarry Wentland #include "dm_services.h" 27b8fdfcc6SHarry Wentland 28b8fdfcc6SHarry Wentland #include "vega10/DC/dce_12_0_offset.h" 29b8fdfcc6SHarry Wentland #include "vega10/DC/dce_12_0_sh_mask.h" 30b8fdfcc6SHarry Wentland #include "vega10/soc15ip.h" 31b8fdfcc6SHarry Wentland 32b8fdfcc6SHarry Wentland #include "dc_types.h" 33b8fdfcc6SHarry Wentland #include "dc_bios_types.h" 34b8fdfcc6SHarry Wentland 35b8fdfcc6SHarry Wentland #include "include/grph_object_id.h" 36b8fdfcc6SHarry Wentland #include "include/logger_interface.h" 37b8fdfcc6SHarry Wentland #include "dce120_timing_generator.h" 38b8fdfcc6SHarry Wentland 39b8fdfcc6SHarry Wentland #include "timing_generator.h" 40b8fdfcc6SHarry Wentland 41b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_N(reg_name, n, ...) \ 42b8fdfcc6SHarry Wentland generic_reg_update_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__) 43b8fdfcc6SHarry Wentland 44b8fdfcc6SHarry Wentland #define CRTC_REG_SET_N(reg_name, n, ...) \ 45b8fdfcc6SHarry Wentland generic_reg_set_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__) 46b8fdfcc6SHarry Wentland 47b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE(reg, field, val) \ 48b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 1, FD(reg##__##field), val) 49b8fdfcc6SHarry Wentland 50b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_2(reg, field1, val1, field2, val2) \ 51b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2) 52b8fdfcc6SHarry Wentland 53b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \ 54b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3) 55b8fdfcc6SHarry Wentland 56b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_4(reg, field1, val1, field2, val2, field3, val3, field4, val4) \ 57b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3, FD(reg##__##field4), val4) 58b8fdfcc6SHarry Wentland 59b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_5(reg, field1, val1, field2, val2, field3, val3, field4, val4, field5, val5) \ 60b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3, FD(reg##__##field4), val4, FD(reg##__##field5), val5) 61b8fdfcc6SHarry Wentland 62b8fdfcc6SHarry Wentland #define CRTC_REG_SET(reg, field, val) \ 63b8fdfcc6SHarry Wentland CRTC_REG_SET_N(reg, 1, FD(reg##__##field), val) 64b8fdfcc6SHarry Wentland 65b8fdfcc6SHarry Wentland #define CRTC_REG_SET_2(reg, field1, val1, field2, val2) \ 66b8fdfcc6SHarry Wentland CRTC_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2) 67b8fdfcc6SHarry Wentland 68b8fdfcc6SHarry Wentland #define CRTC_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \ 69b8fdfcc6SHarry Wentland CRTC_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3) 70b8fdfcc6SHarry Wentland 71b8fdfcc6SHarry Wentland /** 72b8fdfcc6SHarry Wentland ***************************************************************************** 73b8fdfcc6SHarry Wentland * Function: is_in_vertical_blank 74b8fdfcc6SHarry Wentland * 75b8fdfcc6SHarry Wentland * @brief 76b8fdfcc6SHarry Wentland * check the current status of CRTC to check if we are in Vertical Blank 77b8fdfcc6SHarry Wentland * regioneased" state 78b8fdfcc6SHarry Wentland * 79b8fdfcc6SHarry Wentland * @return 80b8fdfcc6SHarry Wentland * true if currently in blank region, false otherwise 81b8fdfcc6SHarry Wentland * 82b8fdfcc6SHarry Wentland ***************************************************************************** 83b8fdfcc6SHarry Wentland */ 84b8fdfcc6SHarry Wentland static bool dce120_timing_generator_is_in_vertical_blank( 85b8fdfcc6SHarry Wentland struct timing_generator *tg) 86b8fdfcc6SHarry Wentland { 87b8fdfcc6SHarry Wentland uint32_t field = 0; 88b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 89b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 90b8fdfcc6SHarry Wentland tg->ctx, 91b8fdfcc6SHarry Wentland mmCRTC0_CRTC_STATUS, 92b8fdfcc6SHarry Wentland tg110->offsets.crtc); 93b8fdfcc6SHarry Wentland 94b8fdfcc6SHarry Wentland field = get_reg_field_value(value, CRTC0_CRTC_STATUS, CRTC_V_BLANK); 95b8fdfcc6SHarry Wentland return field == 1; 96b8fdfcc6SHarry Wentland } 97b8fdfcc6SHarry Wentland 98b8fdfcc6SHarry Wentland 99b8fdfcc6SHarry Wentland /* determine if given timing can be supported by TG */ 100b8fdfcc6SHarry Wentland bool dce120_timing_generator_validate_timing( 101b8fdfcc6SHarry Wentland struct timing_generator *tg, 102b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing, 103b8fdfcc6SHarry Wentland enum signal_type signal) 104b8fdfcc6SHarry Wentland { 105b8fdfcc6SHarry Wentland uint32_t interlace_factor = timing->flags.INTERLACE ? 2 : 1; 106b8fdfcc6SHarry Wentland uint32_t v_blank = 107b8fdfcc6SHarry Wentland (timing->v_total - timing->v_addressable - 108b8fdfcc6SHarry Wentland timing->v_border_top - timing->v_border_bottom) * 109b8fdfcc6SHarry Wentland interlace_factor; 110b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 111b8fdfcc6SHarry Wentland 112b8fdfcc6SHarry Wentland if (!dce110_timing_generator_validate_timing( 113b8fdfcc6SHarry Wentland tg, 114b8fdfcc6SHarry Wentland timing, 115b8fdfcc6SHarry Wentland signal)) 116b8fdfcc6SHarry Wentland return false; 117b8fdfcc6SHarry Wentland 118b8fdfcc6SHarry Wentland 119b8fdfcc6SHarry Wentland if (v_blank < tg110->min_v_blank || 120b8fdfcc6SHarry Wentland timing->h_sync_width < tg110->min_h_sync_width || 121b8fdfcc6SHarry Wentland timing->v_sync_width < tg110->min_v_sync_width) 122b8fdfcc6SHarry Wentland return false; 123b8fdfcc6SHarry Wentland 124b8fdfcc6SHarry Wentland return true; 125b8fdfcc6SHarry Wentland } 126b8fdfcc6SHarry Wentland 127b8fdfcc6SHarry Wentland bool dce120_tg_validate_timing(struct timing_generator *tg, 128b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing) 129b8fdfcc6SHarry Wentland { 130b8fdfcc6SHarry Wentland return dce120_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE); 131b8fdfcc6SHarry Wentland } 132b8fdfcc6SHarry Wentland 133b8fdfcc6SHarry Wentland /******** HW programming ************/ 134b8fdfcc6SHarry Wentland /* Disable/Enable Timing Generator */ 135b8fdfcc6SHarry Wentland bool dce120_timing_generator_enable_crtc(struct timing_generator *tg) 136b8fdfcc6SHarry Wentland { 137b8fdfcc6SHarry Wentland enum bp_result result; 138b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 139b8fdfcc6SHarry Wentland 140b8fdfcc6SHarry Wentland /* Set MASTER_UPDATE_MODE to 0 141b8fdfcc6SHarry Wentland * This is needed for DRR, and also suggested to be default value by Syed.*/ 142b8fdfcc6SHarry Wentland 143b8fdfcc6SHarry Wentland CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_MODE, 144b8fdfcc6SHarry Wentland MASTER_UPDATE_MODE, 0); 145b8fdfcc6SHarry Wentland 146b8fdfcc6SHarry Wentland CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_LOCK, 147b8fdfcc6SHarry Wentland UNDERFLOW_UPDATE_LOCK, 0); 148b8fdfcc6SHarry Wentland 149b8fdfcc6SHarry Wentland /* TODO API for AtomFirmware didn't change*/ 150b8fdfcc6SHarry Wentland result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true); 151b8fdfcc6SHarry Wentland 152b8fdfcc6SHarry Wentland return result == BP_RESULT_OK; 153b8fdfcc6SHarry Wentland } 154b8fdfcc6SHarry Wentland 155b8fdfcc6SHarry Wentland void dce120_timing_generator_set_early_control( 156b8fdfcc6SHarry Wentland struct timing_generator *tg, 157b8fdfcc6SHarry Wentland uint32_t early_cntl) 158b8fdfcc6SHarry Wentland { 159b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 160b8fdfcc6SHarry Wentland 161b8fdfcc6SHarry Wentland CRTC_REG_UPDATE(CRTC0_CRTC_CONTROL, 162b8fdfcc6SHarry Wentland CRTC_HBLANK_EARLY_CONTROL, early_cntl); 163b8fdfcc6SHarry Wentland } 164b8fdfcc6SHarry Wentland 165b8fdfcc6SHarry Wentland /**************** TG current status ******************/ 166b8fdfcc6SHarry Wentland 167b8fdfcc6SHarry Wentland /* return the current frame counter. Used by Linux kernel DRM */ 168b8fdfcc6SHarry Wentland uint32_t dce120_timing_generator_get_vblank_counter( 169b8fdfcc6SHarry Wentland struct timing_generator *tg) 170b8fdfcc6SHarry Wentland { 171b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 172b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 173b8fdfcc6SHarry Wentland tg->ctx, 174b8fdfcc6SHarry Wentland mmCRTC0_CRTC_STATUS_FRAME_COUNT, 175b8fdfcc6SHarry Wentland tg110->offsets.crtc); 176b8fdfcc6SHarry Wentland uint32_t field = get_reg_field_value( 177b8fdfcc6SHarry Wentland value, CRTC0_CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT); 178b8fdfcc6SHarry Wentland 179b8fdfcc6SHarry Wentland return field; 180b8fdfcc6SHarry Wentland } 181b8fdfcc6SHarry Wentland 182b8fdfcc6SHarry Wentland /* Get current H and V position */ 18372ada5f7SEric Cook void dce120_timing_generator_get_crtc_position( 184b8fdfcc6SHarry Wentland struct timing_generator *tg, 18572ada5f7SEric Cook struct crtc_position *position) 186b8fdfcc6SHarry Wentland { 187b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 188b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 189b8fdfcc6SHarry Wentland tg->ctx, 190b8fdfcc6SHarry Wentland mmCRTC0_CRTC_STATUS_POSITION, 191b8fdfcc6SHarry Wentland tg110->offsets.crtc); 192b8fdfcc6SHarry Wentland 19372ada5f7SEric Cook position->horizontal_count = get_reg_field_value(value, 19472ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, CRTC_HORZ_COUNT); 195b8fdfcc6SHarry Wentland 19672ada5f7SEric Cook position->vertical_count = get_reg_field_value(value, 19772ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, CRTC_VERT_COUNT); 19872ada5f7SEric Cook 19972ada5f7SEric Cook value = dm_read_reg_soc15( 20072ada5f7SEric Cook tg->ctx, 20172ada5f7SEric Cook mmCRTC0_CRTC_NOM_VERT_POSITION, 20272ada5f7SEric Cook tg110->offsets.crtc); 20372ada5f7SEric Cook 20472ada5f7SEric Cook position->nominal_vcount = get_reg_field_value(value, 20572ada5f7SEric Cook CRTC0_CRTC_NOM_VERT_POSITION, CRTC_VERT_COUNT_NOM); 206b8fdfcc6SHarry Wentland } 207b8fdfcc6SHarry Wentland 208b8fdfcc6SHarry Wentland /* wait until TG is in beginning of vertical blank region */ 209b8fdfcc6SHarry Wentland void dce120_timing_generator_wait_for_vblank(struct timing_generator *tg) 210b8fdfcc6SHarry Wentland { 211b8fdfcc6SHarry Wentland /* We want to catch beginning of VBlank here, so if the first try are 212b8fdfcc6SHarry Wentland * in VBlank, we might be very close to Active, in this case wait for 213b8fdfcc6SHarry Wentland * another frame 214b8fdfcc6SHarry Wentland */ 215b8fdfcc6SHarry Wentland while (dce120_timing_generator_is_in_vertical_blank(tg)) { 216b8fdfcc6SHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 217b8fdfcc6SHarry Wentland /* error - no point to wait if counter is not moving */ 218b8fdfcc6SHarry Wentland break; 219b8fdfcc6SHarry Wentland } 220b8fdfcc6SHarry Wentland } 221b8fdfcc6SHarry Wentland 222b8fdfcc6SHarry Wentland while (!dce120_timing_generator_is_in_vertical_blank(tg)) { 223b8fdfcc6SHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 224b8fdfcc6SHarry Wentland /* error - no point to wait if counter is not moving */ 225b8fdfcc6SHarry Wentland break; 226b8fdfcc6SHarry Wentland } 227b8fdfcc6SHarry Wentland } 228b8fdfcc6SHarry Wentland } 229b8fdfcc6SHarry Wentland 230b8fdfcc6SHarry Wentland /* wait until TG is in beginning of active region */ 231b8fdfcc6SHarry Wentland void dce120_timing_generator_wait_for_vactive(struct timing_generator *tg) 232b8fdfcc6SHarry Wentland { 233b8fdfcc6SHarry Wentland while (dce120_timing_generator_is_in_vertical_blank(tg)) { 234b8fdfcc6SHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 235b8fdfcc6SHarry Wentland /* error - no point to wait if counter is not moving */ 236b8fdfcc6SHarry Wentland break; 237b8fdfcc6SHarry Wentland } 238b8fdfcc6SHarry Wentland } 239b8fdfcc6SHarry Wentland } 240b8fdfcc6SHarry Wentland 241b8fdfcc6SHarry Wentland /*********** Timing Generator Synchronization routines ****/ 242b8fdfcc6SHarry Wentland 243b8fdfcc6SHarry Wentland /* Setups Global Swap Lock group, TimingServer or TimingClient*/ 244b8fdfcc6SHarry Wentland void dce120_timing_generator_setup_global_swap_lock( 245b8fdfcc6SHarry Wentland struct timing_generator *tg, 246b8fdfcc6SHarry Wentland const struct dcp_gsl_params *gsl_params) 247b8fdfcc6SHarry Wentland { 248b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 249b8fdfcc6SHarry Wentland uint32_t value_crtc_vtotal = 250b8fdfcc6SHarry Wentland dm_read_reg_soc15(tg->ctx, 251b8fdfcc6SHarry Wentland mmCRTC0_CRTC_V_TOTAL, 252b8fdfcc6SHarry Wentland tg110->offsets.crtc); 253b8fdfcc6SHarry Wentland /* Checkpoint relative to end of frame */ 254b8fdfcc6SHarry Wentland uint32_t check_point = 255b8fdfcc6SHarry Wentland get_reg_field_value(value_crtc_vtotal, 256b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL, 257b8fdfcc6SHarry Wentland CRTC_V_TOTAL); 258b8fdfcc6SHarry Wentland 259b8fdfcc6SHarry Wentland 260b8fdfcc6SHarry Wentland dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_GSL_WINDOW, tg110->offsets.crtc, 0); 261b8fdfcc6SHarry Wentland 262b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(DCP0_DCP_GSL_CONTROL, 6, 263b8fdfcc6SHarry Wentland /* This pipe will belong to GSL Group zero. */ 264b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 1, 265b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), gsl_params->gsl_master == tg->inst, 266b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY, 267b8fdfcc6SHarry Wentland /* Keep signal low (pending high) during 6 lines. 268b8fdfcc6SHarry Wentland * Also defines minimum interval before re-checking signal. */ 269b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY, 270b8fdfcc6SHarry Wentland /* DCP_GSL_PURPOSE_SURFACE_FLIP */ 271b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0, 272b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 1); 273b8fdfcc6SHarry Wentland 274b8fdfcc6SHarry Wentland CRTC_REG_SET_2( 275b8fdfcc6SHarry Wentland CRTC0_CRTC_GSL_CONTROL, 276b8fdfcc6SHarry Wentland CRTC_GSL_CHECK_LINE_NUM, check_point - FLIP_READY_BACK_LOOKUP, 277b8fdfcc6SHarry Wentland CRTC_GSL_FORCE_DELAY, VFLIP_READY_DELAY); 278b8fdfcc6SHarry Wentland } 279b8fdfcc6SHarry Wentland 280b8fdfcc6SHarry Wentland /* Clear all the register writes done by setup_global_swap_lock */ 281b8fdfcc6SHarry Wentland void dce120_timing_generator_tear_down_global_swap_lock( 282b8fdfcc6SHarry Wentland struct timing_generator *tg) 283b8fdfcc6SHarry Wentland { 284b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 285b8fdfcc6SHarry Wentland 286b8fdfcc6SHarry Wentland /* Settig HW default values from reg specs */ 287b8fdfcc6SHarry Wentland CRTC_REG_SET_N(DCP0_DCP_GSL_CONTROL, 6, 288b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 0, 289b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), 0, 290b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY, 291b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY, 292b8fdfcc6SHarry Wentland /* DCP_GSL_PURPOSE_SURFACE_FLIP */ 293b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0, 294b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 0); 295b8fdfcc6SHarry Wentland 296b8fdfcc6SHarry Wentland CRTC_REG_SET_2( 297b8fdfcc6SHarry Wentland CRTC0_CRTC_GSL_CONTROL, 298b8fdfcc6SHarry Wentland CRTC_GSL_CHECK_LINE_NUM, 0, 299b8fdfcc6SHarry Wentland CRTC_GSL_FORCE_DELAY, 0x2); /*TODO Why this value here ?*/ 300b8fdfcc6SHarry Wentland } 301b8fdfcc6SHarry Wentland 302b8fdfcc6SHarry Wentland /* Reset slave controllers on master VSync */ 303b8fdfcc6SHarry Wentland void dce120_timing_generator_enable_reset_trigger( 304b8fdfcc6SHarry Wentland struct timing_generator *tg, 305b8fdfcc6SHarry Wentland int source) 306b8fdfcc6SHarry Wentland { 307b8fdfcc6SHarry Wentland enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO; 308b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 309b8fdfcc6SHarry Wentland uint32_t rising_edge = 0; 310b8fdfcc6SHarry Wentland uint32_t falling_edge = 0; 311b8fdfcc6SHarry Wentland /* Setup trigger edge */ 312b8fdfcc6SHarry Wentland uint32_t pol_value = dm_read_reg_soc15( 313b8fdfcc6SHarry Wentland tg->ctx, 314b8fdfcc6SHarry Wentland mmCRTC0_CRTC_V_SYNC_A_CNTL, 315b8fdfcc6SHarry Wentland tg110->offsets.crtc); 316b8fdfcc6SHarry Wentland 317b8fdfcc6SHarry Wentland /* Register spec has reversed definition: 318b8fdfcc6SHarry Wentland * 0 for positive, 1 for negative */ 319b8fdfcc6SHarry Wentland if (get_reg_field_value(pol_value, 320b8fdfcc6SHarry Wentland CRTC0_CRTC_V_SYNC_A_CNTL, 321b8fdfcc6SHarry Wentland CRTC_V_SYNC_A_POL) == 0) { 322b8fdfcc6SHarry Wentland rising_edge = 1; 323b8fdfcc6SHarry Wentland } else { 324b8fdfcc6SHarry Wentland falling_edge = 1; 325b8fdfcc6SHarry Wentland } 326b8fdfcc6SHarry Wentland 327b8fdfcc6SHarry Wentland /* TODO What about other sources ?*/ 328b8fdfcc6SHarry Wentland trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0; 329b8fdfcc6SHarry Wentland 330b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(CRTC0_CRTC_TRIGB_CNTL, 7, 331b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_SOURCE_SELECT), trig_src_select, 332b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_POLARITY_SELECT), TRIGGER_POLARITY_SELECT_LOGIC_ZERO, 333b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_RISING_EDGE_DETECT_CNTL), rising_edge, 334b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL), falling_edge, 335b8fdfcc6SHarry Wentland /* send every signal */ 336b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_FREQUENCY_SELECT), 0, 337b8fdfcc6SHarry Wentland /* no delay */ 338b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_DELAY), 0, 339b8fdfcc6SHarry Wentland /* clear trigger status */ 340b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_TRIGB_CNTL__CRTC_TRIGB_CLEAR), 1); 341b8fdfcc6SHarry Wentland 342b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_3( 343b8fdfcc6SHarry Wentland CRTC0_CRTC_FORCE_COUNT_NOW_CNTL, 344b8fdfcc6SHarry Wentland CRTC_FORCE_COUNT_NOW_MODE, 2, 345b8fdfcc6SHarry Wentland CRTC_FORCE_COUNT_NOW_TRIG_SEL, 1, 346b8fdfcc6SHarry Wentland CRTC_FORCE_COUNT_NOW_CLEAR, 1); 347b8fdfcc6SHarry Wentland } 348b8fdfcc6SHarry Wentland 349b8fdfcc6SHarry Wentland /* disabling trigger-reset */ 350b8fdfcc6SHarry Wentland void dce120_timing_generator_disable_reset_trigger( 351b8fdfcc6SHarry Wentland struct timing_generator *tg) 352b8fdfcc6SHarry Wentland { 353b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 354b8fdfcc6SHarry Wentland 355b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2( 356b8fdfcc6SHarry Wentland CRTC0_CRTC_FORCE_COUNT_NOW_CNTL, 357b8fdfcc6SHarry Wentland CRTC_FORCE_COUNT_NOW_MODE, 0, 358b8fdfcc6SHarry Wentland CRTC_FORCE_COUNT_NOW_CLEAR, 1); 359b8fdfcc6SHarry Wentland 360b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_3( 361b8fdfcc6SHarry Wentland CRTC0_CRTC_TRIGB_CNTL, 362b8fdfcc6SHarry Wentland CRTC_TRIGB_SOURCE_SELECT, TRIGGER_SOURCE_SELECT_LOGIC_ZERO, 363b8fdfcc6SHarry Wentland CRTC_TRIGB_POLARITY_SELECT, TRIGGER_POLARITY_SELECT_LOGIC_ZERO, 364b8fdfcc6SHarry Wentland /* clear trigger status */ 365b8fdfcc6SHarry Wentland CRTC_TRIGB_CLEAR, 1); 366b8fdfcc6SHarry Wentland 367b8fdfcc6SHarry Wentland } 368b8fdfcc6SHarry Wentland 369b8fdfcc6SHarry Wentland /* Checks whether CRTC triggered reset occurred */ 370b8fdfcc6SHarry Wentland bool dce120_timing_generator_did_triggered_reset_occur( 371b8fdfcc6SHarry Wentland struct timing_generator *tg) 372b8fdfcc6SHarry Wentland { 373b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 374b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 375b8fdfcc6SHarry Wentland tg->ctx, 376b8fdfcc6SHarry Wentland mmCRTC0_CRTC_FORCE_COUNT_NOW_CNTL, 377b8fdfcc6SHarry Wentland tg110->offsets.crtc); 378b8fdfcc6SHarry Wentland 379b8fdfcc6SHarry Wentland return get_reg_field_value(value, 380b8fdfcc6SHarry Wentland CRTC0_CRTC_FORCE_COUNT_NOW_CNTL, 381b8fdfcc6SHarry Wentland CRTC_FORCE_COUNT_NOW_OCCURRED) != 0; 382b8fdfcc6SHarry Wentland } 383b8fdfcc6SHarry Wentland 384b8fdfcc6SHarry Wentland 385b8fdfcc6SHarry Wentland /******** Stuff to move to other virtual HW objects *****************/ 386b8fdfcc6SHarry Wentland /* Move to enable accelerated mode */ 387b8fdfcc6SHarry Wentland void dce120_timing_generator_disable_vga(struct timing_generator *tg) 388b8fdfcc6SHarry Wentland { 389b8fdfcc6SHarry Wentland uint32_t addr = 0; 390b8fdfcc6SHarry Wentland uint32_t offset = 0; 391b8fdfcc6SHarry Wentland uint32_t value = 0; 392b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 393b8fdfcc6SHarry Wentland 394b8fdfcc6SHarry Wentland switch (tg110->controller_id) { 395b8fdfcc6SHarry Wentland case CONTROLLER_ID_D0: 396b8fdfcc6SHarry Wentland addr = mmD1VGA_CONTROL; 397b8fdfcc6SHarry Wentland offset = 0; 398b8fdfcc6SHarry Wentland break; 399b8fdfcc6SHarry Wentland case CONTROLLER_ID_D1: 400b8fdfcc6SHarry Wentland addr = mmD2VGA_CONTROL; 401b8fdfcc6SHarry Wentland offset = mmD2VGA_CONTROL - mmD1VGA_CONTROL; 402b8fdfcc6SHarry Wentland break; 403b8fdfcc6SHarry Wentland case CONTROLLER_ID_D2: 404b8fdfcc6SHarry Wentland addr = mmD3VGA_CONTROL; 405b8fdfcc6SHarry Wentland offset = mmD3VGA_CONTROL - mmD1VGA_CONTROL; 406b8fdfcc6SHarry Wentland break; 407b8fdfcc6SHarry Wentland case CONTROLLER_ID_D3: 408b8fdfcc6SHarry Wentland addr = mmD4VGA_CONTROL; 409b8fdfcc6SHarry Wentland offset = mmD4VGA_CONTROL - mmD1VGA_CONTROL; 410b8fdfcc6SHarry Wentland break; 411b8fdfcc6SHarry Wentland case CONTROLLER_ID_D4: 412b8fdfcc6SHarry Wentland addr = mmD1VGA_CONTROL; 413ccaf31ecSRoman Li offset = mmD5VGA_CONTROL - mmD1VGA_CONTROL; 414b8fdfcc6SHarry Wentland break; 415b8fdfcc6SHarry Wentland case CONTROLLER_ID_D5: 416b8fdfcc6SHarry Wentland addr = mmD6VGA_CONTROL; 417b8fdfcc6SHarry Wentland offset = mmD6VGA_CONTROL - mmD1VGA_CONTROL; 418b8fdfcc6SHarry Wentland break; 419b8fdfcc6SHarry Wentland default: 420b8fdfcc6SHarry Wentland break; 421b8fdfcc6SHarry Wentland } 422b8fdfcc6SHarry Wentland 423b8fdfcc6SHarry Wentland value = dm_read_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset); 424b8fdfcc6SHarry Wentland 425b8fdfcc6SHarry Wentland set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE); 426b8fdfcc6SHarry Wentland set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT); 427b8fdfcc6SHarry Wentland set_reg_field_value( 428b8fdfcc6SHarry Wentland value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT); 429b8fdfcc6SHarry Wentland set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN); 430b8fdfcc6SHarry Wentland 431b8fdfcc6SHarry Wentland dm_write_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset, value); 432b8fdfcc6SHarry Wentland } 433b8fdfcc6SHarry Wentland /* TODO: Should we move it to transform */ 434b8fdfcc6SHarry Wentland /* Fully program CRTC timing in timing generator */ 435b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blanking( 436b8fdfcc6SHarry Wentland struct timing_generator *tg, 437b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing) 438b8fdfcc6SHarry Wentland { 439b8fdfcc6SHarry Wentland uint32_t tmp1 = 0; 440b8fdfcc6SHarry Wentland uint32_t tmp2 = 0; 441b8fdfcc6SHarry Wentland uint32_t vsync_offset = timing->v_border_bottom + 442b8fdfcc6SHarry Wentland timing->v_front_porch; 443b8fdfcc6SHarry Wentland uint32_t v_sync_start = timing->v_addressable + vsync_offset; 444b8fdfcc6SHarry Wentland 445b8fdfcc6SHarry Wentland uint32_t hsync_offset = timing->h_border_right + 446b8fdfcc6SHarry Wentland timing->h_front_porch; 447b8fdfcc6SHarry Wentland uint32_t h_sync_start = timing->h_addressable + hsync_offset; 448b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 449b8fdfcc6SHarry Wentland 450b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 451b8fdfcc6SHarry Wentland CRTC0_CRTC_H_TOTAL, 452b8fdfcc6SHarry Wentland CRTC_H_TOTAL, 453b8fdfcc6SHarry Wentland timing->h_total - 1); 454b8fdfcc6SHarry Wentland 455b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 456b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL, 457b8fdfcc6SHarry Wentland CRTC_V_TOTAL, 458b8fdfcc6SHarry Wentland timing->v_total - 1); 459b8fdfcc6SHarry Wentland 460b8fdfcc6SHarry Wentland tmp1 = timing->h_total - 461b8fdfcc6SHarry Wentland (h_sync_start + timing->h_border_left); 462b8fdfcc6SHarry Wentland tmp2 = tmp1 + timing->h_addressable + 463b8fdfcc6SHarry Wentland timing->h_border_left + timing->h_border_right; 464b8fdfcc6SHarry Wentland 465b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2( 466b8fdfcc6SHarry Wentland CRTC0_CRTC_H_BLANK_START_END, 467b8fdfcc6SHarry Wentland CRTC_H_BLANK_END, tmp1, 468b8fdfcc6SHarry Wentland CRTC_H_BLANK_START, tmp2); 469b8fdfcc6SHarry Wentland 470b8fdfcc6SHarry Wentland tmp1 = timing->v_total - (v_sync_start + timing->v_border_top); 471b8fdfcc6SHarry Wentland tmp2 = tmp1 + timing->v_addressable + timing->v_border_top + 472b8fdfcc6SHarry Wentland timing->v_border_bottom; 473b8fdfcc6SHarry Wentland 474b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2( 475b8fdfcc6SHarry Wentland CRTC0_CRTC_V_BLANK_START_END, 476b8fdfcc6SHarry Wentland CRTC_V_BLANK_END, tmp1, 477b8fdfcc6SHarry Wentland CRTC_V_BLANK_START, tmp2); 478b8fdfcc6SHarry Wentland } 479b8fdfcc6SHarry Wentland 480b8fdfcc6SHarry Wentland /* TODO: Should we move it to opp? */ 481b8fdfcc6SHarry Wentland /* Combine with below and move YUV/RGB color conversion to SW layer */ 482b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blank_color( 483b8fdfcc6SHarry Wentland struct timing_generator *tg, 484b8fdfcc6SHarry Wentland const struct tg_color *black_color) 485b8fdfcc6SHarry Wentland { 486b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 487b8fdfcc6SHarry Wentland 488b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_3( 489b8fdfcc6SHarry Wentland CRTC0_CRTC_BLACK_COLOR, 490b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb, 491b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_G_Y, black_color->color_g_y, 492b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr); 493b8fdfcc6SHarry Wentland } 494b8fdfcc6SHarry Wentland /* Combine with above and move YUV/RGB color conversion to SW layer */ 495b8fdfcc6SHarry Wentland void dce120_timing_generator_set_overscan_color_black( 496b8fdfcc6SHarry Wentland struct timing_generator *tg, 497b8fdfcc6SHarry Wentland const struct tg_color *color) 498b8fdfcc6SHarry Wentland { 499b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 500b8fdfcc6SHarry Wentland uint32_t value = 0; 501b8fdfcc6SHarry Wentland CRTC_REG_SET_3( 502b8fdfcc6SHarry Wentland CRTC0_CRTC_OVERSCAN_COLOR, 503b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_BLUE, color->color_b_cb, 504b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_GREEN, color->color_g_y, 505b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_RED, color->color_r_cr); 506b8fdfcc6SHarry Wentland 507b8fdfcc6SHarry Wentland value = dm_read_reg_soc15( 508b8fdfcc6SHarry Wentland tg->ctx, 509b8fdfcc6SHarry Wentland mmCRTC0_CRTC_OVERSCAN_COLOR, 510b8fdfcc6SHarry Wentland tg110->offsets.crtc); 511b8fdfcc6SHarry Wentland 512b8fdfcc6SHarry Wentland dm_write_reg_soc15( 513b8fdfcc6SHarry Wentland tg->ctx, 514b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLACK_COLOR, 515b8fdfcc6SHarry Wentland tg110->offsets.crtc, 516b8fdfcc6SHarry Wentland value); 517b8fdfcc6SHarry Wentland 518b8fdfcc6SHarry Wentland /* This is desirable to have a constant DAC output voltage during the 519b8fdfcc6SHarry Wentland * blank time that is higher than the 0 volt reference level that the 520b8fdfcc6SHarry Wentland * DAC outputs when the NBLANK signal 521b8fdfcc6SHarry Wentland * is asserted low, such as for output to an analog TV. */ 522b8fdfcc6SHarry Wentland dm_write_reg_soc15( 523b8fdfcc6SHarry Wentland tg->ctx, 524b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLANK_DATA_COLOR, 525b8fdfcc6SHarry Wentland tg110->offsets.crtc, 526b8fdfcc6SHarry Wentland value); 527b8fdfcc6SHarry Wentland 528b8fdfcc6SHarry Wentland /* TO DO we have to program EXT registers and we need to know LB DATA 529b8fdfcc6SHarry Wentland * format because it is used when more 10 , i.e. 12 bits per color 530b8fdfcc6SHarry Wentland * 531b8fdfcc6SHarry Wentland * m_mmDxCRTC_OVERSCAN_COLOR_EXT 532b8fdfcc6SHarry Wentland * m_mmDxCRTC_BLACK_COLOR_EXT 533b8fdfcc6SHarry Wentland * m_mmDxCRTC_BLANK_DATA_COLOR_EXT 534b8fdfcc6SHarry Wentland */ 535b8fdfcc6SHarry Wentland } 536b8fdfcc6SHarry Wentland 537b8fdfcc6SHarry Wentland void dce120_timing_generator_set_drr( 538b8fdfcc6SHarry Wentland struct timing_generator *tg, 539b8fdfcc6SHarry Wentland const struct drr_params *params) 540b8fdfcc6SHarry Wentland { 541b8fdfcc6SHarry Wentland 542b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 543b8fdfcc6SHarry Wentland 544b8fdfcc6SHarry Wentland if (params != NULL && 545b8fdfcc6SHarry Wentland params->vertical_total_max > 0 && 546b8fdfcc6SHarry Wentland params->vertical_total_min > 0) { 547b8fdfcc6SHarry Wentland 548b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 549b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL_MIN, 5506c626ffbSYongqiang Sun CRTC_V_TOTAL_MIN, params->vertical_total_min - 1); 551b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 552b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL_MAX, 5536c626ffbSYongqiang Sun CRTC_V_TOTAL_MAX, params->vertical_total_max - 1); 554b8fdfcc6SHarry Wentland CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 6, 555b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 1, 556b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 1, 557b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0, 558b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0, 559b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK_EN), 0, 560b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0); 561b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 562b8fdfcc6SHarry Wentland CRTC0_CRTC_STATIC_SCREEN_CONTROL, 563b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_EVENT_MASK, 564b8fdfcc6SHarry Wentland 0x180); 565b8fdfcc6SHarry Wentland 566b8fdfcc6SHarry Wentland } else { 567b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 568b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL_MIN, 569b8fdfcc6SHarry Wentland CRTC_V_TOTAL_MIN, 0); 570b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 571b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL_MAX, 572b8fdfcc6SHarry Wentland CRTC_V_TOTAL_MAX, 0); 573b8fdfcc6SHarry Wentland CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 5, 574b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 0, 575b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 0, 576b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0, 577b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0, 578b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0); 579b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 580b8fdfcc6SHarry Wentland CRTC0_CRTC_STATIC_SCREEN_CONTROL, 581b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_EVENT_MASK, 582b8fdfcc6SHarry Wentland 0); 583b8fdfcc6SHarry Wentland } 584b8fdfcc6SHarry Wentland } 585b8fdfcc6SHarry Wentland 58672ada5f7SEric Cook /** 58772ada5f7SEric Cook ***************************************************************************** 58872ada5f7SEric Cook * Function: dce120_timing_generator_get_position 58972ada5f7SEric Cook * 59072ada5f7SEric Cook * @brief 59172ada5f7SEric Cook * Returns CRTC vertical/horizontal counters 59272ada5f7SEric Cook * 59372ada5f7SEric Cook * @param [out] position 59472ada5f7SEric Cook ***************************************************************************** 59572ada5f7SEric Cook */ 59672ada5f7SEric Cook void dce120_timing_generator_get_position(struct timing_generator *tg, 59772ada5f7SEric Cook struct crtc_position *position) 59872ada5f7SEric Cook { 59972ada5f7SEric Cook uint32_t value; 60072ada5f7SEric Cook struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 60172ada5f7SEric Cook 60272ada5f7SEric Cook value = dm_read_reg_soc15( 60372ada5f7SEric Cook tg->ctx, 60472ada5f7SEric Cook mmCRTC0_CRTC_STATUS_POSITION, 60572ada5f7SEric Cook tg110->offsets.crtc); 60672ada5f7SEric Cook 60772ada5f7SEric Cook position->horizontal_count = get_reg_field_value( 60872ada5f7SEric Cook value, 60972ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, 61072ada5f7SEric Cook CRTC_HORZ_COUNT); 61172ada5f7SEric Cook 61272ada5f7SEric Cook position->vertical_count = get_reg_field_value( 61372ada5f7SEric Cook value, 61472ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, 61572ada5f7SEric Cook CRTC_VERT_COUNT); 61672ada5f7SEric Cook 61772ada5f7SEric Cook value = dm_read_reg_soc15( 61872ada5f7SEric Cook tg->ctx, 61972ada5f7SEric Cook mmCRTC0_CRTC_NOM_VERT_POSITION, 62072ada5f7SEric Cook tg110->offsets.crtc); 62172ada5f7SEric Cook 62272ada5f7SEric Cook position->nominal_vcount = get_reg_field_value( 62372ada5f7SEric Cook value, 62472ada5f7SEric Cook CRTC0_CRTC_NOM_VERT_POSITION, 62572ada5f7SEric Cook CRTC_VERT_COUNT_NOM); 62672ada5f7SEric Cook } 62772ada5f7SEric Cook 62872ada5f7SEric Cook 62981c50963SSylvia Tsai void dce120_timing_generator_get_crtc_scanoutpos( 630b8fdfcc6SHarry Wentland struct timing_generator *tg, 63181c50963SSylvia Tsai uint32_t *v_blank_start, 63281c50963SSylvia Tsai uint32_t *v_blank_end, 63381c50963SSylvia Tsai uint32_t *h_position, 63481c50963SSylvia Tsai uint32_t *v_position) 635b8fdfcc6SHarry Wentland { 636b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 63772ada5f7SEric Cook struct crtc_position position; 638b8fdfcc6SHarry Wentland 63981c50963SSylvia Tsai uint32_t v_blank_start_end = dm_read_reg_soc15( 640b8fdfcc6SHarry Wentland tg->ctx, 641b8fdfcc6SHarry Wentland mmCRTC0_CRTC_V_BLANK_START_END, 642b8fdfcc6SHarry Wentland tg110->offsets.crtc); 643b8fdfcc6SHarry Wentland 64481c50963SSylvia Tsai *v_blank_start = get_reg_field_value(v_blank_start_end, 64581c50963SSylvia Tsai CRTC0_CRTC_V_BLANK_START_END, 64681c50963SSylvia Tsai CRTC_V_BLANK_START); 64781c50963SSylvia Tsai *v_blank_end = get_reg_field_value(v_blank_start_end, 64881c50963SSylvia Tsai CRTC0_CRTC_V_BLANK_START_END, 64981c50963SSylvia Tsai CRTC_V_BLANK_END); 650b8fdfcc6SHarry Wentland 65172ada5f7SEric Cook dce120_timing_generator_get_crtc_position( 65272ada5f7SEric Cook tg, &position); 65372ada5f7SEric Cook 65472ada5f7SEric Cook *h_position = position.horizontal_count; 65572ada5f7SEric Cook *v_position = position.vertical_count; 656b8fdfcc6SHarry Wentland } 657b8fdfcc6SHarry Wentland 658b8fdfcc6SHarry Wentland void dce120_timing_generator_enable_advanced_request( 659b8fdfcc6SHarry Wentland struct timing_generator *tg, 660b8fdfcc6SHarry Wentland bool enable, 661b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing) 662b8fdfcc6SHarry Wentland { 663b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 664b8fdfcc6SHarry Wentland uint32_t v_sync_width_and_b_porch = 665b8fdfcc6SHarry Wentland timing->v_total - timing->v_addressable - 666b8fdfcc6SHarry Wentland timing->v_border_bottom - timing->v_front_porch; 667b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 668b8fdfcc6SHarry Wentland tg->ctx, 669b8fdfcc6SHarry Wentland mmCRTC0_CRTC_START_LINE_CONTROL, 670b8fdfcc6SHarry Wentland tg110->offsets.crtc); 671b8fdfcc6SHarry Wentland 672b8fdfcc6SHarry Wentland set_reg_field_value( 673b8fdfcc6SHarry Wentland value, 674*a4b0a5b8STom St Denis enable ? 0 : 1, 675b8fdfcc6SHarry Wentland CRTC0_CRTC_START_LINE_CONTROL, 676b8fdfcc6SHarry Wentland CRTC_LEGACY_REQUESTOR_EN); 677b8fdfcc6SHarry Wentland 678b8fdfcc6SHarry Wentland /* Program advanced line position acc.to the best case from fetching data perspective to hide MC latency 679b8fdfcc6SHarry Wentland * and prefilling Line Buffer in V Blank (to 10 lines as LB can store max 10 lines) 680b8fdfcc6SHarry Wentland */ 681b8fdfcc6SHarry Wentland if (v_sync_width_and_b_porch > 10) 682*a4b0a5b8STom St Denis v_sync_width_and_b_porch = 10; 683*a4b0a5b8STom St Denis 684b8fdfcc6SHarry Wentland set_reg_field_value( 685b8fdfcc6SHarry Wentland value, 686b8fdfcc6SHarry Wentland v_sync_width_and_b_porch, 687b8fdfcc6SHarry Wentland CRTC0_CRTC_START_LINE_CONTROL, 688b8fdfcc6SHarry Wentland CRTC_ADVANCED_START_LINE_POSITION); 689b8fdfcc6SHarry Wentland 690b8fdfcc6SHarry Wentland dm_write_reg_soc15(tg->ctx, 691b8fdfcc6SHarry Wentland mmCRTC0_CRTC_START_LINE_CONTROL, 692b8fdfcc6SHarry Wentland tg110->offsets.crtc, 693b8fdfcc6SHarry Wentland value); 694b8fdfcc6SHarry Wentland } 695b8fdfcc6SHarry Wentland 696b8fdfcc6SHarry Wentland void dce120_tg_program_blank_color(struct timing_generator *tg, 697b8fdfcc6SHarry Wentland const struct tg_color *black_color) 698b8fdfcc6SHarry Wentland { 699b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 700b8fdfcc6SHarry Wentland uint32_t value = 0; 701b8fdfcc6SHarry Wentland 702b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_3( 703b8fdfcc6SHarry Wentland CRTC0_CRTC_BLACK_COLOR, 704b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb, 705b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_G_Y, black_color->color_g_y, 706b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr); 707b8fdfcc6SHarry Wentland 708b8fdfcc6SHarry Wentland value = dm_read_reg_soc15( 709b8fdfcc6SHarry Wentland tg->ctx, 710b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLACK_COLOR, 711b8fdfcc6SHarry Wentland tg110->offsets.crtc); 712b8fdfcc6SHarry Wentland dm_write_reg_soc15( 713b8fdfcc6SHarry Wentland tg->ctx, 714b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLANK_DATA_COLOR, 715b8fdfcc6SHarry Wentland tg110->offsets.crtc, 716b8fdfcc6SHarry Wentland value); 717b8fdfcc6SHarry Wentland } 718b8fdfcc6SHarry Wentland 719b8fdfcc6SHarry Wentland void dce120_tg_set_overscan_color(struct timing_generator *tg, 720b8fdfcc6SHarry Wentland const struct tg_color *overscan_color) 721b8fdfcc6SHarry Wentland { 722b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 723b8fdfcc6SHarry Wentland 724b8fdfcc6SHarry Wentland CRTC_REG_SET_3( 725b8fdfcc6SHarry Wentland CRTC0_CRTC_OVERSCAN_COLOR, 726b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_BLUE, overscan_color->color_b_cb, 727b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_GREEN, overscan_color->color_g_y, 728b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_RED, overscan_color->color_r_cr); 729b8fdfcc6SHarry Wentland } 730b8fdfcc6SHarry Wentland 731b8fdfcc6SHarry Wentland void dce120_tg_program_timing(struct timing_generator *tg, 732b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing, 733b8fdfcc6SHarry Wentland bool use_vbios) 734b8fdfcc6SHarry Wentland { 735b8fdfcc6SHarry Wentland if (use_vbios) 736b8fdfcc6SHarry Wentland dce110_timing_generator_program_timing_generator(tg, timing); 737b8fdfcc6SHarry Wentland else 738b8fdfcc6SHarry Wentland dce120_timing_generator_program_blanking(tg, timing); 739b8fdfcc6SHarry Wentland } 740b8fdfcc6SHarry Wentland 741b8fdfcc6SHarry Wentland bool dce120_tg_is_blanked(struct timing_generator *tg) 742b8fdfcc6SHarry Wentland { 743b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 744b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 745b8fdfcc6SHarry Wentland tg->ctx, 746b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLANK_CONTROL, 747b8fdfcc6SHarry Wentland tg110->offsets.crtc); 748b8fdfcc6SHarry Wentland 749b8fdfcc6SHarry Wentland if ( 750b8fdfcc6SHarry Wentland get_reg_field_value( 751b8fdfcc6SHarry Wentland value, 752b8fdfcc6SHarry Wentland CRTC0_CRTC_BLANK_CONTROL, 753b8fdfcc6SHarry Wentland CRTC_BLANK_DATA_EN) == 1 && 754b8fdfcc6SHarry Wentland get_reg_field_value( 755b8fdfcc6SHarry Wentland value, 756b8fdfcc6SHarry Wentland CRTC0_CRTC_BLANK_CONTROL, 757b8fdfcc6SHarry Wentland CRTC_CURRENT_BLANK_STATE) == 1) 758b8fdfcc6SHarry Wentland return true; 759b8fdfcc6SHarry Wentland 760b8fdfcc6SHarry Wentland return false; 761b8fdfcc6SHarry Wentland } 762b8fdfcc6SHarry Wentland 763b8fdfcc6SHarry Wentland void dce120_tg_set_blank(struct timing_generator *tg, 764b8fdfcc6SHarry Wentland bool enable_blanking) 765b8fdfcc6SHarry Wentland { 766b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 767b8fdfcc6SHarry Wentland 768b8fdfcc6SHarry Wentland CRTC_REG_SET( 769b8fdfcc6SHarry Wentland CRTC0_CRTC_DOUBLE_BUFFER_CONTROL, 770b8fdfcc6SHarry Wentland CRTC_BLANK_DATA_DOUBLE_BUFFER_EN, 0); 771b8fdfcc6SHarry Wentland 772b8fdfcc6SHarry Wentland if (enable_blanking) { 773b8fdfcc6SHarry Wentland CRTC_REG_SET( 774b8fdfcc6SHarry Wentland CRTC0_CRTC_BLANK_CONTROL, 775b8fdfcc6SHarry Wentland CRTC_BLANK_DATA_EN, 1); 776b8fdfcc6SHarry Wentland 777b8fdfcc6SHarry Wentland } else 778b8fdfcc6SHarry Wentland dm_write_reg_soc15( 779b8fdfcc6SHarry Wentland tg->ctx, 780b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLANK_CONTROL, 781b8fdfcc6SHarry Wentland tg110->offsets.crtc, 782b8fdfcc6SHarry Wentland 0); 783b8fdfcc6SHarry Wentland } 784b8fdfcc6SHarry Wentland 785b8fdfcc6SHarry Wentland bool dce120_tg_validate_timing(struct timing_generator *tg, 786b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing); 787b8fdfcc6SHarry Wentland 788b8fdfcc6SHarry Wentland void dce120_tg_wait_for_state(struct timing_generator *tg, 789b8fdfcc6SHarry Wentland enum crtc_state state) 790b8fdfcc6SHarry Wentland { 791b8fdfcc6SHarry Wentland switch (state) { 792b8fdfcc6SHarry Wentland case CRTC_STATE_VBLANK: 793b8fdfcc6SHarry Wentland dce120_timing_generator_wait_for_vblank(tg); 794b8fdfcc6SHarry Wentland break; 795b8fdfcc6SHarry Wentland 796b8fdfcc6SHarry Wentland case CRTC_STATE_VACTIVE: 797b8fdfcc6SHarry Wentland dce120_timing_generator_wait_for_vactive(tg); 798b8fdfcc6SHarry Wentland break; 799b8fdfcc6SHarry Wentland 800b8fdfcc6SHarry Wentland default: 801b8fdfcc6SHarry Wentland break; 802b8fdfcc6SHarry Wentland } 803b8fdfcc6SHarry Wentland } 804b8fdfcc6SHarry Wentland 805b8fdfcc6SHarry Wentland void dce120_tg_set_colors(struct timing_generator *tg, 806b8fdfcc6SHarry Wentland const struct tg_color *blank_color, 807b8fdfcc6SHarry Wentland const struct tg_color *overscan_color) 808b8fdfcc6SHarry Wentland { 809b8fdfcc6SHarry Wentland if (blank_color != NULL) 810b8fdfcc6SHarry Wentland dce120_tg_program_blank_color(tg, blank_color); 811b8fdfcc6SHarry Wentland 812b8fdfcc6SHarry Wentland if (overscan_color != NULL) 813b8fdfcc6SHarry Wentland dce120_tg_set_overscan_color(tg, overscan_color); 814b8fdfcc6SHarry Wentland } 815b8fdfcc6SHarry Wentland 816b8fdfcc6SHarry Wentland static void dce120_timing_generator_set_static_screen_control( 817b8fdfcc6SHarry Wentland struct timing_generator *tg, 818b8fdfcc6SHarry Wentland uint32_t value) 819b8fdfcc6SHarry Wentland { 820b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 821b8fdfcc6SHarry Wentland 822b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2(CRTC0_CRTC_STATIC_SCREEN_CONTROL, 823b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_EVENT_MASK, value, 824b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_FRAME_COUNT, 2); 825b8fdfcc6SHarry Wentland } 826b8fdfcc6SHarry Wentland 827b8fdfcc6SHarry Wentland void dce120_timing_generator_set_test_pattern( 828b8fdfcc6SHarry Wentland struct timing_generator *tg, 829b8fdfcc6SHarry Wentland /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode' 830b8fdfcc6SHarry Wentland * because this is not DP-specific (which is probably somewhere in DP 831b8fdfcc6SHarry Wentland * encoder) */ 832b8fdfcc6SHarry Wentland enum controller_dp_test_pattern test_pattern, 833b8fdfcc6SHarry Wentland enum dc_color_depth color_depth) 834b8fdfcc6SHarry Wentland { 835b8fdfcc6SHarry Wentland struct dc_context *ctx = tg->ctx; 836b8fdfcc6SHarry Wentland uint32_t value; 837b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 838b8fdfcc6SHarry Wentland enum test_pattern_color_format bit_depth; 839b8fdfcc6SHarry Wentland enum test_pattern_dyn_range dyn_range; 840b8fdfcc6SHarry Wentland enum test_pattern_mode mode; 841b8fdfcc6SHarry Wentland /* color ramp generator mixes 16-bits color */ 842b8fdfcc6SHarry Wentland uint32_t src_bpc = 16; 843b8fdfcc6SHarry Wentland /* requested bpc */ 844b8fdfcc6SHarry Wentland uint32_t dst_bpc; 845b8fdfcc6SHarry Wentland uint32_t index; 846b8fdfcc6SHarry Wentland /* RGB values of the color bars. 847b8fdfcc6SHarry Wentland * Produce two RGB colors: RGB0 - white (all Fs) 848b8fdfcc6SHarry Wentland * and RGB1 - black (all 0s) 849b8fdfcc6SHarry Wentland * (three RGB components for two colors) 850b8fdfcc6SHarry Wentland */ 851b8fdfcc6SHarry Wentland uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 852b8fdfcc6SHarry Wentland 0x0000, 0x0000}; 853b8fdfcc6SHarry Wentland /* dest color (converted to the specified color format) */ 854b8fdfcc6SHarry Wentland uint16_t dst_color[6]; 855b8fdfcc6SHarry Wentland uint32_t inc_base; 856b8fdfcc6SHarry Wentland 857b8fdfcc6SHarry Wentland /* translate to bit depth */ 858b8fdfcc6SHarry Wentland switch (color_depth) { 859b8fdfcc6SHarry Wentland case COLOR_DEPTH_666: 860b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; 861b8fdfcc6SHarry Wentland break; 862b8fdfcc6SHarry Wentland case COLOR_DEPTH_888: 863b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 864b8fdfcc6SHarry Wentland break; 865b8fdfcc6SHarry Wentland case COLOR_DEPTH_101010: 866b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; 867b8fdfcc6SHarry Wentland break; 868b8fdfcc6SHarry Wentland case COLOR_DEPTH_121212: 869b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; 870b8fdfcc6SHarry Wentland break; 871b8fdfcc6SHarry Wentland default: 872b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 873b8fdfcc6SHarry Wentland break; 874b8fdfcc6SHarry Wentland } 875b8fdfcc6SHarry Wentland 876b8fdfcc6SHarry Wentland switch (test_pattern) { 877b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: 878b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: 879b8fdfcc6SHarry Wentland { 880b8fdfcc6SHarry Wentland dyn_range = (test_pattern == 881b8fdfcc6SHarry Wentland CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? 882b8fdfcc6SHarry Wentland TEST_PATTERN_DYN_RANGE_CEA : 883b8fdfcc6SHarry Wentland TEST_PATTERN_DYN_RANGE_VESA); 884b8fdfcc6SHarry Wentland mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; 885b8fdfcc6SHarry Wentland 886b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 887b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 6, 888b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 6); 889b8fdfcc6SHarry Wentland 890b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL, 891b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_EN, 1, 892b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MODE, mode, 893b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DYNAMIC_RANGE, dyn_range, 894b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth); 895b8fdfcc6SHarry Wentland } 896b8fdfcc6SHarry Wentland break; 897b8fdfcc6SHarry Wentland 898b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: 899b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: 900b8fdfcc6SHarry Wentland { 901b8fdfcc6SHarry Wentland mode = (test_pattern == 902b8fdfcc6SHarry Wentland CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? 903b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_VERTICALBARS : 904b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_HORIZONTALBARS); 905b8fdfcc6SHarry Wentland 906b8fdfcc6SHarry Wentland switch (bit_depth) { 907b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_6: 908b8fdfcc6SHarry Wentland dst_bpc = 6; 909b8fdfcc6SHarry Wentland break; 910b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_8: 911b8fdfcc6SHarry Wentland dst_bpc = 8; 912b8fdfcc6SHarry Wentland break; 913b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_10: 914b8fdfcc6SHarry Wentland dst_bpc = 10; 915b8fdfcc6SHarry Wentland break; 916b8fdfcc6SHarry Wentland default: 917b8fdfcc6SHarry Wentland dst_bpc = 8; 918b8fdfcc6SHarry Wentland break; 919b8fdfcc6SHarry Wentland } 920b8fdfcc6SHarry Wentland 921b8fdfcc6SHarry Wentland /* adjust color to the required colorFormat */ 922b8fdfcc6SHarry Wentland for (index = 0; index < 6; index++) { 923b8fdfcc6SHarry Wentland /* dst = 2^dstBpc * src / 2^srcBpc = src >> 924b8fdfcc6SHarry Wentland * (srcBpc - dstBpc); 925b8fdfcc6SHarry Wentland */ 926b8fdfcc6SHarry Wentland dst_color[index] = 927b8fdfcc6SHarry Wentland src_color[index] >> (src_bpc - dst_bpc); 928b8fdfcc6SHarry Wentland /* CRTC_TEST_PATTERN_DATA has 16 bits, 929b8fdfcc6SHarry Wentland * lowest 6 are hardwired to ZERO 930b8fdfcc6SHarry Wentland * color bits should be left aligned aligned to MSB 931b8fdfcc6SHarry Wentland * XXXXXXXXXX000000 for 10 bit, 932b8fdfcc6SHarry Wentland * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6 933b8fdfcc6SHarry Wentland */ 934b8fdfcc6SHarry Wentland dst_color[index] <<= (16 - dst_bpc); 935b8fdfcc6SHarry Wentland } 936b8fdfcc6SHarry Wentland 937b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, 0); 938b8fdfcc6SHarry Wentland 939b8fdfcc6SHarry Wentland /* We have to write the mask before data, similar to pipeline. 940b8fdfcc6SHarry Wentland * For example, for 8 bpc, if we want RGB0 to be magenta, 941b8fdfcc6SHarry Wentland * and RGB1 to be cyan, 942b8fdfcc6SHarry Wentland * we need to make 7 writes: 943b8fdfcc6SHarry Wentland * MASK DATA 944b8fdfcc6SHarry Wentland * 000001 00000000 00000000 set mask to R0 945b8fdfcc6SHarry Wentland * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0 946b8fdfcc6SHarry Wentland * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0 947b8fdfcc6SHarry Wentland * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1 948b8fdfcc6SHarry Wentland * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1 949b8fdfcc6SHarry Wentland * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1 950b8fdfcc6SHarry Wentland * 100000 11111111 00000000 B1 255, 0xFF00 951b8fdfcc6SHarry Wentland * 952b8fdfcc6SHarry Wentland * we will make a loop of 6 in which we prepare the mask, 953b8fdfcc6SHarry Wentland * then write, then prepare the color for next write. 954b8fdfcc6SHarry Wentland * first iteration will write mask only, 955b8fdfcc6SHarry Wentland * but each next iteration color prepared in 956b8fdfcc6SHarry Wentland * previous iteration will be written within new mask, 957b8fdfcc6SHarry Wentland * the last component will written separately, 958b8fdfcc6SHarry Wentland * mask is not changing between 6th and 7th write 959b8fdfcc6SHarry Wentland * and color will be prepared by last iteration 960b8fdfcc6SHarry Wentland */ 961b8fdfcc6SHarry Wentland 962b8fdfcc6SHarry Wentland /* write color, color values mask in CRTC_TEST_PATTERN_MASK 963b8fdfcc6SHarry Wentland * is B1, G1, R1, B0, G0, R0 964b8fdfcc6SHarry Wentland */ 965b8fdfcc6SHarry Wentland value = 0; 966b8fdfcc6SHarry Wentland for (index = 0; index < 6; index++) { 967b8fdfcc6SHarry Wentland /* prepare color mask, first write PATTERN_DATA 968b8fdfcc6SHarry Wentland * will have all zeros 969b8fdfcc6SHarry Wentland */ 970b8fdfcc6SHarry Wentland set_reg_field_value( 971b8fdfcc6SHarry Wentland value, 972b8fdfcc6SHarry Wentland (1 << index), 973b8fdfcc6SHarry Wentland CRTC0_CRTC_TEST_PATTERN_COLOR, 974b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MASK); 975b8fdfcc6SHarry Wentland /* write color component */ 976b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value); 977b8fdfcc6SHarry Wentland /* prepare next color component, 978b8fdfcc6SHarry Wentland * will be written in the next iteration 979b8fdfcc6SHarry Wentland */ 980b8fdfcc6SHarry Wentland set_reg_field_value( 981b8fdfcc6SHarry Wentland value, 982b8fdfcc6SHarry Wentland dst_color[index], 983b8fdfcc6SHarry Wentland CRTC0_CRTC_TEST_PATTERN_COLOR, 984b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DATA); 985b8fdfcc6SHarry Wentland } 986b8fdfcc6SHarry Wentland /* write last color component, 987b8fdfcc6SHarry Wentland * it's been already prepared in the loop 988b8fdfcc6SHarry Wentland */ 989b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value); 990b8fdfcc6SHarry Wentland 991b8fdfcc6SHarry Wentland /* enable test pattern */ 992b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL, 993b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_EN, 1, 994b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MODE, mode, 995b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0, 996b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth); 997b8fdfcc6SHarry Wentland } 998b8fdfcc6SHarry Wentland break; 999b8fdfcc6SHarry Wentland 1000b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: 1001b8fdfcc6SHarry Wentland { 1002b8fdfcc6SHarry Wentland mode = (bit_depth == 1003b8fdfcc6SHarry Wentland TEST_PATTERN_COLOR_FORMAT_BPC_10 ? 1004b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_DUALRAMP_RGB : 1005b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_SINGLERAMP_RGB); 1006b8fdfcc6SHarry Wentland 1007b8fdfcc6SHarry Wentland switch (bit_depth) { 1008b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_6: 1009b8fdfcc6SHarry Wentland dst_bpc = 6; 1010b8fdfcc6SHarry Wentland break; 1011b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_8: 1012b8fdfcc6SHarry Wentland dst_bpc = 8; 1013b8fdfcc6SHarry Wentland break; 1014b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1015b8fdfcc6SHarry Wentland dst_bpc = 10; 1016b8fdfcc6SHarry Wentland break; 1017b8fdfcc6SHarry Wentland default: 1018b8fdfcc6SHarry Wentland dst_bpc = 8; 1019b8fdfcc6SHarry Wentland break; 1020b8fdfcc6SHarry Wentland } 1021b8fdfcc6SHarry Wentland 1022b8fdfcc6SHarry Wentland /* increment for the first ramp for one color gradation 1023b8fdfcc6SHarry Wentland * 1 gradation for 6-bit color is 2^10 1024b8fdfcc6SHarry Wentland * gradations in 16-bit color 1025b8fdfcc6SHarry Wentland */ 1026b8fdfcc6SHarry Wentland inc_base = (src_bpc - dst_bpc); 1027b8fdfcc6SHarry Wentland 1028b8fdfcc6SHarry Wentland switch (bit_depth) { 1029b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_6: 1030b8fdfcc6SHarry Wentland { 1031b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 1032b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC0, inc_base, 1033b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC1, 0, 1034b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 6, 1035b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 6, 1036b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_RAMP0_OFFSET, 0); 1037b8fdfcc6SHarry Wentland } 1038b8fdfcc6SHarry Wentland break; 1039b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_8: 1040b8fdfcc6SHarry Wentland { 1041b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 1042b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC0, inc_base, 1043b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC1, 0, 1044b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 8, 1045b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 6, 1046b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_RAMP0_OFFSET, 0); 1047b8fdfcc6SHarry Wentland } 1048b8fdfcc6SHarry Wentland break; 1049b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1050b8fdfcc6SHarry Wentland { 1051b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 1052b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC0, inc_base, 1053b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC1, inc_base + 2, 1054b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 8, 1055b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 5, 1056b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_RAMP0_OFFSET, 384 << 6); 1057b8fdfcc6SHarry Wentland } 1058b8fdfcc6SHarry Wentland break; 1059b8fdfcc6SHarry Wentland default: 1060b8fdfcc6SHarry Wentland break; 1061b8fdfcc6SHarry Wentland } 1062b8fdfcc6SHarry Wentland 1063b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, 0); 1064b8fdfcc6SHarry Wentland 1065b8fdfcc6SHarry Wentland /* enable test pattern */ 1066b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, 0); 1067b8fdfcc6SHarry Wentland 1068b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL, 1069b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_EN, 1, 1070b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MODE, mode, 1071b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0, 1072b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth); 1073b8fdfcc6SHarry Wentland } 1074b8fdfcc6SHarry Wentland break; 1075b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: 1076b8fdfcc6SHarry Wentland { 1077b8fdfcc6SHarry Wentland value = 0; 1078b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, value); 1079b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value); 1080b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, value); 1081b8fdfcc6SHarry Wentland } 1082b8fdfcc6SHarry Wentland break; 1083b8fdfcc6SHarry Wentland default: 1084b8fdfcc6SHarry Wentland break; 1085b8fdfcc6SHarry Wentland } 1086b8fdfcc6SHarry Wentland } 1087b8fdfcc6SHarry Wentland 1088667e1498SAndrey Grodzovsky static bool dce120_arm_vert_intr( 1089667e1498SAndrey Grodzovsky struct timing_generator *tg, 1090667e1498SAndrey Grodzovsky uint8_t width) 1091667e1498SAndrey Grodzovsky { 1092667e1498SAndrey Grodzovsky struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 109381c50963SSylvia Tsai uint32_t v_blank_start, v_blank_end, h_position, v_position; 1094667e1498SAndrey Grodzovsky 1095667e1498SAndrey Grodzovsky tg->funcs->get_scanoutpos( 1096667e1498SAndrey Grodzovsky tg, 109781c50963SSylvia Tsai &v_blank_start, 109881c50963SSylvia Tsai &v_blank_end, 109981c50963SSylvia Tsai &h_position, 110081c50963SSylvia Tsai &v_position); 1101667e1498SAndrey Grodzovsky 110281c50963SSylvia Tsai if (v_blank_start == 0 || v_blank_end == 0) 1103667e1498SAndrey Grodzovsky return false; 1104667e1498SAndrey Grodzovsky 1105667e1498SAndrey Grodzovsky CRTC_REG_SET_2( 1106667e1498SAndrey Grodzovsky CRTC0_CRTC_VERTICAL_INTERRUPT0_POSITION, 110781c50963SSylvia Tsai CRTC_VERTICAL_INTERRUPT0_LINE_START, v_blank_start, 110881c50963SSylvia Tsai CRTC_VERTICAL_INTERRUPT0_LINE_END, v_blank_start + width); 1109667e1498SAndrey Grodzovsky 1110667e1498SAndrey Grodzovsky return true; 1111667e1498SAndrey Grodzovsky } 1112667e1498SAndrey Grodzovsky 1113b8fdfcc6SHarry Wentland static struct timing_generator_funcs dce120_tg_funcs = { 1114b8fdfcc6SHarry Wentland .validate_timing = dce120_tg_validate_timing, 1115b8fdfcc6SHarry Wentland .program_timing = dce120_tg_program_timing, 1116b8fdfcc6SHarry Wentland .enable_crtc = dce120_timing_generator_enable_crtc, 1117b8fdfcc6SHarry Wentland .disable_crtc = dce110_timing_generator_disable_crtc, 1118b8fdfcc6SHarry Wentland /* used by enable_timing_synchronization. Not need for FPGA */ 1119b8fdfcc6SHarry Wentland .is_counter_moving = dce110_timing_generator_is_counter_moving, 1120b8fdfcc6SHarry Wentland /* never be called */ 112172ada5f7SEric Cook .get_position = dce120_timing_generator_get_crtc_position, 1122b8fdfcc6SHarry Wentland .get_frame_count = dce120_timing_generator_get_vblank_counter, 1123b8fdfcc6SHarry Wentland .get_scanoutpos = dce120_timing_generator_get_crtc_scanoutpos, 1124b8fdfcc6SHarry Wentland .set_early_control = dce120_timing_generator_set_early_control, 1125b8fdfcc6SHarry Wentland /* used by enable_timing_synchronization. Not need for FPGA */ 1126b8fdfcc6SHarry Wentland .wait_for_state = dce120_tg_wait_for_state, 1127b8fdfcc6SHarry Wentland .set_blank = dce120_tg_set_blank, 1128b8fdfcc6SHarry Wentland .is_blanked = dce120_tg_is_blanked, 1129b8fdfcc6SHarry Wentland /* never be called */ 1130b8fdfcc6SHarry Wentland .set_colors = dce120_tg_set_colors, 1131b8fdfcc6SHarry Wentland .set_overscan_blank_color = dce120_timing_generator_set_overscan_color_black, 1132b8fdfcc6SHarry Wentland .set_blank_color = dce120_timing_generator_program_blank_color, 1133b8fdfcc6SHarry Wentland .disable_vga = dce120_timing_generator_disable_vga, 1134b8fdfcc6SHarry Wentland .did_triggered_reset_occur = dce120_timing_generator_did_triggered_reset_occur, 1135b8fdfcc6SHarry Wentland .setup_global_swap_lock = dce120_timing_generator_setup_global_swap_lock, 1136b8fdfcc6SHarry Wentland .enable_reset_trigger = dce120_timing_generator_enable_reset_trigger, 1137b8fdfcc6SHarry Wentland .disable_reset_trigger = dce120_timing_generator_disable_reset_trigger, 1138b8fdfcc6SHarry Wentland .tear_down_global_swap_lock = dce120_timing_generator_tear_down_global_swap_lock, 1139b8fdfcc6SHarry Wentland .enable_advanced_request = dce120_timing_generator_enable_advanced_request, 1140b8fdfcc6SHarry Wentland .set_drr = dce120_timing_generator_set_drr, 1141b8fdfcc6SHarry Wentland .set_static_screen_control = dce120_timing_generator_set_static_screen_control, 1142667e1498SAndrey Grodzovsky .set_test_pattern = dce120_timing_generator_set_test_pattern, 1143667e1498SAndrey Grodzovsky .arm_vert_intr = dce120_arm_vert_intr, 1144b8fdfcc6SHarry Wentland }; 1145b8fdfcc6SHarry Wentland 1146b8fdfcc6SHarry Wentland 1147b8fdfcc6SHarry Wentland bool dce120_timing_generator_construct( 1148b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110, 1149b8fdfcc6SHarry Wentland struct dc_context *ctx, 1150b8fdfcc6SHarry Wentland uint32_t instance, 1151b8fdfcc6SHarry Wentland const struct dce110_timing_generator_offsets *offsets) 1152b8fdfcc6SHarry Wentland { 1153b8fdfcc6SHarry Wentland if (!tg110) 1154b8fdfcc6SHarry Wentland return false; 1155b8fdfcc6SHarry Wentland 1156b8fdfcc6SHarry Wentland tg110->controller_id = CONTROLLER_ID_D0 + instance; 1157b8fdfcc6SHarry Wentland tg110->base.inst = instance; 1158b8fdfcc6SHarry Wentland 1159b8fdfcc6SHarry Wentland tg110->offsets = *offsets; 1160b8fdfcc6SHarry Wentland 1161b8fdfcc6SHarry Wentland tg110->base.funcs = &dce120_tg_funcs; 1162b8fdfcc6SHarry Wentland 1163b8fdfcc6SHarry Wentland tg110->base.ctx = ctx; 1164b8fdfcc6SHarry Wentland tg110->base.bp = ctx->dc_bios; 1165b8fdfcc6SHarry Wentland 1166b8fdfcc6SHarry Wentland tg110->max_h_total = CRTC0_CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1; 1167b8fdfcc6SHarry Wentland tg110->max_v_total = CRTC0_CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1; 1168b8fdfcc6SHarry Wentland 1169b8fdfcc6SHarry Wentland /*//CRTC requires a minimum HBLANK = 32 pixels and o 1170b8fdfcc6SHarry Wentland * Minimum HSYNC = 8 pixels*/ 1171b8fdfcc6SHarry Wentland tg110->min_h_blank = 32; 1172b8fdfcc6SHarry Wentland /*DCE12_CRTC_Block_ARch.doc*/ 1173b8fdfcc6SHarry Wentland tg110->min_h_front_porch = 0; 1174b8fdfcc6SHarry Wentland tg110->min_h_back_porch = 0; 1175b8fdfcc6SHarry Wentland 1176b8fdfcc6SHarry Wentland tg110->min_h_sync_width = 8; 1177b8fdfcc6SHarry Wentland tg110->min_v_sync_width = 1; 1178b8fdfcc6SHarry Wentland tg110->min_v_blank = 3; 1179b8fdfcc6SHarry Wentland 1180b8fdfcc6SHarry Wentland return true; 1181b8fdfcc6SHarry Wentland } 1182