static void intel_mst_post_disable_dp(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; struct intel_connector *connector = to_intel_connector(old_conn_state->connector); /* this can fail */ drm_dp_check_act_status(&intel_dp->mst_mgr); /* and this can also fail */ drm_dp_update_payload_part2(&intel_dp->mst_mgr); drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port); /* * Power down mst path before disabling the port, otherwise we end * up getting interrupts from the sink upon detecting link loss. */ drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, false); intel_dp->active_mst_links--; intel_mst->connector = NULL; if (intel_dp->active_mst_links == 0) { intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_dig_port->base.post_disable(&intel_dig_port->base, old_crtc_state, NULL); } DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); }
static void intel_mst_post_disable_dp(struct intel_encoder *encoder, struct intel_crtc_state *old_crtc_state, struct drm_connector_state *old_conn_state) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; struct intel_connector *connector = to_intel_connector(old_conn_state->connector); DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); /* this can fail */ drm_dp_check_act_status(&intel_dp->mst_mgr); /* and this can also fail */ drm_dp_update_payload_part2(&intel_dp->mst_mgr); drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port); intel_dp->active_mst_links--; intel_mst->connector = NULL; if (intel_dp->active_mst_links == 0) { intel_dig_port->base.post_disable(&intel_dig_port->base, NULL, NULL); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); } }
static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = intel_dig_port->port; struct intel_connector *connector = to_intel_connector(conn_state->connector); int ret; uint32_t temp; int slots; /* MST encoders are bound to a crtc, not to a connector, * force the mapping here for get_hw_state. */ connector->encoder = encoder; intel_mst->connector = connector; DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); if (intel_dp->active_mst_links == 0) { intel_ddi_clk_select(&intel_dig_port->base, pipe_config); intel_prepare_dp_ddi_buffers(&intel_dig_port->base); intel_dp_set_link_params(intel_dp, pipe_config); intel_ddi_init_dp_buf_reg(&intel_dig_port->base); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); intel_dp_stop_link_train(intel_dp); } ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr, connector->port, pipe_config->pbn, &slots); if (ret == false) { DRM_ERROR("failed to allocate vcpi\n"); return; } intel_dp->active_mst_links++; temp = I915_READ(DP_TP_STATUS(port)); I915_WRITE(DP_TP_STATUS(port), temp); ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr); }
static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = intel_dig_port->base.port; struct intel_connector *connector = to_intel_connector(conn_state->connector); int ret; uint32_t temp; /* MST encoders are bound to a crtc, not to a connector, * force the mapping here for get_hw_state. */ connector->encoder = encoder; intel_mst->connector = connector; DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); if (intel_dp->active_mst_links == 0) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true); if (intel_dp->active_mst_links == 0) intel_dig_port->base.pre_enable(&intel_dig_port->base, pipe_config, NULL); ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr, connector->port, pipe_config->pbn, pipe_config->dp_m_n.tu); if (ret == false) { DRM_ERROR("failed to allocate vcpi\n"); return; } intel_dp->active_mst_links++; temp = I915_READ(DP_TP_STATUS(port)); I915_WRITE(DP_TP_STATUS(port), temp); ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr); }
void runio(struct intel_dp *dp) { u8 read_val; intel_dp_wait_panel_power_control(0xabcd0008); /* vbios spins at this point. Some haswell weirdness? */ intel_dp_wait_panel_power_control(0xabcd0008); /* This should be a function like intel_panel_enable_backlight However, we are not sure how the value 0x3a9 comes up. It has to do something with PWM frequency */ gtt_write(BLC_PWM_CPU_CTL,0x03a903a9); gtt_write(BLC_PWM_PCH_CTL2,0x03a903a9); gtt_write(BLC_PWM_PCH_CTL1,BLM_PCH_PWM_ENABLE); gtt_write(DEIIR,0x00008000); intel_dp_wait_reg(DEIIR, 0x00000000); gtt_write(DSPSTRIDE(dp->plane),dp->stride); intel_dp_sink_dpms(dp, 0); intel_dp_get_max_downspread(dp, &read_val); intel_dp_set_m_n_regs(dp); intel_dp_set_resolution(dp); gtt_write(PIPESRC(dp->pipe),dp->pipesrc); gtt_write(PIPECONF(dp->transcoder),0x00000000); gtt_write(PCH_TRANSCONF(dp->pipe),0x00000000); mainboard_set_port_clk_dp(dp); gtt_write(DSPSTRIDE(dp->plane),dp->stride); gtt_write(DSPCNTR(dp->plane),DISPLAY_PLANE_ENABLE|DISPPLANE_BGRX888); gtt_write(DEIIR,0x00000080); gtt_write(TRANS_DDI_FUNC_CTL_EDP,dp->flags); gtt_write(PIPECONF(dp->transcoder),PIPECONF_ENABLE|PIPECONF_DITHER_EN); intel_dp_wait_panel_power_control(0xabcd000a); /* what is this doing? Not sure yet. */ intel_dp_i2c_write(dp, 0x0); intel_dp_i2c_read(dp, &read_val); intel_dp_i2c_write(dp, 0x04); intel_dp_i2c_read(dp, &read_val); intel_dp_i2c_write(dp, 0x7e); intel_dp_i2c_read(dp, &read_val); /* this needs to be a call to a function */ gtt_write(DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SCRAMBLING_DISABLE_IRONLAKE | DP_SYNC_VS_HIGH |0x00000091); gtt_write(DP_TP_CTL(dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE); gtt_write(DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_SCRAMBLING_DISABLE_IRONLAKE | DP_SYNC_VS_HIGH |0x80040091); /* we may need to move these *after* power well power up and *before* PCH_PP_CONTROL in gma.c */ gtt_write(PCH_PP_ON_DELAYS, PANEL_PORT_SELECT_LVDS |(/* PANEL_POWER_UP_DELAY_MASK */0x1<<16)|(/* PANEL_LIGHT_ON_DELAY_MASK */0xa<<0)|0x0001000a); gtt_write(PCH_PP_ON_DELAYS, PANEL_PORT_SELECT_LVDS |(/* PANEL_POWER_UP_DELAY_MASK */0x7d0<<16)|(/* PANEL_LIGHT_ON_DELAY_MASK */0xa<<0)|0x07d0000a); intel_dp_set_bw(dp); intel_dp_set_lane_count(dp); mainboard_train_link(dp); /* need a function: intel_ddi_set_tp or similar */ gtt_write(DP_TP_CTL(dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE | DP_TP_CTL_LINK_TRAIN_IDLE); gtt_write(DP_TP_CTL(dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE | DP_TP_CTL_LINK_TRAIN_NORMAL); gtt_write(BLC_PWM_CPU_CTL,0x03a903a9); gtt_write(BLC_PWM_PCH_CTL2,0x03a903a9); gtt_write(BLC_PWM_PCH_CTL1,0x80000000); /* some of this is not needed. */ gtt_write(DIGITAL_PORT_HOTPLUG_CNTRL, DIGITAL_PORTA_HOTPLUG_ENABLE ); gtt_write(SDEIIR,0x00000000); gtt_write(DEIIR,0x00000000); gtt_write(DEIIR,0x00008000); intel_dp_wait_reg(DEIIR, 0x00000000); gtt_write(DSPSTRIDE(dp->plane),dp->stride); gtt_write(PIPESRC(dp->pipe),dp->pipesrc); gtt_write(DEIIR,0x00000080); intel_dp_wait_reg(DEIIR, 0x00000000); gtt_write(DSPSTRIDE(dp->plane),dp->stride); gtt_write(DSPCNTR(dp->plane),DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888); gtt_write(PCH_PP_CONTROL,EDP_BLC_ENABLE | PANEL_POWER_RESET | PANEL_POWER_ON); gtt_write(SDEIIR,0x00000000); gtt_write(SDEIIR,0x00000000); gtt_write(DEIIR,0x00000000); }