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 28135d4b10SFeifei Xu #include "dce/dce_12_0_offset.h" 29135d4b10SFeifei Xu #include "dce/dce_12_0_sh_mask.h" 30407e7517SHawking Zhang #include "soc15_hw_ip.h" 31407e7517SHawking Zhang #include "vega10_ip_offset.h" 32b8fdfcc6SHarry Wentland 33b8fdfcc6SHarry Wentland #include "dc_types.h" 34b8fdfcc6SHarry Wentland #include "dc_bios_types.h" 35b8fdfcc6SHarry Wentland 36b8fdfcc6SHarry Wentland #include "include/grph_object_id.h" 37b8fdfcc6SHarry Wentland #include "include/logger_interface.h" 38b8fdfcc6SHarry Wentland #include "dce120_timing_generator.h" 39b8fdfcc6SHarry Wentland 40b8fdfcc6SHarry Wentland #include "timing_generator.h" 41b8fdfcc6SHarry Wentland 42b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_N(reg_name, n, ...) \ 43b8fdfcc6SHarry Wentland generic_reg_update_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__) 44b8fdfcc6SHarry Wentland 45b8fdfcc6SHarry Wentland #define CRTC_REG_SET_N(reg_name, n, ...) \ 46b8fdfcc6SHarry Wentland generic_reg_set_soc15(tg110->base.ctx, tg110->offsets.crtc, reg_name, n, __VA_ARGS__) 47b8fdfcc6SHarry Wentland 48b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE(reg, field, val) \ 49b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 1, FD(reg##__##field), val) 50b8fdfcc6SHarry Wentland 51b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_2(reg, field1, val1, field2, val2) \ 52b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2) 53b8fdfcc6SHarry Wentland 54b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3) \ 55b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3) 56b8fdfcc6SHarry Wentland 57b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_4(reg, field1, val1, field2, val2, field3, val3, field4, val4) \ 58b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3, FD(reg##__##field4), val4) 59b8fdfcc6SHarry Wentland 60b8fdfcc6SHarry Wentland #define CRTC_REG_UPDATE_5(reg, field1, val1, field2, val2, field3, val3, field4, val4, field5, val5) \ 61b8fdfcc6SHarry 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) 62b8fdfcc6SHarry Wentland 63b8fdfcc6SHarry Wentland #define CRTC_REG_SET(reg, field, val) \ 64b8fdfcc6SHarry Wentland CRTC_REG_SET_N(reg, 1, FD(reg##__##field), val) 65b8fdfcc6SHarry Wentland 66b8fdfcc6SHarry Wentland #define CRTC_REG_SET_2(reg, field1, val1, field2, val2) \ 67b8fdfcc6SHarry Wentland CRTC_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2) 68b8fdfcc6SHarry Wentland 69b8fdfcc6SHarry Wentland #define CRTC_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \ 70b8fdfcc6SHarry Wentland CRTC_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3) 71b8fdfcc6SHarry Wentland 72b8fdfcc6SHarry Wentland /** 73b8fdfcc6SHarry Wentland ***************************************************************************** 74b8fdfcc6SHarry Wentland * Function: is_in_vertical_blank 75b8fdfcc6SHarry Wentland * 76b8fdfcc6SHarry Wentland * @brief 77b8fdfcc6SHarry Wentland * check the current status of CRTC to check if we are in Vertical Blank 78b8fdfcc6SHarry Wentland * regioneased" state 79b8fdfcc6SHarry Wentland * 80b8fdfcc6SHarry Wentland * @return 81b8fdfcc6SHarry Wentland * true if currently in blank region, false otherwise 82b8fdfcc6SHarry Wentland * 83b8fdfcc6SHarry Wentland ***************************************************************************** 84b8fdfcc6SHarry Wentland */ 85b8fdfcc6SHarry Wentland static bool dce120_timing_generator_is_in_vertical_blank( 86b8fdfcc6SHarry Wentland struct timing_generator *tg) 87b8fdfcc6SHarry Wentland { 88b8fdfcc6SHarry Wentland uint32_t field = 0; 89b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 90b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 91b8fdfcc6SHarry Wentland tg->ctx, 92b8fdfcc6SHarry Wentland mmCRTC0_CRTC_STATUS, 93b8fdfcc6SHarry Wentland tg110->offsets.crtc); 94b8fdfcc6SHarry Wentland 95b8fdfcc6SHarry Wentland field = get_reg_field_value(value, CRTC0_CRTC_STATUS, CRTC_V_BLANK); 96b8fdfcc6SHarry Wentland return field == 1; 97b8fdfcc6SHarry Wentland } 98b8fdfcc6SHarry Wentland 99b8fdfcc6SHarry Wentland 100b8fdfcc6SHarry Wentland /* determine if given timing can be supported by TG */ 101b8fdfcc6SHarry Wentland bool dce120_timing_generator_validate_timing( 102b8fdfcc6SHarry Wentland struct timing_generator *tg, 103b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing, 104b8fdfcc6SHarry Wentland enum signal_type signal) 105b8fdfcc6SHarry Wentland { 106b8fdfcc6SHarry Wentland uint32_t interlace_factor = timing->flags.INTERLACE ? 2 : 1; 107b8fdfcc6SHarry Wentland uint32_t v_blank = 108b8fdfcc6SHarry Wentland (timing->v_total - timing->v_addressable - 109b8fdfcc6SHarry Wentland timing->v_border_top - timing->v_border_bottom) * 110b8fdfcc6SHarry Wentland interlace_factor; 111b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 112b8fdfcc6SHarry Wentland 113b8fdfcc6SHarry Wentland if (!dce110_timing_generator_validate_timing( 114b8fdfcc6SHarry Wentland tg, 115b8fdfcc6SHarry Wentland timing, 116b8fdfcc6SHarry Wentland signal)) 117b8fdfcc6SHarry Wentland return false; 118b8fdfcc6SHarry Wentland 119b8fdfcc6SHarry Wentland 120b8fdfcc6SHarry Wentland if (v_blank < tg110->min_v_blank || 121b8fdfcc6SHarry Wentland timing->h_sync_width < tg110->min_h_sync_width || 122b8fdfcc6SHarry Wentland timing->v_sync_width < tg110->min_v_sync_width) 123b8fdfcc6SHarry Wentland return false; 124b8fdfcc6SHarry Wentland 125b8fdfcc6SHarry Wentland return true; 126b8fdfcc6SHarry Wentland } 127b8fdfcc6SHarry Wentland 128b8fdfcc6SHarry Wentland bool dce120_tg_validate_timing(struct timing_generator *tg, 129b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing) 130b8fdfcc6SHarry Wentland { 131b8fdfcc6SHarry Wentland return dce120_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE); 132b8fdfcc6SHarry Wentland } 133b8fdfcc6SHarry Wentland 134b8fdfcc6SHarry Wentland /******** HW programming ************/ 135b8fdfcc6SHarry Wentland /* Disable/Enable Timing Generator */ 136b8fdfcc6SHarry Wentland bool dce120_timing_generator_enable_crtc(struct timing_generator *tg) 137b8fdfcc6SHarry Wentland { 138b8fdfcc6SHarry Wentland enum bp_result result; 139b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 140b8fdfcc6SHarry Wentland 141b8fdfcc6SHarry Wentland /* Set MASTER_UPDATE_MODE to 0 142b8fdfcc6SHarry Wentland * This is needed for DRR, and also suggested to be default value by Syed.*/ 143b8fdfcc6SHarry Wentland 144b8fdfcc6SHarry Wentland CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_MODE, 145b8fdfcc6SHarry Wentland MASTER_UPDATE_MODE, 0); 146b8fdfcc6SHarry Wentland 147b8fdfcc6SHarry Wentland CRTC_REG_UPDATE(CRTC0_CRTC_MASTER_UPDATE_LOCK, 148b8fdfcc6SHarry Wentland UNDERFLOW_UPDATE_LOCK, 0); 149b8fdfcc6SHarry Wentland 150b8fdfcc6SHarry Wentland /* TODO API for AtomFirmware didn't change*/ 151b8fdfcc6SHarry Wentland result = tg->bp->funcs->enable_crtc(tg->bp, tg110->controller_id, true); 152b8fdfcc6SHarry Wentland 153b8fdfcc6SHarry Wentland return result == BP_RESULT_OK; 154b8fdfcc6SHarry Wentland } 155b8fdfcc6SHarry Wentland 156b8fdfcc6SHarry Wentland void dce120_timing_generator_set_early_control( 157b8fdfcc6SHarry Wentland struct timing_generator *tg, 158b8fdfcc6SHarry Wentland uint32_t early_cntl) 159b8fdfcc6SHarry Wentland { 160b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 161b8fdfcc6SHarry Wentland 162b8fdfcc6SHarry Wentland CRTC_REG_UPDATE(CRTC0_CRTC_CONTROL, 163b8fdfcc6SHarry Wentland CRTC_HBLANK_EARLY_CONTROL, early_cntl); 164b8fdfcc6SHarry Wentland } 165b8fdfcc6SHarry Wentland 166b8fdfcc6SHarry Wentland /**************** TG current status ******************/ 167b8fdfcc6SHarry Wentland 168b8fdfcc6SHarry Wentland /* return the current frame counter. Used by Linux kernel DRM */ 169b8fdfcc6SHarry Wentland uint32_t dce120_timing_generator_get_vblank_counter( 170b8fdfcc6SHarry Wentland struct timing_generator *tg) 171b8fdfcc6SHarry Wentland { 172b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 173b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 174b8fdfcc6SHarry Wentland tg->ctx, 175b8fdfcc6SHarry Wentland mmCRTC0_CRTC_STATUS_FRAME_COUNT, 176b8fdfcc6SHarry Wentland tg110->offsets.crtc); 177b8fdfcc6SHarry Wentland uint32_t field = get_reg_field_value( 178b8fdfcc6SHarry Wentland value, CRTC0_CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT); 179b8fdfcc6SHarry Wentland 180b8fdfcc6SHarry Wentland return field; 181b8fdfcc6SHarry Wentland } 182b8fdfcc6SHarry Wentland 183b8fdfcc6SHarry Wentland /* Get current H and V position */ 18472ada5f7SEric Cook void dce120_timing_generator_get_crtc_position( 185b8fdfcc6SHarry Wentland struct timing_generator *tg, 18672ada5f7SEric Cook struct crtc_position *position) 187b8fdfcc6SHarry Wentland { 188b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 189b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 190b8fdfcc6SHarry Wentland tg->ctx, 191b8fdfcc6SHarry Wentland mmCRTC0_CRTC_STATUS_POSITION, 192b8fdfcc6SHarry Wentland tg110->offsets.crtc); 193b8fdfcc6SHarry Wentland 19472ada5f7SEric Cook position->horizontal_count = get_reg_field_value(value, 19572ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, CRTC_HORZ_COUNT); 196b8fdfcc6SHarry Wentland 19772ada5f7SEric Cook position->vertical_count = get_reg_field_value(value, 19872ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, CRTC_VERT_COUNT); 19972ada5f7SEric Cook 20072ada5f7SEric Cook value = dm_read_reg_soc15( 20172ada5f7SEric Cook tg->ctx, 20272ada5f7SEric Cook mmCRTC0_CRTC_NOM_VERT_POSITION, 20372ada5f7SEric Cook tg110->offsets.crtc); 20472ada5f7SEric Cook 20572ada5f7SEric Cook position->nominal_vcount = get_reg_field_value(value, 20672ada5f7SEric Cook CRTC0_CRTC_NOM_VERT_POSITION, CRTC_VERT_COUNT_NOM); 207b8fdfcc6SHarry Wentland } 208b8fdfcc6SHarry Wentland 209b8fdfcc6SHarry Wentland /* wait until TG is in beginning of vertical blank region */ 210b8fdfcc6SHarry Wentland void dce120_timing_generator_wait_for_vblank(struct timing_generator *tg) 211b8fdfcc6SHarry Wentland { 212b8fdfcc6SHarry Wentland /* We want to catch beginning of VBlank here, so if the first try are 213b8fdfcc6SHarry Wentland * in VBlank, we might be very close to Active, in this case wait for 214b8fdfcc6SHarry Wentland * another frame 215b8fdfcc6SHarry Wentland */ 216b8fdfcc6SHarry Wentland while (dce120_timing_generator_is_in_vertical_blank(tg)) { 217b8fdfcc6SHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 218b8fdfcc6SHarry Wentland /* error - no point to wait if counter is not moving */ 219b8fdfcc6SHarry Wentland break; 220b8fdfcc6SHarry Wentland } 221b8fdfcc6SHarry Wentland } 222b8fdfcc6SHarry Wentland 223b8fdfcc6SHarry Wentland while (!dce120_timing_generator_is_in_vertical_blank(tg)) { 224b8fdfcc6SHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 225b8fdfcc6SHarry Wentland /* error - no point to wait if counter is not moving */ 226b8fdfcc6SHarry Wentland break; 227b8fdfcc6SHarry Wentland } 228b8fdfcc6SHarry Wentland } 229b8fdfcc6SHarry Wentland } 230b8fdfcc6SHarry Wentland 231b8fdfcc6SHarry Wentland /* wait until TG is in beginning of active region */ 232b8fdfcc6SHarry Wentland void dce120_timing_generator_wait_for_vactive(struct timing_generator *tg) 233b8fdfcc6SHarry Wentland { 234b8fdfcc6SHarry Wentland while (dce120_timing_generator_is_in_vertical_blank(tg)) { 235b8fdfcc6SHarry Wentland if (!tg->funcs->is_counter_moving(tg)) { 236b8fdfcc6SHarry Wentland /* error - no point to wait if counter is not moving */ 237b8fdfcc6SHarry Wentland break; 238b8fdfcc6SHarry Wentland } 239b8fdfcc6SHarry Wentland } 240b8fdfcc6SHarry Wentland } 241b8fdfcc6SHarry Wentland 242b8fdfcc6SHarry Wentland /*********** Timing Generator Synchronization routines ****/ 243b8fdfcc6SHarry Wentland 244b8fdfcc6SHarry Wentland /* Setups Global Swap Lock group, TimingServer or TimingClient*/ 245b8fdfcc6SHarry Wentland void dce120_timing_generator_setup_global_swap_lock( 246b8fdfcc6SHarry Wentland struct timing_generator *tg, 247b8fdfcc6SHarry Wentland const struct dcp_gsl_params *gsl_params) 248b8fdfcc6SHarry Wentland { 249b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 250b8fdfcc6SHarry Wentland uint32_t value_crtc_vtotal = 251b8fdfcc6SHarry Wentland dm_read_reg_soc15(tg->ctx, 252b8fdfcc6SHarry Wentland mmCRTC0_CRTC_V_TOTAL, 253b8fdfcc6SHarry Wentland tg110->offsets.crtc); 254b8fdfcc6SHarry Wentland /* Checkpoint relative to end of frame */ 255b8fdfcc6SHarry Wentland uint32_t check_point = 256b8fdfcc6SHarry Wentland get_reg_field_value(value_crtc_vtotal, 257b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL, 258b8fdfcc6SHarry Wentland CRTC_V_TOTAL); 259b8fdfcc6SHarry Wentland 260b8fdfcc6SHarry Wentland 261b8fdfcc6SHarry Wentland dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_GSL_WINDOW, tg110->offsets.crtc, 0); 262b8fdfcc6SHarry Wentland 263b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_N(DCP0_DCP_GSL_CONTROL, 6, 264b8fdfcc6SHarry Wentland /* This pipe will belong to GSL Group zero. */ 265b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 1, 266b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), gsl_params->gsl_master == tg->inst, 267b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY, 268b8fdfcc6SHarry Wentland /* Keep signal low (pending high) during 6 lines. 269b8fdfcc6SHarry Wentland * Also defines minimum interval before re-checking signal. */ 270b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY, 271b8fdfcc6SHarry Wentland /* DCP_GSL_PURPOSE_SURFACE_FLIP */ 272b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0, 273b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 1); 274b8fdfcc6SHarry Wentland 275b8fdfcc6SHarry Wentland CRTC_REG_SET_2( 276b8fdfcc6SHarry Wentland CRTC0_CRTC_GSL_CONTROL, 277b8fdfcc6SHarry Wentland CRTC_GSL_CHECK_LINE_NUM, check_point - FLIP_READY_BACK_LOOKUP, 278b8fdfcc6SHarry Wentland CRTC_GSL_FORCE_DELAY, VFLIP_READY_DELAY); 279b8fdfcc6SHarry Wentland } 280b8fdfcc6SHarry Wentland 281b8fdfcc6SHarry Wentland /* Clear all the register writes done by setup_global_swap_lock */ 282b8fdfcc6SHarry Wentland void dce120_timing_generator_tear_down_global_swap_lock( 283b8fdfcc6SHarry Wentland struct timing_generator *tg) 284b8fdfcc6SHarry Wentland { 285b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 286b8fdfcc6SHarry Wentland 287b8fdfcc6SHarry Wentland /* Settig HW default values from reg specs */ 288b8fdfcc6SHarry Wentland CRTC_REG_SET_N(DCP0_DCP_GSL_CONTROL, 6, 289b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL0_EN), 0, 290b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_MASTER_EN), 0, 291b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_FORCE_DELAY), HFLIP_READY_DELAY, 292b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_HSYNC_FLIP_CHECK_DELAY), HFLIP_CHECK_DELAY, 293b8fdfcc6SHarry Wentland /* DCP_GSL_PURPOSE_SURFACE_FLIP */ 294b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_SYNC_SOURCE), 0, 295b8fdfcc6SHarry Wentland FD(DCP0_DCP_GSL_CONTROL__DCP_GSL_DELAY_SURFACE_UPDATE_PENDING), 0); 296b8fdfcc6SHarry Wentland 297bf5563edSDave Airlie CRTC_REG_SET_2(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 offset = 0; 390b8fdfcc6SHarry Wentland uint32_t value = 0; 391b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 392b8fdfcc6SHarry Wentland 393b8fdfcc6SHarry Wentland switch (tg110->controller_id) { 394b8fdfcc6SHarry Wentland case CONTROLLER_ID_D0: 395b8fdfcc6SHarry Wentland offset = 0; 396b8fdfcc6SHarry Wentland break; 397b8fdfcc6SHarry Wentland case CONTROLLER_ID_D1: 398b8fdfcc6SHarry Wentland offset = mmD2VGA_CONTROL - mmD1VGA_CONTROL; 399b8fdfcc6SHarry Wentland break; 400b8fdfcc6SHarry Wentland case CONTROLLER_ID_D2: 401b8fdfcc6SHarry Wentland offset = mmD3VGA_CONTROL - mmD1VGA_CONTROL; 402b8fdfcc6SHarry Wentland break; 403b8fdfcc6SHarry Wentland case CONTROLLER_ID_D3: 404b8fdfcc6SHarry Wentland offset = mmD4VGA_CONTROL - mmD1VGA_CONTROL; 405b8fdfcc6SHarry Wentland break; 406b8fdfcc6SHarry Wentland case CONTROLLER_ID_D4: 407ccaf31ecSRoman Li offset = mmD5VGA_CONTROL - mmD1VGA_CONTROL; 408b8fdfcc6SHarry Wentland break; 409b8fdfcc6SHarry Wentland case CONTROLLER_ID_D5: 410b8fdfcc6SHarry Wentland offset = mmD6VGA_CONTROL - mmD1VGA_CONTROL; 411b8fdfcc6SHarry Wentland break; 412b8fdfcc6SHarry Wentland default: 413b8fdfcc6SHarry Wentland break; 414b8fdfcc6SHarry Wentland } 415b8fdfcc6SHarry Wentland 416b8fdfcc6SHarry Wentland value = dm_read_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset); 417b8fdfcc6SHarry Wentland 418b8fdfcc6SHarry Wentland set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE); 419b8fdfcc6SHarry Wentland set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT); 420b8fdfcc6SHarry Wentland set_reg_field_value( 421b8fdfcc6SHarry Wentland value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT); 422b8fdfcc6SHarry Wentland set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN); 423b8fdfcc6SHarry Wentland 424b8fdfcc6SHarry Wentland dm_write_reg_soc15(tg->ctx, mmD1VGA_CONTROL, offset, value); 425b8fdfcc6SHarry Wentland } 426b8fdfcc6SHarry Wentland /* TODO: Should we move it to transform */ 427b8fdfcc6SHarry Wentland /* Fully program CRTC timing in timing generator */ 428b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blanking( 429b8fdfcc6SHarry Wentland struct timing_generator *tg, 430b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing) 431b8fdfcc6SHarry Wentland { 432b8fdfcc6SHarry Wentland uint32_t tmp1 = 0; 433b8fdfcc6SHarry Wentland uint32_t tmp2 = 0; 434b8fdfcc6SHarry Wentland uint32_t vsync_offset = timing->v_border_bottom + 435b8fdfcc6SHarry Wentland timing->v_front_porch; 436b8fdfcc6SHarry Wentland uint32_t v_sync_start = timing->v_addressable + vsync_offset; 437b8fdfcc6SHarry Wentland 438b8fdfcc6SHarry Wentland uint32_t hsync_offset = timing->h_border_right + 439b8fdfcc6SHarry Wentland timing->h_front_porch; 440b8fdfcc6SHarry Wentland uint32_t h_sync_start = timing->h_addressable + hsync_offset; 441b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 442b8fdfcc6SHarry Wentland 443b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 444b8fdfcc6SHarry Wentland CRTC0_CRTC_H_TOTAL, 445b8fdfcc6SHarry Wentland CRTC_H_TOTAL, 446b8fdfcc6SHarry Wentland timing->h_total - 1); 447b8fdfcc6SHarry Wentland 448b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 449b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL, 450b8fdfcc6SHarry Wentland CRTC_V_TOTAL, 45197416d4cSYongqiang Sun timing->v_total - 1); 45297416d4cSYongqiang Sun 45397416d4cSYongqiang Sun /* In case of V_TOTAL_CONTROL is on, make sure V_TOTAL_MAX and 45497416d4cSYongqiang Sun * V_TOTAL_MIN are equal to V_TOTAL. 45597416d4cSYongqiang Sun */ 45697416d4cSYongqiang Sun CRTC_REG_UPDATE( 45797416d4cSYongqiang Sun CRTC0_CRTC_V_TOTAL_MAX, 45897416d4cSYongqiang Sun CRTC_V_TOTAL_MAX, 45997416d4cSYongqiang Sun timing->v_total - 1); 46097416d4cSYongqiang Sun 46197416d4cSYongqiang Sun CRTC_REG_UPDATE( 46297416d4cSYongqiang Sun CRTC0_CRTC_V_TOTAL_MIN, 46397416d4cSYongqiang Sun CRTC_V_TOTAL_MIN, 464b8fdfcc6SHarry Wentland timing->v_total - 1); 465b8fdfcc6SHarry Wentland 466b8fdfcc6SHarry Wentland tmp1 = timing->h_total - 467b8fdfcc6SHarry Wentland (h_sync_start + timing->h_border_left); 468b8fdfcc6SHarry Wentland tmp2 = tmp1 + timing->h_addressable + 469b8fdfcc6SHarry Wentland timing->h_border_left + timing->h_border_right; 470b8fdfcc6SHarry Wentland 471b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2( 472b8fdfcc6SHarry Wentland CRTC0_CRTC_H_BLANK_START_END, 473b8fdfcc6SHarry Wentland CRTC_H_BLANK_END, tmp1, 474b8fdfcc6SHarry Wentland CRTC_H_BLANK_START, tmp2); 475b8fdfcc6SHarry Wentland 476b8fdfcc6SHarry Wentland tmp1 = timing->v_total - (v_sync_start + timing->v_border_top); 477b8fdfcc6SHarry Wentland tmp2 = tmp1 + timing->v_addressable + timing->v_border_top + 478b8fdfcc6SHarry Wentland timing->v_border_bottom; 479b8fdfcc6SHarry Wentland 480b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2( 481b8fdfcc6SHarry Wentland CRTC0_CRTC_V_BLANK_START_END, 482b8fdfcc6SHarry Wentland CRTC_V_BLANK_END, tmp1, 483b8fdfcc6SHarry Wentland CRTC_V_BLANK_START, tmp2); 484b8fdfcc6SHarry Wentland } 485b8fdfcc6SHarry Wentland 486b8fdfcc6SHarry Wentland /* TODO: Should we move it to opp? */ 487b8fdfcc6SHarry Wentland /* Combine with below and move YUV/RGB color conversion to SW layer */ 488b8fdfcc6SHarry Wentland void dce120_timing_generator_program_blank_color( 489b8fdfcc6SHarry Wentland struct timing_generator *tg, 490b8fdfcc6SHarry Wentland const struct tg_color *black_color) 491b8fdfcc6SHarry Wentland { 492b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 493b8fdfcc6SHarry Wentland 494b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_3( 495b8fdfcc6SHarry Wentland CRTC0_CRTC_BLACK_COLOR, 496b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb, 497b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_G_Y, black_color->color_g_y, 498b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr); 499b8fdfcc6SHarry Wentland } 500b8fdfcc6SHarry Wentland /* Combine with above and move YUV/RGB color conversion to SW layer */ 501b8fdfcc6SHarry Wentland void dce120_timing_generator_set_overscan_color_black( 502b8fdfcc6SHarry Wentland struct timing_generator *tg, 503b8fdfcc6SHarry Wentland const struct tg_color *color) 504b8fdfcc6SHarry Wentland { 505b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 506b8fdfcc6SHarry Wentland uint32_t value = 0; 507b8fdfcc6SHarry Wentland CRTC_REG_SET_3( 508b8fdfcc6SHarry Wentland CRTC0_CRTC_OVERSCAN_COLOR, 509b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_BLUE, color->color_b_cb, 510b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_GREEN, color->color_g_y, 511b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_RED, color->color_r_cr); 512b8fdfcc6SHarry Wentland 513b8fdfcc6SHarry Wentland value = dm_read_reg_soc15( 514b8fdfcc6SHarry Wentland tg->ctx, 515b8fdfcc6SHarry Wentland mmCRTC0_CRTC_OVERSCAN_COLOR, 516b8fdfcc6SHarry Wentland tg110->offsets.crtc); 517b8fdfcc6SHarry Wentland 518b8fdfcc6SHarry Wentland dm_write_reg_soc15( 519b8fdfcc6SHarry Wentland tg->ctx, 520b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLACK_COLOR, 521b8fdfcc6SHarry Wentland tg110->offsets.crtc, 522b8fdfcc6SHarry Wentland value); 523b8fdfcc6SHarry Wentland 524b8fdfcc6SHarry Wentland /* This is desirable to have a constant DAC output voltage during the 525b8fdfcc6SHarry Wentland * blank time that is higher than the 0 volt reference level that the 526b8fdfcc6SHarry Wentland * DAC outputs when the NBLANK signal 527b8fdfcc6SHarry Wentland * is asserted low, such as for output to an analog TV. */ 528b8fdfcc6SHarry Wentland dm_write_reg_soc15( 529b8fdfcc6SHarry Wentland tg->ctx, 530b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLANK_DATA_COLOR, 531b8fdfcc6SHarry Wentland tg110->offsets.crtc, 532b8fdfcc6SHarry Wentland value); 533b8fdfcc6SHarry Wentland 534b8fdfcc6SHarry Wentland /* TO DO we have to program EXT registers and we need to know LB DATA 535b8fdfcc6SHarry Wentland * format because it is used when more 10 , i.e. 12 bits per color 536b8fdfcc6SHarry Wentland * 537b8fdfcc6SHarry Wentland * m_mmDxCRTC_OVERSCAN_COLOR_EXT 538b8fdfcc6SHarry Wentland * m_mmDxCRTC_BLACK_COLOR_EXT 539b8fdfcc6SHarry Wentland * m_mmDxCRTC_BLANK_DATA_COLOR_EXT 540b8fdfcc6SHarry Wentland */ 541b8fdfcc6SHarry Wentland } 542b8fdfcc6SHarry Wentland 543b8fdfcc6SHarry Wentland void dce120_timing_generator_set_drr( 544b8fdfcc6SHarry Wentland struct timing_generator *tg, 545b8fdfcc6SHarry Wentland const struct drr_params *params) 546b8fdfcc6SHarry Wentland { 547b8fdfcc6SHarry Wentland 548b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 549b8fdfcc6SHarry Wentland 550b8fdfcc6SHarry Wentland if (params != NULL && 551b8fdfcc6SHarry Wentland params->vertical_total_max > 0 && 552b8fdfcc6SHarry Wentland params->vertical_total_min > 0) { 553b8fdfcc6SHarry Wentland 554b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 555b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL_MIN, 5566c626ffbSYongqiang Sun CRTC_V_TOTAL_MIN, params->vertical_total_min - 1); 557b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 558b8fdfcc6SHarry Wentland CRTC0_CRTC_V_TOTAL_MAX, 5596c626ffbSYongqiang Sun CRTC_V_TOTAL_MAX, params->vertical_total_max - 1); 560b8fdfcc6SHarry Wentland CRTC_REG_SET_N(CRTC0_CRTC_V_TOTAL_CONTROL, 6, 561b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MIN_SEL), 1, 562b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_V_TOTAL_MAX_SEL), 1, 563b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_ON_EVENT), 0, 564b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_FORCE_LOCK_TO_MASTER_VSYNC), 0, 565b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK_EN), 0, 566b8fdfcc6SHarry Wentland FD(CRTC0_CRTC_V_TOTAL_CONTROL__CRTC_SET_V_TOTAL_MIN_MASK), 0); 567b8fdfcc6SHarry Wentland CRTC_REG_UPDATE( 568b8fdfcc6SHarry Wentland CRTC0_CRTC_STATIC_SCREEN_CONTROL, 569b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_EVENT_MASK, 570b8fdfcc6SHarry Wentland 0x180); 571b8fdfcc6SHarry Wentland 572b8fdfcc6SHarry Wentland } else { 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( 5800c8df4bbSAnthony Koo CRTC0_CRTC_V_TOTAL_MIN, 5810c8df4bbSAnthony Koo CRTC_V_TOTAL_MIN, 0); 5820c8df4bbSAnthony Koo CRTC_REG_UPDATE( 5830c8df4bbSAnthony Koo CRTC0_CRTC_V_TOTAL_MAX, 5840c8df4bbSAnthony Koo CRTC_V_TOTAL_MAX, 0); 5850c8df4bbSAnthony Koo CRTC_REG_UPDATE( 586b8fdfcc6SHarry Wentland CRTC0_CRTC_STATIC_SCREEN_CONTROL, 587b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_EVENT_MASK, 588b8fdfcc6SHarry Wentland 0); 589b8fdfcc6SHarry Wentland } 590b8fdfcc6SHarry Wentland } 591b8fdfcc6SHarry Wentland 59272ada5f7SEric Cook /** 59372ada5f7SEric Cook ***************************************************************************** 59472ada5f7SEric Cook * Function: dce120_timing_generator_get_position 59572ada5f7SEric Cook * 59672ada5f7SEric Cook * @brief 59772ada5f7SEric Cook * Returns CRTC vertical/horizontal counters 59872ada5f7SEric Cook * 59972ada5f7SEric Cook * @param [out] position 60072ada5f7SEric Cook ***************************************************************************** 60172ada5f7SEric Cook */ 60272ada5f7SEric Cook void dce120_timing_generator_get_position(struct timing_generator *tg, 60372ada5f7SEric Cook struct crtc_position *position) 60472ada5f7SEric Cook { 60572ada5f7SEric Cook uint32_t value; 60672ada5f7SEric Cook struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 60772ada5f7SEric Cook 60872ada5f7SEric Cook value = dm_read_reg_soc15( 60972ada5f7SEric Cook tg->ctx, 61072ada5f7SEric Cook mmCRTC0_CRTC_STATUS_POSITION, 61172ada5f7SEric Cook tg110->offsets.crtc); 61272ada5f7SEric Cook 61372ada5f7SEric Cook position->horizontal_count = get_reg_field_value( 61472ada5f7SEric Cook value, 61572ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, 61672ada5f7SEric Cook CRTC_HORZ_COUNT); 61772ada5f7SEric Cook 61872ada5f7SEric Cook position->vertical_count = get_reg_field_value( 61972ada5f7SEric Cook value, 62072ada5f7SEric Cook CRTC0_CRTC_STATUS_POSITION, 62172ada5f7SEric Cook CRTC_VERT_COUNT); 62272ada5f7SEric Cook 62372ada5f7SEric Cook value = dm_read_reg_soc15( 62472ada5f7SEric Cook tg->ctx, 62572ada5f7SEric Cook mmCRTC0_CRTC_NOM_VERT_POSITION, 62672ada5f7SEric Cook tg110->offsets.crtc); 62772ada5f7SEric Cook 62872ada5f7SEric Cook position->nominal_vcount = get_reg_field_value( 62972ada5f7SEric Cook value, 63072ada5f7SEric Cook CRTC0_CRTC_NOM_VERT_POSITION, 63172ada5f7SEric Cook CRTC_VERT_COUNT_NOM); 63272ada5f7SEric Cook } 63372ada5f7SEric Cook 63472ada5f7SEric Cook 63581c50963SSylvia Tsai void dce120_timing_generator_get_crtc_scanoutpos( 636b8fdfcc6SHarry Wentland struct timing_generator *tg, 63781c50963SSylvia Tsai uint32_t *v_blank_start, 63881c50963SSylvia Tsai uint32_t *v_blank_end, 63981c50963SSylvia Tsai uint32_t *h_position, 64081c50963SSylvia Tsai uint32_t *v_position) 641b8fdfcc6SHarry Wentland { 642b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 64372ada5f7SEric Cook struct crtc_position position; 644b8fdfcc6SHarry Wentland 64581c50963SSylvia Tsai uint32_t v_blank_start_end = dm_read_reg_soc15( 646b8fdfcc6SHarry Wentland tg->ctx, 647b8fdfcc6SHarry Wentland mmCRTC0_CRTC_V_BLANK_START_END, 648b8fdfcc6SHarry Wentland tg110->offsets.crtc); 649b8fdfcc6SHarry Wentland 65081c50963SSylvia Tsai *v_blank_start = get_reg_field_value(v_blank_start_end, 65181c50963SSylvia Tsai CRTC0_CRTC_V_BLANK_START_END, 65281c50963SSylvia Tsai CRTC_V_BLANK_START); 65381c50963SSylvia Tsai *v_blank_end = get_reg_field_value(v_blank_start_end, 65481c50963SSylvia Tsai CRTC0_CRTC_V_BLANK_START_END, 65581c50963SSylvia Tsai CRTC_V_BLANK_END); 656b8fdfcc6SHarry Wentland 65772ada5f7SEric Cook dce120_timing_generator_get_crtc_position( 65872ada5f7SEric Cook tg, &position); 65972ada5f7SEric Cook 66072ada5f7SEric Cook *h_position = position.horizontal_count; 66172ada5f7SEric Cook *v_position = position.vertical_count; 662b8fdfcc6SHarry Wentland } 663b8fdfcc6SHarry Wentland 664b8fdfcc6SHarry Wentland void dce120_timing_generator_enable_advanced_request( 665b8fdfcc6SHarry Wentland struct timing_generator *tg, 666b8fdfcc6SHarry Wentland bool enable, 667b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing) 668b8fdfcc6SHarry Wentland { 669b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 670b8fdfcc6SHarry Wentland uint32_t v_sync_width_and_b_porch = 671b8fdfcc6SHarry Wentland timing->v_total - timing->v_addressable - 672b8fdfcc6SHarry Wentland timing->v_border_bottom - timing->v_front_porch; 673b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 674b8fdfcc6SHarry Wentland tg->ctx, 675b8fdfcc6SHarry Wentland mmCRTC0_CRTC_START_LINE_CONTROL, 676b8fdfcc6SHarry Wentland tg110->offsets.crtc); 677b8fdfcc6SHarry Wentland 678b8fdfcc6SHarry Wentland set_reg_field_value( 679b8fdfcc6SHarry Wentland value, 680a4b0a5b8STom St Denis enable ? 0 : 1, 681b8fdfcc6SHarry Wentland CRTC0_CRTC_START_LINE_CONTROL, 682b8fdfcc6SHarry Wentland CRTC_LEGACY_REQUESTOR_EN); 683b8fdfcc6SHarry Wentland 684b8fdfcc6SHarry Wentland /* Program advanced line position acc.to the best case from fetching data perspective to hide MC latency 685b8fdfcc6SHarry Wentland * and prefilling Line Buffer in V Blank (to 10 lines as LB can store max 10 lines) 686b8fdfcc6SHarry Wentland */ 687b8fdfcc6SHarry Wentland if (v_sync_width_and_b_porch > 10) 688a4b0a5b8STom St Denis v_sync_width_and_b_porch = 10; 689a4b0a5b8STom St Denis 690b8fdfcc6SHarry Wentland set_reg_field_value( 691b8fdfcc6SHarry Wentland value, 692b8fdfcc6SHarry Wentland v_sync_width_and_b_porch, 693b8fdfcc6SHarry Wentland CRTC0_CRTC_START_LINE_CONTROL, 694b8fdfcc6SHarry Wentland CRTC_ADVANCED_START_LINE_POSITION); 695b8fdfcc6SHarry Wentland 696b8fdfcc6SHarry Wentland dm_write_reg_soc15(tg->ctx, 697b8fdfcc6SHarry Wentland mmCRTC0_CRTC_START_LINE_CONTROL, 698b8fdfcc6SHarry Wentland tg110->offsets.crtc, 699b8fdfcc6SHarry Wentland value); 700b8fdfcc6SHarry Wentland } 701b8fdfcc6SHarry Wentland 702b8fdfcc6SHarry Wentland void dce120_tg_program_blank_color(struct timing_generator *tg, 703b8fdfcc6SHarry Wentland const struct tg_color *black_color) 704b8fdfcc6SHarry Wentland { 705b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 706b8fdfcc6SHarry Wentland uint32_t value = 0; 707b8fdfcc6SHarry Wentland 708b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_3( 709b8fdfcc6SHarry Wentland CRTC0_CRTC_BLACK_COLOR, 710b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_B_CB, black_color->color_b_cb, 711b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_G_Y, black_color->color_g_y, 712b8fdfcc6SHarry Wentland CRTC_BLACK_COLOR_R_CR, black_color->color_r_cr); 713b8fdfcc6SHarry Wentland 714b8fdfcc6SHarry Wentland value = dm_read_reg_soc15( 715b8fdfcc6SHarry Wentland tg->ctx, 716b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLACK_COLOR, 717b8fdfcc6SHarry Wentland tg110->offsets.crtc); 718b8fdfcc6SHarry Wentland dm_write_reg_soc15( 719b8fdfcc6SHarry Wentland tg->ctx, 720b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLANK_DATA_COLOR, 721b8fdfcc6SHarry Wentland tg110->offsets.crtc, 722b8fdfcc6SHarry Wentland value); 723b8fdfcc6SHarry Wentland } 724b8fdfcc6SHarry Wentland 725b8fdfcc6SHarry Wentland void dce120_tg_set_overscan_color(struct timing_generator *tg, 726b8fdfcc6SHarry Wentland const struct tg_color *overscan_color) 727b8fdfcc6SHarry Wentland { 728b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 729b8fdfcc6SHarry Wentland 730b8fdfcc6SHarry Wentland CRTC_REG_SET_3( 731b8fdfcc6SHarry Wentland CRTC0_CRTC_OVERSCAN_COLOR, 732b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_BLUE, overscan_color->color_b_cb, 733b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_GREEN, overscan_color->color_g_y, 734b8fdfcc6SHarry Wentland CRTC_OVERSCAN_COLOR_RED, overscan_color->color_r_cr); 735b8fdfcc6SHarry Wentland } 736b8fdfcc6SHarry Wentland 737b8fdfcc6SHarry Wentland void dce120_tg_program_timing(struct timing_generator *tg, 738b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing, 739b8fdfcc6SHarry Wentland bool use_vbios) 740b8fdfcc6SHarry Wentland { 741b8fdfcc6SHarry Wentland if (use_vbios) 742b8fdfcc6SHarry Wentland dce110_timing_generator_program_timing_generator(tg, timing); 743b8fdfcc6SHarry Wentland else 744b8fdfcc6SHarry Wentland dce120_timing_generator_program_blanking(tg, timing); 745b8fdfcc6SHarry Wentland } 746b8fdfcc6SHarry Wentland 747b8fdfcc6SHarry Wentland bool dce120_tg_is_blanked(struct timing_generator *tg) 748b8fdfcc6SHarry Wentland { 749b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 750b8fdfcc6SHarry Wentland uint32_t value = dm_read_reg_soc15( 751b8fdfcc6SHarry Wentland tg->ctx, 752b8fdfcc6SHarry Wentland mmCRTC0_CRTC_BLANK_CONTROL, 753b8fdfcc6SHarry Wentland tg110->offsets.crtc); 754b8fdfcc6SHarry Wentland 7557b7d6865STom St Denis if (get_reg_field_value( 756b8fdfcc6SHarry Wentland value, 757b8fdfcc6SHarry Wentland CRTC0_CRTC_BLANK_CONTROL, 758b8fdfcc6SHarry Wentland CRTC_BLANK_DATA_EN) == 1 && 759b8fdfcc6SHarry Wentland get_reg_field_value( 760b8fdfcc6SHarry Wentland value, 761b8fdfcc6SHarry Wentland CRTC0_CRTC_BLANK_CONTROL, 762b8fdfcc6SHarry Wentland CRTC_CURRENT_BLANK_STATE) == 1) 763b8fdfcc6SHarry Wentland return true; 764b8fdfcc6SHarry Wentland 765b8fdfcc6SHarry Wentland return false; 766b8fdfcc6SHarry Wentland } 767b8fdfcc6SHarry Wentland 768b8fdfcc6SHarry Wentland void dce120_tg_set_blank(struct timing_generator *tg, 769b8fdfcc6SHarry Wentland bool enable_blanking) 770b8fdfcc6SHarry Wentland { 771b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 772b8fdfcc6SHarry Wentland 773b8fdfcc6SHarry Wentland CRTC_REG_SET( 774b8fdfcc6SHarry Wentland CRTC0_CRTC_DOUBLE_BUFFER_CONTROL, 775*7cb52855SJerry (Fangzhi) Zuo CRTC_BLANK_DATA_DOUBLE_BUFFER_EN, 1); 776b8fdfcc6SHarry Wentland 777cedaf307STom St Denis if (enable_blanking) 778cedaf307STom St Denis CRTC_REG_SET(CRTC0_CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1); 779cedaf307STom St Denis else 780cedaf307STom St Denis dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_BLANK_CONTROL, 781cedaf307STom St Denis tg110->offsets.crtc, 0); 782b8fdfcc6SHarry Wentland } 783b8fdfcc6SHarry Wentland 784b8fdfcc6SHarry Wentland bool dce120_tg_validate_timing(struct timing_generator *tg, 785b8fdfcc6SHarry Wentland const struct dc_crtc_timing *timing); 786b8fdfcc6SHarry Wentland 787b8fdfcc6SHarry Wentland void dce120_tg_wait_for_state(struct timing_generator *tg, 788b8fdfcc6SHarry Wentland enum crtc_state state) 789b8fdfcc6SHarry Wentland { 790b8fdfcc6SHarry Wentland switch (state) { 791b8fdfcc6SHarry Wentland case CRTC_STATE_VBLANK: 792b8fdfcc6SHarry Wentland dce120_timing_generator_wait_for_vblank(tg); 793b8fdfcc6SHarry Wentland break; 794b8fdfcc6SHarry Wentland 795b8fdfcc6SHarry Wentland case CRTC_STATE_VACTIVE: 796b8fdfcc6SHarry Wentland dce120_timing_generator_wait_for_vactive(tg); 797b8fdfcc6SHarry Wentland break; 798b8fdfcc6SHarry Wentland 799b8fdfcc6SHarry Wentland default: 800b8fdfcc6SHarry Wentland break; 801b8fdfcc6SHarry Wentland } 802b8fdfcc6SHarry Wentland } 803b8fdfcc6SHarry Wentland 804b8fdfcc6SHarry Wentland void dce120_tg_set_colors(struct timing_generator *tg, 805b8fdfcc6SHarry Wentland const struct tg_color *blank_color, 806b8fdfcc6SHarry Wentland const struct tg_color *overscan_color) 807b8fdfcc6SHarry Wentland { 808b8fdfcc6SHarry Wentland if (blank_color != NULL) 809b8fdfcc6SHarry Wentland dce120_tg_program_blank_color(tg, blank_color); 810b8fdfcc6SHarry Wentland 811b8fdfcc6SHarry Wentland if (overscan_color != NULL) 812b8fdfcc6SHarry Wentland dce120_tg_set_overscan_color(tg, overscan_color); 813b8fdfcc6SHarry Wentland } 814b8fdfcc6SHarry Wentland 815b8fdfcc6SHarry Wentland static void dce120_timing_generator_set_static_screen_control( 816b8fdfcc6SHarry Wentland struct timing_generator *tg, 817b8fdfcc6SHarry Wentland uint32_t value) 818b8fdfcc6SHarry Wentland { 819b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 820b8fdfcc6SHarry Wentland 821b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2(CRTC0_CRTC_STATIC_SCREEN_CONTROL, 822b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_EVENT_MASK, value, 823b8fdfcc6SHarry Wentland CRTC_STATIC_SCREEN_FRAME_COUNT, 2); 824b8fdfcc6SHarry Wentland } 825b8fdfcc6SHarry Wentland 826b8fdfcc6SHarry Wentland void dce120_timing_generator_set_test_pattern( 827b8fdfcc6SHarry Wentland struct timing_generator *tg, 828b8fdfcc6SHarry Wentland /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode' 829b8fdfcc6SHarry Wentland * because this is not DP-specific (which is probably somewhere in DP 830b8fdfcc6SHarry Wentland * encoder) */ 831b8fdfcc6SHarry Wentland enum controller_dp_test_pattern test_pattern, 832b8fdfcc6SHarry Wentland enum dc_color_depth color_depth) 833b8fdfcc6SHarry Wentland { 834b8fdfcc6SHarry Wentland struct dc_context *ctx = tg->ctx; 835b8fdfcc6SHarry Wentland uint32_t value; 836b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 837b8fdfcc6SHarry Wentland enum test_pattern_color_format bit_depth; 838b8fdfcc6SHarry Wentland enum test_pattern_dyn_range dyn_range; 839b8fdfcc6SHarry Wentland enum test_pattern_mode mode; 840b8fdfcc6SHarry Wentland /* color ramp generator mixes 16-bits color */ 841b8fdfcc6SHarry Wentland uint32_t src_bpc = 16; 842b8fdfcc6SHarry Wentland /* requested bpc */ 843b8fdfcc6SHarry Wentland uint32_t dst_bpc; 844b8fdfcc6SHarry Wentland uint32_t index; 845b8fdfcc6SHarry Wentland /* RGB values of the color bars. 846b8fdfcc6SHarry Wentland * Produce two RGB colors: RGB0 - white (all Fs) 847b8fdfcc6SHarry Wentland * and RGB1 - black (all 0s) 848b8fdfcc6SHarry Wentland * (three RGB components for two colors) 849b8fdfcc6SHarry Wentland */ 850b8fdfcc6SHarry Wentland uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 851b8fdfcc6SHarry Wentland 0x0000, 0x0000}; 852b8fdfcc6SHarry Wentland /* dest color (converted to the specified color format) */ 853b8fdfcc6SHarry Wentland uint16_t dst_color[6]; 854b8fdfcc6SHarry Wentland uint32_t inc_base; 855b8fdfcc6SHarry Wentland 856b8fdfcc6SHarry Wentland /* translate to bit depth */ 857b8fdfcc6SHarry Wentland switch (color_depth) { 858b8fdfcc6SHarry Wentland case COLOR_DEPTH_666: 859b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; 860b8fdfcc6SHarry Wentland break; 861b8fdfcc6SHarry Wentland case COLOR_DEPTH_888: 862b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 863b8fdfcc6SHarry Wentland break; 864b8fdfcc6SHarry Wentland case COLOR_DEPTH_101010: 865b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; 866b8fdfcc6SHarry Wentland break; 867b8fdfcc6SHarry Wentland case COLOR_DEPTH_121212: 868b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; 869b8fdfcc6SHarry Wentland break; 870b8fdfcc6SHarry Wentland default: 871b8fdfcc6SHarry Wentland bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 872b8fdfcc6SHarry Wentland break; 873b8fdfcc6SHarry Wentland } 874b8fdfcc6SHarry Wentland 875b8fdfcc6SHarry Wentland switch (test_pattern) { 876b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: 877b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: 878b8fdfcc6SHarry Wentland { 879b8fdfcc6SHarry Wentland dyn_range = (test_pattern == 880b8fdfcc6SHarry Wentland CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? 881b8fdfcc6SHarry Wentland TEST_PATTERN_DYN_RANGE_CEA : 882b8fdfcc6SHarry Wentland TEST_PATTERN_DYN_RANGE_VESA); 883b8fdfcc6SHarry Wentland mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; 884b8fdfcc6SHarry Wentland 885b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_2(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 886b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 6, 887b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 6); 888b8fdfcc6SHarry Wentland 889b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL, 890b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_EN, 1, 891b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MODE, mode, 892b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DYNAMIC_RANGE, dyn_range, 893b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth); 894b8fdfcc6SHarry Wentland } 895b8fdfcc6SHarry Wentland break; 896b8fdfcc6SHarry Wentland 897b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: 898b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: 899b8fdfcc6SHarry Wentland { 900b8fdfcc6SHarry Wentland mode = (test_pattern == 901b8fdfcc6SHarry Wentland CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? 902b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_VERTICALBARS : 903b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_HORIZONTALBARS); 904b8fdfcc6SHarry Wentland 905b8fdfcc6SHarry Wentland switch (bit_depth) { 906b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_6: 907b8fdfcc6SHarry Wentland dst_bpc = 6; 908b8fdfcc6SHarry Wentland break; 909b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_8: 910b8fdfcc6SHarry Wentland dst_bpc = 8; 911b8fdfcc6SHarry Wentland break; 912b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_10: 913b8fdfcc6SHarry Wentland dst_bpc = 10; 914b8fdfcc6SHarry Wentland break; 915b8fdfcc6SHarry Wentland default: 916b8fdfcc6SHarry Wentland dst_bpc = 8; 917b8fdfcc6SHarry Wentland break; 918b8fdfcc6SHarry Wentland } 919b8fdfcc6SHarry Wentland 920b8fdfcc6SHarry Wentland /* adjust color to the required colorFormat */ 921b8fdfcc6SHarry Wentland for (index = 0; index < 6; index++) { 922b8fdfcc6SHarry Wentland /* dst = 2^dstBpc * src / 2^srcBpc = src >> 923b8fdfcc6SHarry Wentland * (srcBpc - dstBpc); 924b8fdfcc6SHarry Wentland */ 925b8fdfcc6SHarry Wentland dst_color[index] = 926b8fdfcc6SHarry Wentland src_color[index] >> (src_bpc - dst_bpc); 927b8fdfcc6SHarry Wentland /* CRTC_TEST_PATTERN_DATA has 16 bits, 928b8fdfcc6SHarry Wentland * lowest 6 are hardwired to ZERO 929b8fdfcc6SHarry Wentland * color bits should be left aligned aligned to MSB 930b8fdfcc6SHarry Wentland * XXXXXXXXXX000000 for 10 bit, 931b8fdfcc6SHarry Wentland * XXXXXXXX00000000 for 8 bit and XXXXXX0000000000 for 6 932b8fdfcc6SHarry Wentland */ 933b8fdfcc6SHarry Wentland dst_color[index] <<= (16 - dst_bpc); 934b8fdfcc6SHarry Wentland } 935b8fdfcc6SHarry Wentland 936b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, 0); 937b8fdfcc6SHarry Wentland 938b8fdfcc6SHarry Wentland /* We have to write the mask before data, similar to pipeline. 939b8fdfcc6SHarry Wentland * For example, for 8 bpc, if we want RGB0 to be magenta, 940b8fdfcc6SHarry Wentland * and RGB1 to be cyan, 941b8fdfcc6SHarry Wentland * we need to make 7 writes: 942b8fdfcc6SHarry Wentland * MASK DATA 943b8fdfcc6SHarry Wentland * 000001 00000000 00000000 set mask to R0 944b8fdfcc6SHarry Wentland * 000010 11111111 00000000 R0 255, 0xFF00, set mask to G0 945b8fdfcc6SHarry Wentland * 000100 00000000 00000000 G0 0, 0x0000, set mask to B0 946b8fdfcc6SHarry Wentland * 001000 11111111 00000000 B0 255, 0xFF00, set mask to R1 947b8fdfcc6SHarry Wentland * 010000 00000000 00000000 R1 0, 0x0000, set mask to G1 948b8fdfcc6SHarry Wentland * 100000 11111111 00000000 G1 255, 0xFF00, set mask to B1 949b8fdfcc6SHarry Wentland * 100000 11111111 00000000 B1 255, 0xFF00 950b8fdfcc6SHarry Wentland * 951b8fdfcc6SHarry Wentland * we will make a loop of 6 in which we prepare the mask, 952b8fdfcc6SHarry Wentland * then write, then prepare the color for next write. 953b8fdfcc6SHarry Wentland * first iteration will write mask only, 954b8fdfcc6SHarry Wentland * but each next iteration color prepared in 955b8fdfcc6SHarry Wentland * previous iteration will be written within new mask, 956b8fdfcc6SHarry Wentland * the last component will written separately, 957b8fdfcc6SHarry Wentland * mask is not changing between 6th and 7th write 958b8fdfcc6SHarry Wentland * and color will be prepared by last iteration 959b8fdfcc6SHarry Wentland */ 960b8fdfcc6SHarry Wentland 961b8fdfcc6SHarry Wentland /* write color, color values mask in CRTC_TEST_PATTERN_MASK 962b8fdfcc6SHarry Wentland * is B1, G1, R1, B0, G0, R0 963b8fdfcc6SHarry Wentland */ 964b8fdfcc6SHarry Wentland value = 0; 965b8fdfcc6SHarry Wentland for (index = 0; index < 6; index++) { 966b8fdfcc6SHarry Wentland /* prepare color mask, first write PATTERN_DATA 967b8fdfcc6SHarry Wentland * will have all zeros 968b8fdfcc6SHarry Wentland */ 969b8fdfcc6SHarry Wentland set_reg_field_value( 970b8fdfcc6SHarry Wentland value, 971b8fdfcc6SHarry Wentland (1 << index), 972b8fdfcc6SHarry Wentland CRTC0_CRTC_TEST_PATTERN_COLOR, 973b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MASK); 974b8fdfcc6SHarry Wentland /* write color component */ 975b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value); 976b8fdfcc6SHarry Wentland /* prepare next color component, 977b8fdfcc6SHarry Wentland * will be written in the next iteration 978b8fdfcc6SHarry Wentland */ 979b8fdfcc6SHarry Wentland set_reg_field_value( 980b8fdfcc6SHarry Wentland value, 981b8fdfcc6SHarry Wentland dst_color[index], 982b8fdfcc6SHarry Wentland CRTC0_CRTC_TEST_PATTERN_COLOR, 983b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DATA); 984b8fdfcc6SHarry Wentland } 985b8fdfcc6SHarry Wentland /* write last color component, 986b8fdfcc6SHarry Wentland * it's been already prepared in the loop 987b8fdfcc6SHarry Wentland */ 988b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value); 989b8fdfcc6SHarry Wentland 990b8fdfcc6SHarry Wentland /* enable test pattern */ 991b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL, 992b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_EN, 1, 993b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MODE, mode, 994b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0, 995b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth); 996b8fdfcc6SHarry Wentland } 997b8fdfcc6SHarry Wentland break; 998b8fdfcc6SHarry Wentland 999b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: 1000b8fdfcc6SHarry Wentland { 1001b8fdfcc6SHarry Wentland mode = (bit_depth == 1002b8fdfcc6SHarry Wentland TEST_PATTERN_COLOR_FORMAT_BPC_10 ? 1003b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_DUALRAMP_RGB : 1004b8fdfcc6SHarry Wentland TEST_PATTERN_MODE_SINGLERAMP_RGB); 1005b8fdfcc6SHarry Wentland 1006b8fdfcc6SHarry Wentland switch (bit_depth) { 1007b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_6: 1008b8fdfcc6SHarry Wentland dst_bpc = 6; 1009b8fdfcc6SHarry Wentland break; 1010b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_8: 1011b8fdfcc6SHarry Wentland dst_bpc = 8; 1012b8fdfcc6SHarry Wentland break; 1013b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1014b8fdfcc6SHarry Wentland dst_bpc = 10; 1015b8fdfcc6SHarry Wentland break; 1016b8fdfcc6SHarry Wentland default: 1017b8fdfcc6SHarry Wentland dst_bpc = 8; 1018b8fdfcc6SHarry Wentland break; 1019b8fdfcc6SHarry Wentland } 1020b8fdfcc6SHarry Wentland 1021b8fdfcc6SHarry Wentland /* increment for the first ramp for one color gradation 1022b8fdfcc6SHarry Wentland * 1 gradation for 6-bit color is 2^10 1023b8fdfcc6SHarry Wentland * gradations in 16-bit color 1024b8fdfcc6SHarry Wentland */ 1025b8fdfcc6SHarry Wentland inc_base = (src_bpc - dst_bpc); 1026b8fdfcc6SHarry Wentland 1027b8fdfcc6SHarry Wentland switch (bit_depth) { 1028b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_6: 1029b8fdfcc6SHarry Wentland { 1030b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 1031b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC0, inc_base, 1032b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC1, 0, 1033b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 6, 1034b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 6, 1035b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_RAMP0_OFFSET, 0); 1036b8fdfcc6SHarry Wentland } 1037b8fdfcc6SHarry Wentland break; 1038b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_8: 1039b8fdfcc6SHarry Wentland { 1040b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 1041b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC0, inc_base, 1042b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC1, 0, 1043b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 8, 1044b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 6, 1045b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_RAMP0_OFFSET, 0); 1046b8fdfcc6SHarry Wentland } 1047b8fdfcc6SHarry Wentland break; 1048b8fdfcc6SHarry Wentland case TEST_PATTERN_COLOR_FORMAT_BPC_10: 1049b8fdfcc6SHarry Wentland { 1050b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_5(CRTC0_CRTC_TEST_PATTERN_PARAMETERS, 1051b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC0, inc_base, 1052b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_INC1, inc_base + 2, 1053b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_HRES, 8, 1054b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_VRES, 5, 1055b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_RAMP0_OFFSET, 384 << 6); 1056b8fdfcc6SHarry Wentland } 1057b8fdfcc6SHarry Wentland break; 1058b8fdfcc6SHarry Wentland default: 1059b8fdfcc6SHarry Wentland break; 1060b8fdfcc6SHarry Wentland } 1061b8fdfcc6SHarry Wentland 1062b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, 0); 1063b8fdfcc6SHarry Wentland 1064b8fdfcc6SHarry Wentland /* enable test pattern */ 1065b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, 0); 1066b8fdfcc6SHarry Wentland 1067b8fdfcc6SHarry Wentland CRTC_REG_UPDATE_4(CRTC0_CRTC_TEST_PATTERN_CONTROL, 1068b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_EN, 1, 1069b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_MODE, mode, 1070b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_DYNAMIC_RANGE, 0, 1071b8fdfcc6SHarry Wentland CRTC_TEST_PATTERN_COLOR_FORMAT, bit_depth); 1072b8fdfcc6SHarry Wentland } 1073b8fdfcc6SHarry Wentland break; 1074b8fdfcc6SHarry Wentland case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: 1075b8fdfcc6SHarry Wentland { 1076b8fdfcc6SHarry Wentland value = 0; 1077b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_CONTROL, tg110->offsets.crtc, value); 1078b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_COLOR, tg110->offsets.crtc, value); 1079b8fdfcc6SHarry Wentland dm_write_reg_soc15(ctx, mmCRTC0_CRTC_TEST_PATTERN_PARAMETERS, tg110->offsets.crtc, value); 1080b8fdfcc6SHarry Wentland } 1081b8fdfcc6SHarry Wentland break; 1082b8fdfcc6SHarry Wentland default: 1083b8fdfcc6SHarry Wentland break; 1084b8fdfcc6SHarry Wentland } 1085b8fdfcc6SHarry Wentland } 1086b8fdfcc6SHarry Wentland 1087667e1498SAndrey Grodzovsky static bool dce120_arm_vert_intr( 1088667e1498SAndrey Grodzovsky struct timing_generator *tg, 1089667e1498SAndrey Grodzovsky uint8_t width) 1090667e1498SAndrey Grodzovsky { 1091667e1498SAndrey Grodzovsky struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); 109281c50963SSylvia Tsai uint32_t v_blank_start, v_blank_end, h_position, v_position; 1093667e1498SAndrey Grodzovsky 1094667e1498SAndrey Grodzovsky tg->funcs->get_scanoutpos( 1095667e1498SAndrey Grodzovsky tg, 109681c50963SSylvia Tsai &v_blank_start, 109781c50963SSylvia Tsai &v_blank_end, 109881c50963SSylvia Tsai &h_position, 109981c50963SSylvia Tsai &v_position); 1100667e1498SAndrey Grodzovsky 110181c50963SSylvia Tsai if (v_blank_start == 0 || v_blank_end == 0) 1102667e1498SAndrey Grodzovsky return false; 1103667e1498SAndrey Grodzovsky 1104667e1498SAndrey Grodzovsky CRTC_REG_SET_2( 1105667e1498SAndrey Grodzovsky CRTC0_CRTC_VERTICAL_INTERRUPT0_POSITION, 110681c50963SSylvia Tsai CRTC_VERTICAL_INTERRUPT0_LINE_START, v_blank_start, 110781c50963SSylvia Tsai CRTC_VERTICAL_INTERRUPT0_LINE_END, v_blank_start + width); 1108667e1498SAndrey Grodzovsky 1109667e1498SAndrey Grodzovsky return true; 1110667e1498SAndrey Grodzovsky } 1111667e1498SAndrey Grodzovsky 1112395f669eSDave Airlie static const struct timing_generator_funcs dce120_tg_funcs = { 1113b8fdfcc6SHarry Wentland .validate_timing = dce120_tg_validate_timing, 1114b8fdfcc6SHarry Wentland .program_timing = dce120_tg_program_timing, 1115b8fdfcc6SHarry Wentland .enable_crtc = dce120_timing_generator_enable_crtc, 1116b8fdfcc6SHarry Wentland .disable_crtc = dce110_timing_generator_disable_crtc, 1117b8fdfcc6SHarry Wentland /* used by enable_timing_synchronization. Not need for FPGA */ 1118b8fdfcc6SHarry Wentland .is_counter_moving = dce110_timing_generator_is_counter_moving, 1119b8fdfcc6SHarry Wentland /* never be called */ 112072ada5f7SEric Cook .get_position = dce120_timing_generator_get_crtc_position, 1121b8fdfcc6SHarry Wentland .get_frame_count = dce120_timing_generator_get_vblank_counter, 1122b8fdfcc6SHarry Wentland .get_scanoutpos = dce120_timing_generator_get_crtc_scanoutpos, 1123b8fdfcc6SHarry Wentland .set_early_control = dce120_timing_generator_set_early_control, 1124b8fdfcc6SHarry Wentland /* used by enable_timing_synchronization. Not need for FPGA */ 1125b8fdfcc6SHarry Wentland .wait_for_state = dce120_tg_wait_for_state, 1126b8fdfcc6SHarry Wentland .set_blank = dce120_tg_set_blank, 1127b8fdfcc6SHarry Wentland .is_blanked = dce120_tg_is_blanked, 1128b8fdfcc6SHarry Wentland /* never be called */ 1129b8fdfcc6SHarry Wentland .set_colors = dce120_tg_set_colors, 1130b8fdfcc6SHarry Wentland .set_overscan_blank_color = dce120_timing_generator_set_overscan_color_black, 1131b8fdfcc6SHarry Wentland .set_blank_color = dce120_timing_generator_program_blank_color, 1132b8fdfcc6SHarry Wentland .disable_vga = dce120_timing_generator_disable_vga, 1133b8fdfcc6SHarry Wentland .did_triggered_reset_occur = dce120_timing_generator_did_triggered_reset_occur, 1134b8fdfcc6SHarry Wentland .setup_global_swap_lock = dce120_timing_generator_setup_global_swap_lock, 1135b8fdfcc6SHarry Wentland .enable_reset_trigger = dce120_timing_generator_enable_reset_trigger, 1136b8fdfcc6SHarry Wentland .disable_reset_trigger = dce120_timing_generator_disable_reset_trigger, 1137b8fdfcc6SHarry Wentland .tear_down_global_swap_lock = dce120_timing_generator_tear_down_global_swap_lock, 1138b8fdfcc6SHarry Wentland .enable_advanced_request = dce120_timing_generator_enable_advanced_request, 1139b8fdfcc6SHarry Wentland .set_drr = dce120_timing_generator_set_drr, 1140b8fdfcc6SHarry Wentland .set_static_screen_control = dce120_timing_generator_set_static_screen_control, 1141667e1498SAndrey Grodzovsky .set_test_pattern = dce120_timing_generator_set_test_pattern, 1142667e1498SAndrey Grodzovsky .arm_vert_intr = dce120_arm_vert_intr, 1143b8fdfcc6SHarry Wentland }; 1144b8fdfcc6SHarry Wentland 1145b8fdfcc6SHarry Wentland 1146c13b408bSDave Airlie void dce120_timing_generator_construct( 1147b8fdfcc6SHarry Wentland struct dce110_timing_generator *tg110, 1148b8fdfcc6SHarry Wentland struct dc_context *ctx, 1149b8fdfcc6SHarry Wentland uint32_t instance, 1150b8fdfcc6SHarry Wentland const struct dce110_timing_generator_offsets *offsets) 1151b8fdfcc6SHarry Wentland { 1152b8fdfcc6SHarry Wentland tg110->controller_id = CONTROLLER_ID_D0 + instance; 1153b8fdfcc6SHarry Wentland tg110->base.inst = instance; 1154b8fdfcc6SHarry Wentland 1155b8fdfcc6SHarry Wentland tg110->offsets = *offsets; 1156b8fdfcc6SHarry Wentland 1157b8fdfcc6SHarry Wentland tg110->base.funcs = &dce120_tg_funcs; 1158b8fdfcc6SHarry Wentland 1159b8fdfcc6SHarry Wentland tg110->base.ctx = ctx; 1160b8fdfcc6SHarry Wentland tg110->base.bp = ctx->dc_bios; 1161b8fdfcc6SHarry Wentland 1162b8fdfcc6SHarry Wentland tg110->max_h_total = CRTC0_CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1; 1163b8fdfcc6SHarry Wentland tg110->max_v_total = CRTC0_CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1; 1164b8fdfcc6SHarry Wentland 1165b8fdfcc6SHarry Wentland /*//CRTC requires a minimum HBLANK = 32 pixels and o 1166b8fdfcc6SHarry Wentland * Minimum HSYNC = 8 pixels*/ 1167b8fdfcc6SHarry Wentland tg110->min_h_blank = 32; 1168b8fdfcc6SHarry Wentland /*DCE12_CRTC_Block_ARch.doc*/ 1169b8fdfcc6SHarry Wentland tg110->min_h_front_porch = 0; 1170b8fdfcc6SHarry Wentland tg110->min_h_back_porch = 0; 1171b8fdfcc6SHarry Wentland 1172b8fdfcc6SHarry Wentland tg110->min_h_sync_width = 8; 1173b8fdfcc6SHarry Wentland tg110->min_v_sync_width = 1; 1174b8fdfcc6SHarry Wentland tg110->min_v_blank = 3; 1175b8fdfcc6SHarry Wentland } 1176