Re: [Intel-gfx] [PATCH v10 00/15] drm/i915/icl: dsi enabling
On 11/2/2018 5:17 PM, Jani Nikula wrote: Next version of [1]. Sorry for the spam, needed to get the authorship straight. Fixed power domains and compute config hook initialization. Overall, with this series ICL DSI dual link video mode feature looks complete to me. Thanks!! Regards, Madhav BR, Jani. [1] https://patchwork.freedesktop.org/series/51011/ Jani Nikula (1): drm/i915/icl: add dummy DSI GPIO element execution function Madhav Chauhan (14): drm/i915/icl: Allocate DSI encoder/connector drm/i915/icl: Fill DSI ports info drm/i915/icl: Allocate DSI hosts and imlement host transfer drm/i915/icl: Add get config functionality for DSI drm/i915/icl: Get HW state for DSI encoder drm/i915/icl: Add DSI encoder remaining functions drm/i915/icl: Configure DSI Dual link mode drm/i915/icl: Consider DSI for getting transcoder state drm/i915/icl: Get pipe timings for DSI drm/i915/icl: Define missing bitfield for shortplug reg drm/i915/icl: Define Panel power ctrl register drm/i915/icl: Define display GPIO pins for DSI HACK: drm/i915/icl: Add changes to program DSI panel GPIOs HACK: drm/i915/icl: Configure backlight functions for DSI drivers/gpu/drm/i915/i915_reg.h | 12 + drivers/gpu/drm/i915/icl_dsi.c | 417 ++- drivers/gpu/drm/i915/intel_display.c | 34 ++- drivers/gpu/drm/i915/intel_dsi_vbt.c | 58 - drivers/gpu/drm/i915/intel_panel.c | 3 +- 5 files changed, 505 insertions(+), 19 deletions(-) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v11 23/23] HACK: drm/i915/bios: ignore VBT not overflowing the mailbox
On 11/29/2018 7:42 PM, Jani Nikula wrote: Some machines seem to have a broken opregion where the VBT overflows the mailbox. Ignore this until properly fixed. Right, otherwise DSI modeset doesn't progress further. Acked-by: Madhav Chauhan Regards, Madhav Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_bios.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 0694aa8bb9bc..39e502ea557c 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1706,7 +1706,6 @@ bool intel_bios_is_valid_vbt(const void *buf, size_t size) bdb = get_bdb_header(vbt); if (range_overflows_t(size_t, vbt->bdb_offset, bdb->bdb_size, size)) { DRM_DEBUG_DRIVER("BDB incomplete\n"); - return false; } return vbt; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v11 20/23] drm/i915/icl: add pll mapping for DSI
On 11/29/2018 7:42 PM, Jani Nikula wrote: Add encoder specific pll mapping for DSI. The differences with the DDI version are big enough to warrant a separate function. Cc: Madhav Chauhan Cc: Vandita Kulkarni Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index e3aa9d3d2291..1907640a2e6a 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -570,6 +570,27 @@ static void gen11_dsi_ungate_clocks(struct intel_encoder *encoder) mutex_unlock(_priv->dpll_lock); } +static void gen11_dsi_map_pll(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + struct intel_shared_dpll *pll = crtc_state->shared_dpll; + enum port port; + u32 val; + + mutex_lock(_priv->dpll_lock); + + val = I915_READ(DPCLKA_CFGCR0_ICL); + for_each_dsi_port(port, intel_dsi->ports) { + val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); + val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); + } + I915_WRITE(DPCLKA_CFGCR0_ICL, val); We need to read back DPCLKA_CFGCR0_ICL to ensure write completed before next step as per BSPEC. With this fix, Reviewed-by: Madhav Chauhan Regards, Madhav + + mutex_unlock(_priv->dpll_lock); +} + static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) @@ -978,6 +999,9 @@ static void gen11_dsi_pre_enable(struct intel_encoder *encoder, { struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + /* step3b */ + gen11_dsi_map_pll(encoder, pipe_config); /* step4: enable DSI port and DPHY */ gen11_dsi_enable_port_and_phy(encoder, pipe_config); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v11 17/23] drm/i915/icl: add dummy DSI GPIO element execution function
On 11/29/2018 7:42 PM, Jani Nikula wrote: Add dummy debug logging GPIO element execution function for ICL. Looks fine to me. Reviewed-by: Madhav Chauhan Regards, Madhav Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi_vbt.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index b41ca6436401..a1a8b3790e61 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -336,6 +336,12 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv, gpiod_set_value(gpio_desc, value); } +static void icl_exec_gpio(struct drm_i915_private *dev_priv, + u8 gpio_source, u8 gpio_index, bool value) +{ + DRM_DEBUG_KMS("Skipping ICL GPIO element execution\n"); +} + static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) { struct drm_device *dev = intel_dsi->base.base.dev; @@ -359,7 +365,9 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) /* pull up/down */ value = *data++ & 1; - if (IS_VALLEYVIEW(dev_priv)) + if (IS_ICELAKE(dev_priv)) + icl_exec_gpio(dev_priv, gpio_source, gpio_index, value); + else if (IS_VALLEYVIEW(dev_priv)) vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value); else if (IS_CHERRYVIEW(dev_priv)) chv_exec_gpio(dev_priv, gpio_source, gpio_number, value); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v11 01/23] drm/i915/icl: push pll to port mapping/unmapping to ddi encoder hooks
On 11/29/2018 7:42 PM, Jani Nikula wrote: Unclutter the haswell_crtc_enable() and haswell_crtc_disable() functions a bit by moving the pll to port mapping and unmapping functions to the ddi encoder hooks. This allows removal of a bunch of boilerplate code from the functions. Additionally, the ICL DSI encoder needs to do the clock gating and ungating slightly differently, and this allows its own handling in a clean fashion. Looks good to me, Reviewed-by: Madhav Chauhan Regards, Madhav Cc: Madhav Chauhan Cc: Paulo Zanoni Cc: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_ddi.c | 84 +++- drivers/gpu/drm/i915/intel_display.c | 6 --- drivers/gpu/drm/i915/intel_drv.h | 6 --- 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ad11540ac436..7bad6c857b81 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2785,69 +2785,45 @@ uint32_t icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv, return 0; } -void icl_map_plls_to_ports(struct drm_crtc *crtc, - struct intel_crtc_state *crtc_state, - struct drm_atomic_state *old_state) +static void icl_map_plls_to_ports(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_shared_dpll *pll = crtc_state->shared_dpll; - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - struct drm_connector_state *conn_state; - struct drm_connector *conn; - int i; - - for_each_new_connector_in_state(old_state, conn, conn_state, i) { - struct intel_encoder *encoder = - to_intel_encoder(conn_state->best_encoder); - enum port port; - uint32_t val; - - if (conn_state->crtc != crtc) - continue; - - port = encoder->port; - mutex_lock(_priv->dpll_lock); + enum port port = encoder->port; + u32 val; - val = I915_READ(DPCLKA_CFGCR0_ICL); - WARN_ON((val & icl_dpclka_cfgcr0_clk_off(dev_priv, port)) == 0); + mutex_lock(_priv->dpll_lock); - if (intel_port_is_combophy(dev_priv, port)) { - val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); - val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); - I915_WRITE(DPCLKA_CFGCR0_ICL, val); - POSTING_READ(DPCLKA_CFGCR0_ICL); - } + val = I915_READ(DPCLKA_CFGCR0_ICL); + WARN_ON((val & icl_dpclka_cfgcr0_clk_off(dev_priv, port)) == 0); - val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, port); + if (intel_port_is_combophy(dev_priv, port)) { + val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port); + val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); I915_WRITE(DPCLKA_CFGCR0_ICL, val); - - mutex_unlock(_priv->dpll_lock); + POSTING_READ(DPCLKA_CFGCR0_ICL); } + + val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, port); + I915_WRITE(DPCLKA_CFGCR0_ICL, val); + + mutex_unlock(_priv->dpll_lock); } -void icl_unmap_plls_to_ports(struct drm_crtc *crtc, -struct intel_crtc_state *crtc_state, -struct drm_atomic_state *old_state) +static void icl_unmap_plls_to_ports(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - struct drm_connector_state *old_conn_state; - struct drm_connector *conn; - int i; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = encoder->port; + u32 val; - for_each_old_connector_in_state(old_state, conn, old_conn_state, i) { - struct intel_encoder *encoder = - to_intel_encoder(old_conn_state->best_encoder); - enum port port; + mutex_lock(_priv->dpll_lock); - if (old_conn_state->crtc != crtc) - continue; + val = I915_READ(DPCLKA_CFGCR0_ICL); + val |= icl_dpclka_cfgcr0_clk_off(dev_priv, port); + I915_WRITE(DPCLKA_CFGCR0_ICL, val); - port = encoder->port; - mutex_lock(_priv->dpll_lock); - I915_WRITE(DPCLKA_CFGCR0_ICL, - I915_READ(DPCLKA_CFGCR0_ICL) | - icl_dpclka_cfgcr0_clk_off(dev_priv, port)); - mutex_unlock(_priv->dpll_lock); - } + mutex_unlock(_priv->dpll_lock); } void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) @@ -3208,6 +
Re: [Intel-gfx] [PATCH v10 00/15] drm/i915/icl: dsi enabling
On 11/2/2018 7:15 PM, Jani Nikula wrote: On Fri, 02 Nov 2018, Jani Nikula wrote: Next version of [1]. Sorry for the spam, needed to get the authorship straight. Fixed power domains and compute config hook initialization. It looks like DDI intel_ddi_get_hw_state() returns true for ICL DSI as well. I'm not sure how this wasn't a problem before, but if I'm not mistaken it is now. At least that's my only explanation to intel_ddi_get_config() hitting WARN_ON(transcoder_is_dsi(cpu_transcoder)). I didn't observe that while testing. Where can we access the complete log?? Regards, Madhav BR, Jani. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v10 05/15] drm/i915/icl: Get HW state for DSI encoder
On 11/2/2018 5:17 PM, Jani Nikula wrote: From: Madhav Chauhan This patch read out the current hw state for DSI and return true if encoder is active. v2 by Jani: - Squash connector get hw state hook here - Squash encode get hw state fix here v3 by Jani: - Add encoder->get_power_domains() (Imre) v4 by Jani: - Make encoder->get_power_domains() sensible... (Imre) Changes looks fine to me. Regards, Madhav Cc: Imre Deak Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 57 ++ 1 file changed, 57 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index b47e837f4493..1881825432cb 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1068,6 +1068,60 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder, pipe_config->port_clock = pixel_clk; } +static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state) +{ + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u64 domains = 0; + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) + domains |= (port == PORT_A ? POWER_DOMAIN_PORT_DDI_A_IO : + POWER_DOMAIN_PORT_DDI_B_IO); + + return domains; +} + +static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, + enum pipe *pipe) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + enum transcoder dsi_trans; + bool ret = false; + + if (!intel_display_power_get_if_enabled(dev_priv, + encoder->power_domain)) + return false; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans)); + switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { + case TRANS_DDI_EDP_INPUT_A_ON: + *pipe = PIPE_A; + break; + case TRANS_DDI_EDP_INPUT_B_ONOFF: + *pipe = PIPE_B; + break; + case TRANS_DDI_EDP_INPUT_C_ONOFF: + *pipe = PIPE_C; + break; + default: + DRM_ERROR("Invalid PIPE input\n"); + goto out; + } + + tmp = I915_READ(PIPECONF(dsi_trans)); + ret = tmp & PIPECONF_ENABLE; + } +out: + intel_display_power_put(dev_priv, encoder->power_domain); + return ret; +} + static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder) { intel_encoder_destroy(encoder); @@ -1181,10 +1235,12 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) encoder->disable = gen11_dsi_disable; encoder->port = port; encoder->get_config = gen11_dsi_get_config; + encoder->get_hw_state = gen11_dsi_get_hw_state; encoder->type = INTEL_OUTPUT_DSI; encoder->cloneable = 0; encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C); encoder->power_domain = POWER_DOMAIN_PORT_DSI; + encoder->get_power_domains = gen11_dsi_get_power_domains; /* register DSI connector with DRM subsystem */ drm_connector_init(dev, connector, _dsi_connector_funcs, @@ -1193,6 +1249,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; + intel_connector->get_hw_state = intel_connector_get_hw_state; /* attach connector to encoder */ intel_connector_attach_encoder(intel_connector, encoder); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v10 06/15] drm/i915/icl: Add DSI encoder remaining functions
On 11/2/2018 5:17 PM, Jani Nikula wrote: From: Madhav Chauhan This patch implements compute config for Gen11 DSI encoder which is required at the time of modeset. v2 by Jani: - drop the enable nop hook - fixed_mode is always true - HAS_GMCH_DISPLAY() is always false v3 by Jani: - set encoder->compute_config dropped during rebase Ok. :) Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 32 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 1881825432cb..8cdf736c2bbd 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1068,6 +1068,37 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder, pipe_config->port_clock = pixel_clk; } +static bool gen11_dsi_compute_config(struct intel_encoder *encoder, +struct intel_crtc_state *pipe_config, +struct drm_connector_state *conn_state) +{ + struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, + base); + struct intel_connector *intel_connector = intel_dsi->attached_connector; + struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); + const struct drm_display_mode *fixed_mode = + intel_connector->panel.fixed_mode; + struct drm_display_mode *adjusted_mode = + _config->base.adjusted_mode; + + intel_fixed_panel_mode(fixed_mode, adjusted_mode); + intel_pch_panel_fitting(crtc, pipe_config, conn_state->scaling_mode); + + adjusted_mode->flags = 0; + + /* Dual link goes to trancoder DSI'0' */ + if (intel_dsi->ports == BIT(PORT_B)) + pipe_config->cpu_transcoder = TRANSCODER_DSI_1; + else + pipe_config->cpu_transcoder = TRANSCODER_DSI_0; + + pipe_config->clock_set = true; + + //TODO: Add check if DSI PLL calculation is done + + return true; +} + static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { @@ -1235,6 +1266,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) encoder->disable = gen11_dsi_disable; encoder->port = port; encoder->get_config = gen11_dsi_get_config; + encoder->compute_config = gen11_dsi_compute_config; encoder->get_hw_state = gen11_dsi_get_hw_state; encoder->type = INTEL_OUTPUT_DSI; encoder->cloneable = 0; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v10 13/15] drm/i915/icl: add dummy DSI GPIO element execution function
On 11/2/2018 5:17 PM, Jani Nikula wrote: Add dummy debug logging GPIO element execution function for ICL. Signed-off-by: Jani Nikula Its kinda split of "drm/i915/icl: Add changes to program DSI panel GPIOs" to pave out the way further. Looks good to me. Reviewed-by: Madhav Chauhan Regards, Madhav --- drivers/gpu/drm/i915/intel_dsi_vbt.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index b41ca6436401..a1a8b3790e61 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -336,6 +336,12 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv, gpiod_set_value(gpio_desc, value); } +static void icl_exec_gpio(struct drm_i915_private *dev_priv, + u8 gpio_source, u8 gpio_index, bool value) +{ + DRM_DEBUG_KMS("Skipping ICL GPIO element execution\n"); +} + static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) { struct drm_device *dev = intel_dsi->base.base.dev; @@ -359,7 +365,9 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) /* pull up/down */ value = *data++ & 1; - if (IS_VALLEYVIEW(dev_priv)) + if (IS_ICELAKE(dev_priv)) + icl_exec_gpio(dev_priv, gpio_source, gpio_index, value); + else if (IS_VALLEYVIEW(dev_priv)) vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value); else if (IS_CHERRYVIEW(dev_priv)) chv_exec_gpio(dev_priv, gpio_source, gpio_number, value); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v9 09/15] drm/i915/icl: Get pipe timings for DSI
On 11/1/2018 9:04 PM, Jani Nikula wrote: From: Madhav Chauhan Transcoder timings for Gen11 DSI encoder is available at pipe level unlike in older platform where port specific registers need to be accessed. v2 by Jani: - get timings for (!dsi || icl) instead of (dsi && icl). Looks ok. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7337d579cbb6..9137675283d1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9549,7 +9549,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, if (!active) goto out; - if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) { + if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || + IS_ICELAKE(dev_priv)) { haswell_get_ddi_port_state(crtc, pipe_config); intel_get_pipe_timings(crtc, pipe_config); } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v9 08/15] drm/i915/icl: Consider DSI for getting transcoder state
On 11/1/2018 9:04 PM, Jani Nikula wrote: From: Madhav Chauhan For Gen11 DSI, we use similar registers like for eDP to find if DSI encoder is connected or not to a pipe. This patch refactors existing hsw_get_transcoder_state() to handle this. v2 by Jani: - Add WARN_ON(dsi && edp) (Ville) v2 changes looks fine to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 31 --- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2d5d034baa91..7337d579cbb6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9366,6 +9366,8 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; u32 tmp; + bool is_dsi = false; + bool is_edp = false; /* * The pipe->transcoder mapping is fixed with the exception of the eDP @@ -9378,26 +9380,41 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, * consistency and less surprising code; it's in always on power). */ tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); - if (tmp & TRANS_DDI_FUNC_ENABLE) { - enum pipe trans_edp_pipe; + if (tmp & TRANS_DDI_FUNC_ENABLE) + is_edp = true; + + if (IS_ICELAKE(dev_priv)) { + tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_DSI_0)); + if (tmp & TRANS_DDI_FUNC_ENABLE) + is_dsi = true; + } + + WARN_ON(is_edp && is_dsi); + + if (is_edp || is_dsi) { + enum pipe trans_pipe; switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { default: WARN(1, "unknown pipe linked to edp transcoder\n"); /* fall through */ case TRANS_DDI_EDP_INPUT_A_ONOFF: case TRANS_DDI_EDP_INPUT_A_ON: - trans_edp_pipe = PIPE_A; + trans_pipe = PIPE_A; break; case TRANS_DDI_EDP_INPUT_B_ONOFF: - trans_edp_pipe = PIPE_B; + trans_pipe = PIPE_B; break; case TRANS_DDI_EDP_INPUT_C_ONOFF: - trans_edp_pipe = PIPE_C; + trans_pipe = PIPE_C; break; } - if (trans_edp_pipe == crtc->pipe) - pipe_config->cpu_transcoder = TRANSCODER_EDP; + if (trans_pipe == crtc->pipe) { + if (is_edp) + pipe_config->cpu_transcoder = TRANSCODER_EDP; + else if (is_dsi) + pipe_config->cpu_transcoder = TRANSCODER_DSI_0; + } } power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v9 03/15] drm/i915/icl: Allocate DSI hosts and imlement host transfer
On 11/1/2018 9:03 PM, Jani Nikula wrote: Allocate DSI host structure for each DSI port available on gen11 and register them with DSI fwk of DRM. Some of the DSI host operations are also registered as part of this. Retrieves DSI pkt (from DSI msg) to be sent over DSI link using DRM DSI exported functions. A wrapper function is also added as "DSI host transfer" for sending DSI data/cmd. Add DSI packet payload to command payload queue using credit based mechanism for *long* packets. v2 by Jani: - indentation - Use the new credit available helper - Use int for free_credits - Add intel_dsi local variable for better code flow - Use the new credit available helper - Use int for free_credits, i, and j v3 by Jani: - Squash DSI host allocation and transfer patches together Ok. Patch becomes very big, created them as separate logical patch to debug any issue if comes in header and payload functionality :). Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 147 + 1 file changed, 147 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index fe408ff77924..806b8c323b53 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -108,6 +108,90 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) } } +static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data, + u32 len) +{ + struct intel_dsi *intel_dsi = host->intel_dsi; + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); + int free_credits; + int i, j; + + for (i = 0; i < len; i += 4) { + u32 tmp = 0; + + free_credits = payload_credits_available(dev_priv, dsi_trans); + if (free_credits < 1) { + DRM_ERROR("Payload credit not available\n"); + return false; + } + + for (j = 0; j < min_t(u32, len - i, 4); j++) + tmp |= *data++ << 8 * j; + + I915_WRITE(DSI_CMD_TXPYLD(dsi_trans), tmp); + } + + return true; +} + +static int dsi_send_pkt_hdr(struct intel_dsi_host *host, + struct mipi_dsi_packet pkt, bool enable_lpdt) +{ + struct intel_dsi *intel_dsi = host->intel_dsi; + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); + u32 tmp; + int free_credits; + + /* check if header credit available */ + free_credits = header_credits_available(dev_priv, dsi_trans); + if (free_credits < 1) { + DRM_ERROR("send pkt header failed, not enough hdr credits\n"); + return -1; + } + + tmp = I915_READ(DSI_CMD_TXHDR(dsi_trans)); + + if (pkt.payload) + tmp |= PAYLOAD_PRESENT; + else + tmp &= ~PAYLOAD_PRESENT; + + tmp &= ~VBLANK_FENCE; + + if (enable_lpdt) + tmp |= LP_DATA_TRANSFER; + + tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK); + tmp |= ((pkt.header[0] & VC_MASK) << VC_SHIFT); + tmp |= ((pkt.header[0] & DT_MASK) << DT_SHIFT); + tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT); + tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT); + I915_WRITE(DSI_CMD_TXHDR(dsi_trans), tmp); + + return 0; +} + +static int dsi_send_pkt_payld(struct intel_dsi_host *host, + struct mipi_dsi_packet pkt) +{ + /* payload queue can accept *256 bytes*, check limit */ + if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) { + DRM_ERROR("payload size exceeds max queue limit\n"); + return -1; + } + + /* load data into command payload queue */ + if (!add_payld_to_queue(host, pkt.payload, + pkt.payload_length)) { + DRM_ERROR("adding payload to queue failed\n"); + return -1; + } + + return 0; +} + static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -997,6 +1081,58 @@ static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs .atomic_check = intel_digital_connector_atomic_check, }; +static int gen11_dsi_host_attach(struct mipi_dsi_host *host, +struct mipi_dsi_device *dsi) +{ + return 0; +} + +static int gen11_dsi_host_detach(struct mipi_dsi_host *host, +struct mipi_dsi_device *dsi) +{ +
Re: [Intel-gfx] [PATCH v9 01/15] drm/i915/icl: Allocate DSI encoder/connector
On 11/1/2018 9:03 PM, Jani Nikula wrote: From: Madhav Chauhan This patch allocates memory for DSI encoder and connector which will be used for various DSI encoder/connector operations and attaching the same to DRM subsystem. This patch also extracts DSI modes info from VBT and save the desired mode info to connector. v2 by Jani: - Drop GEN11 prefix from encoder name - Drop extra parenthesis - Drop extra local variable - Squash encoder power domain here v3 by Jani: - Squash connector and connector helper functions here - Move intel_dsi_vbt_init call here Ok. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 117 ++--- 1 file changed, 109 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 01f422df8c23..a40083a7eb6a 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -26,6 +26,7 @@ */ #include +#include #include "intel_dsi.h" static inline int header_credits_available(struct drm_i915_private *dev_priv, @@ -799,10 +800,9 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) wait_for_cmds_dispatched_to_panel(encoder); } -static void __attribute__((unused)) -gen11_dsi_pre_enable(struct intel_encoder *encoder, -const struct intel_crtc_state *pipe_config, -const struct drm_connector_state *conn_state) +static void gen11_dsi_pre_enable(struct intel_encoder *encoder, +const struct intel_crtc_state *pipe_config, +const struct drm_connector_state *conn_state) { struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); @@ -945,10 +945,9 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) } } -static void __attribute__((unused)) gen11_dsi_disable( - struct intel_encoder *encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state) +static void gen11_dsi_disable(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) { struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); @@ -972,10 +971,112 @@ static void __attribute__((unused)) gen11_dsi_disable( gen11_dsi_disable_io_power(encoder); } +static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder) +{ + intel_encoder_destroy(encoder); +} + +static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = { + .destroy = gen11_dsi_encoder_destroy, +}; + +static const struct drm_connector_funcs gen11_dsi_connector_funcs = { + .late_register = intel_connector_register, + .early_unregister = intel_connector_unregister, + .destroy = intel_connector_destroy, + .fill_modes = drm_helper_probe_single_connector_modes, + .atomic_get_property = intel_digital_connector_atomic_get_property, + .atomic_set_property = intel_digital_connector_atomic_set_property, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, +}; + +static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs = { + .get_modes = intel_dsi_get_modes, + .mode_valid = intel_dsi_mode_valid, + .atomic_check = intel_digital_connector_atomic_check, +}; + void icl_dsi_init(struct drm_i915_private *dev_priv) { + struct drm_device *dev = _priv->drm; + struct intel_dsi *intel_dsi; + struct intel_encoder *encoder; + struct intel_connector *intel_connector; + struct drm_connector *connector; + struct drm_display_mode *scan, *fixed_mode = NULL; enum port port; if (!intel_bios_is_dsi_present(dev_priv, )) return; + + intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); + if (!intel_dsi) + return; + + intel_connector = intel_connector_alloc(); + if (!intel_connector) { + kfree(intel_dsi); + return; + } + + encoder = _dsi->base; + intel_dsi->attached_connector = intel_connector; + connector = _connector->base; + + /* register DSI encoder with DRM subsystem */ + drm_encoder_init(dev, >base, _dsi_encoder_funcs, +DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port)); + + encoder->pre_enable = gen11_dsi_pre_enable; + encoder->disable = gen11_dsi_disable; + encoder->port = port; + encoder->type = INTEL_OUTPUT_DSI; + encoder->cloneable = 0; + encoder->crtc_mask = BIT(PIPE_A)
Re: [Intel-gfx] [PATCH v8 34/38] drm/i915/icl: Add changes to program DSI panel GPIOs
On 10/30/2018 7:31 PM, Ville Syrjälä wrote: On Tue, Oct 30, 2018 at 01:56:40PM +0200, Jani Nikula wrote: From: Madhav Chauhan For ICELAKE DSI, Display Pins are the only GPIOs that need to be programmed. So DSI driver should have its own implementation to toggle these pins based on GPIO info coming from VBT sequences instead of using platform specific GPIO driver. Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi_vbt.c | 46 +++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 8177305b9c87..04423248bbd7 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -334,6 +334,48 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv, gpiod_set_value(gpio_desc, value); } +static void icl_exec_gpio(struct drm_i915_private *dev_priv, + u8 gpio_source, u8 gpio_index, bool value) +{ + u32 val; + + switch (gpio_index) { + case ICL_GPIO_DDSP_HPD_A: + val = I915_READ(SHOTPLUG_CTL_DDI); + val &= ~ICP_DDIA_HPD_ENABLE; + I915_WRITE(SHOTPLUG_CTL_DDI, val); + val = I915_READ(SHOTPLUG_CTL_DDI); + if (value) + val |= ICP_DDIA_HPD_OP_DRIVE_1; + else + val &= ~ICP_DDIA_HPD_OP_DRIVE_1; + + I915_WRITE(SHOTPLUG_CTL_DDI, val); How badly is this thing going to race with the hotplug irq handler? Agree, icp_irq_handler will create race condition here (was aware). Actually, behavior of GPIO pin like what to do for a particular GPIO was not available in BSPEC during power-on. So just added this patch(tmp method) to complete power ON. My bad, should have added that info in patch description. + break; + case ICL_GPIO_L_VDDEN_1: + val = I915_READ(ICP_PP_CONTROL(1)); + if (value) + val |= PWR_STATE_TARGET; + else + val &= ~PWR_STATE_TARGET; + I915_WRITE(ICP_PP_CONTROL(1), val); + break; + case ICL_GPIO_L_BKLTEN_1: + val = I915_READ(ICP_PP_CONTROL(1)); + if (value) + val |= BACKLIGHT_ENABLE; + else + val &= ~BACKLIGHT_ENABLE; + I915_WRITE(ICP_PP_CONTROL(1), val); :( What a horror show. So basically we're trying to pretend the power sequencer state machine doesn't even exist. Is there some bit somewhere we can actually use to disable the state machine? If not I think this thing needs much more care. Yes :(, We need to definitely think about if we can achieve this using existing panel backlight framework functions. Need discussion to have more clarity on BITS and behavior with VBT team and then decide final approach. Regards, Madhav + break; + default: + /* TODO: Add support for remaining GPIOs */ + DRM_ERROR("Invalid GPIO no from VBT\n"); + break; + } +} + static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) { struct drm_device *dev = intel_dsi->base.base.dev; @@ -357,7 +399,9 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) /* pull up/down */ value = *data++ & 1; - if (IS_VALLEYVIEW(dev_priv)) + if (IS_ICELAKE(dev_priv)) + icl_exec_gpio(dev_priv, gpio_source, gpio_index, value); + else if (IS_VALLEYVIEW(dev_priv)) vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value); else if (IS_CHERRYVIEW(dev_priv)) chv_exec_gpio(dev_priv, gpio_source, gpio_number, value); -- 2.11.0 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 30/38] drm/i915/icl: Configure DSI Dual link mode
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch configures DSI video mode dual link by programming DSS_CTL registers. v2: Use new bitfield definitions from Anusha's patch Correct register to be programmed and use max depth buffer value (James) v3 by Jani: - checkpatch fixes Ok. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 42 +- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index b2897281d42c..f2609e36dd1d 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -257,6 +257,45 @@ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) } } +static void configure_dual_link_mode(struct intel_encoder *encoder, +const 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(>base); + u32 dss_ctl1; + + dss_ctl1 = I915_READ(DSS_CTL1); + dss_ctl1 |= SPLITTER_ENABLE; + dss_ctl1 &= ~OVERLAP_PIXELS_MASK; + dss_ctl1 |= OVERLAP_PIXELS(intel_dsi->pixel_overlap); + + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { + const struct drm_display_mode *adjusted_mode = + _config->base.adjusted_mode; + u32 dss_ctl2; + u16 hactive = adjusted_mode->crtc_hdisplay; + u16 dl_buffer_depth; + + dss_ctl1 &= ~DUAL_LINK_MODE_INTERLEAVE; + dl_buffer_depth = hactive / 2 + intel_dsi->pixel_overlap; + + if (dl_buffer_depth > MAX_DL_BUFFER_TARGET_DEPTH) + DRM_ERROR("DL buffer depth exceed max value\n"); + + dss_ctl1 &= ~LEFT_DL_BUF_TARGET_DEPTH_MASK; + dss_ctl1 |= LEFT_DL_BUF_TARGET_DEPTH(dl_buffer_depth); + dss_ctl2 = I915_READ(DSS_CTL2); + dss_ctl2 &= ~RIGHT_DL_BUF_TARGET_DEPTH_MASK; + dss_ctl2 |= RIGHT_DL_BUF_TARGET_DEPTH(dl_buffer_depth); + I915_WRITE(DSS_CTL2, dss_ctl2); + } else { + /* Interleave */ + dss_ctl1 |= DUAL_LINK_MODE_INTERLEAVE; + } + + I915_WRITE(DSS_CTL1, dss_ctl1); +} + static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -591,7 +630,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder, I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp); } - //TODO: configure DSS_CTL1 + /* configure stream splitting */ + configure_dual_link_mode(encoder, pipe_config); } for_each_dsi_port(port, intel_dsi->ports) { ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 27/38] drm/i915/icl: Add DSI encoder remaining functions
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch implements compute config and enable function for Gen11 DSI encoder which is required at the time of modeset. Enable function is empty as functionality is implemented inside pre-enable function but still needed otherwise null pointer dereference during modeset. v2 by Jani: - drop the enable nop hook - fixed_mode is always true - HAS_GMCH_DISPLAY() is always false Changes looks fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 32 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index c12c7d53bcff..7a000a660c12 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1068,6 +1068,37 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder, pipe_config->port_clock = pixel_clk; } +static bool gen11_dsi_compute_config(struct intel_encoder *encoder, +struct intel_crtc_state *pipe_config, +struct drm_connector_state *conn_state) +{ + struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, + base); + struct intel_connector *intel_connector = intel_dsi->attached_connector; + struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc); + const struct drm_display_mode *fixed_mode = + intel_connector->panel.fixed_mode; + struct drm_display_mode *adjusted_mode = + _config->base.adjusted_mode; + + intel_fixed_panel_mode(fixed_mode, adjusted_mode); + intel_pch_panel_fitting(crtc, pipe_config, conn_state->scaling_mode); + + adjusted_mode->flags = 0; + + /* Dual link goes to trancoder DSI'0' */ + if (intel_dsi->ports == BIT(PORT_B)) + pipe_config->cpu_transcoder = TRANSCODER_DSI_1; + else + pipe_config->cpu_transcoder = TRANSCODER_DSI_0; + + pipe_config->clock_set = true; + + //TODO: Add check if DSI PLL calculation is done + + return true; +} + static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { @@ -1221,6 +1252,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) encoder->disable = gen11_dsi_disable; encoder->port = port; encoder->get_config = gen11_dsi_get_config; + encoder->compute_config = gen11_dsi_compute_config; encoder->get_hw_state = gen11_dsi_get_hw_state; encoder->type = INTEL_OUTPUT_DSI; encoder->cloneable = 0; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 26/38] drm/i915/icl: Add DSI connector helper functions
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch registers DSI connectors helper functions with DRM driver. v2 by Jani: - Indentation change Ok. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 5b33b7ac8e8f..c12c7d53bcff 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1128,6 +1128,12 @@ static const struct drm_connector_funcs gen11_dsi_connector_funcs = { .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; +static const struct drm_connector_helper_funcs gen11_dsi_connector_helper_funcs = { + .get_modes = intel_dsi_get_modes, + .mode_valid = intel_dsi_mode_valid, + .atomic_check = intel_digital_connector_atomic_check, +}; + static int gen11_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *dsi) { @@ -1224,6 +1230,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) /* register DSI connector with DRM subsystem */ drm_connector_init(dev, connector, _dsi_connector_funcs, DRM_MODE_CONNECTOR_DSI); + drm_connector_helper_add(connector, _dsi_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 25/38] drm/i915/icl: Add DSI connector functions
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch assigns connector functions for DSI to DRM connector structure. v2 by Jani: - use common connector destroy hook Looks OK to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 0c1f84cca16e..5b33b7ac8e8f 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -26,6 +26,7 @@ */ #include +#include #include "intel_dsi.h" static inline int header_credits_available(struct drm_i915_private *dev_priv, @@ -1117,6 +1118,14 @@ static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = { }; static const struct drm_connector_funcs gen11_dsi_connector_funcs = { + .late_register = intel_connector_register, + .early_unregister = intel_connector_unregister, + .destroy = intel_connector_destroy, + .fill_modes = drm_helper_probe_single_connector_modes, + .atomic_get_property = intel_digital_connector_atomic_get_property, + .atomic_set_property = intel_digital_connector_atomic_set_property, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; static int gen11_dsi_host_attach(struct mipi_dsi_host *host, ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 24/38] drm/i915/icl: Get HW state for DSI encoder
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch read out the current hw state for DSI and return true if encoder is active. v2 by Jani: - Squash connector get hw state hook here - Squash encode get hw state fix here Looks fine to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 42 ++ 1 file changed, 42 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 83612c444eab..0c1f84cca16e 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1067,6 +1067,46 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder, pipe_config->port_clock = pixel_clk; } +static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, + enum pipe *pipe) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + enum transcoder dsi_trans; + bool ret = false; + + if (!intel_display_power_get_if_enabled(dev_priv, + encoder->power_domain)) + return false; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans)); + switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { + case TRANS_DDI_EDP_INPUT_A_ON: + *pipe = PIPE_A; + break; + case TRANS_DDI_EDP_INPUT_B_ONOFF: + *pipe = PIPE_B; + break; + case TRANS_DDI_EDP_INPUT_C_ONOFF: + *pipe = PIPE_C; + break; + default: + DRM_ERROR("Invalid PIPE input\n"); + goto out; + } + + tmp = I915_READ(PIPECONF(dsi_trans)); + ret = tmp & PIPECONF_ENABLE; + } +out: + intel_display_power_put(dev_priv, encoder->power_domain); + return ret; +} + static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder) { intel_encoder_destroy(encoder); @@ -1166,6 +1206,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) encoder->disable = gen11_dsi_disable; encoder->port = port; encoder->get_config = gen11_dsi_get_config; + encoder->get_hw_state = gen11_dsi_get_hw_state; encoder->type = INTEL_OUTPUT_DSI; encoder->cloneable = 0; encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C); @@ -1177,6 +1218,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; + intel_connector->get_hw_state = intel_connector_get_hw_state; /* attach connector to encoder */ intel_connector_attach_encoder(intel_connector, encoder); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 22/38] drm/i915/icl: Load DSI packet payload to queue
On 10/30/2018 5:26 PM, Jani Nikula wrote: This patch adds DSI packet payload to command payload queue using credit based mechanism for *long* packets. v2 by Jani: - Add intel_dsi local variable for better code flow - Use the new credit available helper - Use int for free_credits, i, and j v2 changes are fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 57 ++ 1 file changed, 57 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index c7b77cd81e45..58774a1ac84b 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -107,6 +107,33 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) } } +static bool add_payld_to_queue(struct intel_dsi_host *host, const u8 *data, + u32 len) +{ + struct intel_dsi *intel_dsi = host->intel_dsi; + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); + int free_credits; + int i, j; + + for (i = 0; i < len; i += 4) { + u32 tmp = 0; + + free_credits = payload_credits_available(dev_priv, dsi_trans); + if (free_credits < 1) { + DRM_ERROR("Payload credit not available\n"); + return false; + } + + for (j = 0; j < min_t(u32, len - i, 4); j++) + tmp |= *data++ << 8 * j; + + I915_WRITE(DSI_CMD_TXPYLD(dsi_trans), tmp); + } + + return true; +} + static int dsi_send_pkt_hdr(struct intel_dsi_host *host, struct mipi_dsi_packet pkt, bool enable_lpdt) { @@ -145,6 +172,25 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host, return 0; } +static int dsi_send_pkt_payld(struct intel_dsi_host *host, + struct mipi_dsi_packet pkt) +{ + /* payload queue can accept *256 bytes*, check limit */ + if (pkt.payload_length > MAX_PLOAD_CREDIT * 4) { + DRM_ERROR("payload size exceeds max queue limit\n"); + return -1; + } + + /* load data into command payload queue */ + if (!add_payld_to_queue(host, pkt.payload, + pkt.payload_length)) { + DRM_ERROR("adding payload to queue failed\n"); + return -1; + } + + return 0; +} + static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -1052,6 +1098,17 @@ static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host, if (ret < 0) return ret; + /* only long packet contains payload */ + if (mipi_dsi_packet_format_is_long(msg->type)) { + ret = dsi_send_pkt_payld(intel_dsi_host, dsi_pkt); + if (ret < 0) + return ret; + } + + //TODO: add payload receive code if needed + + ret = sizeof(dsi_pkt.header) + dsi_pkt.payload_length; + return ret; } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 21/38] drm/i915/icl: Fetch DSI pkt to be transferred
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch retrieves DSI pkt (from DSI msg) to be sent over DSI link using DRM DSI exported functions. A wrapper function is also added as "DSI host transfer" for sending DSI data/cmd. v2 by Jani: - Use the new credit available helper - Use int for free_credits Changes looks fine, this also has squashing of some of the patches for sending packet header. That info can be added in "v2 details" Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 62 ++ 1 file changed, 62 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index d0c60d402dfe..c7b77cd81e45 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -107,6 +107,44 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) } } +static int dsi_send_pkt_hdr(struct intel_dsi_host *host, + struct mipi_dsi_packet pkt, bool enable_lpdt) +{ + struct intel_dsi *intel_dsi = host->intel_dsi; + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + enum transcoder dsi_trans = dsi_port_to_transcoder(host->port); + u32 tmp; + int free_credits; + + /* check if header credit available */ + free_credits = header_credits_available(dev_priv, dsi_trans); + if (free_credits < 1) { + DRM_ERROR("send pkt header failed, not enough hdr credits\n"); + return -1; + } + + tmp = I915_READ(DSI_CMD_TXHDR(dsi_trans)); + + if (pkt.payload) + tmp |= PAYLOAD_PRESENT; + else + tmp &= ~PAYLOAD_PRESENT; + + tmp &= ~VBLANK_FENCE; + + if (enable_lpdt) + tmp |= LP_DATA_TRANSFER; + + tmp &= ~(PARAM_WC_MASK | VC_MASK | DT_MASK); + tmp |= ((pkt.header[0] & VC_MASK) << VC_SHIFT); + tmp |= ((pkt.header[0] & DT_MASK) << DT_SHIFT); + tmp |= (pkt.header[1] << PARAM_WC_LOWER_SHIFT); + tmp |= (pkt.header[2] << PARAM_WC_UPPER_SHIFT); + I915_WRITE(DSI_CMD_TXHDR(dsi_trans), tmp); + + return 0; +} + static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -994,9 +1032,33 @@ static int gen11_dsi_host_detach(struct mipi_dsi_host *host, return 0; } +static ssize_t gen11_dsi_host_transfer(struct mipi_dsi_host *host, + const struct mipi_dsi_msg *msg) +{ + struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host); + struct mipi_dsi_packet dsi_pkt; + ssize_t ret; + bool enable_lpdt = false; + + ret = mipi_dsi_create_packet(_pkt, msg); + if (ret < 0) + return ret; + + if (msg->flags & MIPI_DSI_MSG_USE_LPM) + enable_lpdt = true; + + /* send packet header */ + ret = dsi_send_pkt_hdr(intel_dsi_host, dsi_pkt, enable_lpdt); + if (ret < 0) + return ret; + + return ret; +} + static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { .attach = gen11_dsi_host_attach, .detach = gen11_dsi_host_detach, + .transfer = gen11_dsi_host_transfer, }; void icl_dsi_init(struct drm_i915_private *dev_priv) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 20/38] drm/i915/icl: Add DSI packet payload/header registers
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch defines payload/header registers for each DSI transcoder used for transmitting DSI packets. v2 by Jani: - Drop full register mask and shift for payload - Use lower case for hex 0x v2 change are fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8d089ef848b2..639667d0fb00 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10523,6 +10523,28 @@ enum skl_power_gate { #define MAX_HEADER_CREDIT0x10 #define MAX_PLOAD_CREDIT 0x40 +#define _DSI_CMD_TXHDR_0 0x6b100 +#define _DSI_CMD_TXHDR_1 0x6b900 +#define DSI_CMD_TXHDR(tc) _MMIO_DSI(tc, \ + _DSI_CMD_TXHDR_0,\ + _DSI_CMD_TXHDR_1) +#define PAYLOAD_PRESENT (1 << 31) +#define LP_DATA_TRANSFER (1 << 30) +#define VBLANK_FENCE (1 << 29) +#define PARAM_WC_MASK (0x << 8) +#define PARAM_WC_LOWER_SHIFT 8 +#define PARAM_WC_UPPER_SHIFT 16 +#define VC_MASK (0x3 << 6) +#define VC_SHIFT 6 +#define DT_MASK (0x3f << 0) +#define DT_SHIFT 0 + +#define _DSI_CMD_TXPYLD_0 0x6b104 +#define _DSI_CMD_TXPYLD_1 0x6b904 +#define DSI_CMD_TXPYLD(tc) _MMIO_DSI(tc, \ + _DSI_CMD_TXPYLD_0,\ + _DSI_CMD_TXPYLD_1) + #define _DSI_LP_MSG_0 0x6b0d8 #define _DSI_LP_MSG_1 0x6b8d8 #define DSI_LP_MSG(tc)_MMIO_DSI(tc, \ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 19/38] drm/i915/icl: Allocate hosts for DSI ports
On 10/30/2018 5:26 PM, Jani Nikula wrote: This patch allocates DSI host structure for each DSI port available on gen11 and register them with DSI fwk of DRM. Some of the DSI host operations are also registered as part of this. This patch also fills MIPI config block info from VBT to local structure. v2 by Jani: - indentation Looks fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 32 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index a117ecc6c5a3..d0c60d402dfe 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -982,6 +982,23 @@ static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = { static const struct drm_connector_funcs gen11_dsi_connector_funcs = { }; +static int gen11_dsi_host_attach(struct mipi_dsi_host *host, +struct mipi_dsi_device *dsi) +{ + return 0; +} + +static int gen11_dsi_host_detach(struct mipi_dsi_host *host, +struct mipi_dsi_device *dsi) +{ + return 0; +} + +static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { + .attach = gen11_dsi_host_attach, + .detach = gen11_dsi_host_detach, +}; + void icl_dsi_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = _priv->drm; @@ -1052,6 +1069,21 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) intel_panel_init(_connector->panel, fixed_mode, NULL); intel_panel_setup_backlight(connector, INVALID_PIPE); + for_each_dsi_port(port, intel_dsi->ports) { + struct intel_dsi_host *host; + + host = intel_dsi_host_init(intel_dsi, _dsi_host_ops, port); + if (!host) + goto err; + + intel_dsi->dsi_hosts[port] = host; + } + + if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) { + DRM_DEBUG_KMS("no device found\n"); + goto err; + } + return; err: ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 18/38] drm/i915/icl: Allocate DSI encoder/connector
On 10/30/2018 5:26 PM, Jani Nikula wrote: This patch allocates memory for DSI encoder and connector which will be used for various DSI encoder/connector operations and attaching the same to DRM subsystem. This patch also extracts DSI modes info from VBT and save the desired mode info to connector. v2 by Jani: - Drop GEN11 prefix from encoder name - Drop extra parenthesis - Drop extra local variable - Squash encoder power domain here Looks good to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 96 ++ 1 file changed, 88 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 01f422df8c23..a117ecc6c5a3 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -799,10 +799,9 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) wait_for_cmds_dispatched_to_panel(encoder); } -static void __attribute__((unused)) -gen11_dsi_pre_enable(struct intel_encoder *encoder, -const struct intel_crtc_state *pipe_config, -const struct drm_connector_state *conn_state) +static void gen11_dsi_pre_enable(struct intel_encoder *encoder, +const struct intel_crtc_state *pipe_config, +const struct drm_connector_state *conn_state) { struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); @@ -945,10 +944,9 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) } } -static void __attribute__((unused)) gen11_dsi_disable( - struct intel_encoder *encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state) +static void gen11_dsi_disable(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) { struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); @@ -972,10 +970,92 @@ static void __attribute__((unused)) gen11_dsi_disable( gen11_dsi_disable_io_power(encoder); } +static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder) +{ + intel_encoder_destroy(encoder); +} + +static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = { + .destroy = gen11_dsi_encoder_destroy, +}; + +static const struct drm_connector_funcs gen11_dsi_connector_funcs = { +}; + void icl_dsi_init(struct drm_i915_private *dev_priv) { + struct drm_device *dev = _priv->drm; + struct intel_dsi *intel_dsi; + struct intel_encoder *encoder; + struct intel_connector *intel_connector; + struct drm_connector *connector; + struct drm_display_mode *scan, *fixed_mode = NULL; enum port port; if (!intel_bios_is_dsi_present(dev_priv, )) return; + + intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); + if (!intel_dsi) + return; + + intel_connector = intel_connector_alloc(); + if (!intel_connector) { + kfree(intel_dsi); + return; + } + + encoder = _dsi->base; + intel_dsi->attached_connector = intel_connector; + connector = _connector->base; + + /* register DSI encoder with DRM subsystem */ + drm_encoder_init(dev, >base, _dsi_encoder_funcs, +DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port)); + + encoder->pre_enable = gen11_dsi_pre_enable; + encoder->disable = gen11_dsi_disable; + encoder->port = port; + encoder->type = INTEL_OUTPUT_DSI; + encoder->cloneable = 0; + encoder->crtc_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C); + encoder->power_domain = POWER_DOMAIN_PORT_DSI; + + /* register DSI connector with DRM subsystem */ + drm_connector_init(dev, connector, _dsi_connector_funcs, + DRM_MODE_CONNECTOR_DSI); + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + + /* attach connector to encoder */ + intel_connector_attach_encoder(intel_connector, encoder); + + /* fill mode info from VBT */ + mutex_lock(>mode_config.mutex); + intel_dsi_vbt_get_modes(intel_dsi); + list_for_each_entry(scan, >probed_modes, head) { + if (scan->type & DRM_MODE_TYPE_PREFERRED) { + fixed_mode = drm_mode_duplicate(dev, scan); + break; + } + } + mutex_unlock(>mode_config.mutex); + + if (!fixed_mode) { + DRM_ERROR("DSI fixed mode info missing\n
Re: [Intel-gfx] [PATCH v8 17/38] drm/i915/icl: Find DSI presence for ICL
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch detects DSI presence for ICL platform by reading VBT. DSI detection is done while initializing DSI using newly added function intel_gen11_dsi_init. v2 by Jani: - Preserve old behavour of intel_bios_is_dsi_present() - s/intel_gen11_dsi_init/icl_dsi_init/g Changes looks fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 8 drivers/gpu/drm/i915/intel_bios.c| 12 ++-- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 3 +++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index fd82f349ced9..01f422df8c23 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -971,3 +971,11 @@ static void __attribute__((unused)) gen11_dsi_disable( /* step4: disable IO power */ gen11_dsi_disable_io_power(encoder); } + +void icl_dsi_init(struct drm_i915_private *dev_priv) +{ + enum port port; + + if (!intel_bios_is_dsi_present(dev_priv, )) + return; +} diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 1faa494e2bc9..5fa2133f801d 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -2039,17 +2039,17 @@ bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, dvo_port = child->dvo_port; - switch (dvo_port) { - case DVO_PORT_MIPIA: - case DVO_PORT_MIPIC: + if (dvo_port == DVO_PORT_MIPIA || + (dvo_port == DVO_PORT_MIPIB && IS_ICELAKE(dev_priv)) || + (dvo_port == DVO_PORT_MIPIC && !IS_ICELAKE(dev_priv))) { if (port) *port = dvo_port - DVO_PORT_MIPIA; return true; - case DVO_PORT_MIPIB: - case DVO_PORT_MIPID: + } else if (dvo_port == DVO_PORT_MIPIB || + dvo_port == DVO_PORT_MIPIC || + dvo_port == DVO_PORT_MIPID) { DRM_DEBUG_KMS("VBT has unsupported DSI port %c\n", port_name(dvo_port - DVO_PORT_MIPIA)); - break; } } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c3cadc09f859..1d46f06ede37 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14128,6 +14128,7 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) intel_ddi_init(dev_priv, PORT_D); intel_ddi_init(dev_priv, PORT_E); intel_ddi_init(dev_priv, PORT_F); + icl_dsi_init(dev_priv); } else if (IS_GEN9_LP(dev_priv)) { /* * FIXME: Broxton doesn't support port detection via the diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 268afb6d2746..3081cca1a151 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1854,6 +1854,9 @@ void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port); /* vlv_dsi.c */ void vlv_dsi_init(struct drm_i915_private *dev_priv); +/* icl_dsi.c */ +void icl_dsi_init(struct drm_i915_private *dev_priv); + /* intel_dsi_dcs_backlight.c */ int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 16/38] drm/i915/icl: Program HS_TX_TIMEOUT/LP_RX_TIMEOUT/TA_TIMEOUT registers
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan Program the timeout values (in escape clock) for HS TX, LP RX and TA timeout. HX TX: Ensure that host does not continuously transmit in the HS state. If this timer expires, then host will gracefully end its HS transmission and allow the link to enter into LP state. LP RX: Monitor the length of LP receptions from Peripheral. If timeout happens then host will drive the stop state onto all data lanes (only Data Lane 0 should be receiving anything from the Peripheral). This effectively takes back ownership of the bus transmit in the HS state. TA timeout: Timeout valuefor monitoring Bus Turn-Around (BTA) sequence. BTA sequence should complete within a bounded amount of time, with peripheral acknowledging BTA by driving the stop state. v2 by Jani: - Rebase - Use intel_dsi_bitrate() and intel_dsi_tlpx_ns(intel_dsi) - Squash HX TX, LP RX and TA timeout into one patch - Fix bspec mode set sequence reference - Add FIXME about two timeouts Looks fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 52 drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 1 + 3 files changed, 54 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index ac22c74ae146..fd82f349ced9 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -685,6 +685,55 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder) } } +static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + enum transcoder dsi_trans; + u32 tmp, hs_tx_timeout, lp_rx_timeout, ta_timeout, divisor, mul; + + /* +* escape clock count calculation: +* BYTE_CLK_COUNT = TIME_NS/(8 * UI) +* UI (nsec) = (10^6)/Bitrate +* TIME_NS = (BYTE_CLK_COUNT * 8 * 10^6)/ Bitrate +* ESCAPE_CLK_COUNT = TIME_NS/ESC_CLK_NS +*/ + divisor = intel_dsi_tlpx_ns(intel_dsi) * intel_dsi_bitrate(intel_dsi) * 1000; + mul = 8 * 100; + hs_tx_timeout = DIV_ROUND_UP(intel_dsi->hs_tx_timeout * mul, +divisor); + lp_rx_timeout = DIV_ROUND_UP(intel_dsi->lp_rx_timeout * mul, divisor); + ta_timeout = DIV_ROUND_UP(intel_dsi->turn_arnd_val * mul, divisor); + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + + /* program hst_tx_timeout */ + tmp = I915_READ(DSI_HSTX_TO(dsi_trans)); + tmp &= ~HSTX_TIMEOUT_VALUE_MASK; + tmp |= HSTX_TIMEOUT_VALUE(hs_tx_timeout); + I915_WRITE(DSI_HSTX_TO(dsi_trans), tmp); + + /* FIXME: DSI_CALIB_TO */ + + /* program lp_rx_host timeout */ + tmp = I915_READ(DSI_LPRX_HOST_TO(dsi_trans)); + tmp &= ~LPRX_TIMEOUT_VALUE_MASK; + tmp |= LPRX_TIMEOUT_VALUE(lp_rx_timeout); + I915_WRITE(DSI_LPRX_HOST_TO(dsi_trans), tmp); + + /* FIXME: DSI_PWAIT_TO */ + + /* program turn around timeout */ + tmp = I915_READ(DSI_TA_TO(dsi_trans)); + tmp &= ~TA_TIMEOUT_VALUE_MASK; + tmp |= TA_TIMEOUT_VALUE(ta_timeout); + I915_WRITE(DSI_TA_TO(dsi_trans), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) @@ -704,6 +753,9 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, /* setup D-PHY timings */ gen11_dsi_setup_dphy_timings(encoder); + /* step 4h: setup DSI protocol timeouts */ + gen11_dsi_setup_timeouts(encoder); + /* Step (4h, 4i, 4j, 4k): Configure transcoder */ gen11_dsi_configure_transcoder(encoder, pipe_config); } diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 10fd1582a8e2..f2a3ddedcc5d 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -95,6 +95,7 @@ struct intel_dsi { u16 lp_byte_clk; /* timeouts in byte clocks */ + u16 hs_tx_timeout; u16 lp_rx_timeout; u16 turn_arnd_val; u16 rst_timer_val; diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index cca071406c25..80bd56e96143 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -799,6 +799,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->video_mode_format = mipi_config->video_transfer_mod
Re: [Intel-gfx] [PATCH v8 15/38] drm/i915/icl: Define DSI timeout registers
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch defines DSI_HTX_TO, DSI_LRX_H_TO, DSI_PWAIT_TO and DSI_TA_TO registers for DSI transcoders '0' and '1'. They are used for contention recovery on DPHY. v2: Define SHIFT for bitfields. v3 by Jani: - Fix timeout bit definitions Ok. I was little confused with BSPEC description "HW will set this bit, SW must clear it with a write of 1b" meaning timeout will happen (reverse behavior) when bit is '0' :). Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 43 + 1 file changed, 43 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index bcee91bcfba6..8d089ef848b2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10533,6 +10533,49 @@ enum skl_power_gate { #define LINK_ULPS_TYPE_LP11 (1 << 8) #define LINK_ENTER_ULPS (1 << 0) +/* DSI timeout registers */ +#define _DSI_HSTX_TO_0 0x6b044 +#define _DSI_HSTX_TO_1 0x6b844 +#define DSI_HSTX_TO(tc)_MMIO_DSI(tc, \ + _DSI_HSTX_TO_0,\ + _DSI_HSTX_TO_1) +#define HSTX_TIMEOUT_VALUE_MASK (0x << 16) +#define HSTX_TIMEOUT_VALUE_SHIFT 16 +#define HSTX_TIMEOUT_VALUE(x) ((x) << 16) +#define HSTX_TIMED_OUT(1 << 0) + +#define _DSI_LPRX_HOST_TO_00x6b048 +#define _DSI_LPRX_HOST_TO_10x6b848 +#define DSI_LPRX_HOST_TO(tc) _MMIO_DSI(tc, \ + _DSI_LPRX_HOST_TO_0,\ + _DSI_LPRX_HOST_TO_1) +#define LPRX_TIMED_OUT(1 << 16) +#define LPRX_TIMEOUT_VALUE_MASK (0x << 0) +#define LPRX_TIMEOUT_VALUE_SHIFT 0 +#define LPRX_TIMEOUT_VALUE(x) ((x) << 0) + +#define _DSI_PWAIT_TO_00x6b040 +#define _DSI_PWAIT_TO_10x6b840 +#define DSI_PWAIT_TO(tc) _MMIO_DSI(tc, \ + _DSI_PWAIT_TO_0,\ + _DSI_PWAIT_TO_1) +#define PRESET_TIMEOUT_VALUE_MASK (0x << 16) +#define PRESET_TIMEOUT_VALUE_SHIFT16 +#define PRESET_TIMEOUT_VALUE(x) ((x) << 16) +#define PRESPONSE_TIMEOUT_VALUE_MASK (0x << 0) +#define PRESPONSE_TIMEOUT_VALUE_SHIFT 0 +#define PRESPONSE_TIMEOUT_VALUE(x)((x) << 0) + +#define _DSI_TA_TO_0 0x6b04c +#define _DSI_TA_TO_1 0x6b84c +#define DSI_TA_TO(tc) _MMIO_DSI(tc, \ + _DSI_TA_TO_0,\ + _DSI_TA_TO_1) +#define TA_TIMED_OUT (1 << 16) +#define TA_TIMEOUT_VALUE_MASK (0x << 0) +#define TA_TIMEOUT_VALUE_SHIFT0 +#define TA_TIMEOUT_VALUE(x) ((x) << 0) + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb884) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 08/38] drm/i915/icl: Disable DSI transcoders
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch disables transcoders by writing to TRANS_CONF registers for each DSI ports. v2 by Jani: - Wait for pipeconf active to go low Thanks for catching this, it has to be low. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 26 ++ 1 file changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index f7f48ff147d0..644ad7475920 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -777,6 +777,29 @@ gen11_dsi_pre_enable(struct intel_encoder *encoder, intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); } +static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + enum transcoder dsi_trans; + u32 tmp; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + + /* disable transcoder */ + tmp = I915_READ(PIPECONF(dsi_trans)); + tmp &= ~PIPECONF_ENABLE; + I915_WRITE(PIPECONF(dsi_trans), tmp); + + /* wait for transcoder to be disabled */ + if (intel_wait_for_register(dev_priv, PIPECONF(dsi_trans), + I965_PIPECONF_ACTIVE, 0, 50)) + DRM_ERROR("DSI trancoder not disabled\n"); + } +} + static void __attribute__((unused)) gen11_dsi_disable( struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state, @@ -787,4 +810,7 @@ static void __attribute__((unused)) gen11_dsi_disable( /* step1: turn off backlight */ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); intel_panel_disable_backlight(old_conn_state); + + /* step2d,e: disable transcoder and wait */ + gen11_dsi_disable_transcoder(encoder); } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 05/38] drm/i915/icl: Wait for header/payload credits release
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan Driver needs payload/header credits for sending any command and data over DSI link. These credits are released once command or data sent to link. This patch adds functions to wait for releasing of payload and header credits. As per BSPEC, driver needs to ensure that all of commands/data has been dispatched to panel before the transcoder is enabled. This patch implement those steps i.e. sending NOP DCS command, wait for header/payload credit to be released etc. v2 by Jani: - squash the credit wait helpers patch with the first user - pass dev_priv to the credit wait helpers - bikeshed credit helper names - wait for *at least* the current maximum number of credits - indentation fix - add helpers for credits available This is good optimization, thanks. Looks good. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 74 ++ 1 file changed, 74 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index d9c91001f107..0f0447b6b1be 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -28,6 +28,36 @@ #include #include "intel_dsi.h" +static inline int header_credits_available(struct drm_i915_private *dev_priv, + enum transcoder dsi_trans) +{ + return (I915_READ(DSI_CMD_TXCTL(dsi_trans)) & FREE_HEADER_CREDIT_MASK) + >> FREE_HEADER_CREDIT_SHIFT; +} + +static inline int payload_credits_available(struct drm_i915_private *dev_priv, + enum transcoder dsi_trans) +{ + return (I915_READ(DSI_CMD_TXCTL(dsi_trans)) & FREE_PLOAD_CREDIT_MASK) + >> FREE_PLOAD_CREDIT_SHIFT; +} + +static void wait_for_header_credits(struct drm_i915_private *dev_priv, + enum transcoder dsi_trans) +{ + if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >= + MAX_HEADER_CREDIT, 100)) + DRM_ERROR("DSI header credits not released\n"); +} + +static void wait_for_payload_credits(struct drm_i915_private *dev_priv, +enum transcoder dsi_trans) +{ + if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >= + MAX_PLOAD_CREDIT, 100)) + DRM_ERROR("DSI payload credits not released\n"); +} + static enum transcoder dsi_port_to_transcoder(enum port port) { if (port == PORT_A) @@ -36,6 +66,47 @@ static enum transcoder dsi_port_to_transcoder(enum port port) return TRANSCODER_DSI_1; } +static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + struct mipi_dsi_device *dsi; + enum port port; + enum transcoder dsi_trans; + int ret; + + /* wait for header/payload credits to be released */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + wait_for_header_credits(dev_priv, dsi_trans); + wait_for_payload_credits(dev_priv, dsi_trans); + } + + /* send nop DCS command */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi = intel_dsi->dsi_hosts[port]->device; + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + dsi->channel = 0; + ret = mipi_dsi_dcs_nop(dsi); + if (ret < 0) + DRM_ERROR("error sending DCS NOP command\n"); + } + + /* wait for header credits to be released */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + wait_for_header_credits(dev_priv, dsi_trans); + } + + /* wait for LP TX in progress bit to be cleared */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + if (wait_for_us(!(I915_READ(DSI_LP_MSG(dsi_trans)) & + LPTX_IN_PROGRESS), 20)) + DRM_ERROR("LPTX bit not cleared\n"); + } +} + static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -671,6 +742,9 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); + + /* ensure all panel comman
Re: [Intel-gfx] [PATCH v8 03/38] drm/i915/icl: Set max return packet size for DSI panel
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan This patch programs maximum size of the payload transmitted from peripheral back to the host processor using short packet as a part of panel programming. v2: Rebase v3 by Jani: - Add FIXME note. Looks OK to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 33 + 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 216a1753d246..9c424adc8b75 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -25,6 +25,7 @@ * Jani Nikula */ +#include #include "intel_dsi.h" static enum transcoder dsi_port_to_transcoder(enum port port) @@ -636,6 +637,35 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, gen11_dsi_configure_transcoder(encoder, pipe_config); } +static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + struct mipi_dsi_device *dsi; + enum port port; + enum transcoder dsi_trans; + u32 tmp; + int ret; + + /* set maximum return packet size */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + + /* +* FIXME: This uses the number of DW's currently in the payload +* receive queue. This is probably not what we want here. +*/ + tmp = I915_READ(DSI_CMD_RXCTL(dsi_trans)); + tmp &= NUMBER_RX_PLOAD_DW_MASK; + /* multiply "Number Rx Payload DW" by 4 to get max value */ + tmp = tmp * 4; + dsi = intel_dsi->dsi_hosts[port]->device; + ret = mipi_dsi_set_maximum_return_packet_size(dsi, tmp); + if (ret < 0) + DRM_ERROR("error setting max return pkt size%d\n", tmp); + } +} + static void __attribute__((unused)) gen11_dsi_pre_enable(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, @@ -650,6 +680,9 @@ gen11_dsi_pre_enable(struct intel_encoder *encoder, /* step4: enable DSI port and DPHY */ gen11_dsi_enable_port_and_phy(encoder, pipe_config); + /* step5: program and powerup panel */ + gen11_dsi_powerup_panel(encoder); + /* step6c: configure transcoder timings */ gen11_dsi_set_transcoder_timings(encoder, pipe_config); ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v8 02/38] drm/i915/dsi: move connector mode functions to common file
On 10/30/2018 5:26 PM, Jani Nikula wrote: From: Madhav Chauhan Move DSI connector functions to intel_dsi.c and make them available to both legacy and ICL DSI. v2 by Jani: - Move the functions to intel_dsi.c - Don't reuse intel_dsi_connector_destroy() Patch 1 & 2 v2 changes, i.e. code movement to intel_dsi.c looks fine to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 47 +++ drivers/gpu/drm/i915/intel_dsi.h | 3 +++ drivers/gpu/drm/i915/vlv_dsi.c | 48 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 97e04c272612..b9d5ef79015e 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -29,6 +29,53 @@ int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi) } } +int intel_dsi_get_modes(struct drm_connector *connector) +{ + struct intel_connector *intel_connector = to_intel_connector(connector); + struct drm_display_mode *mode; + + DRM_DEBUG_KMS("\n"); + + if (!intel_connector->panel.fixed_mode) { + DRM_DEBUG_KMS("no fixed mode\n"); + return 0; + } + + mode = drm_mode_duplicate(connector->dev, + intel_connector->panel.fixed_mode); + if (!mode) { + DRM_DEBUG_KMS("drm_mode_duplicate failed\n"); + return 0; + } + + drm_mode_probed_add(connector, mode); + return 1; +} + +enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct intel_connector *intel_connector = to_intel_connector(connector); + const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; + int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; + + DRM_DEBUG_KMS("\n"); + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + if (fixed_mode) { + if (mode->hdisplay > fixed_mode->hdisplay) + return MODE_PANEL; + if (mode->vdisplay > fixed_mode->vdisplay) + return MODE_PANEL; + if (fixed_mode->clock > max_dotclk) + return MODE_CLOCK_HIGH; + } + + return MODE_OK; +} + struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, const struct mipi_dsi_host_ops *funcs, enum port port) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 09f0fa9ccc7d..10fd1582a8e2 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -152,6 +152,9 @@ int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi); /* vlv_dsi.c */ void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port); enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt); +int intel_dsi_get_modes(struct drm_connector *connector); +enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode); struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, const struct mipi_dsi_host_ops *funcs, enum port port); diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index cbb935a9acf3..bab87b62bc2d 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -1212,31 +1212,6 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, } } -static enum drm_mode_status -intel_dsi_mode_valid(struct drm_connector *connector, -struct drm_display_mode *mode) -{ - struct intel_connector *intel_connector = to_intel_connector(connector); - const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; - int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; - - DRM_DEBUG_KMS("\n"); - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (fixed_mode) { - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; - if (fixed_mode->clock > max_dotclk) - return MODE_CLOCK_HIGH; - } - - return MODE_OK; -} - /* return txclkesc cycles in terms of divider and duration in us *
Re: [Intel-gfx] [PATCH v7 17/23] drm/i915/icl: Enable DSI transcoders
On 10/15/2018 7:58 PM, Jani Nikula wrote: From: Madhav Chauhan This patch enables DSI transcoders by writing to TRANS_CONF registers and wait for its state to be enabled. v2 by Jani: - Rebase Patch *17-23* changes like rebase, alignment, comments style changes looks good to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index f6ed57b28676..216a1753d246 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -591,6 +591,28 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, } } +static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + enum transcoder dsi_trans; + u32 tmp; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(PIPECONF(dsi_trans)); + tmp |= PIPECONF_ENABLE; + I915_WRITE(PIPECONF(dsi_trans), tmp); + + /* wait for transcoder to be enabled */ + if (intel_wait_for_register(dev_priv, PIPECONF(dsi_trans), + I965_PIPECONF_ACTIVE, + I965_PIPECONF_ACTIVE, 10)) + DRM_ERROR("DSI transcoder not enabled\n"); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) @@ -630,4 +652,7 @@ gen11_dsi_pre_enable(struct intel_encoder *encoder, /* step6c: configure transcoder timings */ gen11_dsi_set_transcoder_timings(encoder, pipe_config); + + /* step6d: enable dsi transcoder */ + gen11_dsi_enable_transcoder(encoder); } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 16/23] drm/i915/icl: Define TRANS_CONF register for DSI
On 10/15/2018 7:58 PM, Jani Nikula wrote: From: Madhav Chauhan This patch defines TRANS_CONF registers for DSI ports 0 and 1. Bitfields of these registers used for enabling and reading the current state of transcoder. v2: Add blank line before comment v3 by Jani: - Move DSI specific .pipe_offsets to GEN11_FEATURES - Macro placement and comment juggling Changes looks ok. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_pci.c | 3 +++ drivers/gpu/drm/i915/i915_reg.h | 8 2 files changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index b86b735a8634..44e745921ac1 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -595,6 +595,9 @@ static const struct intel_device_info intel_cannonlake_info = { #define GEN11_FEATURES \ GEN10_FEATURES, \ + .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ + PIPE_C_OFFSET, PIPE_EDP_OFFSET, \ + PIPE_DSI0_OFFSET, PIPE_DSI1_OFFSET }, \ .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET, \ TRANSCODER_DSI0_OFFSET, TRANSCODER_DSI1_OFFSET}, \ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c4270ca26a11..839e681bd3a4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5652,6 +5652,10 @@ enum { */ #define PIPE_EDP_OFFSET 0x7f000 +/* ICL DSI 0 and 1 */ +#define PIPE_DSI0_OFFSET 0x7b000 +#define PIPE_DSI1_OFFSET 0x7b800 + #define _MMIO_PIPE2(pipe, reg) _MMIO(dev_priv->info.pipe_offsets[pipe] - \ dev_priv->info.pipe_offsets[PIPE_A] + (reg) + \ dev_priv->info.display_mmio_offset) @@ -6240,6 +6244,10 @@ enum { #define _DSPBOFFSET (dev_priv->info.display_mmio_offset + 0x711A4) #define _DSPBSURFLIVE (dev_priv->info.display_mmio_offset + 0x711AC) +/* ICL DSI 0 and 1 */ +#define _PIPEDSI0CONF 0x7b008 +#define _PIPEDSI1CONF 0x7b808 + /* Sprite A control */ #define _DVSACNTR 0x72180 #define DVS_ENABLE (1 << 31) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 15/23] drm/i915/icl: Configure DSI transcoder timings
On 10/15/2018 7:58 PM, Jani Nikula wrote: From: Madhav Chauhan As part of DSI enable sequence, transcoder timings (horizontal & vertical) need to be set so that transcoder will generate the stream output as per those timings. This patch set required transcoder timings as per BSPEC. v2: Remove TRANS_TIMING_SHIFT usage v3 by Jani: - Rebase - Reduce temp variable use - Checkpatch fix v3 changes are fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 118 + 1 file changed, 118 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 87d5e6435791..f6ed57b28676 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -477,6 +477,121 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder, } static void +gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, +const 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(>base); + const struct drm_display_mode *adjusted_mode = + _config->base.adjusted_mode; + enum port port; + enum transcoder dsi_trans; + /* horizontal timings */ + u16 htotal, hactive, hsync_start, hsync_end, hsync_size; + u16 hfront_porch, hback_porch; + /* vertical timings */ + u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift; + + hactive = adjusted_mode->crtc_hdisplay; + htotal = adjusted_mode->crtc_htotal; + hsync_start = adjusted_mode->crtc_hsync_start; + hsync_end = adjusted_mode->crtc_hsync_end; + hsync_size = hsync_end - hsync_start; + hfront_porch = (adjusted_mode->crtc_hsync_start - + adjusted_mode->crtc_hdisplay); + hback_porch = (adjusted_mode->crtc_htotal - + adjusted_mode->crtc_hsync_end); + vactive = adjusted_mode->crtc_vdisplay; + vtotal = adjusted_mode->crtc_vtotal; + vsync_start = adjusted_mode->crtc_vsync_start; + vsync_end = adjusted_mode->crtc_vsync_end; + vsync_shift = hsync_start - htotal / 2; + + if (intel_dsi->dual_link) { + hactive /= 2; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) + hactive += intel_dsi->pixel_overlap; + htotal /= 2; + } + + /* minimum hactive as per bspec: 256 pixels */ + if (adjusted_mode->crtc_hdisplay < 256) + DRM_ERROR("hactive is less then 256 pixels\n"); + + /* if RGB666 format, then hactive must be multiple of 4 pixels */ + if (intel_dsi->pixel_format == MIPI_DSI_FMT_RGB666 && hactive % 4 != 0) + DRM_ERROR("hactive pixels are not multiple of 4\n"); + + /* program TRANS_HTOTAL register */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + I915_WRITE(HTOTAL(dsi_trans), + (hactive - 1) | ((htotal - 1) << 16)); + } + + /* TRANS_HSYNC register to be programmed only for video mode */ + if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { + if (intel_dsi->video_mode_format == + VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) { + /* BSPEC: hsync size should be atleast 16 pixels */ + if (hsync_size < 16) + DRM_ERROR("hsync size < 16 pixels\n"); + } + + if (hback_porch < 16) + DRM_ERROR("hback porch < 16 pixels\n"); + + if (intel_dsi->dual_link) { + hsync_start /= 2; + hsync_end /= 2; + } + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + I915_WRITE(HSYNC(dsi_trans), + (hsync_start - 1) | ((hsync_end - 1) << 16)); + } + } + + /* program TRANS_VTOTAL register */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + /* +* FIXME: Programing this by assuming progressive mode, since +* non-interlaced info from VBT is not saved inside +* struct drm_display_mode. +* For interlace mode: program required pixel minus 2 +*/ + I915_WRITE(VTOTAL(dsi_trans), + (vactive - 1) | ((vtotal - 1) << 16)); + } + + if (vs
Re: [Intel-gfx] [PATCH v7 14/23] drm/i915/icl: Define DSI transcoder timing registers
On 10/15/2018 7:58 PM, Jani Nikula wrote: From: Madhav Chauhan This patch defines registers and bitfields used for programming DSI transcoder's horizontal and vertical timings. v2: Remove TRANS_TIMING_SHIFT definition v3 by Jani: - Group macros by transcoder Separation of DSI0 and DSI 1 specific registers are fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 79e633c1e9ad..c4270ca26a11 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4061,6 +4061,20 @@ enum { #define _VSYNCSHIFT_B 0x61028 #define _PIPE_MULT_B 0x6102c +/* DSI 0 timing regs */ +#define _HTOTAL_DSI0 0x6b000 +#define _HSYNC_DSI00x6b008 +#define _VTOTAL_DSI0 0x6b00c +#define _VSYNC_DSI00x6b014 +#define _VSYNCSHIFT_DSI0 0x6b028 + +/* DSI 1 timing regs */ +#define _HTOTAL_DSI1 0x6b800 +#define _HSYNC_DSI10x6b808 +#define _VTOTAL_DSI1 0x6b80c +#define _VSYNC_DSI10x6b814 +#define _VSYNCSHIFT_DSI1 0x6b828 + #define TRANSCODER_A_OFFSET 0x6 #define TRANSCODER_B_OFFSET 0x61000 #define TRANSCODER_C_OFFSET 0x62000 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 13/23] drm/i915/icl: Program TRANS_DDI_FUNC_CTL registers
On 10/15/2018 7:58 PM, Jani Nikula wrote: From: Madhav Chauhan This patch select input PIPE for DSI, data lanes width, enable port sync mode and wait for DSI link to become ready. v2 by Jani: - Use MISSING_CASE with fallthrough instead of DRM_ERROR - minor stylistic changes v2 changes are good. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 64 +++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 756c75d0c86c..87d5e6435791 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -340,10 +340,14 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) } } -static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder) +static void +gen11_dsi_configure_transcoder(struct intel_encoder *encoder, + const 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(>base); + struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); + enum pipe pipe = intel_crtc->pipe; u32 tmp; enum port port; enum transcoder dsi_trans; @@ -420,9 +424,61 @@ static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder) I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp); } + + /* enable port sync mode if dual link */ + if (intel_dsi->dual_link) { + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(TRANS_DDI_FUNC_CTL2(dsi_trans)); + tmp |= PORT_SYNC_MODE_ENABLE; + I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp); + } + + //TODO: configure DSS_CTL1 + } + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + + /* select data lane width */ + tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans)); + tmp &= ~DDI_PORT_WIDTH_MASK; + tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count); + + /* select input pipe */ + tmp &= ~TRANS_DDI_EDP_INPUT_MASK; + switch (pipe) { + default: + MISSING_CASE(pipe); + /* fallthrough */ + case PIPE_A: + tmp |= TRANS_DDI_EDP_INPUT_A_ON; + break; + case PIPE_B: + tmp |= TRANS_DDI_EDP_INPUT_B_ONOFF; + break; + case PIPE_C: + tmp |= TRANS_DDI_EDP_INPUT_C_ONOFF; + break; + } + + /* enable DDI buffer */ + tmp |= TRANS_DDI_FUNC_ENABLE; + I915_WRITE(TRANS_DDI_FUNC_CTL(dsi_trans), tmp); + } + + /* wait for link ready */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + if (wait_for_us((I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)) & + LINK_READY), 2500)) + DRM_ERROR("DSI link not ready\n"); + } } -static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) +static void +gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config) { /* step 4a: power up all lanes of the DDI used by DSI */ gen11_dsi_power_up_lanes(encoder); @@ -440,7 +496,7 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) gen11_dsi_setup_dphy_timings(encoder); /* Step (4h, 4i, 4j, 4k): Configure transcoder */ - gen11_dsi_configure_transcoder(encoder); + gen11_dsi_configure_transcoder(encoder, pipe_config); } static void __attribute__((unused)) @@ -455,5 +511,5 @@ gen11_dsi_pre_enable(struct intel_encoder *encoder, gen11_dsi_program_esc_clk_div(encoder); /* step4: enable DSI port and DPHY */ - gen11_dsi_enable_port_and_phy(encoder); + gen11_dsi_enable_port_and_phy(encoder, pipe_config); } ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 12/23] drm/i915/icl: Define TRANS_DDI_FUNC_CTL DSI registers
On 10/15/2018 7:58 PM, Jani Nikula wrote: From: Madhav Chauhan This patch defines TRANS_DDI_FUNC_CTL and TRANS_DDI_FUNC_CTL2 registers and their bitfields for DSI. These registers are used for enabling port sync mode, input pipe select, data lane width configuration etc. v2: Changes: - Remove redundant extra line - Correct some of bitfield definition v3 by Jani: - Move DSI transcoder offsets to GEN11_FEATURES v3 changes looks fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_pci.c | 3 +++ drivers/gpu/drm/i915/i915_reg.h | 17 + 2 files changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 0a05cc7ace14..b86b735a8634 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -595,6 +595,9 @@ static const struct intel_device_info intel_cannonlake_info = { #define GEN11_FEATURES \ GEN10_FEATURES, \ + .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ + TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET, \ + TRANSCODER_DSI0_OFFSET, TRANSCODER_DSI1_OFFSET}, \ GEN(11), \ .ddb_size = 2048, \ .has_logical_ring_elsq = 1 diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b065e4ca0b45..79e633c1e9ad 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4066,6 +4066,8 @@ enum { #define TRANSCODER_C_OFFSET 0x62000 #define CHV_TRANSCODER_C_OFFSET 0x63000 #define TRANSCODER_EDP_OFFSET 0x6f000 +#define TRANSCODER_DSI0_OFFSET 0x6b000 +#define TRANSCODER_DSI1_OFFSET 0x6b800 #define _MMIO_TRANS2(pipe, reg) _MMIO(dev_priv->info.trans_offsets[(pipe)] - \ dev_priv->info.trans_offsets[TRANSCODER_A] + (reg) + \ @@ -9021,6 +9023,8 @@ enum skl_power_gate { #define _TRANS_DDI_FUNC_CTL_B 0x61400 #define _TRANS_DDI_FUNC_CTL_C 0x62400 #define _TRANS_DDI_FUNC_CTL_EDP 0x6F400 +#define _TRANS_DDI_FUNC_CTL_DSI0 0x6b400 +#define _TRANS_DDI_FUNC_CTL_DSI1 0x6bc00 #define TRANS_DDI_FUNC_CTL(tran) _MMIO_TRANS2(tran, _TRANS_DDI_FUNC_CTL_A) #define TRANS_DDI_FUNC_ENABLE (1 << 31) @@ -9058,6 +9062,19 @@ enum skl_power_gate { | TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ \ | TRANS_DDI_HDMI_SCRAMBLING) +#define _TRANS_DDI_FUNC_CTL2_A 0x60404 +#define _TRANS_DDI_FUNC_CTL2_B 0x61404 +#define _TRANS_DDI_FUNC_CTL2_C 0x62404 +#define _TRANS_DDI_FUNC_CTL2_EDP 0x6f404 +#define _TRANS_DDI_FUNC_CTL2_DSI0 0x6b404 +#define _TRANS_DDI_FUNC_CTL2_DSI1 0x6bc04 +#define TRANS_DDI_FUNC_CTL2(tran) _MMIO_TRANS2(tran, \ +_TRANS_DDI_FUNC_CTL2_A) +#define PORT_SYNC_MODE_ENABLE (1 << 4) +#define PORT_SYNC_MODE_MASTER_SELECT(x) ((x) < 0) +#define PORT_SYNC_MODE_MASTER_SELECT_MASK (0x7 << 0) +#define PORT_SYNC_MODE_MASTER_SELECT_SHIFT0 + /* DisplayPort Transport Control */ #define _DP_TP_CTL_A 0x64040 #define _DP_TP_CTL_B 0x64140 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 11/23] drm/i915/icl: Configure DSI transcoders
On 10/15/2018 7:57 PM, Jani Nikula wrote: From: Madhav Chauhan This patch programs DSI operation mode, pixel format, BGR info, link calibration etc for the DSI transcoder. This patch also extract BGR info of the DSI panel from VBT and save it inside struct intel_dsi which used for configuring DSI transcoder. v2: Rebase v3: Use newly defined bitfields. v4 by Jani: - Use intel_dsi_bitrate() - Make bgr_enabled bool - Use 0 instead of 0x0 - Replace DRM_ERROR() with MISSING_CASE() on pixel format and video mode - Use is_vid_mode() v4 changes are fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 87 +++- drivers/gpu/drm/i915/intel_dsi.h | 3 ++ drivers/gpu/drm/i915/intel_dsi_vbt.c | 1 + 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 407c3065d08d..756c75d0c86c 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,7 +27,7 @@ #include "intel_dsi.h" -static enum transcoder __attribute__((unused)) dsi_port_to_transcoder(enum port port) +static enum transcoder dsi_port_to_transcoder(enum port port) { if (port == PORT_A) return TRANSCODER_DSI_0; @@ -340,6 +340,88 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) } } +static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + enum transcoder dsi_trans; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)); + + if (intel_dsi->eotp_pkt) + tmp &= ~EOTP_DISABLED; + else + tmp |= EOTP_DISABLED; + + /* enable link calibration if freq > 1.5Gbps */ + if (intel_dsi_bitrate(intel_dsi) >= 1500 * 1000) { + tmp &= ~LINK_CALIBRATION_MASK; + tmp |= CALIBRATION_ENABLED_INITIAL_ONLY; + } + + /* configure continuous clock */ + tmp &= ~CONTINUOUS_CLK_MASK; + if (intel_dsi->clock_stop) + tmp |= CLK_ENTER_LP_AFTER_DATA; + else + tmp |= CLK_HS_CONTINUOUS; + + /* configure buffer threshold limit to minimum */ + tmp &= ~PIX_BUF_THRESHOLD_MASK; + tmp |= PIX_BUF_THRESHOLD_1_4; + + /* set virtual channel to '0' */ + tmp &= ~PIX_VIRT_CHAN_MASK; + tmp |= PIX_VIRT_CHAN(0); + + /* program BGR transmission */ + if (intel_dsi->bgr_enabled) + tmp |= BGR_TRANSMISSION; + + /* select pixel format */ + tmp &= ~PIX_FMT_MASK; + switch (intel_dsi->pixel_format) { + default: + MISSING_CASE(intel_dsi->pixel_format); + /* fallthrough */ + case MIPI_DSI_FMT_RGB565: + tmp |= PIX_FMT_RGB565; + break; + case MIPI_DSI_FMT_RGB666_PACKED: + tmp |= PIX_FMT_RGB666_PACKED; + break; + case MIPI_DSI_FMT_RGB666: + tmp |= PIX_FMT_RGB666_LOOSE; + break; + case MIPI_DSI_FMT_RGB888: + tmp |= PIX_FMT_RGB888; + break; + } + + /* program DSI operation mode */ + if (is_vid_mode(intel_dsi)) { + tmp &= ~OP_MODE_MASK; + switch (intel_dsi->video_mode_format) { + default: + MISSING_CASE(intel_dsi->video_mode_format); + /* fallthrough */ + case VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS: + tmp |= VIDEO_MODE_SYNC_EVENT; + break; + case VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE: + tmp |= VIDEO_MODE_SYNC_PULSE; + break; + } + } + + I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -356,6 +438,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder)
Re: [Intel-gfx] [PATCH v7 10/23] drm/i915/icl: Define TRANS_DSI_FUNC_CONF register
On 10/15/2018 7:57 PM, Jani Nikula wrote: From: Madhav Chauhan This patch defines transcoder function configuration registers and its bitfields for both DSI ports. Used while programming/enabling DSI transcoder. v2: Changes (Jani N) - Define _SHIFT and _MASK for bitfields - Define values for fields already shifted in place v3 by Jani: - Fix _SHIFT fields copy-pasted from _MASK - Indentation fixes - Reduce S3D orientation to single macro - Wrap a macro parameter in parens v3 changes looks fine. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 45 + 1 file changed, 45 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 436ff68b6b18..b065e4ca0b45 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10379,6 +10379,51 @@ enum skl_power_gate { #define TA_GET_MASK (0xf << 0) #define TA_GET_SHIFT 0 +/* DSI transcoder configuration */ +#define _DSI_TRANS_FUNC_CONF_0 0x6b030 +#define _DSI_TRANS_FUNC_CONF_1 0x6b830 +#define DSI_TRANS_FUNC_CONF(tc)_MMIO_DSI(tc, \ + _DSI_TRANS_FUNC_CONF_0,\ + _DSI_TRANS_FUNC_CONF_1) +#define OP_MODE_MASK (0x3 << 28) +#define OP_MODE_SHIFT 28 +#define CMD_MODE_NO_GATE (0x0 << 28) +#define CMD_MODE_TE_GATE (0x1 << 28) +#define VIDEO_MODE_SYNC_EVENT (0x2 << 28) +#define VIDEO_MODE_SYNC_PULSE (0x3 << 28) +#define LINK_READY(1 << 20) +#define PIX_FMT_MASK (0x3 << 16) +#define PIX_FMT_SHIFT 16 +#define PIX_FMT_RGB565(0x0 << 16) +#define PIX_FMT_RGB666_PACKED (0x1 << 16) +#define PIX_FMT_RGB666_LOOSE (0x2 << 16) +#define PIX_FMT_RGB888(0x3 << 16) +#define PIX_FMT_RGB101010 (0x4 << 16) +#define PIX_FMT_RGB121212 (0x5 << 16) +#define PIX_FMT_COMPRESSED(0x6 << 16) +#define BGR_TRANSMISSION (1 << 15) +#define PIX_VIRT_CHAN(x) ((x) << 12) +#define PIX_VIRT_CHAN_MASK(0x3 << 12) +#define PIX_VIRT_CHAN_SHIFT 12 +#define PIX_BUF_THRESHOLD_MASK(0x3 << 10) +#define PIX_BUF_THRESHOLD_SHIFT 10 +#define PIX_BUF_THRESHOLD_1_4 (0x0 << 10) +#define PIX_BUF_THRESHOLD_1_2 (0x1 << 10) +#define PIX_BUF_THRESHOLD_3_4 (0x2 << 10) +#define PIX_BUF_THRESHOLD_FULL(0x3 << 10) +#define CONTINUOUS_CLK_MASK (0x3 << 8) +#define CONTINUOUS_CLK_SHIFT 8 +#define CLK_ENTER_LP_AFTER_DATA (0x0 << 8) +#define CLK_HS_OR_LP (0x2 << 8) +#define CLK_HS_CONTINUOUS (0x3 << 8) +#define LINK_CALIBRATION_MASK (0x3 << 4) +#define LINK_CALIBRATION_SHIFT4 +#define CALIBRATION_DISABLED (0x0 << 4) +#define CALIBRATION_ENABLED_INITIAL_ONLY (0x2 << 4) +#define CALIBRATION_ENABLED_INITIAL_PERIODIC (0x3 << 4) +#define S3D_ORIENTATION_LANDSCAPE (1 << 1) +#define EOTP_DISABLED (1 << 0) + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb884) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 07/23] drm/i915/icl: Program TA_TIMING_PARAM registers
On 10/15/2018 7:57 PM, Jani Nikula wrote: From: Madhav Chauhan This patch programs D-PHY timing parameters for the bus turn around flow(in escape clocks) only if dsi link frequency <=800 MHz using DPHY_TA_TIMING_PARAM and its identical register DSI_TA_TIMING_PARAM (inside DSI Controller within the Display Core). v2: Changes - Don't use KHz() macro (Ville/Jani N) - Use newly defined bitfields v3 by Jani: - Use intel_dsi_bitrate() in favor of a new field - Remove redundant parens v3 changes looks fine to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 21 + 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 9602b6532028..f9df3a7fa66b 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -309,6 +309,27 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) I915_WRITE(DSI_DATA_TIMING_PARAM(port), intel_dsi->dphy_data_lane_reg); } + + /* +* If DSI link operating at or below an 800 MHz, +* TA_SURE should be override and programmed to +* a value '0' inside TA_PARAM_REGISTERS otherwise +* leave all fields at HW default values. +*/ + if (intel_dsi_bitrate(intel_dsi) <= 80) { + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(DPHY_TA_TIMING_PARAM(port)); + tmp &= ~TA_SURE_MASK; + tmp |= TA_SURE_OVERRIDE | TA_SURE(0); + I915_WRITE(DPHY_TA_TIMING_PARAM(port), tmp); + + /* shadow register inside display core */ + tmp = I915_READ(DSI_TA_TIMING_PARAM(port)); + tmp &= ~TA_SURE_MASK; + tmp |= TA_SURE_OVERRIDE | TA_SURE(0); + I915_WRITE(DSI_TA_TIMING_PARAM(port), tmp); + } + } } static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 06/23] drm/i915/icl: Program DSI clock and data lane timing params
On 10/15/2018 7:57 PM, Jani Nikula wrote: From: Madhav Chauhan This patch programs D-PHY timing parameters for the clock and data lane (in escape clocks) of DSI controller (DSI port 0 and 1). These programmed timings would be used by DSI Controller to calculate link transition latencies of the data and clock lanes. v2: Use newly defined bitfields for data and clock lane v3 by Jani: - Rebase on dphy abstraction - Reduce local variables - Remove unrelated comment changes (Ville) - Use the same style for range checks as VLV (Ville) - Assign, don't OR dphy_reg contents v3 changes looks fine to me. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 18 ++ drivers/gpu/drm/i915/intel_dsi.h | 3 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 110 ++- 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index ff5b285ca495..9602b6532028 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -291,6 +291,24 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) tmp |= intel_dsi->init_count; I915_WRITE(ICL_DSI_T_INIT_MASTER(port), tmp); } + + /* Program DPHY clock lanes timings */ + for_each_dsi_port(port, intel_dsi->ports) { + I915_WRITE(DPHY_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg); + + /* shadow register inside display core */ + I915_WRITE(DSI_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg); + } + + /* Program DPHY data lanes timings */ + for_each_dsi_port(port, intel_dsi->ports) { + I915_WRITE(DPHY_DATA_TIMING_PARAM(port), + intel_dsi->dphy_data_lane_reg); + + /* shadow register inside display core */ + I915_WRITE(DSI_DATA_TIMING_PARAM(port), + intel_dsi->dphy_data_lane_reg); + } } static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index d7c0c599b52d..12b758ebefce 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -85,6 +85,9 @@ struct intel_dsi { u32 port_bits; u32 bw_timer; u32 dphy_reg; + + /* data lanes dphy timing */ + u32 dphy_data_lane_reg; u32 video_frmt_cfg_bits; u16 lp_byte_clk; diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 5e16b4c5f531..3035422aa0d6 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -510,6 +510,111 @@ int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi) return 1; } +#define ICL_PREPARE_CNT_MAX 0x7 +#define ICL_CLK_ZERO_CNT_MAX 0xf +#define ICL_TRAIL_CNT_MAX 0x7 +#define ICL_TCLK_PRE_CNT_MAX 0x3 +#define ICL_TCLK_POST_CNT_MAX 0x7 +#define ICL_HS_ZERO_CNT_MAX0xf +#define ICL_EXIT_ZERO_CNT_MAX 0x7 + +static void icl_dphy_param_init(struct intel_dsi *intel_dsi) +{ + struct drm_device *dev = intel_dsi->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; + u32 tlpx_ns; + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; + u32 ths_prepare_ns, tclk_trail_ns; + u32 hs_zero_cnt; + u32 tclk_pre_cnt, tclk_post_cnt; + + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); + + tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); + ths_prepare_ns = max(mipi_config->ths_prepare, +mipi_config->tclk_prepare); + + /* +* prepare cnt in escape clocks +* this field represents a hexadecimal value with a precision +* of 1.2 – i.e. the most significant bit is the integer +* and the least significant 2 bits are fraction bits. +* so, the field can represent a range of 0.25 to 1.75 +*/ + prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns); + if (prepare_cnt > ICL_PREPARE_CNT_MAX) { + DRM_DEBUG_KMS("prepare_cnt out of range (%d)\n", prepare_cnt); + prepare_cnt = ICL_PREPARE_CNT_MAX; + } + + /* clk zero count in escape clocks */ + clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - + ths_prepare_ns, tlpx_ns); + if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { + DRM_DEBUG_KMS("clk_zero_cnt out of range (%d)\n", clk_zero_cnt); + clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; + } + + /* trail cnt in escape clocks*/ + trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); + if (trail_cnt > ICL
Re: [Intel-gfx] [PATCH v7 04/23] drm/i915/dsi: abstract intel_dsi_tlpx_ns()
On 10/16/2018 6:36 PM, Jani Nikula wrote: On Tue, 16 Oct 2018, Madhav Chauhan wrote: On 10/15/2018 7:57 PM, Jani Nikula wrote: Will be needed in the future. No functional changes. Agree, will be needing this while setting up DSI protocol timeouts for ICL. Cc: Madhav Chauhan Cc: Ville Syrjala Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 13 + drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 16 +--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 4daa1da94047..a32cc1f4b384 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -15,3 +15,16 @@ int intel_dsi_bitrate(const struct intel_dsi *intel_dsi) return intel_dsi->pclk * bpp / intel_dsi->lane_count; } + +int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi) +{ + switch (intel_dsi->escape_clk_div) { + default: + case 0: + return 50; + case 1: + return 100; + case 2: + return 200; + } +} Can we change the return of this function to unsigned int, there is no way that this function can return < 0 as per current implementation?? I'd rather not. I'm sure I should be able to justify this exhaustively with examples, but I think gratuitous use of unsigned types leads to issues with integer promotions and signed/unsigned comparisons etc. So if it's "just a number", used for arithmetics, I'll pretty much choose int every time. And because you can silently assign negative numbers to unsigned types, it's not a good safeguard to ensure positive numbers. Unless you're happy with large positive numbers... Unsigned types are best for register contents, bits, masks, etc. Agree with issues mentioned, i thought that should be case to case :), but fine with uniform approach. Reviewed-by: Madhav Chauhan Regards, Madhav BR, Jani. Regards, Madhav diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 68f14d8f1e18..0d911a4adfaa 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -131,6 +131,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) /* intel_dsi.c */ int intel_dsi_bitrate(const struct intel_dsi *intel_dsi); +int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi); /* vlv_dsi.c */ void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port); diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index fdeba8386d53..b0d8548f0462 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -512,21 +512,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) u32 lp_to_hs_switch, hs_to_lp_switch; u32 mul; - switch (intel_dsi->escape_clk_div) { - case 0: - tlpx_ns = 50; - break; - case 1: - tlpx_ns = 100; - break; - - case 2: - tlpx_ns = 200; - break; - default: - tlpx_ns = 50; - break; - } + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); switch (intel_dsi->lane_count) { case 1: ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 05/23] drm/i915/icl: Make common DSI functions available
On 10/16/2018 6:09 PM, Jani Nikula wrote: On Tue, 16 Oct 2018, Madhav Chauhan wrote: On 10/15/2018 7:57 PM, Jani Nikula wrote: From: Madhav Chauhan This patch moves couple of legacy DSI functions to header and common DSI files so that they can be re-used by Gen11 DSI. No functional change. v2 by Jani: - Move intel_dsi_msleep() to intel_dsi_vbt.c This will be used by icl dsi as well and and delay is directly passed Shouldn't we have this inside intel_dsi.c?? Or Because seq version from VBT is getting checked inside this function, so that is taking the precedence?? I had it in intel_dsi.c at first, but decided on intel_dsi_vbt.c instead because it does have a dependency on the VBT. And I presume on ICL this will be a NOP due to v3+ sequence. Ok with this change. Thanks!! Regards, Madhav BR, Jani. Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.h | 11 +++ drivers/gpu/drm/i915/intel_dsi_vbt.c | 11 +++ drivers/gpu/drm/i915/vlv_dsi.c | 21 - 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 0d911a4adfaa..d7c0c599b52d 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -129,6 +129,16 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) return container_of(encoder, struct intel_dsi, base.base); } +static inline bool is_vid_mode(struct intel_dsi *intel_dsi) +{ + return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE; +} + +static inline bool is_cmd_mode(struct intel_dsi *intel_dsi) +{ + return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE; +} + /* intel_dsi.c */ int intel_dsi_bitrate(const struct intel_dsi *intel_dsi); int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi); @@ -162,5 +172,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id); int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi); void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, enum mipi_seq seq_id); +void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec); #endif /* _INTEL_DSI_H */ diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index b0d8548f0462..5e16b4c5f531 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -481,6 +481,17 @@ void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, } } +void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) +{ + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + + /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */ + if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3) + return; + + msleep(msec); +} + int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi) { struct intel_connector *connector = intel_dsi->attached_connector; diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index dbca30460a6b..ee0cd5d0bf91 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -290,16 +290,6 @@ static void band_gap_reset(struct drm_i915_private *dev_priv) mutex_unlock(_priv->sb_lock); } -static inline bool is_vid_mode(struct intel_dsi *intel_dsi) -{ - return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE; -} - -static inline bool is_cmd_mode(struct intel_dsi *intel_dsi) -{ - return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE; -} - static bool intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -746,17 +736,6 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder, const 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) -{ - struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); - - /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */ - if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3) - return; - - msleep(msec); -} - /* * Panel enable/disable sequences from the VBT spec. * ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 02/23] drm/i915/dsi: refactor bitrate calculations in intel_dsi_vbt_init()
On 10/16/2018 6:14 PM, Jani Nikula wrote: On Tue, 16 Oct 2018, Madhav Chauhan wrote: On 10/15/2018 7:57 PM, Jani Nikula wrote: Abstract bitrate calculation to a newly resurrected intel_dsi.c file that will contain common code for VLV and ICL DSI. No functional changes. Cc: Madhav Chauhan Cc: Ville Syrjala Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile| 1 + drivers/gpu/drm/i915/intel_dsi.c | 17 + drivers/gpu/drm/i915/intel_dsi.h | 3 +++ drivers/gpu/drm/i915/intel_dsi_vbt.c | 28 ++-- 4 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_dsi.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 48cae0eae3f9..22cbf9c3bb0c 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -143,6 +143,7 @@ i915-y += dvo_ch7017.o \ intel_dp_link_training.o \ intel_dp_mst.o \ intel_dp.o \ + intel_dsi.o \ intel_dsi_dcs_backlight.o \ intel_dsi_vbt.o \ intel_dvo.o \ diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c new file mode 100644 index ..4daa1da94047 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2018 Intel Corporation + */ + +#include +#include "intel_dsi.h" + +int intel_dsi_bitrate(const struct intel_dsi *intel_dsi) +{ + int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); + + if (WARN_ON(bpp < 0)) + bpp = 16; Shouldn't we keep the default bpp to 24 here as in most of the cases bpp is 24 for DSI or why 16?? *shrug* Not sure it matters all that much really. We set the pixel format in intel_dsi_vbt.c, and if that gives us something bogus, not much of a chance any of it will work. More than anything I just wanted to avoid a negative return from this function. Agree, Reviewed-by: Madhav Chauhan Regards, Madhav BR, Jani. Regards, Madhav + + return intel_dsi->pclk * bpp / intel_dsi->lane_count; +} diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index ad7c1cb32983..68f14d8f1e18 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -129,6 +129,9 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) return container_of(encoder, struct intel_dsi, base.base); } +/* intel_dsi.c */ +int intel_dsi_bitrate(const struct intel_dsi *intel_dsi); + /* vlv_dsi.c */ void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port); enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt); diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index ac83d6b89ae0..6c4cc92f5947 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -506,14 +506,12 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps; struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode; - u32 bpp; - u32 tlpx_ns, extra_byte_count, bitrate, tlpx_ui; + u32 tlpx_ns, extra_byte_count, tlpx_ui; u32 ui_num, ui_den; u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; u32 ths_prepare_ns, tclk_trail_ns; u32 tclk_prepare_clkzero, ths_prepare_hszero; u32 lp_to_hs_switch, hs_to_lp_switch; - u32 pclk, computed_ddr; u32 mul; u16 burst_mode_ratio; enum port port; @@ -526,7 +524,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->pixel_format = pixel_format_from_register_bits( mipi_config->videomode_color_format << 7); - bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); intel_dsi->dual_link = mipi_config->dual_link; intel_dsi->pixel_overlap = mipi_config->pixel_overlap; @@ -541,19 +538,18 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; - pclk = mode->clock; + /* Starting point, adjusted depending on dual link and burst mode */ + intel_dsi->pclk = mode->clock; /* In dual link mode each port needs half of pixel clock */ if (intel_dsi->dual_link) { - pclk = pclk / 2; + intel_dsi->pclk /= 2; /* we can enable pixel_overlap if needed by panel. In this * case we need to increase the pixelclock for extra pixels */ if (intel_dsi->dual_lin
Re: [Intel-gfx] [PATCH v7 05/23] drm/i915/icl: Make common DSI functions available
On 10/15/2018 7:57 PM, Jani Nikula wrote: From: Madhav Chauhan This patch moves couple of legacy DSI functions to header and common DSI files so that they can be re-used by Gen11 DSI. No functional change. v2 by Jani: - Move intel_dsi_msleep() to intel_dsi_vbt.c This will be used by icl dsi as well and and delay is directly passed Shouldn't we have this inside intel_dsi.c?? Or Because seq version from VBT is getting checked inside this function, so that is taking the precedence?? Regards, Madhav Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.h | 11 +++ drivers/gpu/drm/i915/intel_dsi_vbt.c | 11 +++ drivers/gpu/drm/i915/vlv_dsi.c | 21 - 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 0d911a4adfaa..d7c0c599b52d 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -129,6 +129,16 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) return container_of(encoder, struct intel_dsi, base.base); } +static inline bool is_vid_mode(struct intel_dsi *intel_dsi) +{ + return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE; +} + +static inline bool is_cmd_mode(struct intel_dsi *intel_dsi) +{ + return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE; +} + /* intel_dsi.c */ int intel_dsi_bitrate(const struct intel_dsi *intel_dsi); int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi); @@ -162,5 +172,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id); int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi); void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, enum mipi_seq seq_id); +void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec); #endif /* _INTEL_DSI_H */ diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index b0d8548f0462..5e16b4c5f531 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -481,6 +481,17 @@ void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, } } +void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) +{ + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + + /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */ + if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3) + return; + + msleep(msec); +} + int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi) { struct intel_connector *connector = intel_dsi->attached_connector; diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index dbca30460a6b..ee0cd5d0bf91 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -290,16 +290,6 @@ static void band_gap_reset(struct drm_i915_private *dev_priv) mutex_unlock(_priv->sb_lock); } -static inline bool is_vid_mode(struct intel_dsi *intel_dsi) -{ - return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE; -} - -static inline bool is_cmd_mode(struct intel_dsi *intel_dsi) -{ - return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE; -} - static bool intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -746,17 +736,6 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder, const 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) -{ - struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); - - /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */ - if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3) - return; - - msleep(msec); -} - /* * Panel enable/disable sequences from the VBT spec. * ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 04/23] drm/i915/dsi: abstract intel_dsi_tlpx_ns()
On 10/15/2018 7:57 PM, Jani Nikula wrote: Will be needed in the future. No functional changes. Agree, will be needing this while setting up DSI protocol timeouts for ICL. Cc: Madhav Chauhan Cc: Ville Syrjala Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 13 + drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 16 +--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 4daa1da94047..a32cc1f4b384 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -15,3 +15,16 @@ int intel_dsi_bitrate(const struct intel_dsi *intel_dsi) return intel_dsi->pclk * bpp / intel_dsi->lane_count; } + +int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi) +{ + switch (intel_dsi->escape_clk_div) { + default: + case 0: + return 50; + case 1: + return 100; + case 2: + return 200; + } +} Can we change the return of this function to unsigned int, there is no way that this function can return < 0 as per current implementation?? Regards, Madhav diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 68f14d8f1e18..0d911a4adfaa 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -131,6 +131,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) /* intel_dsi.c */ int intel_dsi_bitrate(const struct intel_dsi *intel_dsi); +int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi); /* vlv_dsi.c */ void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port); diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index fdeba8386d53..b0d8548f0462 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -512,21 +512,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) u32 lp_to_hs_switch, hs_to_lp_switch; u32 mul; - switch (intel_dsi->escape_clk_div) { - case 0: - tlpx_ns = 50; - break; - case 1: - tlpx_ns = 100; - break; - - case 2: - tlpx_ns = 200; - break; - default: - tlpx_ns = 50; - break; - } + tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); switch (intel_dsi->lane_count) { case 1: ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v7 03/23] drm/i915/dsi: abstract dphy parameter init
On 10/15/2018 7:57 PM, Jani Nikula wrote: intel_dsi_vbt_init() has grown too unwieldy, and it's about to be modified due to ICL DSI. Abstract out the VLV specific dphy param init. No functional changes. Intentionally no stylistic changes during code movement. Cc: Madhav Chauhan Cc: Ville Syrjala Signed-off-by: Jani Nikula Looks ok to me, Reviewed-by: Madhav Chauhan Regards, Madhav --- drivers/gpu/drm/i915/intel_dsi_vbt.c | 147 +++ 1 file changed, 78 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 6c4cc92f5947..fdeba8386d53 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -499,13 +499,11 @@ int intel_dsi_vbt_get_modes(struct intel_dsi *intel_dsi) return 1; } -bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) +static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) { struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; - struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps; - struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode; u32 tlpx_ns, extra_byte_count, tlpx_ui; u32 ui_num, ui_den; u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; @@ -513,72 +511,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) u32 tclk_prepare_clkzero, ths_prepare_hszero; u32 lp_to_hs_switch, hs_to_lp_switch; u32 mul; - u16 burst_mode_ratio; - enum port port; - - DRM_DEBUG_KMS("\n"); - - intel_dsi->eotp_pkt = mipi_config->eot_pkt_disabled ? 0 : 1; - intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0; - intel_dsi->lane_count = mipi_config->lane_cnt + 1; - intel_dsi->pixel_format = - pixel_format_from_register_bits( - mipi_config->videomode_color_format << 7); - - intel_dsi->dual_link = mipi_config->dual_link; - intel_dsi->pixel_overlap = mipi_config->pixel_overlap; - intel_dsi->operation_mode = mipi_config->is_cmd_mode; - intel_dsi->video_mode_format = mipi_config->video_transfer_mode; - intel_dsi->escape_clk_div = mipi_config->byte_clk_sel; - intel_dsi->lp_rx_timeout = mipi_config->lp_rx_timeout; - intel_dsi->turn_arnd_val = mipi_config->turn_around_timeout; - intel_dsi->rst_timer_val = mipi_config->device_reset_timer; - intel_dsi->init_count = mipi_config->master_init_timer; - intel_dsi->bw_timer = mipi_config->dbi_bw_timer; - intel_dsi->video_frmt_cfg_bits = - mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; - - /* Starting point, adjusted depending on dual link and burst mode */ - intel_dsi->pclk = mode->clock; - - /* In dual link mode each port needs half of pixel clock */ - if (intel_dsi->dual_link) { - intel_dsi->pclk /= 2; - - /* we can enable pixel_overlap if needed by panel. In this -* case we need to increase the pixelclock for extra pixels -*/ - if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { - intel_dsi->pclk += DIV_ROUND_UP(mode->vtotal * intel_dsi->pixel_overlap * 60, 1000); - } - } - - /* Burst Mode Ratio -* Target ddr frequency from VBT / non burst ddr freq -* multiply by 100 to preserve remainder -*/ - if (intel_dsi->video_mode_format == VIDEO_MODE_BURST) { - if (mipi_config->target_burst_mode_freq) { - u32 bitrate = intel_dsi_bitrate(intel_dsi); - - if (mipi_config->target_burst_mode_freq < bitrate) { - DRM_ERROR("Burst mode freq is less than computed\n"); - return false; - } - - burst_mode_ratio = DIV_ROUND_UP( - mipi_config->target_burst_mode_freq * 100, - bitrate); - - intel_dsi->pclk = DIV_ROUND_UP(intel_dsi->pclk * burst_mode_ratio, 100); - } else { - DRM_ERROR("Burst mode target is not set\n"); - return false; - } - } else - burst_mode_ratio = 100; - - intel_dsi->burst_mode_ratio = burst_mode_ratio; switch (intel_dsi->escape_clk_div) { case 0: @@ -738,6 +670,83 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) DIV_ROUND_UP(2
Re: [Intel-gfx] [PATCH v7 02/23] drm/i915/dsi: refactor bitrate calculations in intel_dsi_vbt_init()
On 10/15/2018 7:57 PM, Jani Nikula wrote: Abstract bitrate calculation to a newly resurrected intel_dsi.c file that will contain common code for VLV and ICL DSI. No functional changes. Cc: Madhav Chauhan Cc: Ville Syrjala Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/Makefile| 1 + drivers/gpu/drm/i915/intel_dsi.c | 17 + drivers/gpu/drm/i915/intel_dsi.h | 3 +++ drivers/gpu/drm/i915/intel_dsi_vbt.c | 28 ++-- 4 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_dsi.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 48cae0eae3f9..22cbf9c3bb0c 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -143,6 +143,7 @@ i915-y += dvo_ch7017.o \ intel_dp_link_training.o \ intel_dp_mst.o \ intel_dp.o \ + intel_dsi.o \ intel_dsi_dcs_backlight.o \ intel_dsi_vbt.o \ intel_dvo.o \ diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c new file mode 100644 index ..4daa1da94047 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2018 Intel Corporation + */ + +#include +#include "intel_dsi.h" + +int intel_dsi_bitrate(const struct intel_dsi *intel_dsi) +{ + int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); + + if (WARN_ON(bpp < 0)) + bpp = 16; Shouldn't we keep the default bpp to 24 here as in most of the cases bpp is 24 for DSI or why 16?? Regards, Madhav + + return intel_dsi->pclk * bpp / intel_dsi->lane_count; +} diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index ad7c1cb32983..68f14d8f1e18 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -129,6 +129,9 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) return container_of(encoder, struct intel_dsi, base.base); } +/* intel_dsi.c */ +int intel_dsi_bitrate(const struct intel_dsi *intel_dsi); + /* vlv_dsi.c */ void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port); enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt); diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index ac83d6b89ae0..6c4cc92f5947 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -506,14 +506,12 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps; struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode; - u32 bpp; - u32 tlpx_ns, extra_byte_count, bitrate, tlpx_ui; + u32 tlpx_ns, extra_byte_count, tlpx_ui; u32 ui_num, ui_den; u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; u32 ths_prepare_ns, tclk_trail_ns; u32 tclk_prepare_clkzero, ths_prepare_hszero; u32 lp_to_hs_switch, hs_to_lp_switch; - u32 pclk, computed_ddr; u32 mul; u16 burst_mode_ratio; enum port port; @@ -526,7 +524,6 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->pixel_format = pixel_format_from_register_bits( mipi_config->videomode_color_format << 7); - bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); intel_dsi->dual_link = mipi_config->dual_link; intel_dsi->pixel_overlap = mipi_config->pixel_overlap; @@ -541,19 +538,18 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; - pclk = mode->clock; + /* Starting point, adjusted depending on dual link and burst mode */ + intel_dsi->pclk = mode->clock; /* In dual link mode each port needs half of pixel clock */ if (intel_dsi->dual_link) { - pclk = pclk / 2; + intel_dsi->pclk /= 2; /* we can enable pixel_overlap if needed by panel. In this * case we need to increase the pixelclock for extra pixels */ if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { - pclk += DIV_ROUND_UP(mode->vtotal * - intel_dsi->pixel_overlap * - 60, 1000); + intel_dsi->pclk += DIV_ROUND_UP(mode->vtotal * intel_dsi->pixel_overlap * 60, 1000); } } @@ -563,19 +559,18 @@ bool intel_dsi_vbt_init
Re: [Intel-gfx] [PATCH v7 01/23] drm/i915: make encoder enable and disable hooks optional
On 10/15/2018 7:57 PM, Jani Nikula wrote: Encoders are not alike, make enable and disable hooks optional like other hooks. Utilize this in DSI code, and remove the silly nop hook. Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 6 -- drivers/gpu/drm/i915/vlv_dsi.c | 16 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 41abd03ce6a6..32ea71bac663 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5461,7 +5461,8 @@ static void intel_encoders_enable(struct drm_crtc *crtc, if (conn_state->crtc != crtc) continue; - encoder->enable(encoder, crtc_state, conn_state); + if (encoder->enable) + encoder->enable(encoder, crtc_state, conn_state); intel_opregion_notify_encoder(encoder, true); } } @@ -5482,7 +5483,8 @@ static void intel_encoders_disable(struct drm_crtc *crtc, continue; intel_opregion_notify_encoder(encoder, false); - encoder->disable(encoder, old_crtc_state, old_conn_state); + if (encoder->disable) + encoder->disable(encoder, old_crtc_state, old_conn_state); } encoder->disable() gets called directly inside intel_sanitize_encoder() without intel_encoders_disable().I think, we need to put the check there as well. With that fix, Reviewed-by: Madhav Chauhan Regards, Madhav } diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index bafeb2a19b90..dbca30460a6b 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -794,6 +794,10 @@ static void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) * - wait t4 - wait t4 */ +/* + * DSI port enable has to be done before pipe and plane enable, so we do it in + * the pre_enable hook instead of the enable hook. + */ static void intel_dsi_pre_enable(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) @@ -896,17 +900,6 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, } /* - * DSI port enable has to be done before pipe and plane enable, so we do it in - * the pre_enable hook. - */ -static void intel_dsi_enable_nop(struct intel_encoder *encoder, -const struct intel_crtc_state *pipe_config, -const struct drm_connector_state *conn_state) -{ - DRM_DEBUG_KMS("\n"); -} - -/* * DSI port disable has to be done after pipe and plane disable, so we do it in * the post_disable hook. */ @@ -1764,7 +1757,6 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) intel_encoder->compute_config = intel_dsi_compute_config; intel_encoder->pre_enable = intel_dsi_pre_enable; - intel_encoder->enable = intel_dsi_enable_nop; intel_encoder->disable = intel_dsi_disable; intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->get_hw_state = intel_dsi_get_hw_state; ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 13/20] drm/i915/icl: Define TRANS_DDI_FUNC_CTL DSI registers
This patch defines TRANS_DDI_FUNC_CTL and TRANS_DDI_FUNC_CTL2 registers and their bitfields for DSI. These registers are used for enabling port sync mode, input pipe select, data lane width configuration etc. v2: Changes: - Remove redundant extra line - Correct some of bitfield definition Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_pci.c | 3 ++- drivers/gpu/drm/i915/i915_reg.h | 17 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index d6f7b9f..bd4e0fd 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -36,7 +36,8 @@ .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ - TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \ + TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET, \ + TRANSCODER_DSI0_OFFSET, TRANSCODER_DSI1_OFFSET}, \ .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET } #define GEN_CHV_PIPEOFFSETS \ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 41ef285..a7e1fce 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4066,6 +4066,8 @@ enum { #define TRANSCODER_C_OFFSET 0x62000 #define CHV_TRANSCODER_C_OFFSET 0x63000 #define TRANSCODER_EDP_OFFSET 0x6f000 +#define TRANSCODER_DSI0_OFFSET 0x6b000 +#define TRANSCODER_DSI1_OFFSET 0x6b800 #define _MMIO_TRANS2(pipe, reg) _MMIO(dev_priv->info.trans_offsets[(pipe)] - \ dev_priv->info.trans_offsets[TRANSCODER_A] + (reg) + \ @@ -9014,6 +9016,8 @@ enum skl_power_gate { #define _TRANS_DDI_FUNC_CTL_B 0x61400 #define _TRANS_DDI_FUNC_CTL_C 0x62400 #define _TRANS_DDI_FUNC_CTL_EDP0x6F400 +#define _TRANS_DDI_FUNC_CTL_DSI0 0x6b400 +#define _TRANS_DDI_FUNC_CTL_DSI1 0x6bc00 #define TRANS_DDI_FUNC_CTL(tran) _MMIO_TRANS2(tran, _TRANS_DDI_FUNC_CTL_A) #define TRANS_DDI_FUNC_ENABLE (1 << 31) @@ -9051,6 +9055,19 @@ enum skl_power_gate { | TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ \ | TRANS_DDI_HDMI_SCRAMBLING) +#define _TRANS_DDI_FUNC_CTL2_A 0x60404 +#define _TRANS_DDI_FUNC_CTL2_B 0x61404 +#define _TRANS_DDI_FUNC_CTL2_C 0x62404 +#define _TRANS_DDI_FUNC_CTL2_EDP 0x6f404 +#define _TRANS_DDI_FUNC_CTL2_DSI0 0x6b404 +#define _TRANS_DDI_FUNC_CTL2_DSI1 0x6bc04 +#define TRANS_DDI_FUNC_CTL2(tran) _MMIO_TRANS2(tran, \ +_TRANS_DDI_FUNC_CTL2_A) +#define PORT_SYNC_MODE_ENABLE (1 << 4) +#define PORT_SYNC_MODE_MASTER_SELECT(x) ((x) < 0) +#define PORT_SYNC_MODE_MASTER_SELECT_MASK (0x7 << 0) +#define PORT_SYNC_MODE_MASTER_SELECT_SHIFT0 + /* DisplayPort Transport Control */ #define _DP_TP_CTL_A 0x64040 #define _DP_TP_CTL_B 0x64140 -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 04/20] drm/i915/icl: Program T_INIT_MASTER registers
This patch programs the time (in escape clocks) to drive the link in the initialization (i.e. LP-11) state. v2: Rebase v3: Remove step hard coding comments (Jani N) Signed-off-by: Madhav Chauhan Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 190316c..ff5b285 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -277,6 +277,22 @@ static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder) } } +static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + + /* Program T-INIT master registers */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_DSI_T_INIT_MASTER(port)); + tmp &= ~MASTER_INIT_TIMER_MASK; + tmp |= intel_dsi->init_count; + I915_WRITE(ICL_DSI_T_INIT_MASTER(port), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -290,6 +306,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) /* enable DDI buffer */ gen11_dsi_enable_ddi_buffer(encoder); + + /* setup D-PHY timings */ + gen11_dsi_setup_dphy_timings(encoder); } static void __attribute__((unused)) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 00/20] ICELAKE DSI DRIVER
From ICELAKE platform onwards, new MIPI DSI IP controller is integrated to GPU/Display Engine and same could be extended for future Intel platforms as well. DSI IP controller supports MIPI DSI 1.3 and DPHY 1.2 specification. So, a new DSI driver has been added inside I915. Given below patches are the part of new DSI driver which implements BSPEC sequence till panel programming. Rest of the patches will be published to GITHUB. v2: Addressed review comments from Jani N for Patches 1-6 and rebase for some other few patches. v3: Renamed intel_dsi_new.c to gen11_dsi.c as per discussion with Jani, Daniel, Ville. Also addressed review comments for couple of patches. v4: Rename gen11_dsi.c to icl_dsi.c (Ville). No functional changes. v5: Rebase on drm-tip after initial 7 patches got merged. v6: Addressed various review comments from Jani N, Ville, Vandita. Madhav Chauhan (20): drm/i915/icl: Configure lane sequencing of combo phy transmitter drm/i915/icl: DSI vswing programming sequence drm/i915/icl: Enable DDI Buffer drm/i915/icl: Program T_INIT_MASTER registers drm/i915/icl: Define data/clock lanes dphy timing registers drm/i915/icl: Program DSI clock and data lane timing params drm/i915/icl: Define TA_TIMING_PARAM registers drm/i915/icl: Program TA_TIMING_PARAM registers drm/i915/icl: Get DSI transcoder for a given port drm/i915/icl: Add macros for MMIO of DSI transcoder registers drm/i915/icl: Define TRANS_DSI_FUNC_CONF register drm/i915/icl: Configure DSI transcoders drm/i915/icl: Define TRANS_DDI_FUNC_CTL DSI registers drm/i915/icl: Program TRANS_DDI_FUNC_CTL registers drm/i915/icl: Define DSI transcoder timing registers drm/i915/icl: Configure DSI transcoder timings drm/i915/icl: Define TRANS_CONF register for DSI drm/i915/icl: Enable DSI transcoders drm/i915/icl: Define DSI panel programming registers drm/i915/icl: Set max return packet size for DSI panel drivers/gpu/drm/i915/i915_pci.c | 6 +- drivers/gpu/drm/i915/i915_reg.h | 208 + drivers/gpu/drm/i915/icl_dsi.c | 567 ++- drivers/gpu/drm/i915/intel_display.h | 6 +- drivers/gpu/drm/i915/intel_dsi.h | 7 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 202 + 6 files changed, 934 insertions(+), 62 deletions(-) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 01/20] drm/i915/icl: Configure lane sequencing of combo phy transmitter
This patch set the loadgen select and latency optimization for aux and transmit lanes of combo phy transmitters. It will be used for MIPI DSI HS operations. v2: Rebase v3: Add empty line to make code more legible (Ville). Signed-off-by: Madhav Chauhan Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 39 +++ 1 file changed, 39 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 13830e4..1607cac 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -105,10 +105,49 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) } } +static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + u32 tmp; + int lane; + + /* Step 4b(i) set loadgen select for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp &= ~LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + for (lane = 0; lane <= 3; lane++) { + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp &= ~LOADGEN_SELECT; + if (lane != 2) + tmp |= LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } + + /* Step 4b(ii) set latency optimization for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + } + +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ gen11_dsi_power_up_lanes(encoder); + + /* step 4b: configure lane sequencing of the Combo-PHY transmitters */ + gen11_dsi_config_phy_lanes_sequence(encoder); } static void __attribute__((unused)) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 16/20] drm/i915/icl: Configure DSI transcoder timings
As part of DSI enable sequence, transcoder timings (horizontal & vertical) need to be set so that transcoder will generate the stream output as per those timings. This patch set required transcoder timings as per BSPEC. v2: Remove TRANS_TIMING_SHIFT usage Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 128 + 1 file changed, 128 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 1d39975..e7f6005 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -472,6 +472,130 @@ static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder, } } +static void gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, + const 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(>base); + const struct drm_display_mode *adjusted_mode = + _config->base.adjusted_mode; + enum port port; + u32 tmp; + enum transcoder dsi_trans; + /* horizontal timings */ + u16 htotal, hactive, hsync_start, hsync_end, hsync_size; + u16 hfront_porch, hback_porch; + /* vertical timings */ + u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift; + + hactive = adjusted_mode->crtc_hdisplay; + htotal = adjusted_mode->crtc_htotal; + hsync_start = adjusted_mode->crtc_hsync_start; + hsync_end = adjusted_mode->crtc_hsync_end; + hsync_size = hsync_end - hsync_start; + hfront_porch = (adjusted_mode->crtc_hsync_start - + adjusted_mode->crtc_hdisplay); + hback_porch = (adjusted_mode->crtc_htotal - + adjusted_mode->crtc_hsync_end); + vactive = adjusted_mode->crtc_vdisplay; + vtotal = adjusted_mode->crtc_vtotal; + vsync_start = adjusted_mode->crtc_vsync_start; + vsync_end = adjusted_mode->crtc_vsync_end; + vsync_shift = hsync_start - htotal/2; + + if (intel_dsi->dual_link) { + hactive /= 2; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) + hactive += intel_dsi->pixel_overlap; + htotal /= 2; + } + + /* minimum hactive as per bspec: 256 pixels */ + if (adjusted_mode->crtc_hdisplay < 256) + DRM_ERROR("hactive is less then 256 pixels\n"); + + /* if RGB666 format, then hactive must be multiple of 4 pixels */ + if ((intel_dsi->pixel_format == MIPI_DSI_FMT_RGB666) && + ((hactive % 4) != 0)) + DRM_ERROR("hactive pixels are not multiple of 4\n"); + + /* program TRANS_HTOTAL register */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + /* BSPEC: program required pixels minus 1 */ + tmp = (hactive - 1); + tmp |= ((htotal - 1) << 16); + I915_WRITE(HTOTAL(dsi_trans), tmp); + } + + /* TRANS_HSYNC register to be programmed only for video mode */ + if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { + if (intel_dsi->video_mode_format == + VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) { + /* BSPEC: hsync size should be atleast 16 pixels */ + if (hsync_size < 16) + DRM_ERROR("hsync size < 16 pixels\n"); + } + + if (hback_porch < 16) + DRM_ERROR("hback porch < 16 pixels\n"); + + if (intel_dsi->dual_link) { + hsync_start /= 2; + hsync_end /= 2; + } + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + /* BSPEC: program required pixels minus 1 */ + tmp = (hsync_start - 1); + tmp |= ((hsync_end - 1) << 16); + I915_WRITE(HSYNC(dsi_trans), tmp); + } + } + + /* program TRANS_VTOTAL register */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + /* +* FIXME: Programing this by assuming progressive mode, since +* non-interlaced info from VBT is not saved inside +* struct drm_display_mode. +* For interlace mode: program required pixel minus 2 +*/ + tmp = ((vtotal - 1) << 16); + /* BSPEC: program required pixels minus 1 */ + tmp |=
[Intel-gfx] [PATCH v6 18/20] drm/i915/icl: Enable DSI transcoders
This patch enables DSI transcoders by writing to TRANS_CONF registers and wait for its state to be enabled. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index e7f6005..ae8877a 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -596,6 +596,28 @@ static void gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, } } +static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + enum transcoder dsi_trans; + u32 tmp; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(PIPECONF(dsi_trans)); + tmp |= PIPECONF_ENABLE; + I915_WRITE(PIPECONF(dsi_trans), tmp); + + /* wait for transcoder to be enabled */ + if (intel_wait_for_register(dev_priv, PIPECONF(dsi_trans), + I965_PIPECONF_ACTIVE, + I965_PIPECONF_ACTIVE, 10)) + DRM_ERROR("DSI transcoder not enabled\n"); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) { @@ -635,4 +657,6 @@ gen11_dsi_pre_enable(struct intel_encoder *encoder, /* step6c: configure transcoder timings */ gen11_dsi_set_transcoder_timings(encoder, pipe_config); + /* step6d: enable dsi transcoder */ + gen11_dsi_enable_transcoder(encoder); } -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 10/20] drm/i915/icl: Add macros for MMIO of DSI transcoder registers
This patch adds _MMIO_DSI macros for accessing DSI transcoder registers. v2: Use _MMIO_TRANS() (Ville) Credits-to: Jani N Cc: Jani Nikula Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b27d0c1..58b82b2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9786,6 +9786,10 @@ enum skl_power_gate { #define _MIPI_PORT(port, a, c) (((port) == PORT_A) ? a : c)/* ports A and C only */ #define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c)) +/* Gen11 DSI */ +#define _MMIO_DSI(tc, dsi0, dsi1) _MMIO_TRANS((tc) - TRANSCODER_DSI_0, \ + dsi0, dsi1) + #define MIPIO_TXESC_CLK_DIV1 _MMIO(0x160004) #define GLK_TX_ESC_CLK_DIV1_MASK 0x3FF #define MIPIO_TXESC_CLK_DIV2 _MMIO(0x160008) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 08/20] drm/i915/icl: Program TA_TIMING_PARAM registers
This patch programs D-PHY timing parameters for the bus turn around flow(in escape clocks) only if dsi link frequency <=800 MHz using DPHY_TA_TIMING_PARAM and its identical register DSI_TA_TIMING_PARAM (inside DSI Controller within the Display Core). v2: Changes - Don't use KHz() macro (Ville/Jani N) - Use newly defined bitfields Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 21 + drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 1 + 3 files changed, 23 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 9602b65..0fb7b6f 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -309,6 +309,27 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) I915_WRITE(DSI_DATA_TIMING_PARAM(port), intel_dsi->dphy_data_lane_reg); } + + /* +* If DSI link operating at or below an 800 MHz, +* TA_SURE should be override and programmed to +* a value '0' inside TA_PARAM_REGISTERS otherwise +* leave all fields at HW default values. +*/ + if (intel_dsi->bitrate_khz <= 80) { + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(DPHY_TA_TIMING_PARAM(port)); + tmp &= ~TA_SURE_MASK; + tmp |= (TA_SURE_OVERRIDE | TA_SURE(0)); + I915_WRITE(DPHY_TA_TIMING_PARAM(port), tmp); + + /* shadow register inside display core */ + tmp = I915_READ(DSI_TA_TIMING_PARAM(port)); + tmp &= ~TA_SURE_MASK; + tmp |= (TA_SURE_OVERRIDE | TA_SURE(0)); + I915_WRITE(DSI_TA_TIMING_PARAM(port), tmp); + } + } } static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 9fd8526..25e7396 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -101,6 +101,7 @@ struct intel_dsi { u16 init_count; u32 pclk; + u32 bitrate_khz; u16 burst_mode_ratio; /* all delays in ms */ diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index fbb159b..11f184f 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -589,6 +589,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->pclk = pclk; bitrate = (pclk * bpp) / intel_dsi->lane_count; + intel_dsi->bitrate_khz = bitrate; switch (intel_dsi->escape_clk_div) { case 0: -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 07/20] drm/i915/icl: Define TA_TIMING_PARAM registers
This patch defines DSI_TA_TIMING_PARAM and DPHY_TA_TIMING_PARAM registers used in dphy programming. v2: Changes (Jani N) - Define mask/shift for bitfields - Use bitfields name as per BSPEC - Define remaining bitfields Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 23 +++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6c8999d..b27d0c1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10343,6 +10343,29 @@ enum skl_power_gate { #define HS_EXIT_MASK (0x7 << 0) #define HS_EXIT_SHIFT 0 +#define _DPHY_TA_TIMING_PARAM_00x162188 +#define _DPHY_TA_TIMING_PARAM_10x6c188 +#define DPHY_TA_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DPHY_TA_TIMING_PARAM_0,\ + _DPHY_TA_TIMING_PARAM_1) +#define _DSI_TA_TIMING_PARAM_0 0x6b098 +#define _DSI_TA_TIMING_PARAM_1 0x6b898 +#define DSI_TA_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DSI_TA_TIMING_PARAM_0,\ + _DSI_TA_TIMING_PARAM_1) +#define TA_SURE_OVERRIDE (1 << 31) +#define TA_SURE(x)((x) << 16) +#define TA_SURE_MASK (0x1f << 16) +#define TA_SURE_SHIFT 16 +#define TA_GO_OVERRIDE(1 << 15) +#define TA_GO(x) ((x) << 8) +#define TA_GO_MASK(0xf << 8) +#define TA_GO_SHIFT 8 +#define TA_GET_OVERRIDE (1 << 7) +#define TA_GET(x) ((x) << 0) +#define TA_GET_MASK (0xf << 0) +#define TA_GET_SHIFT 0 + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 09/20] drm/i915/icl: Get DSI transcoder for a given port
This patch adds a helper function to retrieve DSI transcoder for a given DSI port using newly defined enum names for DSI transcoders. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 9 + drivers/gpu/drm/i915/intel_display.h | 6 -- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 0fb7b6f..30684f0 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,6 +27,15 @@ #include "intel_dsi.h" +static enum transcoder __attribute__((unused)) dsi_port_to_transcoder( + enum port port) +{ + if (port == PORT_A) + return TRANSCODER_DSI_0; + else + return TRANSCODER_DSI_1; +} + static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h index ed474da..dc9603e 100644 --- a/drivers/gpu/drm/i915/intel_display.h +++ b/drivers/gpu/drm/i915/intel_display.h @@ -61,8 +61,10 @@ enum transcoder { TRANSCODER_B, TRANSCODER_C, TRANSCODER_EDP, - TRANSCODER_DSI_A, - TRANSCODER_DSI_C, + TRANSCODER_DSI_0, + TRANSCODER_DSI_1, + TRANSCODER_DSI_A = TRANSCODER_DSI_0,/* legacy DSI */ + TRANSCODER_DSI_C = TRANSCODER_DSI_1,/* legacy DSI */ I915_MAX_TRANSCODERS }; -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 20/20] drm/i915/icl: Set max return packet size for DSI panel
This patch programs maximum size of the payload transmitted from peripheral back to the host processor using short packet as a part of panel programming. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 28 1 file changed, 28 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index ae8877a..a243349 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -25,6 +25,7 @@ * Jani Nikula */ +#include #include "intel_dsi.h" static enum transcoder dsi_port_to_transcoder(enum port port) @@ -640,6 +641,30 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, gen11_dsi_configure_transcoder(encoder, pipe_config); } +static void gen11_dsi_powerup_panel(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + struct mipi_dsi_device *dsi; + enum port port; + enum transcoder dsi_trans; + u32 tmp; + int ret; + + /* set maximum return packet size */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(DSI_CMD_RXCTL(dsi_trans)); + tmp &= NUMBER_RX_PLOAD_DW_MASK; + /* multiply "Number Rx Payload DW" by 4 to get max value */ + tmp = tmp * 4; + dsi = intel_dsi->dsi_hosts[port]->device; + ret = mipi_dsi_set_maximum_return_packet_size(dsi, tmp); + if (ret < 0) + DRM_ERROR("error setting max return pkt size%d\n", tmp); + } +} + static void __attribute__((unused)) gen11_dsi_pre_enable(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, @@ -654,6 +679,9 @@ gen11_dsi_pre_enable(struct intel_encoder *encoder, /* step4: enable DSI port and DPHY */ gen11_dsi_enable_port_and_phy(encoder, pipe_config); + /* step5: program and powerup panel */ + gen11_dsi_powerup_panel(encoder); + /* step6c: configure transcoder timings */ gen11_dsi_set_transcoder_timings(encoder, pipe_config); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 06/20] drm/i915/icl: Program DSI clock and data lane timing params
This patch programs D-PHY timing parameters for the clock and data lane (in escape clocks) of DSI controller (DSI port 0 and 1). These programmed timings would be used by DSI Controller to calculate link transition latencies of the data and clock lanes. v2: Use newly defined bitfields for data and clock lane Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 18 drivers/gpu/drm/i915/intel_dsi.h | 3 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 200 +-- 3 files changed, 165 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index ff5b285..9602b65 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -291,6 +291,24 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) tmp |= intel_dsi->init_count; I915_WRITE(ICL_DSI_T_INIT_MASTER(port), tmp); } + + /* Program DPHY clock lanes timings */ + for_each_dsi_port(port, intel_dsi->ports) { + I915_WRITE(DPHY_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg); + + /* shadow register inside display core */ + I915_WRITE(DSI_CLK_TIMING_PARAM(port), intel_dsi->dphy_reg); + } + + /* Program DPHY data lanes timings */ + for_each_dsi_port(port, intel_dsi->ports) { + I915_WRITE(DPHY_DATA_TIMING_PARAM(port), + intel_dsi->dphy_data_lane_reg); + + /* shadow register inside display core */ + I915_WRITE(DSI_DATA_TIMING_PARAM(port), + intel_dsi->dphy_data_lane_reg); + } } static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index ad7c1cb..9fd8526 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -85,6 +85,9 @@ struct intel_dsi { u32 port_bits; u32 bw_timer; u32 dphy_reg; + + /* data lanes dphy timing */ + u32 dphy_data_lane_reg; u32 video_frmt_cfg_bits; u16 lp_byte_clk; diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index ac83d6b..fbb159b 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -509,7 +509,9 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) u32 bpp; u32 tlpx_ns, extra_byte_count, bitrate, tlpx_ui; u32 ui_num, ui_den; - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; + u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt, hs_zero_cnt; + u32 tclk_pre_cnt, tclk_post_cnt; + u32 tclk_pre_ns, tclk_post_ns; u32 ths_prepare_ns, tclk_trail_ns; u32 tclk_prepare_clkzero, ths_prepare_hszero; u32 lp_to_hs_switch, hs_to_lp_switch; @@ -624,76 +626,157 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) tclk_prepare_clkzero = mipi_config->tclk_prepare_clkzero; ths_prepare_hszero = mipi_config->ths_prepare_hszero; - + tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); + ths_prepare_ns = max(mipi_config->ths_prepare, + mipi_config->tclk_prepare); /* * B060 * LP byte clock = TLPX/ (8UI) */ intel_dsi->lp_byte_clk = DIV_ROUND_UP(tlpx_ns * ui_den, 8 * ui_num); - /* DDR clock period = 2 * UI -* UI(sec) = 1/(bitrate * 10^3) (bitrate is in KHZ) -* UI(nsec) = 10^6 / bitrate -* DDR clock period (nsec) = 2 * UI = (2 * 10^6)/ bitrate -* DDR clock count = ns_value / DDR clock period -* + /* * For GEMINILAKE dphy_param_reg will be programmed in terms of * HS byte clock count for other platform in HS ddr clock count */ mul = IS_GEMINILAKE(dev_priv) ? 8 : 2; - ths_prepare_ns = max(mipi_config->ths_prepare, -mipi_config->tclk_prepare); - /* prepare count */ - prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * mul); + if (IS_ICELAKE(dev_priv)) { + /* +* prepare cnt in escape clocks +* this field represents a hexadecimal value with a precision +* of 1.2 – i.e. the most significant bit is the integer +* and the least significant 2 bits are fraction bits. +* so, the field can represent a range of 0.25 to 1.75 +*/ + prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns); + + /* clk zero count in escape clocks */ + clk_zero_cnt = DIV_ROUND_UP( + (tclk_prepare_clkzero - ths_prepare_ns), + tl
[Intel-gfx] [PATCH v6 15/20] drm/i915/icl: Define DSI transcoder timing registers
This patch defines registers and bitfields used for programming DSI transcoder's horizontal and vertical timings. v2: Remove TRANS_TIMING_SHIFT definition Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a7e1fce..a87f0ef 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4061,6 +4061,18 @@ enum { #define _VSYNCSHIFT_B 0x61028 #define _PIPE_MULT_B 0x6102c +/* DSI trancoders (0 & 1) timing regs */ +#define _HTOTAL_DSI0 0x6b000 +#define _HTOTAL_DSI1 0x6b800 +#define _HSYNC_DSI00x6b008 +#define _HSYNC_DSI10x6b808 +#define _VTOTAL_DSI0 0x6b00c +#define _VTOTAL_DSI1 0x6b80c +#define _VSYNC_DSI00x6b014 +#define _VSYNC_DSI10x6b814 +#define _VSYNCSHIFT_DSI0 0x6b028 +#define _VSYNCSHIFT_DSI1 0x6b828 + #define TRANSCODER_A_OFFSET 0x6 #define TRANSCODER_B_OFFSET 0x61000 #define TRANSCODER_C_OFFSET 0x62000 -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 11/20] drm/i915/icl: Define TRANS_DSI_FUNC_CONF register
This patch defines transcoder function configuration registers and its bitfields for both DSI ports. Used while programming/enabling DSI transcoder. v2: Changes (Jani N) - Define _SHIFT and _MASK for bitfields - Define values for fields already shifted in place Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 48 + 1 file changed, 48 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 58b82b2..41ef285 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10370,6 +10370,54 @@ enum skl_power_gate { #define TA_GET_MASK (0xf << 0) #define TA_GET_SHIFT 0 +/* DSI transcoder configuration */ +#define _DSI_TRANS_FUNC_CONF_0 0x6b030 +#define _DSI_TRANS_FUNC_CONF_1 0x6b830 +#define DSI_TRANS_FUNC_CONF(tc)_MMIO_DSI(tc, \ + _DSI_TRANS_FUNC_CONF_0,\ + _DSI_TRANS_FUNC_CONF_1) +#define OP_MODE_MASK (0x3 << 28) +#define OP_MODE_SHIFT 28 +#define CMD_MODE_NO_GATE (0x0 << 28) +#define CMD_MODE_TE_GATE (0x1 << 28) +#define VIDEO_MODE_SYNC_EVENT (0x2 << 28) +#define VIDEO_MODE_SYNC_PULSE (0x3 << 28) +#define LINK_READY(1 << 20) +#define PIX_FMT_MASK (0x3 << 16) +#define PIX_FMT_SHIFT 16 +#define PIX_FMT_RGB565(0x0 << 16) +#define PIX_FMT_RGB666_PACKED (0x1 << 16) +#define PIX_FMT_RGB666_LOOSE (0x2 << 16) +#define PIX_FMT_RGB888(0x3 << 16) +#define PIX_FMT_RGB101010 (0x4 << 16) +#define PIX_FMT_RGB121212 (0x5 << 16) +#define PIX_FMT_COMPRESSED(0x6 << 16) +#define BGR_TRANSMISSION (1 << 15) +#define PIX_VIRT_CHAN(x) (x << 12) +#define PIX_VIRT_CHAN_MASK(0x3 << 12) +#define PIX_VIRT_CHAN_SHIFT 12 +#define PIX_BUF_THRESHOLD_MASK(0x3 << 10) +#define PIX_BUF_THRESHOLD_SHIFT 10 +#define PIX_BUF_THRESHOLD_1_4 (0x0 << 10) +#define PIX_BUF_THRESHOLD_1_2 (0x1 << 10) +#define PIX_BUF_THRESHOLD_3_4 (0x2 << 10) +#define PIX_BUF_THRESHOLD_FULL(0x3 << 10) +#define CONTINUOUS_CLK_MASK (0x3 << 8) +#define CONTINUOUS_CLK_SHIFT (0x3 << 8) +#define CLK_ENTER_LP_AFTER_DATA (0x0 << 8) +#define CLK_HS_OR_LP (0x2 << 8) +#define CLK_HS_CONTINUOUS (0x3 << 8) +#define LINK_CALIBRATION_MASK (0x3 << 4) +#define LINK_CALIBRATION_SHIFT(0x3 << 4) +#define CALIBRATION_DISABLED (0x0 << 4) +#define CALIBRATION_ENABLED_INITIAL_ONLY (0x2 << 4) +#define CALIBRATION_ENABLED_INITIAL_PERIODIC (0x3 << 4) +#define S3D_ORIENTATION_MASK (0x1 << 1) +#define S3D_ORIENTATION_SHIFT 1 +#define S3D_ORIENTATION_PORTRAIT (0x0 << 1) +#define S3D_ORIENTATION_LANDSCAPE (0x1 << 1) +#define EOTP_DISABLED (1 << 0) + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 19/20] drm/i915/icl: Define DSI panel programming registers
This patch defines DSI_CMD_RXCTL, DSI_CMD_TXCTL registers, bitfields, masks and macros used for configuring DSI panel. v2: Define remaining bitfields Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 38 ++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 34a0afa..0b10d49 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10455,6 +10455,44 @@ enum skl_power_gate { #define S3D_ORIENTATION_LANDSCAPE (0x1 << 1) #define EOTP_DISABLED (1 << 0) +#define _DSI_CMD_RXCTL_0 0x6b0d4 +#define _DSI_CMD_RXCTL_1 0x6b8d4 +#define DSI_CMD_RXCTL(tc) _MMIO_DSI(tc, \ + _DSI_CMD_RXCTL_0,\ + _DSI_CMD_RXCTL_1) +#define READ_UNLOADS_DW (1 << 16) +#define RECEIVED_UNASSIGNED_TRIGGER (1 << 15) +#define RECEIVED_ACKNOWLEDGE_TRIGGER (1 << 14) +#define RECEIVED_TEAR_EFFECT_TRIGGER (1 << 13) +#define RECEIVED_RESET_TRIGGER(1 << 12) +#define RECEIVED_PAYLOAD_WAS_LOST (1 << 11) +#define RECEIVED_CRC_WAS_LOST (1 << 10) +#define NUMBER_RX_PLOAD_DW_MASK (0xff << 0) +#define NUMBER_RX_PLOAD_DW_SHIFT 0 + +#define _DSI_CMD_TXCTL_0 0x6b0d0 +#define _DSI_CMD_TXCTL_1 0x6b8d0 +#define DSI_CMD_TXCTL(tc) _MMIO_DSI(tc, \ + _DSI_CMD_TXCTL_0,\ + _DSI_CMD_TXCTL_1) +#define KEEP_LINK_IN_HS (1 << 24) +#define FREE_HEADER_CREDIT_MASK (0x1f << 8) +#define FREE_HEADER_CREDIT_SHIFT 0x8 +#define FREE_PLOAD_CREDIT_MASK(0xff << 0) +#define FREE_PLOAD_CREDIT_SHIFT 0 +#define MAX_HEADER_CREDIT 0x10 +#define MAX_PLOAD_CREDIT 0x40 + +#define _DSI_LP_MSG_0 0x6b0d8 +#define _DSI_LP_MSG_1 0x6b8d8 +#define DSI_LP_MSG(tc) _MMIO_DSI(tc, \ + _DSI_LP_MSG_0,\ + _DSI_LP_MSG_1) +#define LPTX_IN_PROGRESS (1 << 17) +#define LINK_IN_ULPS (1 << 16) +#define LINK_ULPS_TYPE_LP11 (1 << 8) +#define LINK_ENTER_ULPS (1 << 0) + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 12/20] drm/i915/icl: Configure DSI transcoders
This patch programs DSI operation mode, pixel format, BGR info, link calibration etc for the DSI transcoder. This patch also extract BGR info of the DSI panel from VBT and save it inside struct intel_dsi which used for configuring DSI transcoder. v2: Rebase v3: Use newly defined bitfields. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 86 +++- drivers/gpu/drm/i915/intel_dsi.h | 3 ++ drivers/gpu/drm/i915/intel_dsi_vbt.c | 1 + 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 30684f0..03534c6 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,8 +27,7 @@ #include "intel_dsi.h" -static enum transcoder __attribute__((unused)) dsi_port_to_transcoder( - enum port port) +static enum transcoder dsi_port_to_transcoder(enum port port) { if (port == PORT_A) return TRANSCODER_DSI_0; @@ -341,6 +340,86 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) } } +static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + enum transcoder dsi_trans; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)); + + if (intel_dsi->eotp_pkt == 0) + tmp |= EOTP_DISABLED; + else + tmp &= ~EOTP_DISABLED; + + /* enable link calibration if freq > 1.5Gbps */ + if (intel_dsi->bitrate_khz >= (1500 * 1000)) { + tmp &= ~LINK_CALIBRATION_MASK; + tmp |= CALIBRATION_ENABLED_INITIAL_ONLY; + } + + /* configure continuous clock */ + tmp &= ~CONTINUOUS_CLK_MASK; + if (intel_dsi->clock_stop) + tmp |= CLK_ENTER_LP_AFTER_DATA; + else + tmp |= CLK_HS_CONTINUOUS; + + /* configure buffer threshold limit to minimum */ + tmp &= ~PIX_BUF_THRESHOLD_MASK; + tmp |= PIX_BUF_THRESHOLD_1_4; + + /* set virtual channel to '0' */ + tmp &= ~PIX_VIRT_CHAN_MASK; + tmp |= PIX_VIRT_CHAN(0x0); + + /* program BGR transmission */ + if (intel_dsi->bgr_enabled) + tmp |= BGR_TRANSMISSION; + + /* select pixel format */ + tmp &= ~PIX_FMT_MASK; + + switch (intel_dsi->pixel_format) { + case MIPI_DSI_FMT_RGB888: + tmp |= PIX_FMT_RGB888; + break; + case MIPI_DSI_FMT_RGB666: + tmp |= PIX_FMT_RGB666_LOOSE; + break; + case MIPI_DSI_FMT_RGB666_PACKED: + tmp |= PIX_FMT_RGB666_PACKED; + break; + case MIPI_DSI_FMT_RGB565: + tmp |= PIX_FMT_RGB565; + break; + default: + DRM_ERROR("DSI pixel format unsupported\n"); + } + + /* program DSI operation mode */ + if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) { + tmp &= ~OP_MODE_MASK; + if (intel_dsi->video_mode_format == + VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE) { + tmp |= VIDEO_MODE_SYNC_PULSE; + } else if (intel_dsi->video_mode_format == + VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS) { + tmp |= VIDEO_MODE_SYNC_EVENT; + } else { + DRM_ERROR("DSI Video Mode unsupported\n"); + } + } + + I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -357,6 +436,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) /* setup D-PHY timings */ gen11_dsi_setup_dphy_timings(encoder); + + /* Step (4h, 4i, 4j, 4k): Configure transcoder */ + gen11_dsi_configure_transcoder(encoder); } static void __attribute__((unused)) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 25e7
[Intel-gfx] [PATCH v6 14/20] drm/i915/icl: Program TRANS_DDI_FUNC_CTL registers
This patch select input PIPE for DSI, data lanes width, enable port sync mode and wait for DSI link to become ready. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 61 +++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 03534c6..1d39975 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -340,10 +340,13 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) } } -static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder) +static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder, + const 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(>base); + struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc); + enum pipe pipe = intel_crtc->pipe; u32 tmp; enum port port; enum transcoder dsi_trans; @@ -418,9 +421,59 @@ static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder) I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp); } + + /* enable port sync mode if dual link */ + if (intel_dsi->dual_link) { + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(TRANS_DDI_FUNC_CTL2(dsi_trans)); + tmp |= PORT_SYNC_MODE_ENABLE; + I915_WRITE(TRANS_DDI_FUNC_CTL2(dsi_trans), tmp); + } + + //TODO: configure DSS_CTL1 + } + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + /*select dala lane width */ + tmp = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans)); + tmp &= ~DDI_PORT_WIDTH_MASK; + tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count); + tmp &= ~TRANS_DDI_EDP_INPUT_MASK; + + /* select input pipe */ + switch (pipe) { + case PIPE_A: + tmp |= TRANS_DDI_EDP_INPUT_A_ON; + break; + case PIPE_B: + tmp |= TRANS_DDI_EDP_INPUT_B_ONOFF; + break; + case PIPE_C: + tmp |= TRANS_DDI_EDP_INPUT_C_ONOFF; + break; + default: + DRM_ERROR("invalid pipe select\n"); + break; + } + + /* enable DDI buffer */ + tmp |= TRANS_DDI_FUNC_ENABLE; + I915_WRITE(TRANS_DDI_FUNC_CTL(dsi_trans), tmp); + } + + /* wait for link ready */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + if (wait_for_us((I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)) & + LINK_READY), 2500)) + DRM_ERROR("DSI link not ready\n"); + } } -static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) +static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config) { /* step 4a: power up all lanes of the DDI used by DSI */ gen11_dsi_power_up_lanes(encoder); @@ -438,7 +491,7 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) gen11_dsi_setup_dphy_timings(encoder); /* Step (4h, 4i, 4j, 4k): Configure transcoder */ - gen11_dsi_configure_transcoder(encoder); + gen11_dsi_configure_transcoder(encoder, pipe_config); } static void __attribute__((unused)) @@ -453,5 +506,5 @@ gen11_dsi_pre_enable(struct intel_encoder *encoder, gen11_dsi_program_esc_clk_div(encoder); /* step4: enable DSI port and DPHY */ - gen11_dsi_enable_port_and_phy(encoder); + gen11_dsi_enable_port_and_phy(encoder, pipe_config); } -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 05/20] drm/i915/icl: Define data/clock lanes dphy timing registers
This patch defines DSI_CLK_TIMING_PARAM, DPHY_CLK_TIMING_PARAM, DSI_DATA_TIMING_PARAM, DPHY_DATA_TIMING_PARAM register used in dphy programming. v2: Define mask/shift for bitfields and keep names as per BSPEC (Jani N) Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 58 + 1 file changed, 58 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4948b35..6c8999d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10285,6 +10285,64 @@ enum skl_power_gate { _ICL_DSI_T_INIT_MASTER_0,\ _ICL_DSI_T_INIT_MASTER_1) +#define _DPHY_CLK_TIMING_PARAM_0 0x162180 +#define _DPHY_CLK_TIMING_PARAM_1 0x6c180 +#define DPHY_CLK_TIMING_PARAM(port)_MMIO_PORT(port,\ + _DPHY_CLK_TIMING_PARAM_0,\ + _DPHY_CLK_TIMING_PARAM_1) +#define _DSI_CLK_TIMING_PARAM_00x6b080 +#define _DSI_CLK_TIMING_PARAM_10x6b880 +#define DSI_CLK_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DSI_CLK_TIMING_PARAM_0,\ + _DSI_CLK_TIMING_PARAM_1) +#define CLK_PREPARE_OVERRIDE (1 << 31) +#define CLK_PREPARE(x)((x) << 28) +#define CLK_PREPARE_MASK (0x7 << 28) +#define CLK_PREPARE_SHIFT 28 +#define CLK_ZERO_OVERRIDE (1 << 27) +#define CLK_ZERO(x) ((x) << 20) +#define CLK_ZERO_MASK (0xf << 20) +#define CLK_ZERO_SHIFT20 +#define CLK_PRE_OVERRIDE (1 << 19) +#define CLK_PRE(x)((x) << 16) +#define CLK_PRE_MASK (0x3 << 16) +#define CLK_PRE_SHIFT 16 +#define CLK_POST_OVERRIDE (1 << 15) +#define CLK_POST(x) ((x) << 8) +#define CLK_POST_MASK (0x7 << 8) +#define CLK_POST_SHIFT8 +#define CLK_TRAIL_OVERRIDE(1 << 7) +#define CLK_TRAIL(x) ((x) << 0) +#define CLK_TRAIL_MASK(0xf << 0) +#define CLK_TRAIL_SHIFT 0 + +#define _DPHY_DATA_TIMING_PARAM_0 0x162184 +#define _DPHY_DATA_TIMING_PARAM_1 0x6c184 +#define DPHY_DATA_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DPHY_DATA_TIMING_PARAM_0,\ + _DPHY_DATA_TIMING_PARAM_1) +#define _DSI_DATA_TIMING_PARAM_0 0x6B084 +#define _DSI_DATA_TIMING_PARAM_1 0x6B884 +#define DSI_DATA_TIMING_PARAM(port)_MMIO_PORT(port,\ + _DSI_DATA_TIMING_PARAM_0,\ + _DSI_DATA_TIMING_PARAM_1) +#define HS_PREPARE_OVERRIDE (1 << 31) +#define HS_PREPARE(x) ((x) << 24) +#define HS_PREPARE_MASK (0x7 << 24) +#define HS_PREPARE_SHIFT 24 +#define HS_ZERO_OVERRIDE (1 << 23) +#define HS_ZERO(x)((x) << 16) +#define HS_ZERO_MASK (0xf << 16) +#define HS_ZERO_SHIFT 16 +#define HS_TRAIL_OVERRIDE (1 << 15) +#define HS_TRAIL(x) ((x) << 8) +#define HS_TRAIL_MASK (0x7 << 8) +#define HS_TRAIL_SHIFT8 +#define HS_EXIT_OVERRIDE (1 << 7) +#define HS_EXIT(x)((x) << 0) +#define HS_EXIT_MASK (0x7 << 0) +#define HS_EXIT_SHIFT 0 + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 17/20] drm/i915/icl: Define TRANS_CONF register for DSI
This patch defines TRANS_CONF registers for DSI ports 0 and 1. Bitfields of these registers used for enabling and reading the current state of transcoder. v2: Add blank line before comment Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_pci.c | 3 ++- drivers/gpu/drm/i915/i915_reg.h | 8 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index bd4e0fd..f1af50b 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -34,7 +34,8 @@ #define GEN_DEFAULT_PIPEOFFSETS \ .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ - PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ + PIPE_C_OFFSET, PIPE_EDP_OFFSET, \ + PIPE_DSI0_OFFSET, PIPE_DSI1_OFFSET}, \ .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET, \ TRANSCODER_DSI0_OFFSET, TRANSCODER_DSI1_OFFSET}, \ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a87f0ef..34a0afa 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5543,6 +5543,10 @@ enum { #define DSL_LINEMASK_GEN20x0fff #define DSL_LINEMASK_GEN30x1fff #define _PIPEACONF 0x70008 + +/* gen 11 DSI transcoder '0' and '1' */ +#define _PIPEDSI0CONF 0x7b008 +#define _PIPEDSI1CONF 0x7b808 #define PIPECONF_ENABLE (1 << 31) #define PIPECONF_DISABLE 0 #define PIPECONF_DOUBLE_WIDE (1 << 30) @@ -5650,6 +5654,10 @@ enum { */ #define PIPE_EDP_OFFSET0x7f000 +/* gen 11 DSI transcoder '0' and '1' */ +#define PIPE_DSI0_OFFSET 0x7b000 +#define PIPE_DSI1_OFFSET 0x7b800 + #define _MMIO_PIPE2(pipe, reg) _MMIO(dev_priv->info.pipe_offsets[pipe] - \ dev_priv->info.pipe_offsets[PIPE_A] + (reg) + \ dev_priv->info.display_mmio_offset) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 03/20] drm/i915/icl: Enable DDI Buffer
This patch enables DDI buffer by writing to DDI_BUF_CTL register and wait for DDI status to be *not idle* for a port. v2: Rebase v3: Remove step hard coding comments (Jani N) Signed-off-by: Madhav Chauhan Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/icl_dsi.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index e5c18a8..190316c 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -258,6 +258,25 @@ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder) } } +static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(DDI_BUF_CTL(port)); + tmp |= DDI_BUF_CTL_ENABLE; + I915_WRITE(DDI_BUF_CTL(port), tmp); + + if (wait_for_us(!(I915_READ(DDI_BUF_CTL(port)) & + DDI_BUF_IS_IDLE), + 500)) + DRM_ERROR("DDI port:%c buffer idle\n", port_name(port)); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -268,6 +287,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) /* step 4c: configure voltage swing and skew */ gen11_dsi_voltage_swing_program_seq(encoder); + + /* enable DDI buffer */ + gen11_dsi_enable_ddi_buffer(encoder); } static void __attribute__((unused)) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v6 02/20] drm/i915/icl: DSI vswing programming sequence
This patch setup voltage swing before enabling combo PHY DDI (shared with DSI). Note that DSI voltage swing programming is for high speed data buffers. HW automatically handles the voltage swing for the low power data buffers. v2: Rebase v3: Address various review comments related to VSWING programming (Jani N) Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 120 + 1 file changed, 120 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 1607cac..e5c18a8 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,6 +27,71 @@ #include "intel_dsi.h" +static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + u32 tmp; + int lane; + + for_each_dsi_port(port, intel_dsi->ports) { + + /* +* Program voltage swing and pre-emphasis level values as per +* table in BSPEC under DDI buffer programing +*/ + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK); + tmp |= SCALING_MODE_SEL(0x2); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + tmp |= RTERM_SELECT(0x6); + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK); + tmp |= SCALING_MODE_SEL(0x2); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + tmp |= RTERM_SELECT(0x6); + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK | +RCOMP_SCALAR_MASK); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK | +RCOMP_SCALAR_MASK); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | +CURSOR_COEFF_MASK); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x3f); + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + + for (lane = 0; lane <= 3; lane++) { + /* Bspec: must not use GRP register for write */ + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | +CURSOR_COEFF_MASK); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x3f); + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } +} + static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -141,6 +206,58 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) } +static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + + /* clear common keeper enable bit */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(port)); + tmp &= ~COMMON_KEEPER_EN; + I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(port)); + tmp &= ~COMMON_KEEPER_EN; + I915_WRITE(ICL_PORT_PCS_DW1_AUX(port), tmp); + } + + /* +* Set SUS Clock Config bitfield to 11b +* Note: loadgen select program is done +* as part of lane phy sequence configuration +*/ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_CL_DW5(port)); + tmp |= SUS_CLOCK_CONFIG; + I915_WRITE(ICL_PORT_CL_DW5(port), tmp); + } + + /* Clear tra
Re: [Intel-gfx] [PATCH v5 11/13] drm/i915/icl: Add macros for MMIO of DSI transcoder registers
On 9/14/2018 6:36 PM, Madhav Chauhan wrote: On 9/14/2018 5:55 PM, Ville Syrjälä wrote: On Fri, Sep 14, 2018 at 11:42:33AM +0530, Madhav Chauhan wrote: On 9/12/2018 11:30 PM, Ville Syrjälä wrote: On Wed, Sep 12, 2018 at 03:06:41PM +0530, Madhav Chauhan wrote: On 7/19/2018 9:52 PM, Ville Syrjälä wrote: On Tue, Jul 10, 2018 at 03:10:12PM +0530, Madhav Chauhan wrote: This patch adds _MMIO_DSI and _DSI_TRANS macros for accessing DSI transcoder registers. Credits-to: Jani N Cc: Jani Nikula Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1d13ba9..62bc76e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9576,6 +9576,11 @@ enum skl_power_gate { #define _MIPI_PORT(port, a, c)(((port) == PORT_A) ? a : c)/* ports A and C only */ #define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c)) +/* gen11 DSI */ +#define _DSI_TRANS(tc, dsi0, dsi1)(((tc) == TRANSCODER_DSI_0) ?\ + (dsi0) : (dsi1)) _PIPE() etc. should result in slughtly better code IIRC. Can you please clarify on this?? Plenty of examples in i915_reg.h for using _PIPE(). I meant what are advantages of using _PIPE against the current approach?? Uniform style, better generated code usually (look at the generated asm to verify). Got it. Also if we use _PIPE, are you suggesting something below: #define _MMIO_DSI(tc, dsi0, dsi1)_MMIO_PIPE(tc, dsi0, dsi1)) Using above macro we will get wrong DSI addresses as TRANS_DSI_0 value is 5. (tc)-TRANSCODER_DSI_0 Can we use _MMIO_TRANS here, _TRANS & _PIPE have same definition?? That will emphasize that these registers are transcoder specific not the PIPE. Regards, Madhav Thanks for clarification Ville, will use _PIPE(). Regards, Madhav Or do you mean to use PORT instead of TRANS_DSI_0/1 to _MMIO_DSI?? Regards, Madhav Regards, Madhav +#define _MMIO_DSI(tc, dsi0, dsi1)_MMIO(_DSI_TRANS(tc, dsi0, dsi1)) + #define MIPIO_TXESC_CLK_DIV1 _MMIO(0x160004) #define GLK_TX_ESC_CLK_DIV1_MASK0x3FF #define MIPIO_TXESC_CLK_DIV2 _MMIO(0x160008) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 11/13] drm/i915/icl: Add macros for MMIO of DSI transcoder registers
On 9/14/2018 5:55 PM, Ville Syrjälä wrote: On Fri, Sep 14, 2018 at 11:42:33AM +0530, Madhav Chauhan wrote: On 9/12/2018 11:30 PM, Ville Syrjälä wrote: On Wed, Sep 12, 2018 at 03:06:41PM +0530, Madhav Chauhan wrote: On 7/19/2018 9:52 PM, Ville Syrjälä wrote: On Tue, Jul 10, 2018 at 03:10:12PM +0530, Madhav Chauhan wrote: This patch adds _MMIO_DSI and _DSI_TRANS macros for accessing DSI transcoder registers. Credits-to: Jani N Cc: Jani Nikula Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1d13ba9..62bc76e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9576,6 +9576,11 @@ enum skl_power_gate { #define _MIPI_PORT(port, a, c) (((port) == PORT_A) ? a : c)/* ports A and C only */ #define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c)) +/* gen11 DSI */ +#define _DSI_TRANS(tc, dsi0, dsi1) (((tc) == TRANSCODER_DSI_0) ? \ +(dsi0) : (dsi1)) _PIPE() etc. should result in slughtly better code IIRC. Can you please clarify on this?? Plenty of examples in i915_reg.h for using _PIPE(). I meant what are advantages of using _PIPE against the current approach?? Uniform style, better generated code usually (look at the generated asm to verify). Got it. Also if we use _PIPE, are you suggesting something below: #define _MMIO_DSI(tc, dsi0, dsi1)_MMIO_PIPE(tc, dsi0, dsi1)) Using above macro we will get wrong DSI addresses as TRANS_DSI_0 value is 5. (tc)-TRANSCODER_DSI_0 Thanks for clarification Ville, will use _PIPE(). Regards, Madhav Or do you mean to use PORT instead of TRANS_DSI_0/1 to _MMIO_DSI?? Regards, Madhav Regards, Madhav +#define _MMIO_DSI(tc, dsi0, dsi1) _MMIO(_DSI_TRANS(tc, dsi0, dsi1)) + #define MIPIO_TXESC_CLK_DIV1_MMIO(0x160004) #define GLK_TX_ESC_CLK_DIV1_MASK 0x3FF #define MIPIO_TXESC_CLK_DIV2_MMIO(0x160008) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 11/13] drm/i915/icl: Add macros for MMIO of DSI transcoder registers
On 9/12/2018 11:30 PM, Ville Syrjälä wrote: On Wed, Sep 12, 2018 at 03:06:41PM +0530, Madhav Chauhan wrote: On 7/19/2018 9:52 PM, Ville Syrjälä wrote: On Tue, Jul 10, 2018 at 03:10:12PM +0530, Madhav Chauhan wrote: This patch adds _MMIO_DSI and _DSI_TRANS macros for accessing DSI transcoder registers. Credits-to: Jani N Cc: Jani Nikula Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1d13ba9..62bc76e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9576,6 +9576,11 @@ enum skl_power_gate { #define _MIPI_PORT(port, a, c) (((port) == PORT_A) ? a : c)/* ports A and C only */ #define _MMIO_MIPI(port, a, c) _MMIO(_MIPI_PORT(port, a, c)) +/* gen11 DSI */ +#define _DSI_TRANS(tc, dsi0, dsi1) (((tc) == TRANSCODER_DSI_0) ? \ +(dsi0) : (dsi1)) _PIPE() etc. should result in slughtly better code IIRC. Can you please clarify on this?? Plenty of examples in i915_reg.h for using _PIPE(). I meant what are advantages of using _PIPE against the current approach?? Also if we use _PIPE, are you suggesting something below: #define _MMIO_DSI(tc, dsi0, dsi1)_MMIO_PIPE(tc, dsi0, dsi1)) Using above macro we will get wrong DSI addresses as TRANS_DSI_0 value is 5. Or do you mean to use PORT instead of TRANS_DSI_0/1 to _MMIO_DSI?? Regards, Madhav Regards, Madhav +#define _MMIO_DSI(tc, dsi0, dsi1) _MMIO(_DSI_TRANS(tc, dsi0, dsi1)) + #define MIPIO_TXESC_CLK_DIV1 _MMIO(0x160004) #define GLK_TX_ESC_CLK_DIV1_MASK0x3FF #define MIPIO_TXESC_CLK_DIV2 _MMIO(0x160008) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 11/13] drm/i915/icl: Add macros for MMIO of DSI transcoder registers
On 7/19/2018 9:52 PM, Ville Syrjälä wrote: On Tue, Jul 10, 2018 at 03:10:12PM +0530, Madhav Chauhan wrote: This patch adds _MMIO_DSI and _DSI_TRANS macros for accessing DSI transcoder registers. Credits-to: Jani N Cc: Jani Nikula Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1d13ba9..62bc76e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9576,6 +9576,11 @@ enum skl_power_gate { #define _MIPI_PORT(port, a, c)(((port) == PORT_A) ? a : c)/* ports A and C only */ #define _MMIO_MIPI(port, a, c)_MMIO(_MIPI_PORT(port, a, c)) +/* gen11 DSI */ +#define _DSI_TRANS(tc, dsi0, dsi1) (((tc) == TRANSCODER_DSI_0) ? \ +(dsi0) : (dsi1)) _PIPE() etc. should result in slughtly better code IIRC. Can you please clarify on this?? Regards, Madhav +#define _MMIO_DSI(tc, dsi0, dsi1) _MMIO(_DSI_TRANS(tc, dsi0, dsi1)) + #define MIPIO_TXESC_CLK_DIV1 _MMIO(0x160004) #define GLK_TX_ESC_CLK_DIV1_MASK 0x3FF #define MIPIO_TXESC_CLK_DIV2 _MMIO(0x160008) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 12/13] drm/i915/icl: Define TRANS_DSI_FUNC_CONF register
On 9/12/2018 1:00 AM, Jani Nikula wrote: On Tue, 10 Jul 2018, Madhav Chauhan wrote: This patch defines transcoder function configuration registers and its bitfields for both DSI ports. Used while programming/enabling DSI transcoder. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 47 + 1 file changed, 47 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 62bc76e..71ce6ba 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10134,6 +10134,53 @@ enum skl_power_gate { #define TA_SURE_TIME(x) (x << 16) #define TA_SURE_TIME_MASK(0x1f << 16) +/* DSI transcoder configuration */ +#define _DSI_TRANS_FUNC_CONF_0 0x6b030 +#define _DSI_TRANS_FUNC_CONF_1 0x6b830 +#define DSI_TRANS_FUNC_CONF(tc)_MMIO_DSI(tc, \ + _DSI_TRANS_FUNC_CONF_0,\ + _DSI_TRANS_FUNC_CONF_1) +#define OP_MODE(x)(x << 28) +#define OP_MODE_MASK (0x3 << 28) +#define CMD_MODE_NO_GATE 0x0 +#define CMD_MODE_TE_GATE 0x1 +#define VIDEO_MODE_SYNC_EVENT 0x2 +#define VIDEO_MODE_SYNC_PULSE 0x3 The convention is to define macros for field values that you can OR directly in place instead of requiring a shift. Please stick to the conventions. Use _SHIFT and _MASK. We can debate the relative merits of both approaches at some point, but this is not the time. Just to understand this point correctly, #define OP_MODE(x) ((x) << 28) is OK but #define OP_MODE_MASK (0x3 << 28) is NOT OK and should be: #define OP_MODE_MASK0x3 #define OP_MODE_SHIFT 28 Regards, Madhav BR, Jani. +#define LINK_READY(1 << 20) +#define PIX_FMT(x)(x << 16) +#define PIX_FMT_MASK (0x3 << 16) +#define PIX_FMT_RGB5650x0 +#define PIX_FMT_RGB666_PACKED 0x1 +#define PIX_FMT_RGB666_LOOSE 0x2 +#define PIX_FMT_RGB8880x3 +#define PIX_FMT_RGB101010 0x4 +#define PIX_FMT_RGB121212 0x5 +#define PIX_FMT_COMPRESSED0x6 +#define BGR_TRANSMISSION (1 << 15) +#define PIX_VIRT_CHAN(x) (x << 12) +#define PIX_VIRT_CHAN_MASK(0x3 << 12) +#define PIX_BUF_THRESHOLD(x) ((x & 0x3) << 10) +#define PIX_BUF_THRESHOLD_MASK(0x3 << 10) +#define PIX_BUF_THRESHOLD_1_4 0x0 +#define PIX_BUF_THRESHOLD_1_2 0x1 +#define PIX_BUF_THRESHOLD_3_4 0x2 +#define PIX_BUF_THRESHOLD_FULL0x3 +#define CONTINUOUS_CLK(x) (x << 8) +#define CONTINUOUS_CLK_MASK (0x3 << 8) +#define CLK_ENTER_LP_AFTER_DATA 0x0 +#define CLK_HS_OR_LP 0x2 +#define CLK_HS_CONTINUOUS 0x3 +#define LINK_CALIBRATION(x) (x << 4) +#define LINK_CALIBRATION_MASK (0x3 << 4) +#define CALIBRATION_DISABLED 0x0 +#define CALIBRATION_ENABLED_INITIAL_ONLY 0x2 +#define CALIBRATION_ENABLED_INITIAL_PERIODIC 0x3 +#define S3D_ORIENTATION(x)(x << 1) +#define S3D_ORIENTATION_MASK (0x1 << 1) +#define S3D_ORIENTATION_PORTRAIT 0x0 +#define S3D_ORIENTATION_LANDSCAPE 0x1 +#define EOTP_DISABLED (1 << 0) + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb884) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 09/13] drm/i915/icl: Program TA_TIMING_PARAM registers
On 9/12/2018 12:56 AM, Jani Nikula wrote: On Fri, 20 Jul 2018, "Chauhan, Madhav" wrote: -Original Message- From: Ville Syrjälä [mailto:ville.syrj...@linux.intel.com] Sent: Thursday, July 19, 2018 9:51 PM To: Chauhan, Madhav Cc: intel-gfx@lists.freedesktop.org; Nikula, Jani ; Zanoni, Paulo R ; Vivi, Rodrigo Subject: Re: [Intel-gfx] [PATCH v5 09/13] drm/i915/icl: Program TA_TIMING_PARAM registers On Tue, Jul 10, 2018 at 03:10:10PM +0530, Madhav Chauhan wrote: This patch programs D-PHY timing parameters for the bus turn around flow(in escape clocks) only if dsi link frequency <=800 MHz using DPHY_TA_TIMING_PARAM and its identical register DSI_TA_TIMING_PARAM (inside DSI Controller within the Display Core). Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 21 + drivers/gpu/drm/i915/intel_dsi.h | 1 + drivers/gpu/drm/i915/intel_dsi_vbt.c | 1 + 3 files changed, 23 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 832772d..8fd5284 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -302,6 +302,27 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) I915_WRITE(DSI_DATA_TIMING_PARAM(port), intel_dsi->dphy_data_lane_reg); } + + /* +* If DSI link operating at or below an 800 MHz, +* TA_SURE should be override and programmed to +* a value '0' inside TA_PARAM_REGISTERS otherwise +* leave all fields at HW default values. +*/ + if (intel_dsi->bitrate_khz <= KHz(800)) { The KHz(800) confuses me. My brain thinks this value is 800 kHz when it's not. So I'd write it without the KHz() macro. Ok. Initially I wrote without using KHz macro, but got comment to use KHz macro :) Did I? Oh well. Go with 80. Ok :) Please don't add additional state with intel_dsi->bitrate_khz when you can calculate the bitrate at any time. Add a function to do it if you like, and use it in both places. Ok. But we will reusing this bitrate(same value) in multiple place. Shouldn't we cache it rather than calculating everytime?? Regards, Madhav BR, Jani. Regards, Madhav + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(DPHY_TA_TIMING_PARAM(port)); + tmp &= ~TA_SURE_TIME_MASK; + tmp |= (TA_SURE_OVERRIDE | TA_SURE_TIME(0)); + I915_WRITE(DPHY_TA_TIMING_PARAM(port), tmp); + + /* shadow register inside display core */ + tmp = I915_READ(DSI_TA_TIMING_PARAM(port)); + tmp &= ~TA_SURE_TIME_MASK; + tmp |= (TA_SURE_OVERRIDE | TA_SURE_TIME(0)); + I915_WRITE(DSI_TA_TIMING_PARAM(port), tmp); + } + } } static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 9fd8526..25e7396 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -101,6 +101,7 @@ struct intel_dsi { u16 init_count; u32 pclk; + u32 bitrate_khz; u16 burst_mode_ratio; /* all delays in ms */ diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 428290d..a9a98a4 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -589,6 +589,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->pclk = pclk; bitrate = (pclk * bpp) / intel_dsi->lane_count; + intel_dsi->bitrate_khz = bitrate; switch (intel_dsi->escape_clk_div) { case 0: -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 08/13] drm/i915/icl: Define TA_TIMING_PARAM registers
On 9/12/2018 12:53 AM, Jani Nikula wrote: On Tue, 10 Jul 2018, Madhav Chauhan wrote: This patch defines DSI_TA_TIMING_PARAM and DPHY_TA_TIMING_PARAM registers used in dphy programming. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0dbdd57..1d13ba9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10115,6 +10115,20 @@ enum skl_power_gate { #define HS_EXIT_OVERRIDE (1 << 7) #define HS_EXIT_TIME(x) (x << 0) +#define _DPHY_TA_TIMING_PARAM_0 0x162188 +#define _DPHY_TA_TIMING_PARAM_10x6c188 +#define DPHY_TA_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DPHY_TA_TIMING_PARAM_0,\ + _DPHY_TA_TIMING_PARAM_1) +#define _DSI_TA_TIMING_PARAM_0 0x6b098 +#define _DSI_TA_TIMING_PARAM_1 0x6b898 +#define DSI_TA_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DSI_TA_TIMING_PARAM_0,\ + _DSI_TA_TIMING_PARAM_1) +#define TA_SURE_OVERRIDE (1 << 31) +#define TA_SURE_TIME(x) (x << 16) +#define TA_SURE_TIME_MASK (0x1f << 16) Please stick to _SHIFT. And in any case macro arguments need parens around them. Please add all the fields for the registers in one go. Ok. Thanks!! Regards, Madhav BR, Jani. + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb884) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 06/13] drm/i915/icl: Define data/clock lanes dphy timing registers
On 9/12/2018 12:44 AM, Jani Nikula wrote: On Tue, 10 Jul 2018, Madhav Chauhan wrote: This patch defines DSI_CLK_TIMING_PARAM, DPHY_CLK_TIMING_PARAM, DSI_DATA_TIMING_PARAM, DPHY_DATA_TIMING_PARAM register used in dphy programming. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 40 1 file changed, 40 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6129372..0dbdd57 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10075,6 +10075,46 @@ enum skl_power_gate { _ICL_DSI_T_INIT_MASTER_0,\ _ICL_DSI_T_INIT_MASTER_1) +#define _DPHY_CLK_TIMING_PARAM_0 0x162180 +#define _DPHY_CLK_TIMING_PARAM_1 0x6c180 +#define DPHY_CLK_TIMING_PARAM(port)_MMIO_PORT(port,\ + _DPHY_CLK_TIMING_PARAM_0,\ + _DPHY_CLK_TIMING_PARAM_1) +#define _DSI_CLK_TIMING_PARAM_00x6b080 +#define _DSI_CLK_TIMING_PARAM_10x6b880 +#define DSI_CLK_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DSI_CLK_TIMING_PARAM_0,\ + _DSI_CLK_TIMING_PARAM_1) +#define CLK_PREP_OVERRIDE (1 << 31) +#define CLK_PREP_TIME(x) (x << 28) +#define CLK_ZERO_OVERRIDE (1 << 27) +#define CLK_ZERO_TIME(x) (x << 20) +#define CLK_PRE_OVERRIDE (1 << 19) +#define CLK_PRE_TIME(x) (x << 16) +#define CLK_POST_OVERRIDE (1 << 15) +#define CLK_POST_TIME(x) (x << 8) +#define CLK_TRAIL_OVERRIDE(1 << 7) +#define CLK_TRAIL_TIME(x) (x << 0) I would prefer we stuck to the convention of defining _SHIFT and _MASK macros for the bitfields. Even if the above style has started to creep in without proper discussion. (I approve of the function-like macros for things that aren't straight shifts; stuff with split bitfields or calculations.) No matter what, you need to wrap the macro arguments in parens! Also, please don't do your own abbreviations or renames of the field names when the bspec name is short/good enough. Ok. I will add the mask and wrap the arguments in parens. Also will recheck the names as per BSPEC. Regards, Madhav + +#define _DPHY_DATA_TIMING_PARAM_0 0x162184 +#define _DPHY_DATA_TIMING_PARAM_1 0x6c184 +#define DPHY_DATA_TIMING_PARAM(port) _MMIO_PORT(port,\ + _DPHY_DATA_TIMING_PARAM_0,\ + _DPHY_DATA_TIMING_PARAM_1) +#define _DSI_DATA_TIMING_PARAM_0 0x6B084 +#define _DSI_DATA_TIMING_PARAM_1 0x6B884 +#define DSI_DATA_TIMING_PARAM(port)_MMIO_PORT(port,\ + _DSI_DATA_TIMING_PARAM_0,\ + _DSI_DATA_TIMING_PARAM_1) +#define HS_PREP_OVERRIDE (1 << 31) +#define HS_PREP_TIME(x) (x << 24) +#define HS_ZERO_OVERRIDE (1 << 23) +#define HS_ZERO_TIME(x) (x << 16) +#define HS_TRAIL_OVERRIDE (1 << 15) +#define HS_TRAIL_TIME(x) (x << 8) +#define HS_EXIT_OVERRIDE (1 << 7) +#define HS_EXIT_TIME(x) (x << 0) Same as above. The register offsets and shifts etc. look ok. BR, Jani. + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL(dev_priv->mipi_mmio_base + 0xb884) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 03/13] drm/i915/icl: Enable DDI Buffer
On 9/12/2018 12:24 AM, Jani Nikula wrote: On Tue, 10 Jul 2018, Madhav Chauhan wrote: This patch enables DDI buffer by writing to DDI_BUF_CTL register and wait for DDI status to be *not idle* for a port. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index dc16c1f..41faa19 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -251,6 +251,25 @@ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder) } } +static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(DDI_BUF_CTL(port)); + tmp |= DDI_BUF_CTL_ENABLE; + I915_WRITE(DDI_BUF_CTL(port), tmp); + + if (wait_for_us(!(I915_READ(DDI_BUF_CTL(port)) & + DDI_BUF_IS_IDLE), + 500)) IMO a "== 0" check reads better in wait_for_us. + DRM_ERROR("DDI port:%c buffer idle\n", port_name(port)); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -261,6 +280,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) /* step 4c: configure voltage swing and skew */ gen11_dsi_voltage_swing_program_seq(encoder); + + /* step 4d: enable DDI buffer */ Alas, this is step 4e now, and you have a new 4d to take care of for B0+. Yes. Will remove step hardcoding comments from patch. Regards, Madhav Regardless, Reviewed-by: Jani Nikula + gen11_dsi_enable_ddi_buffer(encoder); } static void __attribute__((unused)) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 02/13] drm/i915/icl: DSI vswing programming sequence
On 9/12/2018 12:20 AM, Jani Nikula wrote: On Tue, 10 Jul 2018, Madhav Chauhan wrote: This patch setup voltage swing before enabling combo PHY DDI (shared with DSI). Note that DSI voltage swing programming is for high speed data buffers. HW automatically handles the voltage swing for the low power data buffers. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 114 + 1 file changed, 114 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index a571339..dc16c1f 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,6 +27,65 @@ #include "intel_dsi.h" +static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + u32 tmp; + int lane; + + for_each_dsi_port(port, intel_dsi->ports) { + + /* Bspec: set scaling mode to 0x6 */ Today bspec says 2. Also, please don't duplicate the value in the comment. Right..thanks for catching :) + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp |= SCALING_MODE_SEL(6); + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); Like Ville said, adding a blank line between each read-modify-write group helps readability. Perhaps add /* DW5 */ etc. comments to group the, eh, groups. Ok. + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp |= SCALING_MODE_SEL(6); + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); Are you missing RTERM_SELECT? Looks this was not earlier and added recently. Will program in next version. Why do you do two read-modify-writes (RMW) on both GRP and AUX, instead of doing all the changes at once? Do you mean for tmp |= TAP2_DISABLE | TAP3_DISABLE ?? If yes, because GRP and AUX might contain different values and need to read them explicitly. The RMW doesn't actually clear the fields before changing them, just ORs more stuff on top of them, and cursor program or coeff polarity might contain garbage (at least in theory). The same below. Yeah, we need to reset those bits using MASK and then do 'OR'. Or are you suggesting something else?? + + /* +* swing and scaling values are taken from DSI +* table under vswing programming sequence for +* combo phy ddi in BSPEC. +* program swing values +*/ Please reflow the comment. Ok. + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); This would benefit from +#define SWING_SEL_MASK (SWING_SEL_UPPER_MASK | SWING_SEL_LOWER_MASK) +#define SWING_SEL(x) (SWING_SEL_UPPER(x) | SWING_SEL_LOWER(x)) in i915_reg.h. But I can look the other way and fix it myself later... + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + + /* program scaling values */ + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x18); 0x3f? Yes, now its changed to 0x3f. Again, you need to zero the fields before ORin the new values into them. Agree. + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + + for (lane = 0; lane <= 3; lane++) { + /* Bspec: must not use GRP register for write */ I'll take your word for it, although I've missed such a requirement. :-) + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x18); 0x3f? Yes. + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } +} + static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -140,6 +199,58 @@ static void gen11_dsi_config_
Re: [Intel-gfx] [v5, 02/13] drm/i915/icl: DSI vswing programming sequence
On 9/11/2018 11:46 PM, Jani Nikula wrote: On Mon, 10 Sep 2018, Madhav Chauhan wrote: On 9/6/2018 7:31 PM, Kulkarni, Vandita wrote: On 7/10/2018 3:10 PM, Madhav Chauhan wrote: This patch setup voltage swing before enabling combo PHY DDI (shared with DSI). Note that DSI voltage swing programming is for high speed data buffers. HW automatically handles the voltage swing for the low power data buffers. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 114 + 1 file changed, 114 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index a571339..dc16c1f 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,6 +27,65 @@ #include "intel_dsi.h" +static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + u32 tmp; + int lane; + + for_each_dsi_port(port, intel_dsi->ports) { + + /* Bspec: set scaling mode to 0x6 */ + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp |= SCALING_MODE_SEL(6); + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp |= SCALING_MODE_SEL(6); + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + + /* +* swing and scaling values are taken from DSI +* table under vswing programming sequence for +* combo phy ddi in BSPEC. +* program swing values +*/ + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + + /* program scaling values */ + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x18); + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + + for (lane = 0; lane <= 3; lane++) { + /* Bspec: must not use GRP register for write */ + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x18); + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } +} + static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -140,6 +199,58 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) } } I see from the bspec that except for the Loadgen Select and Latency Optimization all other DDI buffer programming can be taken from the DDI Buffer section. Can we use this function "icl_ddi_combo_vswing_program" function which is already there patch for reference: https://patchwork.freedesktop.org/patch/213515/ For code already merged upstream, please use commit id or file references. We can't directly use that implementation. Reasons: 1. For DSI we use AUX register as well to write which is not the case for DDI. We need to add multiple INTEL_OUTPUT_DSI checks . 2. DSI specific icl_combo_phy_ddi_buf_trans not added in intel_ddi.c which will be used while doing vswing programming 3. intel_ddi_dp_level doesn't support "level" calculation for DSI. Also in past we had similar discussion (with Jani N) to keep DSI specific entries/code in DSI encoder. Jani N whats the suggestion here?? Let's go with the slightly duplicated code, at least for now to get this merged. This is tedious stuff to review, and combining that with merging to DP/HDMI buf programming makes it unnecessarily hard. We can refactor afterwards as needed. BR, Jani. Thanks for clarification Jani. Regards, Madhav Regards, Madhav Thanks, Vandita +static void gen11_dsi_voltage_swing_program_seq(str
Re: [Intel-gfx] [PATCH v5 01/13] drm/i915/icl: Configure lane sequencing of combo phy transmitter
On 9/11/2018 11:16 PM, Jani Nikula wrote: On Fri, 27 Jul 2018, "Chauhan, Madhav" wrote: -Original Message- From: Chauhan, Madhav Sent: Friday, July 20, 2018 12:06 AM To: Ville Syrjälä Cc: intel-gfx@lists.freedesktop.org; Nikula, Jani ; Zanoni, Paulo R ; Vivi, Rodrigo Subject: RE: [Intel-gfx] [PATCH v5 01/13] drm/i915/icl: Configure lane sequencing of combo phy transmitter -Original Message- From: Ville Syrjälä [mailto:ville.syrj...@linux.intel.com] Sent: Thursday, July 19, 2018 9:42 PM To: Chauhan, Madhav Cc: intel-gfx@lists.freedesktop.org; Nikula, Jani ; Zanoni, Paulo R ; Vivi, Rodrigo Subject: Re: [Intel-gfx] [PATCH v5 01/13] drm/i915/icl: Configure lane sequencing of combo phy transmitter On Tue, Jul 10, 2018 at 03:10:02PM +0530, Madhav Chauhan wrote: This patch set the loadgen select and latency optimization for aux and transmit lanes of combo phy transmitters. It will be used for MIPI DSI HS operations. Thanks for reviewing DSI patches. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 13830e4..a571339 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -105,10 +105,48 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) } } +static void gen11_dsi_config_phy_lanes_sequence(struct +intel_encoder +*encoder) { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + u32 tmp; + int lane; tmp/lane could be moved to into the loops. Was it due to intel_dsi->ports have no port assigned and loop for_each_dsi_port() will not proceed further?? If that's the case, these encoder enable/disable function should be called Only when dsi_init is success and then, intel_dsi->ports have some valid port value. Please clarify. Ville's comments are purely about style and readability. Regards, Madhav Same in other patches. Agree, make sense. Just to understand + + /* Step 4b(i) set loadgen select for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp &= ~LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + for (lane = 0; lane <= 3; lane++) { + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp &= ~LOADGEN_SELECT; + if (lane != 2) + tmp |= LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } + + /* Step 4b(ii) set latency optimization for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); The "read something, modify, write something else" pattern always gives me the creeps. But I guess reading _GRP is not an option? Anyway, for the actual content, Reviewed-by: Jani Nikula Thanks for the review. Yes, we need to read *only* LN0 and if same value, then write through GRP register. Regards, Madhav + } An empty line here and there would make this a bit more legible. Same in other patches. Ok. Thought this will be additional line, multiple Places in code use this :) Regards, Madhav +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ gen11_dsi_power_up_lanes(encoder); + + /* step 4b: configure lane sequencing of the Combo-PHY +transmitters */ + gen11_dsi_config_phy_lanes_sequence(encoder); } static void __attribute__((unused)) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 00/13] ICELAKE DSI DRIVER
On 9/12/2018 1:05 AM, Jani Nikula wrote: On Tue, 10 Jul 2018, Madhav Chauhan wrote: From ICELAKE platform onwards, new MIPI DSI IP controller is integrated to GPU/Display Engine and same could be extended for future Intel platforms as well. DSI IP controller supports MIPI DSI 1.3 and DPHY 1.2 specification. So, a new DSI driver has been added inside I915. Given below patches are the part of new DSI driver which implements BSPEC sequence till transcoder configuration. Rest of the patches published to GITHUB and latest snapshot can be downloaded using: #git clone https://github.com/madhavchauhan/Intel-DSI-Driver.git v2: Addressed review comments from Jani N for Patches 1-6 and rebase for some other few patches. v3: Renamed intel_dsi_new.c to gen11_dsi.c as per discussion with Jani, Daniel, Ville. Also addressed review comments for couple of patches. v4: Rename gen11_dsi.c to icl_dsi.c (Ville). No functional changes. v5: Rebase on drm-tip after initial 7 patches got merged. Hi Madhav, I think there's enough review here to warrant a revised set. I regret I haven't been able to review this earlier, and I'm now throwing the ball back in your court... with the added pressure that I'd really like to get this merged for v4.20. Which means the deadline for merging is about 1½ weeks away. Is there any chance? Agree, i will publish next series soon. Do you mean to merge these 13 patches to 4.20 or the complete implementation of 65 patches?? Regards, Madhav BR, Jani. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v5 01/13] drm/i915/icl: Configure lane sequencing of combo phy transmitter
On 9/10/2018 5:50 PM, Lisovskiy, Stanislav wrote: On Tue, 2018-07-10 at 15:10 +0530, Madhav Chauhan wrote: This patch set the loadgen select and latency optimization for aux and transmit lanes of combo phy transmitters. It will be used for MIPI DSI HS operations. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 13830e4..a571339 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -105,10 +105,48 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) } } +static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder- base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi( base); + enum port port; + u32 tmp; + int lane; + + /* Step 4b(i) set loadgen select for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp &= ~LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + for (lane = 0; lane <= 3; lane++) { + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp &= ~LOADGEN_SELECT; + if (lane != 2) + tmp |= LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } + + /* Step 4b(ii) set latency optimization for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + } +} I think bspec states that latency optimization should be set only for Transmit lanes 0, 1, 3. Is it fine to use a group access(i.e ICL_PORT_TX_DW2_GRP) here? I think it states also that no latency optimization is needed for the clock lane. There is a separate comment added in BSPEC : "The Latency Optimization of the Clock Lane can be either left at it's default value ('h0) or programmed to the same value as the other lanes. If programmed with the same value as the other lanes, then the Group access can be used for PORT_TX_DW2 programming" Regards, Madhav ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [v5, 02/13] drm/i915/icl: DSI vswing programming sequence
On 9/6/2018 7:31 PM, Kulkarni, Vandita wrote: On 7/10/2018 3:10 PM, Madhav Chauhan wrote: This patch setup voltage swing before enabling combo PHY DDI (shared with DSI). Note that DSI voltage swing programming is for high speed data buffers. HW automatically handles the voltage swing for the low power data buffers. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 114 + 1 file changed, 114 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index a571339..dc16c1f 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,6 +27,65 @@ #include "intel_dsi.h" +static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + u32 tmp; + int lane; + + for_each_dsi_port(port, intel_dsi->ports) { + + /* Bspec: set scaling mode to 0x6 */ + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp |= SCALING_MODE_SEL(6); + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp |= SCALING_MODE_SEL(6); + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + + /* +* swing and scaling values are taken from DSI +* table under vswing programming sequence for +* combo phy ddi in BSPEC. +* program swing values +*/ + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + + /* program scaling values */ + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x18); + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + + for (lane = 0; lane <= 3; lane++) { + /* Bspec: must not use GRP register for write */ + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x18); + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } +} + static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -140,6 +199,58 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) } } I see from the bspec that except for the Loadgen Select and Latency Optimization all other DDI buffer programming can be taken from the DDI Buffer section. Can we use this function "icl_ddi_combo_vswing_program" function which is already there patch for reference: https://patchwork.freedesktop.org/patch/213515/ We can't directly use that implementation. Reasons: 1. For DSI we use AUX register as well to write which is not the case for DDI. We need to add multiple INTEL_OUTPUT_DSI checks . 2. DSI specific icl_combo_phy_ddi_buf_trans not added in intel_ddi.c which will be used while doing vswing programming 3. intel_ddi_dp_level doesn't support "level" calculation for DSI. Also in past we had similar discussion (with Jani N) to keep DSI specific entries/code in DSI encoder. Jani N whats the suggestion here?? Regards, Madhav Thanks, Vandita +static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + + /* Step C.1:clear common keeper enable bit */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(port)); + tmp &= ~COMMON_KEEPER_EN; + I915_WRITE(ICL_POR
[Intel-gfx] [PATCH 07/12] drm/i915/icl: Configure TE interrupts for DSI
This patch implements a helper function for enabling or disabling TE interrupts. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 20 drivers/gpu/drm/i915/intel_drv.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index bf7ad5e..0ae62a1 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -46,6 +46,26 @@ struct intel_encoder *gen11_dsi_find_cmd_mode_encoder(struct intel_crtc *crtc) return NULL; } +void gen11_dsi_configure_te_interrupt(struct intel_encoder *encoder, + bool enable) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(GEN8_DE_PORT_IMR); + if (enable) + tmp |= (port == PORT_A ? ICL_DSI0_TE : ICL_DSI1_TE); + else + tmp &= (port == PORT_A ? ~ICL_DSI0_TE : ~ICL_DSI1_TE); + + I915_WRITE(GEN8_DE_PORT_IMR, tmp); + POSTING_READ(GEN8_DE_PORT_IMR); + } +} + static void wait_for_dsi_hdr_credit_release(struct intel_dsi *intel_dsi, enum transcoder dsi_trans) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7dadfc1..e39f812 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1757,6 +1757,8 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv); /* icl_dsi.c */ void intel_gen11_dsi_init(struct drm_i915_private *dev_priv); struct intel_encoder *gen11_dsi_find_cmd_mode_encoder(struct intel_crtc *crtc); +void gen11_dsi_configure_te_interrupt(struct intel_encoder *encoder, + bool enable); /* intel_dsi_dcs_backlight.c */ int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/12] drm/i915/icl: Enable/disable TE interrupts
If DSI is operating in command mode, then display engine won't be receiving VBLANK interrupt instead of that Tearing Event(TE) interrupt will be received. So in this scenario, we need to enable/disable TE interrupt rather than VBLANK interrupts. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_irq.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5dadefc..a24c670 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3398,10 +3398,18 @@ static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe) static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + struct intel_encoder *encoder; unsigned long irqflags; spin_lock_irqsave(_priv->irq_lock, irqflags); - bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); + encoder = gen11_dsi_find_cmd_mode_encoder(crtc); + + if (IS_ICELAKE(dev_priv) && encoder) + gen11_dsi_configure_te_interrupt(encoder, true); + else + bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); + spin_unlock_irqrestore(_priv->irq_lock, irqflags); /* Even if there is no DMC, frame counter can get stuck when @@ -3452,10 +3460,18 @@ static void ironlake_disable_vblank(struct drm_device *dev, unsigned int pipe) static void gen8_disable_vblank(struct drm_device *dev, unsigned int pipe) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + struct intel_encoder *encoder; unsigned long irqflags; spin_lock_irqsave(_priv->irq_lock, irqflags); - bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); + encoder = gen11_dsi_find_cmd_mode_encoder(crtc); + + if (IS_ICELAKE(dev_priv) && encoder) + gen11_dsi_configure_te_interrupt(encoder, false); + else + bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); + spin_unlock_irqrestore(_priv->irq_lock, irqflags); } -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/12] drm/i915/icl: Transcoder timings for command mode
This patch calculate HOTAL and VTOTAL value to be programmed when DSI is operating in command mode as per BSPEC. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index af72b57..c93d02c 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -811,6 +811,12 @@ static void gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder, htotal /= 2; } + if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) { + htotal = hactive + 160; + //TODO: Calculate VTOTAL = ceiling( 400us / Line Time) + //Info missing from BSPEC + } + /* minimum hactive as per bspec: 256 pixels */ if (adjusted_mode->crtc_hdisplay < 256) DRM_ERROR("hactive is less then 256 pixels\n"); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/12] drm/i915/icl: Send frame to DSI panel
In DSI command mode, for sending the frame to panel DSI controller need to issue the command unlike in DSI video mode. This patch does the same. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index bd3cdde..af72b57 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -117,6 +117,23 @@ static void gen11_dsi_clear_te_interrupt(struct intel_encoder *encoder) } +static void gen11_dsi_initiate_frame_req(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + enum transcoder dsi_trans; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(DSI_CMD_FRMCTL(dsi_trans)); + tmp |= PERIODIC_FRAME_UPDATE_ENABLE; + I915_WRITE(DSI_CMD_FRMCTL(dsi_trans), tmp); + } + +} + static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -900,6 +917,9 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder) I965_PIPECONF_ACTIVE, 10)) DRM_ERROR("DSI transcoder not enabled\n"); } + + /* For command mode, send a frame to panel */ + gen11_dsi_initiate_frame_req(encoder); } static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/12] drm/i915/icl: Unmask/Clear DSI TE interrupts
While enabling DSI transcoder, TE interrupts need to be unmasked also they need to be cleared when TE interrupts are received. This patch does same by programming DSI interrupt specific registers. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_irq.c | 2 ++ drivers/gpu/drm/i915/icl_dsi.c | 34 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8ca2396..b1e836a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1897,6 +1897,8 @@ void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, DRM_ERROR("Invalid PIPE\n"); } + //TODO: Clear DSI interrupt here + drm_handle_vblank(_priv->drm, pipe); } diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 0ae62a1..bd3cdde 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -66,6 +66,7 @@ void gen11_dsi_configure_te_interrupt(struct intel_encoder *encoder, } } + static void wait_for_dsi_hdr_credit_release(struct intel_dsi *intel_dsi, enum transcoder dsi_trans) { @@ -96,6 +97,26 @@ static enum transcoder dsi_port_to_transcoder(enum port port) return TRANSCODER_DSI_1; } +static void gen11_dsi_clear_te_interrupt(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + enum port port; + enum transcoder dsi_trans; + + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(DSI_INTR_IDENT_REG(dsi_trans)); + if (tmp & TE_EVENT) { + /* TE event received, clear it */ + tmp |= TE_EVENT; + I915_WRITE(DSI_INTR_IDENT_REG(dsi_trans), tmp); + } + } + +} + static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -666,11 +687,24 @@ static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder, tmp &= ~OP_MODE_MASK; tmp |= OP_MODE(CMD_MODE_TE_GATE); tmp |= TE_SOURCE_GPIO; + } I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp); } + if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) { + + /* unmask and clear DSI TE interrupt */ + for_each_dsi_port(port, intel_dsi->ports) { + dsi_trans = dsi_port_to_transcoder(port); + tmp = I915_READ(DSI_INTR_MASK_REG(dsi_trans)); + tmp &= ~TE_EVENT; + I915_WRITE(DSI_INTR_MASK_REG(dsi_trans), tmp); + } + gen11_dsi_clear_te_interrupt(encoder); + } + /* enable port sync mode if dual link */ if (intel_dsi->dual_link) { for_each_dsi_port(port, intel_dsi->ports) { -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/12] drm/i915/icl: DSI TE interrupt handler
When DSI is operating in command mode, timing information is given by the panel using TE signal. TE signals are received as an interrupt. This patch adds the handler for TE interrupts. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_irq.c | 43 + 1 file changed, 43 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a24c670..8ca2396 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1861,6 +1861,45 @@ static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) intel_guc_to_host_event_handler(_priv->guc); } +void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, + u32 iir_value) +{ + enum pipe pipe = INVALID_PIPE; + enum port port; + enum transcoder tc; + u32 val; + + port = (iir_value & ICL_DSI0_TE) ? PORT_A : PORT_B; + tc = (port == PORT_A) ? TRANSCODER_DSI_0 : TRANSCODER_DSI_1; + + /* Check if DSI configured in command mode */ + val = I915_READ(DSI_TRANS_FUNC_CONF(tc)); + val = (val & OP_MODE_MASK) >> 28; + + if (val != CMD_MODE_TE_GATE) { + DRM_ERROR("DSI trancoder not configured in command mode\n"); + return; + } + + /* Get PIPE for handling VBLANK event */ + val = I915_READ(TRANS_DDI_FUNC_CTL(tc)); + switch (val & TRANS_DDI_EDP_INPUT_MASK) { + case TRANS_DDI_EDP_INPUT_A_ON: + pipe = PIPE_A; + break; + case TRANS_DDI_EDP_INPUT_B_ONOFF: + pipe = PIPE_B; + break; + case TRANS_DDI_EDP_INPUT_C_ONOFF: + pipe = PIPE_C; + break; + default: + DRM_ERROR("Invalid PIPE\n"); + } + + drm_handle_vblank(_priv->drm, pipe); +} + static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) { enum pipe pipe; @@ -2815,6 +2854,10 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) found = true; } + if (IS_ICELAKE(dev_priv) && + (iir & (ICL_DSI0_TE | ICL_DSI1_TE))) + gen11_dsi_te_interrupt_handler(dev_priv, iir); + if (!found) DRM_ERROR("Unexpected DE Port interrupt\n"); } -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/12] drm/i915/icl: Define DSI cmd mode registers
This patch adds definition of registers required for DSI command mode operation. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 51 + 1 file changed, 51 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6c863d8..81dc656 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10535,6 +10535,57 @@ enum skl_power_gate { #define LINK_ULPS_TYPE_LP11 (1 << 8) #define LINK_ENTER_ULPS (1 << 0) +#define _DSI_INTR_MASK_REG_0 0x6b070 +#define _DSI_INTR_MASK_REG_1 0x6b870 +#define DSI_INTR_MASK_REG(tc) _MMIO_DSI(tc, \ + _DSI_INTR_MASK_REG_0,\ + _DSI_INTR_MASK_REG_1) + +#define _DSI_INTR_IDENT_REG_0 0x6b074 +#define _DSI_INTR_IDENT_REG_1 0x6b874 +#define DSI_INTR_IDENT_REG(tc) _MMIO_DSI(tc, \ + _DSI_INTR_IDENT_REG_0,\ + _DSI_INTR_IDENT_REG_1) +#define TE_EVENT (1 << 31) +#define RX_DATA_OR_BTA_TERMINATED (1 << 30) +#define TX_DATA (1 << 29) +#define ULPS_ENTRY_DONE (1 << 28) +#define NON_TE_TRIGGER_RECEIVED (1 << 27) +#define HOST_CHKSUM_ERROR (1 << 26) +#define HOST_MULTI_ECC_ERROR (1 << 25) +#define HOST_SINGL_ECC_ERROR (1 << 24) +#define HOST_CONTENTION_DETECTED (1 << 23) +#define HOST_FALSE_CONTROL_ERROR (1 << 22) +#define HOST_TIMEOUT_ERROR(1 << 21) +#define HOST_LOW_POWER_TX_SYNC_ERROR (1 << 20) +#define HOST_ESCAPE_MODE_ENTRY_ERROR (1 << 19) +#define FRAME_UPDATE_DONE (1 << 16) +#define PROTOCOL_VIOLATION_REPORTED (1 << 15) +#define INVALID_TX_LENGTH (1 << 13) +#define INVALID_VC(1 << 12) +#define INVALID_DATA_TYPE (1 << 11) +#define PERIPHERAL_CHKSUM_ERROR (1 << 10) +#define PERIPHERAL_MULTI_ECC_ERROR(1 << 9) +#define PERIPHERAL_SINGLE_ECC_ERROR (1 << 8) +#define PERIPHERAL_CONTENTION_DETECTED(1 << 7) +#define PERIPHERAL_FALSE_CTRL_ERROR (1 << 6) +#define PERIPHERAL_TIMEOUT_ERROR (1 << 5) +#define PERIPHERAL_LP_TX_SYNC_ERROR (1 << 4) +#define PERIPHERAL_ESC_MODE_ENTRY_CMD_ERROR (1 << 3) +#define EOT_SYNC_ERROR(1 << 2) +#define SOT_SYNC_ERROR(1 << 1) +#define SOT_ERROR (1 << 0) + +#define _DSI_CMD_FRMCTL_0 0x6b034 +#define _DSI_CMD_FRMCTL_1 0x6b834 +#define DSI_CMD_FRMCTL(tc) _MMIO_DSI(tc, \ + _DSI_CMD_FRMCTL_0,\ + _DSI_CMD_FRMCTL_1) +#define FRAME_UPDATE_REQ_PRESENT (1 << 31) +#define PERIODIC_FRAME_UPDATE_ENABLE (1 << 29) +#define NULL_PACKET_ENABLE(1 << 28) +#define FRAME_IN_PROGRESS (1 << 0) + /* DSI timeout registers */ #define _DSI_HSTX_TO_0 0x6b044 #define _DSI_HSTX_TO_1 0x6b844 -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/12] drm/i915/icl: DSI transcoder config for command mode
This patch configures DSI transcoder behavior when operating in command mode. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/icl_dsi.c | 4 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 81dc656..de671f2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10447,6 +10447,7 @@ enum skl_power_gate { #define CMD_MODE_TE_GATE 0x1 #define VIDEO_MODE_SYNC_EVENT 0x2 #define VIDEO_MODE_SYNC_PULSE 0x3 +#define TE_SOURCE_GPIO(1 << 27) #define LINK_READY(1 << 20) #define PIX_FMT(x)(x << 16) #define PIX_FMT_MASK (0x3 << 16) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index a175349..b189398 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -625,6 +625,10 @@ static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder, } else { DRM_ERROR("DSI Video Mode unsupported\n"); } + } else { /* command mode */ + tmp &= ~OP_MODE_MASK; + tmp |= OP_MODE(CMD_MODE_TE_GATE); + tmp |= TE_SOURCE_GPIO; } I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/12] drm/i915/icl: Define TE interrupt related bits
This patch defines bitfields required for handling TE interrupts when DSI is operating in command mode. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index de671f2..a8e5faa 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7267,11 +7267,15 @@ enum { #define GEN8_DE_PORT_IMR _MMIO(0x4) #define GEN8_DE_PORT_IIR _MMIO(0x8) #define GEN8_DE_PORT_IER _MMIO(0xc) +#define ICL_DSI_1 (1 << 31) +#define ICL_DSI_0 (1 << 30) #define ICL_AUX_CHANNEL_E (1 << 29) #define CNL_AUX_CHANNEL_F (1 << 28) #define GEN9_AUX_CHANNEL_D(1 << 27) #define GEN9_AUX_CHANNEL_C(1 << 26) #define GEN9_AUX_CHANNEL_B(1 << 25) +#define ICL_DSI1_TE (1 << 24) +#define ICL_DSI0_TE (1 << 23) #define BXT_DE_PORT_HP_DDIC (1 << 5) #define BXT_DE_PORT_HP_DDIB (1 << 4) #define BXT_DE_PORT_HP_DDIA (1 << 3) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/12] drm/i915/icl: Config utility pin for DSI
This patch configures utility pin for DSI command mode operation as per BSPEC DSI trancoder enable sequence. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 19a3815..a175349 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -874,6 +874,21 @@ static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder) } } +static void gen11_dsi_config_utility_pin(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + u32 tmp; + + if (intel_dsi->operation_mode != INTEL_DSI_COMMAND_MODE) + return; + + tmp = I915_READ(UTIL_PIN_CTL); + tmp |= ICL_UTIL_PIN_DIRECTION; + tmp |= UTIL_PIN_ENABLE; + I915_WRITE(UTIL_PIN_CTL, tmp); +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) { @@ -892,6 +907,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, /* step 4e: setup D-PHY timings */ gen11_dsi_setup_dphy_timings(encoder); + /* step 4f: config utility pin */ + gen11_dsi_config_utility_pin(encoder); + /* step 4g: setup DSI protocol timeouts */ gen11_dsi_setup_timeouts(encoder); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 06/12] drm/i915/icl: Find encoder for DSI command mode
This patch adds a helper function to find encoder if DSI is operating in command mode. This function will be used while enabling/disabling TE interrupts for DSI. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 17 + drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index b189398..bf7ad5e 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -29,6 +29,23 @@ #include #include "intel_dsi.h" +struct intel_encoder *gen11_dsi_find_cmd_mode_encoder(struct intel_crtc *crtc) +{ + struct drm_device *dev = crtc->base.dev; + struct intel_encoder *encoder; + struct intel_dsi *intel_dsi; + + for_each_encoder_on_crtc(dev, >base, encoder) { + if (encoder->type != INTEL_OUTPUT_DSI) + continue; + intel_dsi = enc_to_intel_dsi(>base); + if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) + return encoder; + } + + return NULL; +} + static void wait_for_dsi_hdr_credit_release(struct intel_dsi *intel_dsi, enum transcoder dsi_trans) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1b12d53..7dadfc1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1756,6 +1756,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv); /* icl_dsi.c */ void intel_gen11_dsi_init(struct drm_i915_private *dev_priv); +struct intel_encoder *gen11_dsi_find_cmd_mode_encoder(struct intel_crtc *crtc); /* intel_dsi_dcs_backlight.c */ int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/12] drm/i915/icl: Define utility pin ctrl register bits
This patch defines utility pin control register bitfields for ICL platform and also re-arrange existing definition to align with guideline. Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/i915_reg.h | 22 ++ 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 77b38fe..6c863d8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4910,14 +4910,20 @@ enum { #define BLM_PCH_POLARITY (1 << 29) #define BLC_PWM_PCH_CTL2 _MMIO(0xc8254) -#define UTIL_PIN_CTL _MMIO(0x48400) -#define UTIL_PIN_ENABLE (1 << 31) - -#define UTIL_PIN_PIPE(x) ((x) << 29) -#define UTIL_PIN_PIPE_MASK (3 << 29) -#define UTIL_PIN_MODE_PWM(1 << 24) -#define UTIL_PIN_MODE_MASK (0xf << 24) -#define UTIL_PIN_POLARITY(1 << 22) +#define UTIL_PIN_CTL _MMIO(0x48400) +#define UTIL_PIN_ENABLE (1 << 31) +#define UTIL_PIN_PIPE_MASK(3 << 29) +#define UTIL_PIN_PIPE(x) ((x) << 29) +#define UTIL_PIN_MODE_MASK(0xf << 24) +#define UTIL_PIN_MODE_DATA(0 << 24) +#define UTIL_PIN_MODE_PWM (1 << 24) +#define UTIL_PIN_MODE_VBLANK (4 << 24) +#define UTIL_PIN_MODE_VSYNC (5 << 24) +#define UTIL_PIN_MODE_EYE_LEVEL (8 << 24) +#define UTIL_PIN_OP_DATA (1 << 23) +#define UTIL_PIN_POLARITY (1 << 22) +#define ICL_UTIL_PIN_DIRECTION(1 << 19) +#define ICL_UTIL_PIN_IP_DATA (1 << 16) /* BXT backlight register definition. */ #define _BXT_BLC_PWM_CTL1 0xC8250 -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/12] ICL DSI CMD MODE
MIPI DSI supports video and command mode type of operations. Command Mode refers to operation in which transactions primarily take the form of sending commands and data to a peripheral such as a display module, that incorporates a display controller. The host processor indirectly controls activity at the peripheral by sending commands, parameters and data to the display controller. This series implement DSI command mode support for ICELAKE platform. Patches are *not* tested and based on the following DSI patches published on GITHUB: https://github.com/madhavchauhan/Intel-DSI-Driver Madhav Chauhan (12): drm/i915/icl: Define utility pin ctrl register bits drm/i915/icl: Config utility pin for DSI drm/i915/icl: Define DSI cmd mode registers drm/i915/icl: DSI transcoder config for command mode drm/i915/icl: Define TE interrupt related bits drm/i915/icl: Find encoder for DSI command mode drm/i915/icl: Configure TE interrupts for DSI drm/i915/icl: Enable/disable TE interrupts drm/i915/icl: DSI TE interrupt handler drm/i915/icl: Unmask/Clear DSI TE interrupts drm/i915/icl: Send frame to DSI panel drm/i915/icl: Transcoder timings for command mode drivers/gpu/drm/i915/i915_irq.c | 65 - drivers/gpu/drm/i915/i915_reg.h | 78 ++--- drivers/gpu/drm/i915/icl_dsi.c | 119 +++ drivers/gpu/drm/i915/intel_drv.h | 3 + 4 files changed, 255 insertions(+), 10 deletions(-) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 21/23] drm/i915/icl: Add Display Stream Splitter control registers
On 7/31/2018 7:43 AM, Manasi Navare wrote: From: "Srivatsa, Anusha" Add defines for DSS_CTL registers. These registers specify the big joiner, splitter, overlap pixels and info regarding display stream compression enabled on left or right branch. v2: - Add define to conditionally check the buffer target depth (James Ausmus) Suggested-by: Madhav Chauhan Cc: Madhav Chauhan Cc: Manasi Navare Cc: Rodrigo Vivi Signed-off-by: Anusha Srivatsa --- drivers/gpu/drm/i915/i915_reg.h | 33 + 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b8e41db..0ae38b6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7792,6 +7792,39 @@ enum { #define RC_MAX_QP_SHIFT 5 #define RC_MIN_QP_SHIFT 0 +/* Display Stream Splitter Control */ +#define DSS_CTL1 _MMIO(0x67400) +#define SPLITTER_ENABLE (1 << 31) +#define JOINER_ENABLE (1 << 30) +#define DUAL_LINK_MODE_INTERLEAVE (1 << 24) +#define DUAL_LINK_MODE_FRONTBACK (0 << 24) +#define OVERLAP_PIXELS_MASK (0xf << 16) +#define OVERLAP_PIXELS(pixels)((pixels) << 16) +#define LEFT_DL_BUF_TARGET_DEPTH_MASK (0xfff << 0) +#define LEFT_DL_BUF_TARGET_DEPTH(pixels) ((pixels) << 0) +#define MAX_DL_BUFFER_TARGET_DEPTH0x5A0 Please use lower case for hex values. With this fix, Reviewed-by: Madhav Chauhan Regards, Madhav + +#define DSS_CTL2 _MMIO(0x67404) +#define LEFT_BRANCH_VDSC_ENABLE (1 << 31) +#define RIGHT_BRANCH_VDSC_ENABLE (1 << 15) +#define RIGHT_DL_BUF_TARGET_DEPTH_MASK(0xfff << 0) +#define RIGHT_DL_BUF_TARGET_DEPTH(pixels) ((pixels) << 0) + +#define _ICL_PIPE_DSS_CTL1_PB 0x78200 +#define _ICL_PIPE_DSS_CTL1_PC 0x78400 +#define ICL_PIPE_DSS_CTL1(pipe)_MMIO_PIPE((pipe) - PIPE_B, \ + _ICL_PIPE_DSS_CTL1_PB, \ + _ICL_PIPE_DSS_CTL1_PC) +#define BIG_JOINER_ENABLE (1 << 29) +#define MASTER_BIG_JOINER_ENABLE (1 << 28) +#define VGA_CENTERING_ENABLE (1 << 27) + +#define _ICL_PIPE_DSS_CTL2_PB 0x78204 +#define _ICL_PIPE_DSS_CTL2_PC 0x78404 +#define ICL_PIPE_DSS_CTL2(pipe)_MMIO_PIPE((pipe) - PIPE_B, \ + _ICL_PIPE_DSS_CTL2_PB, \ + _ICL_PIPE_DSS_CTL2_PC) + #define DSCA_RC_RANGE_PARAMETERS_1_MMIO(0x6B248) #define DSCA_RC_RANGE_PARAMETERS_1_UDW_MMIO(0x6B248 + 4) #define DSCC_RC_RANGE_PARAMETERS_1_MMIO(0x6BA48) ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v5 01/13] drm/i915/icl: Configure lane sequencing of combo phy transmitter
This patch set the loadgen select and latency optimization for aux and transmit lanes of combo phy transmitters. It will be used for MIPI DSI HS operations. v2: Rebase Signed-off-by: Madhav Chauhan --- drivers/gpu/drm/i915/icl_dsi.c | 38 ++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 13830e4..a571339 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -105,10 +105,48 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) } } +static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(>base); + enum port port; + u32 tmp; + int lane; + + /* Step 4b(i) set loadgen select for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp &= ~LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + for (lane = 0; lane <= 3; lane++) { + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp &= ~LOADGEN_SELECT; + if (lane != 2) + tmp |= LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } + + /* Step 4b(ii) set latency optimization for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ gen11_dsi_power_up_lanes(encoder); + + /* step 4b: configure lane sequencing of the Combo-PHY transmitters */ + gen11_dsi_config_phy_lanes_sequence(encoder); } static void __attribute__((unused)) -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx