> -----Original Message----- > From: Nikula, Jani > Sent: Monday, May 15, 2017 9:19 PM > To: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>; Chauhan, Madhav > <madhav.chauhan@xxxxxxxxx> > Cc: intel-gfx@xxxxxxxxxxxxxxxxxxxxx; Conselvan De Oliveira, Ander > <ander.conselvan.de.oliveira@xxxxxxxxx>; Hiremath, Shashidhar > <shashidhar.hiremath@xxxxxxxxx> > Subject: Re: [PATCH 2/2] drm/i915/glk: Enable cold boot for GLK > DSI > > On Tue, 09 May 2017, Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> wrote: > > On Tue, May 09, 2017 at 06:59:25PM +0530, Madhav Chauhan wrote: > >> As per BSEPC, if device ready bit is '0' in enable IO sequence then > >> its a cold boot/reset scenario eg: S3/S4 resume. In these conditions > >> we need to program certain registers and prepare port from the middle > >> of DSI enable sequence otherwise feature like S3/S4 doesn't work. > > > > Can't we just always follow the "cold boot" sequence? Less codepaths > > means less bugs. > > I agree. Madhav? Cold Boot scenario represents when DSI controller/IO is not initialized even once before use eg: 1. Connected HDMI boot with DSI panel 2. S3/S4 While normal scenario is: 1. Boot with DSI panel without HDMI. DSI will be initialized once by GOP/BIOS If we use cold boot sequence always, normal scenario doesn’t work as few registers can’t be Programmed as per cold boot scenario. LP_WAKE bit (MIPI_CTRL REG) is one of the example. Moreover, current changes works very well for all above scenarios :). > > BR, > Jani. > > > > > >> > >> Signed-off-by: Madhav Chauhan <madhav.chauhan@xxxxxxxxx> > >> --- > >> drivers/gpu/drm/i915/intel_dsi.c | 79 > >> ++++++++++++++++++++++++---------------- > >> 1 file changed, 48 insertions(+), 31 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/i915/intel_dsi.c > >> b/drivers/gpu/drm/i915/intel_dsi.c > >> index fc0ef49..6b68864 100644 > >> --- a/drivers/gpu/drm/i915/intel_dsi.c > >> +++ b/drivers/gpu/drm/i915/intel_dsi.c > >> @@ -346,12 +346,17 @@ static bool intel_dsi_compute_config(struct > intel_encoder *encoder, > >> return true; > >> } > >> > >> -static void glk_dsi_device_ready(struct intel_encoder *encoder) > >> +static void intel_dsi_prepare(struct intel_encoder *intel_encoder, > >> + struct intel_crtc_state *pipe_config); > >> + > >> +static void glk_dsi_device_ready(struct intel_encoder *encoder, > >> + struct intel_crtc_state *pipe_config) > >> { > >> struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > >> struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); > >> enum port port; > >> u32 tmp, val; > >> + bool cold_boot = false; > >> > >> /* Set the MIPI mode > >> * If MIPI_Mode is off, then writing to LP_Wake bit is not reflecting. > >> @@ -370,7 +375,10 @@ static void glk_dsi_device_ready(struct > intel_encoder *encoder) > >> /* Program LP Wake */ > >> for_each_dsi_port(port, intel_dsi->ports) { > >> tmp = I915_READ(MIPI_CTRL(port)); > >> - tmp |= GLK_LP_WAKE; > >> + if (!(I915_READ(MIPI_DEVICE_READY(port)) & > DEVICE_READY)) > >> + tmp &= ~GLK_LP_WAKE; > >> + else > >> + tmp |= GLK_LP_WAKE; > >> I915_WRITE(MIPI_CTRL(port), tmp); > >> } > >> > >> @@ -382,6 +390,15 @@ static void glk_dsi_device_ready(struct > intel_encoder *encoder) > >> DRM_ERROR("MIPIO port is powergated\n"); > >> } > >> > >> + /* Check if cold boot scenario */ > >> + for_each_dsi_port(port, intel_dsi->ports) { > >> + cold_boot |= !(I915_READ(MIPI_DEVICE_READY(port)) & > >> + DEVICE_READY); > >> + } > >> + > >> + if (cold_boot) > >> + intel_dsi_prepare(encoder, pipe_config); > >> + > >> /* Wait for MIPI PHY status bit to set */ > >> for_each_dsi_port(port, intel_dsi->ports) { > >> if (intel_wait_for_register(dev_priv, > >> @@ -402,34 +419,34 @@ static void glk_dsi_device_ready(struct > intel_encoder *encoder) > >> val |= DEVICE_READY; > >> I915_WRITE(MIPI_DEVICE_READY(port), val); > >> usleep_range(10, 15); > >> - } > >> - > >> - /* Enter ULPS */ > >> - val = I915_READ(MIPI_DEVICE_READY(port)); > >> - val &= ~ULPS_STATE_MASK; > >> - val |= (ULPS_STATE_ENTER | DEVICE_READY); > >> - I915_WRITE(MIPI_DEVICE_READY(port), val); > >> + } else { > >> + /* Enter ULPS */ > >> + val = I915_READ(MIPI_DEVICE_READY(port)); > >> + val &= ~ULPS_STATE_MASK; > >> + val |= (ULPS_STATE_ENTER | DEVICE_READY); > >> + I915_WRITE(MIPI_DEVICE_READY(port), val); > >> > >> - /* Wait for ULPS active */ > >> - if (intel_wait_for_register(dev_priv, > >> + /* Wait for ULPS active */ > >> + if (intel_wait_for_register(dev_priv, > >> MIPI_CTRL(port), GLK_ULPS_NOT_ACTIVE, 0, > 20)) > >> - DRM_ERROR("ULPS not active\n"); > >> + DRM_ERROR("ULPS not active\n"); > >> > >> - /* Exit ULPS */ > >> - val = I915_READ(MIPI_DEVICE_READY(port)); > >> - val &= ~ULPS_STATE_MASK; > >> - val |= (ULPS_STATE_EXIT | DEVICE_READY); > >> - I915_WRITE(MIPI_DEVICE_READY(port), val); > >> + /* Exit ULPS */ > >> + val = I915_READ(MIPI_DEVICE_READY(port)); > >> + val &= ~ULPS_STATE_MASK; > >> + val |= (ULPS_STATE_EXIT | DEVICE_READY); > >> + I915_WRITE(MIPI_DEVICE_READY(port), val); > >> > >> - /* Enter Normal Mode */ > >> - val = I915_READ(MIPI_DEVICE_READY(port)); > >> - val &= ~ULPS_STATE_MASK; > >> - val |= (ULPS_STATE_NORMAL_OPERATION | DEVICE_READY); > >> - I915_WRITE(MIPI_DEVICE_READY(port), val); > >> + /* Enter Normal Mode */ > >> + val = I915_READ(MIPI_DEVICE_READY(port)); > >> + val &= ~ULPS_STATE_MASK; > >> + val |= (ULPS_STATE_NORMAL_OPERATION | > DEVICE_READY); > >> + I915_WRITE(MIPI_DEVICE_READY(port), val); > >> > >> - tmp = I915_READ(MIPI_CTRL(port)); > >> - tmp &= ~GLK_LP_WAKE; > >> - I915_WRITE(MIPI_CTRL(port), tmp); > >> + tmp = I915_READ(MIPI_CTRL(port)); > >> + tmp &= ~GLK_LP_WAKE; > >> + I915_WRITE(MIPI_CTRL(port), tmp); > >> + } > >> } > >> > >> /* Wait for Stop state */ > >> @@ -515,7 +532,8 @@ static void vlv_dsi_device_ready(struct > intel_encoder *encoder) > >> } > >> } > >> > >> -static void intel_dsi_device_ready(struct intel_encoder *encoder) > >> +static void intel_dsi_device_ready(struct intel_encoder *encoder, > >> + struct intel_crtc_state *pipe_config) > >> { > >> struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > >> > >> @@ -524,7 +542,7 @@ static void intel_dsi_device_ready(struct > intel_encoder *encoder) > >> else if (IS_BROXTON(dev_priv)) > >> bxt_dsi_device_ready(encoder); > >> else if (IS_GEMINILAKE(dev_priv)) > >> - glk_dsi_device_ready(encoder); > >> + glk_dsi_device_ready(encoder, pipe_config); > >> } > >> > >> static void glk_dsi_enter_low_power_mode(struct intel_encoder > >> *encoder) @@ -710,8 +728,6 @@ static void intel_dsi_port_disable(struct > intel_encoder *encoder) > >> } > >> } > >> > >> -static void intel_dsi_prepare(struct intel_encoder *intel_encoder, > >> - struct intel_crtc_state *pipe_config); > >> static void intel_dsi_unprepare(struct intel_encoder *encoder); > >> > >> static void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) > >> @@ -800,7 +816,8 @@ static void intel_dsi_pre_enable(struct > intel_encoder *encoder, > >> I915_WRITE(DSPCLK_GATE_D, val); > >> } > >> > >> - intel_dsi_prepare(encoder, pipe_config); > >> + if (!IS_GEMINILAKE(dev_priv)) > >> + intel_dsi_prepare(encoder, pipe_config); > >> > >> /* Power on, try both CRC pmic gpio and VBT */ > >> if (intel_dsi->gpio_panel) > >> @@ -812,7 +829,7 @@ static void intel_dsi_pre_enable(struct > intel_encoder *encoder, > >> intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); > >> > >> /* Put device in ready state (LP-11) */ > >> - intel_dsi_device_ready(encoder); > >> + intel_dsi_device_ready(encoder, pipe_config); > >> > >> /* Send initialization commands in LP mode */ > >> intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); > >> -- > >> 1.9.1 > >> > >> _______________________________________________ > >> Intel-gfx mailing list > >> Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx > > -- > Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx