static void intel_dsi_pre_enable(struct intel_encoder *encoder) { struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); DRM_DEBUG_KMS("\n"); if (intel_dsi->dev.dev_ops->panel_reset) intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev); /* put device in ready state */ intel_dsi_device_ready(encoder); if (intel_dsi->dev.dev_ops->send_otp_cmds) intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev); }
static void intel_dsi_pre_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum pipe pipe = intel_crtc->pipe; u32 tmp; DRM_DEBUG_KMS("\n"); /* Disable DPOunit clock gating, can stall pipe * and we need DPLL REFA always enabled */ tmp = I915_READ(DPLL(pipe)); tmp |= DPLL_REFA_CLK_ENABLE_VLV; I915_WRITE(DPLL(pipe), tmp); /* update the hw state for DPLL */ intel_crtc->config.dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV | DPLL_REFA_CLK_ENABLE_VLV; tmp = I915_READ(DSPCLK_GATE_D); tmp |= DPOUNIT_CLOCK_GATE_DISABLE; I915_WRITE(DSPCLK_GATE_D, tmp); /* put device in ready state */ intel_dsi_device_ready(encoder); msleep(intel_dsi->panel_on_delay); if (intel_dsi->dev.dev_ops->panel_reset) intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev); if (intel_dsi->dev.dev_ops->send_otp_cmds) intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev); wait_for_dsi_fifo_empty(intel_dsi); /* Enable port in pre-enable phase itself because as per hw team * recommendation, port should be enabled befor plane & pipe */ intel_dsi_enable(encoder); }
static void intel_dsi_mode_set(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); int pipe = intel_crtc->pipe; unsigned int bpp = intel_crtc->config.pipe_bpp; struct drm_display_mode *adjusted_mode = &intel_crtc->config.adjusted_mode; u32 val; intel_dsi_device_ready(intel_encoder); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0); dsi_config(encoder); I915_WRITE(MIPI_LP_RX_TIMEOUT(pipe), intel_dsi->lp_rx_timeout); I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), intel_dsi->turn_arnd_val); I915_WRITE(MIPI_DEVICE_RESET_TIMER(pipe), intel_dsi->rst_timer_val); /* in terms of low power clock */ I915_WRITE(MIPI_INIT_COUNT(pipe), intel_dsi->init_count); I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(pipe), \ intel_dsi->hs_to_lp_count); I915_WRITE(MIPI_LP_BYTECLK(pipe), intel_dsi->lp_byte_clk); I915_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe), ((u32)intel_dsi->clk_lp_to_hs_count << LP_HS_SSW_CNT_SHIFT) | (intel_dsi->clk_hs_to_lp_count << HS_LP_PWR_SW_CNT_SHIFT)); if (is_vid_mode(intel_dsi)) { I915_WRITE(MIPI_DPI_RESOLUTION(pipe), (adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT) | (adjusted_mode->hdisplay << HORIZONTAL_ADDRESS_SHIFT)); set_dsi_timings(encoder, adjusted_mode); if (intel_dsi->video_mode_type == DSI_VIDEO_BURST) { I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe), txbyteclkhs(adjusted_mode->htotal, bpp, intel_dsi->lane_count) + 1); } else { I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe), txbyteclkhs(adjusted_mode->vtotal * adjusted_mode->htotal, bpp, intel_dsi->lane_count) + 1); } } else { val = intel_dsi->channel << CMD_MODE_CHANNEL_NUMBER_SHIFT | intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT | intel_dsi->data_width; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), val); I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe), txbyteclkhs(adjusted_mode->hdisplay * adjusted_mode->vdisplay, bpp, intel_dsi->lane_count) + 1); I915_WRITE(MIPI_DBI_BW_CTRL(pipe), intel_dsi->bw_timer); } I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP); val = I915_READ(MIPI_DSI_FUNC_PRG(pipe)); val &= ~VID_MODE_FORMAT_MASK; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), val); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1); #if 0 //in dual display config, dsi 0 is not init. so this function may not //be called with pipe0. set this flag for pipe0 so that pipe b can work #ifdef BYT_DUAL_MIPI_DSI if(pipe != 0) { I915_WRITE_BITS(MIPI_PORT_CTRL(0), LP_OUTPUT_HOLD, LP_OUTPUT_HOLD); usleep_range(1000, 1500); } #endif #endif if (intel_dsi->dev.dev_ops->send_otp_cmds) intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0); set_dsi_timings(encoder, adjusted_mode); /* Some panels might have resolution which is not a multiple of * 64 like 1366 x 768. Enable RANDOM resolution support for such * panels by default */ I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe), intel_dsi->video_frmt_cfg_bits | intel_dsi->video_mode_type | IP_TG_CONFIG | RANDOM_DPI_DISPLAY_RESOLUTION); val = 0; if (intel_dsi->eotp_pkt == 0) val |= EOT_DISABLE; if (intel_dsi->clock_stop) val |= CLOCKSTOP; I915_WRITE(MIPI_EOT_DISABLE(pipe), val); val = intel_dsi->channel << VID_MODE_CHANNEL_NUMBER_SHIFT | intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT | intel_dsi->pixel_format; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), val); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1); I915_WRITE(MIPI_INTR_STAT(pipe), 0xFFFFFFFF); /* Max packet return size limits the size of returning * packet so that host processor can prevent buffer overflow * condition when receiving data from peripheral. DCS read * need this to be set.*/ I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 0xff); }
/* Encoder dpms must, add functionality later */ void intel_dsi_encoder_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct intel_encoder *intel_encoder = &intel_dsi->base; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); int pipe = intel_crtc->pipe; u32 val; DRM_DEBUG_KMS("\n"); if (dev_priv->mipi_fw) { /* IAFW enabled MIPI; we do not need to * do anything for this dpms call * * Next enabling will be done by driver * so clear the mmipi_fw flag */ dev_priv->mipi_fw = 0; DRM_DEBUG_KMS("FW enabled MIPI nothing to do\n"); return; } if (mode != DRM_MODE_DPMS_ON) mode = DRM_MODE_DPMS_OFF; DRM_DEBUG_DRIVER("DPMS mode = %d\n", mode); if (mode == DRM_MODE_DPMS_ON) { intel_dsi_device_ready(intel_encoder); /* need to resend OTP as panel off was done in * DPMS off */ /* Clock needs to be in LP11 mode before we can send * commands to panel */ I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0); I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP); val = I915_READ(MIPI_DSI_FUNC_PRG(pipe)); val &= ~VID_MODE_FORMAT_MASK; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), val); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1); if (intel_dsi->dev.dev_ops->send_otp_cmds) intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev); /* Now we need to restore MIPI_DSI_FUNC_PRG to needed value */ I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0); val = intel_dsi->channel << VID_MODE_CHANNEL_NUMBER_SHIFT | intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT | intel_dsi->pixel_format; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), val); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1); } }