diff options
author | Andrew Jiang <Andrew.Jiang@amd.com> | 2017-09-26 01:03:14 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-10-21 23:44:08 +0300 |
commit | 8740196935625dfb171ab115120315060e4a8a41 (patch) | |
tree | db1df033caec4cd63ea59e47940db192433feb38 /drivers/gpu/drm/amd/display/dc/dce | |
parent | b87d78d6aa104b207ff588d2cfd13633c2385994 (diff) | |
download | linux-8740196935625dfb171ab115120315060e4a8a41.tar.xz |
drm/amd/display: Move power control from link encoder to hwsequencer
A recent commit moved the backlight control code along with the register
defines, but did not move the power control code. This along with
remnant fields in the dce110_link_enc_registers struct made it so that
the code still compiled, but any attempts to access the
LVTMA_PWRSEQ_STATE register led to reading from an address of 0. This
patch corrects that.
Also, rename blacklight_control to edp_backlight_control (Typo fix).
Signed-off-by: Andrew Jiang <Andrew.Jiang@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 171 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h | 8 |
3 files changed, 15 insertions, 182 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index 227c9b655b65..0a058e0c3fec 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -391,23 +391,27 @@ struct dce_hwseq_registers { HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\ HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\ HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\ HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\ HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\ HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\ HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_) #define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\ @@ -416,7 +420,8 @@ struct dce_hwseq_registers { SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\ SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\ SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\ HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\ @@ -424,7 +429,8 @@ struct dce_hwseq_registers { HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\ HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\ HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ @@ -489,7 +495,8 @@ struct dce_hwseq_registers { HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \ - HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh) + HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \ + HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh) #define HWSEQ_REG_FIELD_LIST(type) \ type DCFE_CLOCK_ENABLE; \ @@ -520,7 +527,8 @@ struct dce_hwseq_registers { type LOGICAL_ADDR; \ type ENABLE_L1_TLB;\ type SYSTEM_ACCESS_MODE;\ - type LVTMA_BLON; + type LVTMA_BLON;\ + type LVTMA_PWRSEQ_TARGET_STATE_R; #define HWSEQ_DCN_REG_FIELD_LIST(type) \ type VUPDATE_NO_LOCK_EVENT_CLEAR; \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 1cb727bdaa56..0cf0fff74d44 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -82,13 +82,6 @@ #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 -/* all values are in milliseconds */ -/* For eDP, after power-up/power/down, - * 300/500 msec max. delay from LCDVCC to black video generation */ -#define PANEL_POWER_UP_TIMEOUT 300 -#define PANEL_POWER_DOWN_TIMEOUT 500 -#define HPD_CHECK_INTERVAL 10 - /* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */ #define TMDS_MIN_PIXEL_CLOCK 25000 /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */ @@ -122,7 +115,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { .psr_program_dp_dphy_fast_training = dce110_psr_program_dp_dphy_fast_training, .psr_program_secondary_packet = dce110_psr_program_secondary_packet, - .power_control = dce110_link_encoder_edp_power_control, .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, .enable_hpd = dce110_link_encoder_enable_hpd, .disable_hpd = dce110_link_encoder_disable_hpd, @@ -492,165 +484,6 @@ static void configure_encoder( REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1); } -static bool is_panel_powered_on(struct dce110_link_encoder *enc110) -{ - bool ret; - uint32_t value; - - REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value); - ret = value; - - return ret == 1; -} - - -/* TODO duplicate of dc_link.c version */ -static struct gpio *get_hpd_gpio(const struct link_encoder *enc) -{ - enum bp_result bp_result; - struct dc_bios *dcb = enc->ctx->dc_bios; - struct graphics_object_hpd_info hpd_info; - struct gpio_pin_info pin_info; - - if (dcb->funcs->get_hpd_info(dcb, enc->connector, &hpd_info) != BP_RESULT_OK) - return NULL; - - bp_result = dcb->funcs->get_gpio_pin_info(dcb, - hpd_info.hpd_int_gpio_uid, &pin_info); - - if (bp_result != BP_RESULT_OK) { - ASSERT(bp_result == BP_RESULT_NORECORD); - return NULL; - } - - return dal_gpio_service_create_irq( - enc->ctx->gpio_service, - pin_info.offset, - pin_info.mask); -} - -/* - * @brief - * eDP only. - */ -static void link_encoder_edp_wait_for_hpd_ready( - struct dce110_link_encoder *enc110, - bool power_up) -{ - struct dc_context *ctx = enc110->base.ctx; - struct graphics_object_id connector = enc110->base.connector; - struct gpio *hpd; - bool edp_hpd_high = false; - uint32_t time_elapsed = 0; - uint32_t timeout = power_up ? - PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; - - if (dal_graphics_object_id_get_connector_id(connector) != - CONNECTOR_ID_EDP) { - BREAK_TO_DEBUGGER(); - return; - } - - if (!power_up) - /* from KV, we will not HPD low after turning off VCC - - * instead, we will check the SW timer in power_up(). */ - return; - - /* when we power on/off the eDP panel, - * we need to wait until SENSE bit is high/low */ - - /* obtain HPD */ - /* TODO what to do with this? */ - hpd = get_hpd_gpio(&enc110->base); - - if (!hpd) { - BREAK_TO_DEBUGGER(); - return; - } - - dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); - - /* wait until timeout or panel detected */ - - do { - uint32_t detected = 0; - - dal_gpio_get_value(hpd, &detected); - - if (!(detected ^ power_up)) { - edp_hpd_high = true; - break; - } - - msleep(HPD_CHECK_INTERVAL); - - time_elapsed += HPD_CHECK_INTERVAL; - } while (time_elapsed < timeout); - - dal_gpio_close(hpd); - - dal_gpio_destroy_irq(&hpd); - - if (false == edp_hpd_high) { - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: wait timed out!\n", __func__); - } -} - -/* - * @brief - * eDP only. Control the power of the eDP panel. - */ -void dce110_link_encoder_edp_power_control( - struct link_encoder *enc, - bool power_up) -{ - struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); - struct dc_context *ctx = enc110->base.ctx; - struct bp_transmitter_control cntl = { 0 }; - enum bp_result bp_result; - - if (dal_graphics_object_id_get_connector_id(enc110->base.connector) != - CONNECTOR_ID_EDP) { - BREAK_TO_DEBUGGER(); - return; - } - - if ((power_up && !is_panel_powered_on(enc110)) || - (!power_up && is_panel_powered_on(enc110))) { - - /* Send VBIOS command to prompt eDP panel power */ - - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: Panel Power action: %s\n", - __func__, (power_up ? "On":"Off")); - - cntl.action = power_up ? - TRANSMITTER_CONTROL_POWER_ON : - TRANSMITTER_CONTROL_POWER_OFF; - cntl.transmitter = enc110->base.transmitter; - cntl.connector_obj_id = enc110->base.connector; - cntl.coherent = false; - cntl.lanes_number = LANE_COUNT_FOUR; - cntl.hpd_sel = enc110->base.hpd_source; - - bp_result = link_transmitter_control(enc110, &cntl); - - if (BP_RESULT_OK != bp_result) { - - dm_logger_write(ctx->logger, LOG_ERROR, - "%s: Panel Power bp_result: %d\n", - __func__, bp_result); - } - } else { - dm_logger_write(ctx->logger, LOG_HW_RESUME_S3, - "%s: Skipping Panel Power action: %s\n", - __func__, (power_up ? "On":"Off")); - } - - link_encoder_edp_wait_for_hpd_ready(enc110, true); -} - static void aux_initialize( struct dce110_link_encoder *enc110) { @@ -1018,7 +851,7 @@ void dce110_link_encoder_hw_init( ASSERT(result == BP_RESULT_OK); } else if (enc110->base.connector.id == CONNECTOR_ID_EDP) { - enc->funcs->power_control(&enc110->base, true); + ctx->dc->hwss.edp_power_control(enc, true); } aux_initialize(enc110); @@ -1218,7 +1051,7 @@ void dce110_link_encoder_disable_output( return; } if (enc110->base.connector.id == CONNECTOR_ID_EDP) - ctx->dc->hwss.backlight_control(link, false); + ctx->dc->hwss.edp_backlight_control(link, false); /* Power-down RX and disable GPU PHY should be paired. * Disabling PHY without powering down RX may cause * symbol lock loss, on which we will get DP Sink interrupt. */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index c65def5f6a44..494067dedd03 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -114,10 +114,6 @@ struct dce110_link_enc_hpd_registers { }; struct dce110_link_enc_registers { - /* Backlight registers */ - uint32_t LVTMA_PWRSEQ_CNTL; - uint32_t LVTMA_PWRSEQ_STATE; - /* DMCU registers */ uint32_t MASTER_COMM_DATA_REG1; uint32_t MASTER_COMM_DATA_REG2; @@ -250,10 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table( struct link_encoder *enc, const struct link_mst_stream_allocation_table *table); -void dce110_link_encoder_edp_power_control( - struct link_encoder *enc, - bool power_up); - void dce110_link_encoder_connect_dig_be_to_fe( struct link_encoder *enc, enum engine_id engine, |