static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); int pipe = intel_crtc->pipe; u32 val; DRM_DEBUG_KMS("\n"); I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); usleep_range(2000, 2500); I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); usleep_range(2000, 2500); I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); usleep_range(2000, 2500); val = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD); usleep_range(1000, 1500); if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT) == 0x00000), 30)) DRM_ERROR("DSI LP not going Low\n"); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); usleep_range(2000, 2500); vlv_disable_dsi_pll(encoder); }
static void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); int pipe = intel_crtc->pipe; u32 val; DRM_DEBUG_KMS("\n"); mutex_lock(&dev_priv->dpio_lock); /* program rcomp for compliance, reduce from 50 ohms to 45 ohms * needed everytime after power gate */ vlv_flisdsi_write(dev_priv, 0x04, 0x0004); mutex_unlock(&dev_priv->dpio_lock); /* bandgap reset is needed after everytime we do power gate */ band_gap_reset(dev_priv); I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); usleep_range(2500, 3000); val = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD); usleep_range(1000, 1500); I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); usleep_range(2500, 3000); I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); usleep_range(2500, 3000); }
static void intel_dsi_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 temp; DRM_DEBUG_KMS("\n"); if (is_vid_mode(intel_dsi)) { dpi_send_cmd(intel_dsi, SHUTDOWN); msleep(10); /* de-assert ip_tg_enable signal */ temp = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); msleep(2); } /* if disable packets are sent before sending shutdown packet then in * some next enable sequence send turn on packet error is observed */ if (intel_dsi->dev.dev_ops->disable) intel_dsi->dev.dev_ops->disable(&intel_dsi->dev); }
static void intel_dsi_disable(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 temp; DRM_DEBUG_KMS("\n"); intel_dsi->dev.dev_ops->disable(&intel_dsi->dev); if (is_vid_mode(intel_dsi)) { dpi_send_cmd(intel_dsi, SHUTDOWN); msleep(10); /* de-assert ip_tg_enable signal */ temp = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); msleep(2); } temp = I915_READ(MIPI_DEVICE_READY(pipe)); if (temp & DEVICE_READY) { temp &= ~DEVICE_READY; temp &= ~ULPS_STATE_MASK; I915_WRITE(MIPI_DEVICE_READY(pipe), temp); } }
static void intel_dsi_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 temp; DRM_DEBUG_KMS("\n"); if (is_cmd_mode(intel_dsi)) I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4); else { msleep(20); /* XXX */ dpi_send_cmd(intel_dsi, TURN_ON); msleep(100); /* assert ip_tg_enable signal */ temp = I915_READ(MIPI_PORT_CTRL(pipe)) & ~LANE_CONFIGURATION_MASK; temp = temp | intel_dsi->port_bits; I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); } if (intel_dsi->dev.dev_ops->enable) intel_dsi->dev.dev_ops->enable(&intel_dsi->dev); }
void intel_dsi_port_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 val, port_control = 0; if (intel_dsi->dual_link) { port_control = (intel_dsi->dual_link - 1) << DUAL_LINK_MODE_SHIFT; if (pipe == PIPE_A) port_control |= LANE_CONFIGURATION_DUAL_LINK_A; else port_control |= LANE_CONFIGURATION_DUAL_LINK_B; /*Pixel overlap count; only for VLV CO stepping */ if (IS_VALLEYVIEW_C0(dev) && (intel_dsi->dual_link & MIPI_DUAL_LINK_FRONT_BACK)) { val = I915_READ(VLV_CHICKEN_3); val &= ~PIXEL_OVERLAP_CNT_MASK | intel_dsi->pixel_overlap << PIXEL_OVERLAP_CNT_SHIFT; I915_WRITE(VLV_CHICKEN_3, val); } /* Port A */ val = I915_READ(MIPI_PORT_CTRL(0)); val = val | port_control; I915_WRITE(MIPI_PORT_CTRL(0), val | DPI_ENABLE); if (!IS_VALLEYVIEW_C0(dev)) { /* for stepping before C0; we need to enable * PORTC explicitly. From C0 onwards enable PORT A * also enabled PORT C for dual link */ val = I915_READ(MIPI_PORT_CTRL(1)); I915_WRITE(MIPI_PORT_CTRL(1), val | DPI_ENABLE); } else { if (intel_crtc->config.dither) { val = I915_READ(MIPI_PORT_CTRL(0)); val = val | DITHERING_ENABLE; I915_WRITE(MIPI_PORT_CTRL(0), val); val = I915_READ(MIPI_PORT_CTRL(1)); val = val | DITHERING_ENABLE; I915_WRITE(MIPI_PORT_CTRL(1), val); } } usleep_range(2000, 2500); } else { val = I915_READ(MIPI_PORT_CTRL(pipe)); val = val | port_control; if (intel_crtc->config.dither && IS_VALLEYVIEW_C0(dev)) val |= DITHERING_ENABLE; I915_WRITE(MIPI_PORT_CTRL(pipe), val | DPI_ENABLE); usleep_range(2000, 2500); } }
void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 val; DRM_DEBUG_KMS("\n"); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER | DEVICE_READY, ULPS_STATE_MASK | DEVICE_READY); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT | DEVICE_READY, ULPS_STATE_MASK | DEVICE_READY); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER | DEVICE_READY, ULPS_STATE_MASK | DEVICE_READY); usleep_range(2000, 2500); if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & 0x20000) == 0x00000), 30)) DRM_ERROR("DSI LP not going Low\n"); I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), 0, LP_OUTPUT_HOLD); usleep_range(1000, 1500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), 0x00, DEVICE_READY); usleep_range(2000, 2500); intel_disable_dsi_pll(intel_dsi); val = I915_READ(DSPCLK_GATE_D); val &= ~VSUNIT_CLOCK_GATE_DISABLE; I915_WRITE(DSPCLK_GATE_D, val); if (intel_dsi->dev.dev_ops->disable_panel_power) intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev); #ifdef CONFIG_CRYSTAL_COVE if (BYT_CR_CONFIG) { /* Disable Panel */ vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PCONF0, 0x2000CC00); vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PAD, 0x00000004); udelay(500); } else intel_mid_pmic_writeb(PMIC_PANEL_EN, 0x00); #else /* need to code for BYT-CR for example where things have changed */ DRM_ERROR("PANEL Disable to supported yet\n"); #endif msleep(intel_dsi->panel_off_delay); msleep(intel_dsi->panel_pwr_cycle_delay); }
static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; enum intel_display_power_domain power_domain; u32 port, func; enum pipe p; DRM_DEBUG_KMS("\n"); power_domain = intel_display_port_power_domain(encoder); if (!intel_display_power_enabled(dev_priv, power_domain)) return false; /* XXX: this only works for one DSI output */ for (p = PIPE_A; p <= PIPE_B; p++) { port = I915_READ(MIPI_PORT_CTRL(p)); func = I915_READ(MIPI_DSI_FUNC_PRG(p)); if ((port & DPI_ENABLE) || (func & CMD_MODE_DATA_WIDTH_MASK)) { if (I915_READ(MIPI_DEVICE_READY(p)) & DEVICE_READY) { *pipe = p; return true; } } } return false; }
static void intel_dsi_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 temp; DRM_DEBUG_KMS("\n"); if (is_vid_mode(intel_dsi)) { wait_for_dsi_fifo_empty(intel_dsi); /* de-assert ip_tg_enable signal */ temp = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); msleep(2); } /* Panel commands can be sent when clock is in LP11 */ I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0); temp = I915_READ(MIPI_CTRL(pipe)); temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; I915_WRITE(MIPI_CTRL(pipe), temp | intel_dsi->escape_clk_div << ESCAPE_CLOCK_DIVIDER_SHIFT); I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP); temp = I915_READ(MIPI_DSI_FUNC_PRG(pipe)); temp &= ~VID_MODE_FORMAT_MASK; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), temp); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x1); /* if disable packets are sent before sending shutdown packet then in * some next enable sequence send turn on packet error is observed */ if (intel_dsi->dev.dev_ops->disable) intel_dsi->dev.dev_ops->disable(&intel_dsi->dev); wait_for_dsi_fifo_empty(intel_dsi); }
static void intel_dsi_post_disable(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 tmp; wait_for_dsi_fifo_empty(intel_dsi); I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), 0, DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); usleep_range(2000, 2500); /* Panel commands can be sent when clock is in LP11 */ tmp = I915_READ(MIPI_DEVICE_READY(pipe)); tmp &= ~DEVICE_READY; I915_WRITE(MIPI_DEVICE_READY(pipe), tmp); tmp = I915_READ(MIPI_CTRL(pipe)); tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK; I915_WRITE(MIPI_CTRL(pipe), tmp | intel_dsi->escape_clk_div << ESCAPE_CLOCK_DIVIDER_SHIFT); tmp = I915_READ(MIPI_DSI_FUNC_PRG(pipe)); tmp &= ~VID_MODE_FORMAT_MASK; I915_WRITE(MIPI_DSI_FUNC_PRG(pipe), tmp); I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP); tmp = I915_READ(MIPI_DEVICE_READY(pipe)); tmp &= DEVICE_READY; I915_WRITE(MIPI_DEVICE_READY(pipe), tmp); /* if disable packets are sent before sending shutdown packet then in * some next enable sequence send turn on packet error is observed */ if (intel_dsi->dev.dev_ops->disable) intel_dsi->dev.dev_ops->disable(&intel_dsi->dev); wait_for_dsi_fifo_empty(intel_dsi); intel_dsi_clear_device_ready(encoder); }
static void intel_dsi_enable(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 temp; DRM_DEBUG_KMS("\n"); temp = I915_READ(MIPI_DEVICE_READY(pipe)); if ((temp & DEVICE_READY) == 0) { temp &= ~ULPS_STATE_MASK; I915_WRITE(MIPI_DEVICE_READY(pipe), temp | DEVICE_READY); } else if (temp & ULPS_STATE_MASK) { temp &= ~ULPS_STATE_MASK; I915_WRITE(MIPI_DEVICE_READY(pipe), temp | ULPS_STATE_EXIT); /* * We need to ensure that there is a minimum of 1 ms time * available before clearing the UPLS exit state. */ msleep(2); I915_WRITE(MIPI_DEVICE_READY(pipe), temp); } if (is_cmd_mode(intel_dsi)) I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4); if (is_vid_mode(intel_dsi)) { msleep(20); /* XXX */ dpi_send_cmd(intel_dsi, TURN_ON); msleep(100); /* assert ip_tg_enable signal */ temp = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); } intel_dsi->dev.dev_ops->enable(&intel_dsi->dev); }
static void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); int pipe = intel_crtc->pipe; u32 val; DRM_DEBUG_KMS("\n"); val = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD); usleep_range(1000, 1500); I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT); usleep_range(2000, 2500); I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); usleep_range(2000, 2500); I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); usleep_range(2000, 2500); I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); usleep_range(2000, 2500); }
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_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; bool is_dsi; u32 temp; DRM_DEBUG_KMS("\n"); is_dsi = intel_pipe_has_type(encoder->base.crtc, INTEL_OUTPUT_DSI); intel_enable_dsi_pll(intel_dsi); printk("====>DLP3430 debug 2.20.\n"); if (is_cmd_mode(intel_dsi)) { /* XXX: Implement me */ I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4); } else { intel_dsi->hs = 1; dpi_send_cmd(intel_dsi, TURN_ON); usleep_range(1000, 1500); if (intel_dsi->dev.dev_ops->enable) intel_dsi->dev.dev_ops->enable(&intel_dsi->dev); temp = I915_READ(MIPI_PORT_CTRL(pipe)); temp = temp | intel_dsi->port_bits; if (is_dsi && intel_crtc->config.dither) temp |= DITHERING_ENABLE; I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE); usleep_range(2000, 2500); } }
void intel_dsi_port_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; if (intel_dsi->dual_link) { I915_WRITE_BITS(MIPI_PORT_CTRL(0), 0, DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(0)); I915_WRITE_BITS(MIPI_PORT_CTRL(1), 0, DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(1)); } else { I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), 0, DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); } usleep_range(2000, 2500); }
void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 tmp; DRM_DEBUG_KMS("\n"); /* program rcomp for compliance * reduce form 50 ohms to 45 ohms */ intel_flisdsi_write32(dev_priv, 0x04, 0x00f0); band_gap_reset(dev_priv); #ifdef CONFIG_CRYSTAL_COVE /* Panel Enable */ if (BYT_CR_CONFIG) { /* cabc disable */ vlv_gpio_nc_write(dev_priv, GPIO_NC_9_PCONF0, 0x2000CC00); vlv_gpio_nc_write(dev_priv, GPIO_NC_9_PAD, 0x00000004); /* panel enable */ vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PCONF0, 0x2000CC00); vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PAD, 0x00000005); udelay(500); } else intel_mid_pmic_writeb(PMIC_PANEL_EN, 0x01); #else /* need to code for BYT-CR for example where things have changed */ DRM_ERROR("PANEL Enable to supported yet\n"); #endif msleep(intel_dsi->panel_on_delay); if (intel_dsi->dev.dev_ops->panel_reset) intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev); /* Disable DPOunit clock gating, can stall pipe */ tmp = I915_READ(DPLL(pipe)); tmp |= DPLL_RESERVED_BIT; I915_WRITE(DPLL(pipe), tmp); tmp = I915_READ(DSPCLK_GATE_D); tmp |= VSUNIT_CLOCK_GATE_DISABLE; I915_WRITE(DSPCLK_GATE_D, tmp); intel_enable_dsi_pll(intel_dsi); //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 I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), LP_OUTPUT_HOLD, LP_OUTPUT_HOLD); usleep_range(1000, 1500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), 0x00, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); }
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); }
void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int pipe = intel_crtc->pipe; u32 tmp; int count = 1; DRM_DEBUG_KMS("\n"); /* program rcomp for compliance * reduce form 50 ohms to 45 ohms */ intel_flisdsi_write32(dev_priv, 0x04, 0x0004); band_gap_reset(dev_priv); #ifdef CONFIG_CRYSTAL_COVE if (BYT_CR_CONFIG) { /* cabc disable */ vlv_gpio_nc_write(dev_priv, GPIO_NC_9_PCONF0, 0x2000CC00); vlv_gpio_nc_write(dev_priv, GPIO_NC_9_PAD, 0x00000004); /* panel enable */ vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PCONF0, 0x2000CC00); vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PAD, 0x00000005); udelay(500); } else intel_mid_pmic_writeb(PMIC_PANEL_EN, 0x01); #else /* need to code for BYT-CR for example where things have changed */ DRM_ERROR("PANEL Enable to supported yet\n"); #endif msleep(intel_dsi->panel_on_delay); if (intel_dsi->dev.dev_ops->panel_reset) intel_dsi->dev.dev_ops->panel_reset(&intel_dsi->dev); /* Disable DPOunit clock gating, can stall pipe */ tmp = I915_READ(DPLL(pipe)); tmp |= DPLL_RESERVED_BIT; I915_WRITE(DPLL(pipe), tmp); tmp = I915_READ(DSPCLK_GATE_D); tmp |= VSUNIT_CLOCK_GATE_DISABLE; I915_WRITE(DSPCLK_GATE_D, tmp); intel_enable_dsi_pll(intel_dsi); if (intel_dsi->operation_mode == DSI_VIDEO_MODE) { I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), LP_OUTPUT_HOLD, LP_OUTPUT_HOLD); usleep_range(1000, 1500); if (intel_dsi->dual_link) count = 2; do { I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), 0x00, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), DEVICE_READY, DEVICE_READY | ULPS_STATE_MASK); usleep_range(2000, 2500); /* For Port C for dual link */ pipe = PIPE_B; } while (--count > 0); } }